Jump to content

Tom Atom

Members
  • Content Count

    594
  • Joined

  • Last visited

  • Days Won

    6

Reputation Activity

  1. Like
    Tom Atom got a reaction from enderandpeter in Sprite is not rendered correctly (extra lines on the edge)   
    @pingu found the problem... it is related to Phaser texture creating. See method createTextureFromSource() (https://github.com/photonstorm/phaser/blob/master/src/renderer/webgl/WebGLRenderer.js#L1144)
    It sets wrap mode to CLAMP_TO_EDGE by default, which would be OK and no bleeding would be shown. But... if texture dimensions are power of two (which is your case), then it changes wrap mode to REPEAT. You can encounter imprecisions in GPU calculations, so your texture is drawn and small part is repeated - it is that bleeding. Your current sprite scale is 0.406, if you set it to 0.5, then calculations are little different and bleeding is not shown. If you animated scale, then bleeding would probably blink - sometimes shown, sometimes not.
    So, solutions are:
     - add extra padding around your shape as @bossikkk suggested. If you want to preserve texture size 512x512, then draw your shape 510x510 and leave 1px empty on all sides,
     - simply change dimensions of your texture to not be power of 2 - like add 1 empty line and column to make it 513x513 texture (this is OK for development, but I do not like this solution - not sure, but I have somewhere back in my mind, that some GPUs are adding extra space for non POT textures to force them to nearest POT - in your case it would be 1024x1024 with lot of memory eaten.)
     
  2. Thanks
    Tom Atom got a reaction from Diztraido in rotate sprite along z-axis   
    Tween with yoyo should do all the job for you! Let's say, you have coin atlas and two sprites in it: "front" and "back". Then you can listen to onComplete and change frame in it:
    var sprite = game.add.sprite(0, 0, 'coin', 'front'); sprite.position.set(100,100); sprite.anchor.set(0.5, 0); var tween = game.add.tween(sprite.scale).to( { x: -1 }, 1000, "Linear", true, 0, -1, true); tween.onLoop.add(function() { sprite.frameName = (sprite.frameName === 'front') ? 'back' : 'front'; }, this);  
  3. Like
    Tom Atom got a reaction from Balamurugan in TypeScript vs JavaScript?   
    Hi, it is always good to know pure JS, but with TS you get type checking, which prevents errors and increases productivity. TS is not separate language, but it is superset of JS. If you have Java (or C#) experience, then OOP is similar in it (as well as in ES6, but there it is without type checking). If you are on Windows, there is also very luxury IDE - Microsoft Visual Studio Community 2015, which is free for individual developers. It has great intellisense support.
    In my book I made small comparsion of TS / ES6 / JS:
     Just for example, consider this simple TypeScript class:


    class MyClass { private _position: Phaser.Point = new Phaser.Point(); public constructor(position: Phaser.Point) { this._position.copyFrom(position); } public moveBy(x: number, y: number): void { this._position.add(x, y); } }  It is compiled into this JavaScript code:


    var MyClass = (function () { function MyClass(position) { this._position = new Phaser.Point(); this._position.copyFrom(position); } MyClass.prototype.moveBy = function (x, y) { this._position.add(x, y); }; return MyClass; } ());  Or into this ES6 code:


     
    class MyClass { constructor(position) { this._position = new Phaser.Point(); this._position.copyFrom(position); } moveBy(x, y) { this._position.add(x, y); } }  
  4. Like
    Tom Atom reacted to Bikas in Postmortem: Adventure Drivers   
    Hello! 
    Adventure Drivers is my second HTML5 game after Medieval Defense Z. 
    My main work went into engine, tools, code and levels and the art was done by Gudo1.
    I can share some of the details of what went into making this game. I also wrote a postmortem about my previous game Medieval Defense Z which you can check it here: http://www.html5gamedevs.com/topic/28332-postmortem-medieval-defense-z/

    About Adventure Drivers
        - 60fps 2D racing game.
        - Written in Haxe.
        - Used Pixi v4, Howler and Nape Physics Engine.
        - Over 50k lines of code.
    Visual Assets
    All the visual assets were in flash SWF files and i needed to get sprites into spritesheets. Exporting hundreds of assets to PNG's by hand was too time consuming, so i wrote a command line tool in Adobe Air which takes assets from SWF files, applies transformations such as scale or rotation and exports all movie clips as images to a single graphics folder. The tool also creates XML file which has the animation data and anchor values for every image. Then i used TexturePacker command line tool to pack everything into a single spritesheet. For bitmap fonts i used Littera and packed font PNG's into the main spritesheet. After loading .fnt file i had loop over all chars and add x and y offsets based on the location of the font texture in the main spritesheet.
     
    Audio Assets
    Audacity and ffmpeg worked really well. Audacity for quick sound editing and ffmpeg for converting between various formats. Like in Medieval Defense Z i chose M4A for iOS and OGG for android and PC.
    Batch script to convert all WAV files to OGG (64 bit rate):
        for %%i in (*.wav) do (
            ffmpeg -y -i "%%i" -codec:a libvorbis -qscale:a 4 -ac 1 "%%~ni.ogg"
        )
    Batch script to convert all WAV files to M4a (64 bit rate):
        for %%i in (*.wav) do (
            fdkaac -b 64k -o "%%~ni.m4a" "%%i"
        )
        
    Editing in Audacity: Fade In/Out, Amplify, Normalize, Change Speed and Equalization were the most useful tools/functions.

    Level Editor
    Used my own editor written in Action Script 3 which is basically a general purpose non-tile based 2D object placer with prefabs, grouping, undo/redo, etc. In order to create levels faster i also used Perlin Noise algorithm for terrain generation and procedurally placed decorations. After generating the level i still had to cleanup decorations, adjust terrain, add caves, place obstacles and items. 
    For saving to files i wrote a simple NodeJS server in Haxe and used POST to send and receive data which then is saved to disk.

    Physics
    Nape Physics Engine was great until i needed to run my game on mobile... Dynamic polygons became a real drag on CPU and i needed to simplify geometry in order to have any gains in terms of performance. Weirdly enough the terrain size was not that influential as much as adding 1 more car.
    Also there was this weird issue with inlined code. Inlined code ran SLOWER in chrome than non-inlined... It was especially noticeable then physics engine caused large lag spikes. I noticed the same problem in Medieval Defense Z and large functions. I could not find anything online, so i disabled inline and split some of the large functions into smaller ones.
    Frameworks and Rendering
    At first i used Phaser framework but the performance issues were never ending. The transform updates were a major bottleneck so i had to pretty much hack around and disable portions of the framework until i was just using basic Pixi sprites and groups. Thankfully i didn't use much of any other stuff from Phaser (no camera, no physics, etc.) which made it easier to transition to Pixi v4.
    One of the biggest issues was the terrain drawing. Phaser does not have any equivalent for large mesh rendering with exception of using tiles and masks which are very slow. So i needed to write a complicated set of functions to cut the terrain into thousands of rectangles and add them to the stage during gameplay. After converting to Pixi v4 i simply used pixi Mesh object and EarCut library for cutting polygon into a triangles. This was about 10x simpler to implement and it improved the performance. For Canvas i still needed to hack around and use pattern fill in Phaser and in Pixi.

    Sounds
    Different js sound libraries had a major difference in performance. Phaser sound library was quite good, however it did not have .rate property which i needed for the car engine sound, so i used 2 different engine sound loops with different rates and changed volume based on driving speed. I tried Pixi sound library but it had incredibly poor performance on mobile and was basically unusable even though this library had really nice features. Ended up with Howler which has the ability to set .rate and the performance was really good. Also Pixi v4 + Howler did not crash my old android device which was nice.  
    Bots
    The AI code can be broken down in 3 steps: data gathering, decisions and actions. 
    In data gathering step the bot collects and processes information. For example: how long back and front wheels are on the ground or in air, how the rotation changed in the past second, average speed, etc.
    Decisions are made in timed intervals and they depend on the "personality" of the car which i describe in 4 values: "ability", "aggression", "craziness" and "panic". The bot "decides" only if all conditions are satisfied. The decisions include: air rotation, ground rotation, random_rotation, random_jump, flip, wheelie, nitro, jump_over, jump_pickup and use_ability. For some of the decisions the bot also has to check nearby items and other cars.
    The last step is "action" which simply means that the bot performs a function for a limited time unless some unexpected thing occurs. So the bot will stop the air flip action if any of the wheels interact with the ground.

    Backgrounds
    I wanted to do something interesting with the backgrounds so i decided to try pseudo 2.5D background scrolling stuff to see how it goes. The waves looked really nice so we went with it.
    If you want to do something similar, the function you are looking for is this:
        public static applyProjectionWithCamera(to_projection:Point, eye:Point3, camera:Point3, point:Point3):Point{
            to_projection.x = (eye.z * (point.x + camera.x - eye.x)) / (eye.z + (point.z + camera.z)) + eye.x;
            to_projection.y = (eye.z * (point.y + camera.y - eye.y)) / (eye.z + (point.z + camera.z)) + eye.y;
            return to_projection;
        }
        
    Eye has fixed x = 0, y = 0 and z = 800 values. Camera x, y, z values are tied to the game camera which is tied to the player position. Each sprite has 3 3D points (triangle) associated with it and these points are placed somewhere in the background with high z value (distance), varying x value (horizontal) and high y value (vertical) for the clouds. Then i calculate 2D points (projections) for every 3D point. And set x, y, width and height for the sprite based on the 3 projected points.

    The Game
    For now we are doing a limited release on few websites and the game should playable very soon.
    If you found this post useful let me know.  

  5. Like
    Tom Atom got a reaction from vasilii in [Phaser] Dots & Boxes   
    Dots & Boxes is web version of classic pencil and paper game for two players (https://en.wikipedia.org/wiki/Dots_and_Boxes). You can play either against your friend or against computer AI. Rules are simple: connect dots with lines to form boxes. Player closing up box gets extra move. Game was created for Coolmath Games.
       
    You can play it here.
  6. Like
    Tom Atom got a reaction from Umz in [Phaser] Dots & Boxes   
    Dots & Boxes is web version of classic pencil and paper game for two players (https://en.wikipedia.org/wiki/Dots_and_Boxes). You can play either against your friend or against computer AI. Rules are simple: connect dots with lines to form boxes. Player closing up box gets extra move. Game was created for Coolmath Games.
       
    You can play it here.
  7. Like
    Tom Atom got a reaction from webdva in [WIP] Strange Platformer Game   
    setting preserveDrawingBuffer to true works, but it has impact on performance on some devices - see this thread:
    It looks like flickering is related to specifis GPUs. So, you can make test for GPU in your game and set preserveDrawingBuffer accordingly. This is snippet from one of our games:
    public static getRenderer(): number { let badGPUList = [ /.*Mali.400.*/i, /.*Mali.450.*/i, /.*Mediatek.MT6582.*/i ]; // from:https://gist.github.com/cvan/042b2448fcecefafbb6a91469484cdf8 let canvas = document.createElement('canvas'); let gl: WebGLRenderingContext; let debugInfo; let renderer: string; try { gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); } catch (e) { return Phaser.AUTO; } if (!gl) { return Phaser.AUTO; } debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); if (!debugInfo) { return Phaser.AUTO; } renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); console.log("renderer: " + renderer); for (let i = 0; i < badGPUList.length; i++) { let badGPURegEx = badGPUList[i]; if (badGPURegEx.test(renderer)) { console.log("In bad GPUs list => render to CANVAS"); return Phaser.CANVAS; } } return Phaser.AUTO; }  
  8. Like
    Tom Atom got a reaction from damager in "Shaking" a sprite   
    Hi, you can create your own tweening function. For shaking you can use "wiggle" function:
    function wiggle(aProgress: number, aPeriod1: number, aPeriod2: number): number { var current1: number = aProgress * Math.PI * 2 * aPeriod1; var current2: number = aProgress * (Math.PI * 2 * aPeriod2 + Math.PI / 2); return Math.sin(current1) * Math.cos(current2); } and call it from your game like this:
    tweenX.to({ x: this.position.x + aRadius}, aTime, function (k) { return Easing.wiggle(k, aXPeriod1, aXPeriod2); }, true, 0, -1); ... change arguments aXPeriod1 and aXPeriod2 to make different shakes. aRadius gives number of pixels from current x position.
    To shake in both X and Y directions add another tween for Y with different periods.
    If set for x and y with different periods it in fact does nice sin/cos spline movement in range of aRadius (can be different for x and y tween). If period is high and time short, then it makes fast shake. Nice thing is, that this shake looks more natural than just random offsetting. If time is long then you can have for example randomly moving dust particles. See http://sbc.littlecolor.com/woodventure/ - branches are using it, sunrays are using it and dust particles are too using it... even hedgehog's muzzle is using it :-)
  9. Like
    Tom Atom got a reaction from khleug35 in How to make the enemy auto change direction face to player??   
    Your solution is OK, but you should generalize it like this:
    if (player.x - enemy.x > 0) { enemy.scale.x = 1; } else { enemy.scale.x = -1; } ... so you are not dependent on fixed (340) position of enemy.
  10. Like
    Tom Atom got a reaction from pingu in How to correctly show load progress in Facebook instant games?   
    @pingu it is ok in this case, because that part of update is called only once. Why not call it in the end of create()? Because there still may be music/sound decoding process ongoing. During update you are regularly checking if audio is ready and then, before you change state to Manu/Play or whatever "real" game state, you start FB too. So, when real game is entered, everything is ready.
    (Of course, there is possibility to do it in create and set some flag. Then in update check if sounds are ready and FB game started too - this will run in parallel instead one after each other as in my case).
     
  11. Like
    Tom Atom got a reaction from pingu in How to correctly show load progress in Facebook instant games?   
    You have to send loading progress to FB from your game - create & use loadUpdate(). Do not set it to 100 in preload(). In preload() you only prepare list of assets for loading - it is not actual loading.  Actual loading is started by Phaser when preload() exits.
    loadUpdate() { if (App.Global.FBINSTANT) { console.log("FB setLoadingProgress called " + this.load.progress); FBInstant.setLoadingProgress(this.load.progress); } }  
  12. Thanks
    Tom Atom got a reaction from Tommy_ in problem with space shooter lab example   
    Try this:
    if (cursors.up.isDown) { //this.physics.velocityFromRotation(ship.rotation, 600, ship.body.acceleration); ship.setVelocity(Math.cos(ship.rotation) * 600, Math.sin(ship.rotation) * 600); // 1 } else { ship.setAcceleration(0); ship.setVelocity(0,0); // 2 } In physics, you use acceleration to calculate new velocity and velocity to get new position.
    If you are driving car and accelerating for some time, your velocity increases. When you yake the foot out of the gas, your acceleration is 0, it does not increase velocity and your velocity is constant (unless there is inplemented something like friction or drag, which will slow you down).
     What you need is immediate change in velocity - it is commented as // 1.
     You can also add line // 2  to immediately stop ship if not holding up key... but it looks ugly (it is like you not only put foot out of gas, but stomped on break in the same time)
    Alternatively,  you can change original line to this:
    this.physics.velocityFromRotation(ship.rotation, 600, ship.body.velocity);  
     
  13. Like
    Tom Atom got a reaction from vornay in possible to do long running algorithms?   
    No, there is no such time - your game is running in single thread and you are in risk, that browser will say your game is not responsive. If you do not want to split your long running task into smaller steps, then you have to use Web Workers as @stupot suggested - it will start separate thread. Look at here: https://www.w3schools.com/htmL/html5_webworkers.asp Unfortunatelly, Web Workers are not supported in old browsers (not a big problem), you have to have its task in separate file and you have to take care of communication between your game and Worker - postMessage / onmessage.
  14. Like
    Tom Atom got a reaction from vornay in possible to do long running algorithms?   
    I was just solving this recently - AI thinking / computer generating in 2 games.
     for computer generating I had long time running loop. I changed it, that I record some variables, that allow me to re-enter method and continue where it ended last time. Then in my update() method I am calling it as long as it is generating. Something like bellow. Every frame I do as many steps as time "lastDelta * 0.9" allows me. Making only one step per frame would be bad - if you needed 10000 steps then it would take 166 seconds with 60 FPS: private _computerIsGenerating: boolean; // ------------------------------------------------------------------------- public update(): void { if (this._computerIsGenerating) { if (this.generate()) { this._computerIsGenerating = false; } } } // ------------------------------------------------------------------------- private generate(): boolean { let enterTime = this.time.time; let lastDelta = this.time.elapsed; do { // step generator let ready = this._generator.generateStep(); // found new puzzle if (ready) { return true; } } while (Date.now() - enterTime < lastDelta * 0.9); return false; } for AI thinking in another game, AI was doing lot of different things like board analysis, looking for some possible moves, etc. in one big loop. I broke it into states and whenever state is changed, I return and next frame I continue again with last state.
  15. Like
    Tom Atom got a reaction from turnA in Question about asset loading   
    Hi, you can load assets outside preload method. Look at this example: http://labs.phaser.io/edit.html?src=src\loader\loader%20events\start%20loader%20manually.js
     
     
  16. Like
    Tom Atom got a reaction from fazz in Question about asset loading   
    Hi, you can load assets outside preload method. Look at this example: http://labs.phaser.io/edit.html?src=src\loader\loader%20events\start%20loader%20manually.js
     
     
  17. Like
    Tom Atom got a reaction from pingu in Sprite is not rendered correctly (extra lines on the edge)   
    @pingu found the problem... it is related to Phaser texture creating. See method createTextureFromSource() (https://github.com/photonstorm/phaser/blob/master/src/renderer/webgl/WebGLRenderer.js#L1144)
    It sets wrap mode to CLAMP_TO_EDGE by default, which would be OK and no bleeding would be shown. But... if texture dimensions are power of two (which is your case), then it changes wrap mode to REPEAT. You can encounter imprecisions in GPU calculations, so your texture is drawn and small part is repeated - it is that bleeding. Your current sprite scale is 0.406, if you set it to 0.5, then calculations are little different and bleeding is not shown. If you animated scale, then bleeding would probably blink - sometimes shown, sometimes not.
    So, solutions are:
     - add extra padding around your shape as @bossikkk suggested. If you want to preserve texture size 512x512, then draw your shape 510x510 and leave 1px empty on all sides,
     - simply change dimensions of your texture to not be power of 2 - like add 1 empty line and column to make it 513x513 texture (this is OK for development, but I do not like this solution - not sure, but I have somewhere back in my mind, that some GPUs are adding extra space for non POT textures to force them to nearest POT - in your case it would be 1024x1024 with lot of memory eaten.)
     
  18. Like
    Tom Atom got a reaction from NoxBrutalis in Sprite is not rendered correctly (extra lines on the edge)   
    @pingu found the problem... it is related to Phaser texture creating. See method createTextureFromSource() (https://github.com/photonstorm/phaser/blob/master/src/renderer/webgl/WebGLRenderer.js#L1144)
    It sets wrap mode to CLAMP_TO_EDGE by default, which would be OK and no bleeding would be shown. But... if texture dimensions are power of two (which is your case), then it changes wrap mode to REPEAT. You can encounter imprecisions in GPU calculations, so your texture is drawn and small part is repeated - it is that bleeding. Your current sprite scale is 0.406, if you set it to 0.5, then calculations are little different and bleeding is not shown. If you animated scale, then bleeding would probably blink - sometimes shown, sometimes not.
    So, solutions are:
     - add extra padding around your shape as @bossikkk suggested. If you want to preserve texture size 512x512, then draw your shape 510x510 and leave 1px empty on all sides,
     - simply change dimensions of your texture to not be power of 2 - like add 1 empty line and column to make it 513x513 texture (this is OK for development, but I do not like this solution - not sure, but I have somewhere back in my mind, that some GPUs are adding extra space for non POT textures to force them to nearest POT - in your case it would be 1024x1024 with lot of memory eaten.)
     
  19. Like
    Tom Atom got a reaction from BdR in Loading files with pack attribute in scene settings config   
    Hi,
     I am using Typescript and this works for me:
    export class Preloader extends SceneBase { // ------------------------------------------------------------------------- public constructor() { // list of files to load as scene payload let files = []; // general config files.push({ type: "json", key: "Config", url: "assets/config.json" }); // sponsor specific config if exists if (Sponsor.isFeatureOn("hasConfig")) { let sponsorConfigUrl = `assets/sponsor/config_${Sponsor.features().name}.json`; files.push({ type: "json", key: "SponsorConfig", url: sponsorConfigUrl }); } // preload assets - like loading bar, etc. super({ key: "Preloader", pack: { files: files } }); } : : : I am loading game configs during constructor and I plan to load loading bar graphics too.
    I think, your problem is, you defined pack, but are not passing it to super class constructor - you are passing only "key" for scene name. See my super call in the end.
  20. Like
    Tom Atom reacted to zelcard in [Phaser] Underworld Chaos   
    Underworld Chaos is a level-based retro platformer-shooter which graphics brings out the best of 16-bit color pallete for the ultimate old-school experience.
    Currently there are over 40 levels, 20 types of enemies and over 5 different pickups available in classic mode as well as endless mode for those who are chasing after a highscore.
    LINK TO PLAY:
    https://zelcard.itch.io/underworld-chaos
     
     


  21. Thanks
    Tom Atom got a reaction from Balamurugan in Tween sprite with multiple text   
    You will never handle this with single game object. You have to build your own complex game object with other game objects.
    Split it into atomic objects that are present in Phaser. Then build up. For example, Phaser has Sprite and BitmapText - these are atomic for you. Create new class extending Phaser Container, put Sprite and BitmapText into it and you have new game object element "Sprite with text" ... so you can, for example, make: "* 3500"
    Then create buttons and any other elements you need and finally create WinDialog (again extending Phaser Container) and compose it from your basic elements.
    You can then tween whole dialog (like pop) or tween any individual elements.
    BTW, dialog like this is lot of work. Do not expect single function or game object to do all the work for you...On the other hand, if you make your elements good, then you can reuse it for other dialogs (and even outside of dialogs) in game - like "Sprite with text" in game HUD
     
  22. Like
    Tom Atom reacted to BdR in Mario Bros and Highway LCD game simulators   
    Cross post  I've just updated the lcdgame.js library, see github page: https://github.com/BdR76/lcdgame.js
    See main page with all games here: http://bdrgames.nl/lcdgames/
    Mario Bros and Highway are playable on pc and laptop, tablet/mobile support not yet available unfortunately. works in most browsers now, including tablet and mobile.

    edit: Sea Ranger is now also playable

    edit2: Donkey Kong II and Tom's Adventure have recently been added as playable games

    edit3: Jungle Kong and Eagle n Chicken are now also playable

    http://www.bdrgames.nl/lcdgames/games/junglekong/
    http://bdrgames.nl/lcdgames/games/donkeykong2/
    http://bdrgames.nl/lcdgames/games/tomsadventure/
    http://www.bdrgames.nl/lcdgames/games/highway/
    http://bdrgames.nl/lcdgames/games/mariobros/
    http://www.bdrgames.nl/lcdgames/games/searanger/
    http://www.bdrgames.nl/lcdgames/games/eaglenchicken/
     
     
  23. Like
    Tom Atom got a reaction from Umz in [Phaser] Soccer Champ   
    Hi, Soccer Champ is skill based one-button game with dogs playing cards ... football! Just click mouse when ball is on crosshair and try to get as high score as possible in limited time.
    You can play it here: https://play.famobi.com/soccer-champ-2018

  24. Like
    Tom Atom reacted to Journey Kim in Samsara - Stones of Eternity   
    I've released my game for HTML5 using Kotlin and Phaser 2! Samsara - Stones of Eternity is brand-new, super addictive puzzle game.
    Play Samsara - Stones of Eternity
    I started this project about three years ago on iOS using Swift and SpriteKit. This year, I've ported to Android using Kotlin and libGDX. As Kotlin is a mother of Swift, works were not too hard. Last month, I tried publishing for HTML5, but libGDX doesn't support Kotlin for HTML5! After some struggling, I found Kotlin can cross-pile to javascript. So I decided using Phaser, of course. Only one problem was how I could bridge Kotlin and Phaser.
    Thanks to hiperbou, developer of phaser-kotlin, I easily port my game HTML5.
    You can play three unique modes with three themes. For 3x3 games, you can use your keyboard(U, I, O, J, K, L, M, comma, period) or numeric keypad, also. 'X' key and enter key are used for cancel and confirm for pop up menu.
     
     
     

  25. Like
    Tom Atom reacted to enriqueto in [Phaser] Soccer Snakes   
    Its game play is original. It uses p2.js for physics and the excellent spriter library for the bones animations. An iteration with power-ups and a tournament structure should follow.

    Hopefully it performs well. I guess it will because it has good ingredients: snakes + football + occasional explosions.
    Play it here.
     
     
×
×
  • Create New...