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 Kacper Pietrzak in How to create a sprite with two colliders, where only one triggers callback but doesn't trigger colliision.   
    Hi, every P2 Shape has property "sensor": https://github.com/schteppe/p2.js/blob/6c012bf2f5246881aef004e7050f1fb5f3e51392/src/shapes/Shape.js#L136
    Here is also sensor demo: http://schteppe.github.io/p2.js/examples/canvas/sensors.html
  2. Like
    Tom Atom got a reaction from ForgeableSum in Questions about embedding sounds/music in your game   
    Hi, I had to do this in one of our games. Reason was, that there was bug in Chrome in past, when decoding of audio files took ages. So, we loaded only initial menu music in preloader state and the in create() method we started loading of other music tracks for levels:
    // start loading in game music var musicLoader = new MusicManager(this.game); musicLoader.loadMusic(); Music Manager class looked like this - it creates its own instance of Phaser.Loader:
    module Shards { export class MusicManager { private _game: Phaser.Game; private _loader: Phaser.Loader; private _musicToPlay: number; // ------------------------------------------------------------------------- public constructor(game: Phaser.Game) { this._game = game; this._loader = new Phaser.Loader(game); this._musicToPlay = -1; } // ------------------------------------------------------------------------- public loadMusic(): void { // load music var path = "assets/"; for (var i = 0; i < Global.MAX_MUSIC; i++) { var music = "Music" + i; console.log("loading music ..." + music); /* if (this.game.device.ie && this.game.device.ieVersion <= 10) { this._loader.audio(music, [path + music + ".mp3"]); } else */ { this._loader.audio(music, [path + music + ".ogg", path + music + ".m4a"]); } } this._loader.onFileComplete.add(this.onFileComplete, this); this._loader.start(); } // ------------------------------------------------------------------------- public onFileComplete(progress: number, cacheKey: string, success: boolean, totalLoaded: number, totalFiles: number): void { //console.log("file loaded " + cacheKey + " adding to audio"); var music = this._game.add.audio(cacheKey); Utils.AudioUtils.addMusic(cacheKey, music); } // ------------------------------------------------------------------------- public getMusic(): string { var index = this._musicToPlay; if (index === -1) { index = this._game.rnd.integerInRange(0, Global.MAX_MUSIC - 1); this._musicToPlay = index; } do { var musicName = "Music" + index; console.log("request to play music ..." + musicName); if (this._game.cache.getSound(musicName) && this._game.cache.isSoundDecoded(musicName)) { // index for next music this._musicToPlay = (index + 1) % Global.MAX_MUSIC; console.log("returning music " + musicName); return musicName; } index = (index + 1) % Global.MAX_MUSIC; } while (index !== this._musicToPlay); return null; } } }  It loads music files while game is already running. getMusic() method is trying to play them one after another. But it also checks if next music is already ready (loaded and decoded). If not, it returns next, that is already prepared.
     Word of warning - if your music files have 75MB, it will have much more after decoding - it is the same as decoding .jpg into texture.
     For audiosprites: I also use tool mentioned by @Zygomatic and I am using export from it directly in game. One problem is, that IE cannot play one sound multiple times (even if you set allowMultiple to true) - as I found, it relates to whole audiosprite file, so playing "soundA" interrupts playing "soundB". In the end, I had to make separate assets for IE and others. Assets for IE are per file, while aseets for others are audiosprites (both .ogg and .mp4). Correct assets are loaded in preloader. While for IE I do not use audiosprite, I still use export from audiosprites tool to at least read sound names from it (so I do not have to mange any extra list in code).
     
    EDIT: one more thing - I think, that music using audio tag (not WebAudio) can be easily streamed. Others may know more about it. Look here: http://stackoverflow.com/questions/24221591/streaming-mp3-instead-of-downloading-it-with-html5-audio-tag
     
  3. Like
    Tom Atom got a reaction from Befive.Info in Questions about embedding sounds/music in your game   
    Hi, I had to do this in one of our games. Reason was, that there was bug in Chrome in past, when decoding of audio files took ages. So, we loaded only initial menu music in preloader state and the in create() method we started loading of other music tracks for levels:
    // start loading in game music var musicLoader = new MusicManager(this.game); musicLoader.loadMusic(); Music Manager class looked like this - it creates its own instance of Phaser.Loader:
    module Shards { export class MusicManager { private _game: Phaser.Game; private _loader: Phaser.Loader; private _musicToPlay: number; // ------------------------------------------------------------------------- public constructor(game: Phaser.Game) { this._game = game; this._loader = new Phaser.Loader(game); this._musicToPlay = -1; } // ------------------------------------------------------------------------- public loadMusic(): void { // load music var path = "assets/"; for (var i = 0; i < Global.MAX_MUSIC; i++) { var music = "Music" + i; console.log("loading music ..." + music); /* if (this.game.device.ie && this.game.device.ieVersion <= 10) { this._loader.audio(music, [path + music + ".mp3"]); } else */ { this._loader.audio(music, [path + music + ".ogg", path + music + ".m4a"]); } } this._loader.onFileComplete.add(this.onFileComplete, this); this._loader.start(); } // ------------------------------------------------------------------------- public onFileComplete(progress: number, cacheKey: string, success: boolean, totalLoaded: number, totalFiles: number): void { //console.log("file loaded " + cacheKey + " adding to audio"); var music = this._game.add.audio(cacheKey); Utils.AudioUtils.addMusic(cacheKey, music); } // ------------------------------------------------------------------------- public getMusic(): string { var index = this._musicToPlay; if (index === -1) { index = this._game.rnd.integerInRange(0, Global.MAX_MUSIC - 1); this._musicToPlay = index; } do { var musicName = "Music" + index; console.log("request to play music ..." + musicName); if (this._game.cache.getSound(musicName) && this._game.cache.isSoundDecoded(musicName)) { // index for next music this._musicToPlay = (index + 1) % Global.MAX_MUSIC; console.log("returning music " + musicName); return musicName; } index = (index + 1) % Global.MAX_MUSIC; } while (index !== this._musicToPlay); return null; } } }  It loads music files while game is already running. getMusic() method is trying to play them one after another. But it also checks if next music is already ready (loaded and decoded). If not, it returns next, that is already prepared.
     Word of warning - if your music files have 75MB, it will have much more after decoding - it is the same as decoding .jpg into texture.
     For audiosprites: I also use tool mentioned by @Zygomatic and I am using export from it directly in game. One problem is, that IE cannot play one sound multiple times (even if you set allowMultiple to true) - as I found, it relates to whole audiosprite file, so playing "soundA" interrupts playing "soundB". In the end, I had to make separate assets for IE and others. Assets for IE are per file, while aseets for others are audiosprites (both .ogg and .mp4). Correct assets are loaded in preloader. While for IE I do not use audiosprite, I still use export from audiosprites tool to at least read sound names from it (so I do not have to mange any extra list in code).
     
    EDIT: one more thing - I think, that music using audio tag (not WebAudio) can be easily streamed. Others may know more about it. Look here: http://stackoverflow.com/questions/24221591/streaming-mp3-instead-of-downloading-it-with-html5-audio-tag
     
  4. Like
    Tom Atom got a reaction from mattstyles in Learnignto use Phaser   
    If you have node.js installed, you can use "http-server" (https://www.npmjs.com/package/http-server)
     - to install it, write: npm install http-server -g
     - to run it, write: http-server
     Nothing more is needed.
     
  5. Like
    Tom Atom got a reaction from Varan in fasten the button on the stage   
    Use fixedToCamera property to fix it and cameraOffset to set its position. Look at this example: http://phaser.io/examples/v2/camera/fixed-to-camera
     
  6. Like
    Tom Atom reacted to ForgeableSum in Strike Tactics: A futuristic RTS made with Phaser.io   
    Nope, I only need to create 1 BMD for all textures and draw to it once when a user selects a different texture than the one already being used.
    1. A Single BMD for ALL textures: when a new texture is clicked, I don't create a new BMD, that would be wasteful. Clearing and redrawing the same BMD I used on the previous texture is far more efficient. You'll run into a memory bottleneck if you continually create new BMDs, instead clear and redraw the same BMD for every texture, whenever you need it. One BMD to rule them all!
    2. Draw to the BMD only once: I think you may have missed something from my post above. There is no need to redraw the BMD for every new stroke. Once you've created that overlay, and anchored it in the exact center, all you need is to calculate the correct relative position when it is drawn to a render texture. For example:
    Suppose my map size is 100 x 100 and 10 x 10 pixels for each tile. The user clicks to place a texture at (45,0). This intersects two tiles: [tile #4 on X and #1 on Y] and [tile #5 on X and #1 on Y]. Both tile #4 and #5 are converted into render textures and the base texture is drawn on top of each. A BMD is then drawn to create the overlay, which is anchored at (.5,.5). The overlay is drawn on top of both render textures, but in different positions:
    Tile #4 is at 40,0 and Tile #5 is at 50,0 (tile anchors are 0,0)
    Therefore, when the BMD is rendered to the render texture (tile #4), it is rendered at:
    X: (45 - 40) = 5
    Y: (0 - 0) = 0
    So, (5,0), and this is using the simple formula (to calculate the point the user clicks relative to the tile instead of the game world).
    At tile #5, it is rendered at:
    X: (45 - 50) = -5
    Y: (0 - 0) = 0
    (-5,0). Ultimately, we've drawn to the BMD only once and rendered it to 2 different render textures.
      
  7. Like
    Tom Atom reacted to BdR in [phaser] Snake Slider, puzzle game now in JS   
    I've finished porting my Snake Slider puzzle game using Phaser.
    >> Snake Slider playable demo <<
    It's a unique sliding puzzle game. The goal is to move the green snake to the exit. You can slide any snake by dragging them by their head or tail. Use as few moves as possible to earn all three coins. There also are apples and mushrooms that will make the snakes longer or shorter, blocks to push around and locks to unlock. The game also features hand-drawn graphics and multi-language support.
    It's based on an older iPhone/Android game, this is the JavaScript version which is completely re-written. It's powered by Phaser and it's slightly improved compared to the older version; it has an animated tutorial hand, a visible cursor, sound effect when moving, and overall more animations (menus, buttons etc).
    Let me know what you think. Can you can solve all levels? 


  8. Like
    Tom Atom reacted to ForgeableSum in Strike Tactics: A futuristic RTS made with Phaser.io   
    Official Trailer: 
     
    Learn more:
    http://striketactics.net/about
     
    Official strike tactics website.
  9. Like
    Tom Atom got a reaction from CharlesCraft50 in How to use Spriter in Phaser   
    Just change this line:
    this._item.position.set(spriter.x + transformed.x, spriter.y + transformed.y); to this:
    this._item.position.set(spriter.x + transformed.x * 0.14, spriter.y + transformed.y * 0.14);  
    Item will still have its original size, as it is not part of the scaled group. If you want to scale it too, then write this in create() method:
    this._item.scale.set(0.14);  
    Why this works: transformed.x and y is point in local space of animation (because animation is Phaser.Group and it is attached to scene graph / display list) - it has its 0,0 origin, rotation, scale. Whole this space is put somewhere int the wolrd - at 420,400 in example. Your item object (book image) is not in animation space, but in world space. So, you have move transformed.x and y into world space and then set your item position to it. Simply, it would be transformed.x + _spriterGroup.x and transformed.y + _spriterGroup.y - this would be enough if there was no scale.
     In you case, you use scale 0.14. It means, that point 100,100 relative to animation origin is 100 * 0.14, 100 * 0.14 in world space (... of course + whole animation position).
     The same goes for rotation (which can be seen in example).
     Another approach would be to make item part of _spriterGroup - child object of it. Then setting to transformed.x and transformed.y would be enough, because scale would be applied to whole group (including its children) and translation to correct posiiton in world too.
  10. Like
    Tom Atom got a reaction from CharlesCraft50 in How to use Spriter in Phaser   
    @CharlesCraft50 - please, send me your Spriter animation (whole package - xml + graphics) and also put here code you used to load and run it (sending whole game code would be better, so I can run it on my PC).
  11. Like
    Tom Atom got a reaction from CharlesCraft50 in How to use Spriter in Phaser   
    Hi, you can follow this tutorial: http://sbcgamesdev.blogspot.cz/2016/04/phaser-tutorial-using-spriter-player.html
  12. Like
    Tom Atom got a reaction from CharlesCraft50 in How to use Spriter in Phaser   
    @CharlesCraft50 to check if animation is finished or another loop started, you can subscribe to receive these signals in Spriter.SpriterGroup:
    // onLoop(SpriterGroup); public onLoop: Phaser.Signal = new Phaser.Signal(); // onFinish(SpriterGroup); public onFinish: Phaser.Signal = new Phaser.Signal();  If "mySpriterAnim" is you SpriterGroup instance, then do this:
    mySpriterAnim.onLoop.add(function() { console.log("animation looped"); }, this);  to pause animation, just stop updating it or if you need to pause it while playing, you can get / set "paused" property of Spriter.SpriterGroup.
     
    Btw, this is complete list of signals from Spriter.SpriterGroup (last two were added in last week):
    // onLoop(SpriterGroup); public onLoop: Phaser.Signal = new Phaser.Signal(); // onFinish(SpriterGroup); public onFinish: Phaser.Signal = new Phaser.Signal(); // onSound(SpriterGroup, string); // string for line name which equals soud name without extension public onSound: Phaser.Signal = new Phaser.Signal(); // onEvent(SpriterGroup, string); // string for line name which equals event name public onEvent: Phaser.Signal = new Phaser.Signal(); // onTagChange(SpriterGroup, string, boolean); // string for tag name, boolean for change (true = set / false = unset) public onTagChange: Phaser.Signal = new Phaser.Signal(); // onVariableSet(SpriterGroup, Variable); // Variable is Spriter variable def with access to value public onVariableSet: Phaser.Signal = new Phaser.Signal(); // onBoxUpdated(SpriterGroup, SpriterObject); public onBoxUpdated: Phaser.Signal = new Phaser.Signal(); // onPointUpdated(SpriterGroup, SpriterObject); public onPointUpdated: Phaser.Signal = new Phaser.Signal();  
  13. Like
    Tom Atom got a reaction from CharlesCraft50 in How to use Spriter in Phaser   
    Spriter character is for example in this game:
    or this one:
     Problem with physics is, that if you apply it on every single part of Spriter character, they will fall down with gravity ... maybe physics will fight with animation. What you need is:
    1] create empty sprite,
    2] enable physics and set body and its size for this sprite (do not enable physics for children!),
    3] add Spriter.SpriterGroup as child of this sprite
    This is directly from Summer Love - "Hero" frame is empty / blank sprite with size 20x90 - it is just because Arcade physics will automatically set body size to these dimensions:
    module Leto { export class Player extends Phaser.Sprite { private _spriterGroup: Spriter.SpriterGroup; // ------------------------------------------------------------------------- public constructor(game: Phaser.Game) { super(game, 0, 0, "Sprites", "Hero"); // create Spriter loader - class that can change Spriter file into internal structure var spriterLoader = new Spriter.Loader(); // create Spriter file object - it wraps XML/JSON loaded with Phaser Loader var spriterFile = new Spriter.SpriterXml(game.cache.getXML("PlayerAnim")); // proces Spriter file (XML/JSON) with Spriter loader - outputs Spriter animation which you can instantiate multiple times with SpriterGroup var spriterData = spriterLoader.load(spriterFile); // create actual renderable object - it is extension of Phaser.Group this._spriterGroup = new Spriter.SpriterGroup(this.game, spriterData, "Sprites", "panak", "beh", 200); // set position size this._spriterGroup.position.set(10, 87); // adds SpriterGroup to Phaser.World to appear on screen this.addChild(this._spriterGroup); } } }  
  14. Like
    Tom Atom got a reaction from CharlesCraft50 in [Phaser] Summer Love   
    Summer Love is small infinite horizontal runner made in Phaser. That weird name comes from fact it should promote some summer music festival with this name.
    Later in game there are spikes and if you pick heart, you can do additional in-air jump. Hero's animation was made with Spriter (tool for skeletal animations).
    Game is controlled with space or left mouse button.
    Play it here: https://www.gameeapp.com/game/kiBJvHa

  15. Like
    Tom Atom got a reaction from CharlesCraft50 in [Phaser] Rio Sprint   
    Hi, this is another small game made for Gamee platform. This time it is hurdle race named Rio Sprint. You can play it here: https://www.gameeapp.com/game/rd4Rewu3fR
     To run fast, press right key quickly, to jump press left key.
         
  16. Like
    Tom Atom got a reaction from scheffgames in rotate sprite along z-axis   
    HI, what you want is in fact rotation alond Y axis (vertical one). You can fake it with changing scale X from 1 to -1 and then back.
  17. Like
    Tom Atom got a reaction from qbss in rotate sprite along z-axis   
    HI, what you want is in fact rotation alond Y axis (vertical one). You can fake it with changing scale X from 1 to -1 and then back.
  18. Like
    Tom Atom got a reaction from samme in Phaser Bug(?) when reloading page with F5   
    Found, that file.data.complete is reset to false for short time period as well as width and height are set to zero (see my previous post). It is only done if xhr.load request follows (as well as for width and height).
     
    Commenting this piece of code in loadImageTag solves the issue:
    /*// Image is immediately-available/cachedif (file.data.complete && file.data.width && file.data.height){file.data.onload = null;file.data.onerror = null;this.fileComplete(file);}*/  If image is in cache, it is taken from there anyway, only fileComplete is called from onload callback ... looks like FF needs it in this way. And again: problem happens only if image loading is followed with loading of other file throught xhrLoad (.json for atlas). If loading only image then previous piece of code can be left uncommented.
  19. Like
    Tom Atom got a reaction from jopcode in how do double jump?   
    Hi, first part, resetting your jump properties if on ground, is OK:
    this.onTheGround = this.player.body.blocked.down; if(this.onTheGround) { this.jumps = 3; this.jumping = false; } Second part is problematic. To check if key was just pressed use justDown instead of isDown. Also code logic seems little bit strange to me.
     
    In attachment you will find complete small endless runner example. I implemented your triple jump into it. It is written in TypeScript, but you should have no problems to rewrite it into JS, if you need.
    SimpleRunner.zip
    Crucial parts are:
     + define these variables for jumping:
    // jumping private _nextJumpTime: number = 0; private _jumping: boolean = false; private _jumps: number = 3;  + in update see code for jumping (key used for jumping is space in example):
    let onGround = this.physics.arcade.collide(this._player, this._platforms); let body = <Phaser.Physics.Arcade.Body>this._player.body; let canJump = onGround && this.game.time.time > this._nextJumpTime; let canJumpInAir = this._jumping && this._jumps > 0; if (canJump) { this._jumping = false; this._jumps = 3; } if (this._input.justDown && (canJump || canJumpInAir)) { if (onGround) { this._jumping = true; this._nextJumpTime = this.game.time.time + 250; } --this._jumps; body.velocity.y = -850; }  
  20. Like
    Tom Atom got a reaction from PhasedEvolution in [Phaser] Little Plane   
    You do not need to change this. Scale modes are applied to rendered frame. It means that 100 pixels distance in your game is always 100 pixels regardless of final scale. In case you changed x dimension of game... ok, you can now see more of the game world, but 100 pixels is still 100 pixels.
     Here in attachment you will find "minimal game" - just press space to jump from platform to platform (F5 reload when dead). It scales dynamically when running. There are monsters placed on some platforms randomly, which move from left to right (with random speed). Their speed is not changing in code after they are spawn. It may only seem to you that speed on screen changed, if tiles are scaled down or up, but it always takes constatnt time for them to move from left side to right side.
    SimpleRunner.zip
     Check app.ts file - it is main (and only) code file. If you do not like TypeScript, there is compiled app.js.
  21. Like
    Tom Atom got a reaction from Umz in [Phaser] Little Plane   
    What I will write here is how it works for me best - other people may have their own ways. It will be example of horizontal scrolling game and explanation will be applied to this type of game.
     Let's say we have basic resolution 800 x 600 and browser window is 1200 x 700. Grey rect is browser window and blue one is our basic game resolution.

     Besic resolution for me is mainly best resolution from game design point of view. As we are making side scroller, it is ok for us if player can see a little bit more or less to the right. On the other hand we have no extra content to display vertically. So, we want to fit our game into window height primarilly and see what happens to width. First, we calculate vertical scale:
     scaleY = window_height / game_height ... 700/600 = 1,1667 in our case,
     If we scaled game uniformly, what would be its scaled width? It would be 800 * scaleY = 800 * 1,1667 = 933 pixels.
     But window width is 1200 ... we want our uniformly scaled game to fill entire window, but if we scale 800 x 600 by 1,1667 we only get 933 x 700.
     So, we have to consider different game size than 800 x 600 to pass into Phaser. We know, we want to fill 1200 pixels wide window after 1,1667 scale. So our game has to be 1200 / 1,1667 pixels wide ... 1200 / 1,1667 = 1028 pixels (rounded down).
     When creating game, pass 1028 x 600 instead of 800 x 600. Now you game will look like this:

     solid area is original 800 x 600, but together with stripped part it is 1028 x 600. We still do not fill entire window. Now, Phaser scale modes come into play. Following picture is from my book, where is full chapter related to scaling horizontal endless runner game (https://gumroad.com/l/CZuhn). Our current state is in fact NO_SCALE:

     Red rect is game, blue is window. Beside these modes, Phaser also has USER_SCALE that allows you to set custom scale for both x and y.
     As you already recalculated width, you can now simply use EXACT_FIT. It will not deform your game, as you adjusted its width, so it will scale uniformly.
     All these modes scales whole game canvas after it is rendered! Do not scale individual game objects, gravity, velocities, etc. or you will get lost quickly. You do not need it - your game is now 1028 x 600 (originally it was designed for 800 x 600). Y dimension did not change - no reason for changing gravity, height of sprites, etc. In X dimension you can now see more of the level to the right, but again: no reason to change velocities, sprite scales, etc.
     The above is simple example - we are calculating new game dims before game is created. But you can make it all dynamic (which is how it is made in that mentioned book). Phaser tells you when window size is changed and you can handle it. Look at Goblin Run game here: http://sbc.littlecolor.com/goblinrun/ (it is game created in book) and try to resize browser window - game will dynamically match it ... even very crazy dimensions like this:

     
  22. Like
    Tom Atom got a reaction from Umz in [Phaser] Little Plane   
    Hi, Little Plane is another one-button game made for Gamee platform. Dodge dangerous pillars, pass through deadly tunnels and collect money.
    Game was made in Phaser and uses P2 physics.
        
    Play it here: https://www.gameeapp.com/game/5IsYwla
     
  23. Like
    Tom Atom got a reaction from PhasedEvolution in [Phaser] Little Plane   
    Games for Gamee have always fixed base size 640 x 640, so scaling is very easy - it is scaled to fill given square space on page (what is scaled is not game or individual sprites, but whole game canvas after game frame is rendered into it). But as it is evolving they canceled height limit and new games can be 640 x whatever.
     Generaly, scaling strategy should be choosen based on your game. From my experience, one of decision points is whether game is on one screen or whether it is scrolling. For one screen games scaling I wrote article some time ago (http://sbcgamesdev.blogspot.cz/2015/04/phaser-tutorial-manage-different-screen.html). Shortly, I add some areas that are sometimes displayed and sometimes not - depends on screen aspect. If game is scrolling in one direction only, then I scale non-scrolling dimension to fit window, keep scale facotr and recalculate game size in scrolling dimension to fit window after the same scale factor is applied.
     
  24. Like
    Tom Atom got a reaction from MustSeeMelons in Phaser sprite rendering oddity   
    Hi, make sure your platform blocks have these settings:
    let body = <Phaser.Physics.Arcade.Body>sprite.body; body.allowGravity = false; body.immovable = true; body.moves = false;  body.moves = false says, that your platform blocks are not being moved by physics, but by you. This property is set to true by default.
     To make a little promo , I wrote book on making Endless platformer with Phaser/TypeScript: https://gumroad.com/l/CZuhn. FInal game is here: http://sbc.littlecolor.com/goblinrun/
     
  25. Like
    Tom Atom reacted to Megabyte in Pixel Cave [roguelike]   
    Hi, its my firsh HTML5 game, I made it after playing PIxel Dungeon : )
    For UI i used react.js. Gameplay part is canvas+js. No any other frameworks. Maybe for next my game ill take phaser. : )
    Features:
    8 bosses about 25 enemies items with random generated properties random generated levels You can play it here: https://pixel-cave.com
    About any bugs you can report me in game menu. : ) I've fixed some bugs, reported via these menu already.


×
×
  • Create New...