Aquarius Posted March 27, 2017 Share Posted March 27, 2017 Hello, I have a situation where i have different sprites ont the game, with the same frame rate. Actually they are all moving synchronously (see actual.png). What I want is to randomly shift the animation, to have a more natural feeling (see wanted.png). i tried to launch the play method in a randomly timeout, but it seems that there is unique timeline for every sprite. any clues ? Link to comment Share on other sites More sharing options...
scheffgames Posted March 27, 2017 Share Posted March 27, 2017 Not tested but maybe you could set the currentFrame property to a different value (say 2 or 3 instead of 0) and then hit play(). Link to comment Share on other sites More sharing options...
Aquarius Posted March 27, 2017 Author Share Posted March 27, 2017 Oh, nice though, i'll try i now. Link to comment Share on other sites More sharing options...
Aquarius Posted March 27, 2017 Author Share Posted March 27, 2017 // ... sprite creation, adding animations ... zombie.play("down"); let frameIndex = game.rnd.integerInRange(0,sprite.animations.currentAnim.frameTotal); zombie.animations.currentAnim.setFrame(frameIndex); Well, it works, but every sprite change their frame at the same time In fact I want to set a delay in milliseconds, so every sprite will update their frame at a different moment. I think that a I have to overload the currentAnim.update() Method Link to comment Share on other sites More sharing options...
scheffgames Posted March 27, 2017 Share Posted March 27, 2017 There's no reason this shouldn't work - maybe something in the code that's not showed here? Also, how do you create your zombie objects? something like should work: function Zombie(x,y,texture){ this.obj = game.add.sprite(x,y,texture); this.obj.anim = this.obj.animations.add(texture,[0,1,2,3,4,5]); this.obj.anim.currentFrame = 3; var frameRate = 10; this.obj.anim.play(frameRate,true); } and create it like this; var zombie1 = new Zombie(0,0,"myTexture"); Link to comment Share on other sites More sharing options...
Aquarius Posted March 27, 2017 Author Share Posted March 27, 2017 the code wasn't correct, I wanted to rename the zombie variable in order to be more clear. the real code (as you can see, i am working in typescript ) let zombie = this.phaserGame.add.sprite(position.x, position.y - 32, 'Male-Zombies-Gore'); zombie.smoothed = false; zombie.animations.add("up", ["zombie-up-1", "zombie-up-2", "zombie-up-3"], framerate, true); zombie.animations.add("down", ["zombie-down-1", "zombie-down-2", "zombie-down-3"], framerate, true); zombie.animations.add("right", ["zombie-right-1", "zombie-right-2", "zombie-right-3"], framerate, true); zombie.animations.add("left", ["zombie-left-1", "zombie-left-2", "zombie-left-3"], framerate, true); zombie.play("down"); let frameIndex = this.phaserGame.rnd.integerInRange(0,zombie.animations.currentAnim.frameTotal); zombie.animations.currentAnim.setFrame(frameIndex); I didn't said it wans't working, each zombie have a different step. But, they change their step at the same time. ex : t0 : spriteA: showFrame1 spriteB: showFrame3 spriteC: showFrame8 t1: spriteA: showFrame1 spriteB: showFrame3 spriteC: showFrame8 t2: spriteA: showFrame2 // changing frame spriteB: showFrame4 // changing frame spriteC: showFrame9 // changing frame What I want : t0 : spriteA: showFrame1 spriteB: showFrame3 spriteC: showFrame8 t1: spriteA: showFrame1 spriteB: showFrame3 spriteC: showFrame8 t2: spriteA: showFrame1 spriteB: showFrame4 //changing frame spriteC: showFrame8 t3: spriteA: showFrame2 // changing frame spriteB: showFrame4 spriteC: showFrame9 // changing frame So, what I am actually doing, is to create a DelayedAnimation, that extends Phaser.Animation export default class DelayedAnimation extends Phaser.Animation { private timelineDelay;number /** overload update method */ update(): boolean { // in this method i will add the timelinedelay to the game time to pick the frame to display /* ... */ this._frameDiff = this.game.time.time - this._timeNextFrame; //<= I think adding my delay here. /* ... */ } } I will let you know when I have the result i want. Sorry if it wasn't very clear, english is not my natural language Link to comment Share on other sites More sharing options...
Aquarius Posted March 27, 2017 Author Share Posted March 27, 2017 IT WORKS !! export default class DelayedAnimation extends Phaser.Animation { // NEVER MIND, it's just for Typescript compilation, overloading some Animation's variable _parent: any; _frameData: any; _frames: any; _frameIndex: number; isReversed: any; _timeLastFrame: number; _frameDiff: number; _frameSkip: number; _timeNextFrame: any; // my new variable. private timelineDelay:number // a method to add my DelayedAnimation to a sprite animations static addToAnimations(animationManager: any, delay, name, frames, frameRate, loop, useNumericIndex?) { frames = frames || []; frameRate = frameRate || 60; if (loop === undefined) { loop = false; } // If they didn't set the useNumericIndex then let's at least try and guess it if (useNumericIndex === undefined) { if (frames && typeof frames[0] === 'number') { useNumericIndex = true; } else { useNumericIndex = false; } } animationManager._outputFrames = []; animationManager._frameData.getFrameIndexes(frames, useNumericIndex, animationManager._outputFrames); let delayedAnimation = new DelayedAnimation(animationManager.game, animationManager.sprite, name, animationManager._frameData, animationManager._outputFrames, frameRate, loop); delayedAnimation.timelineDelay = delay; animationManager._anims[name] = delayedAnimation; animationManager.currentAnim = animationManager._anims[name]; if (animationManager.sprite.tilingTexture) { animationManager.sprite.refreshTexture = true; } return animationManager._anims[name]; } update(): boolean { // all these lines are from original Phaser Code. if (this.isPaused) { return false; } if (this.isPlaying && this.game.time.time >= this._timeNextFrame) { this._frameSkip = 1; // Lagging? // my only change is here this._frameDiff = this.game.time.time - this._timeNextFrame + this.timelineDelay; // end of change this._timeLastFrame = this.game.time.time; if (this._frameDiff > this.delay) { // We need to skip a frame, work out how many this._frameSkip = Math.floor(this._frameDiff / this.delay); this._frameDiff -= (this._frameSkip * this.delay); } // And what's left now? this._timeNextFrame = this.game.time.time + (this.delay - this._frameDiff); if (this.isReversed) { this._frameIndex -= this._frameSkip; } else { this._frameIndex += this._frameSkip; } if (!this.isReversed && this._frameIndex >= this._frames.length || this.isReversed && this._frameIndex <= -1) { if (this.loop) { // Update current state before event callback this._frameIndex = Math.abs(this._frameIndex) % this._frames.length; if (this.isReversed) { this._frameIndex = this._frames.length - 1 - this._frameIndex; } this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]); // Instead of calling updateCurrentFrame we do it here instead if (this.currentFrame) { this._parent.setFrame(this.currentFrame); } this.loopCount++; this._parent.events.onAnimationLoop$dispatch(this._parent, this); this.onLoop.dispatch(this._parent, this); if (this.onUpdate) { this.onUpdate.dispatch(this, this.currentFrame); // False if the animation was destroyed from within a callback return !!this._frameData; } else { return true; } } else { this.complete(); return false; } } else { return this.updateCurrentFrame(true); } } return false; } } Link to comment Share on other sites More sharing options...
Recommended Posts