Meowts Posted March 8, 2015 Share Posted March 8, 2015 Hey, So I'm trying to implement the State design pattern, and I've come across some strange behavior. What I'm trying to achieve:The longer the player is moving left or right, the faster they move until max speed is reached (same as good ol' Mario). Result:The timer that the affects speed increment sometimes doesn't happen...? I'll move left and right, sometimes it increments, sometimes it doesn't. Also, sometimes when pressing the left key while in Standing state, the velocity of the player sprite will continue to increase, seemingly not entering the Standing state... (ie, press left, stop pressing left, player sprite keeps moving forward). However from logging when entering the states, it definitely should be hitting the right update function... Hypothesis: Either... A: The timer isn't instancing quick enough, or being mixed up somehow? B: There's something about Javascript I don't quite get, and should switch to C++... XD Code://As for what's being called... there's an instance of Player called player_, and it's being called in main update loop as player_.update();//player.js:create : function(){ this.state = Player.State.Standing(this);}update : function() { this.state.update();}//and in playerState.js:Player.State = function(){};Player.State.Standing = function(player){ this.player = player;};Player.State.Walking = function(player){ this.player = player; isWalking = false;};Player.State.Jumping = function(player){ this.player = player; isJumping = false;};Player.State.Standing.prototype = { update : function(){ //Slow down if already moving if(this.player.movingLeft || this.player.movingRight){ if(this.player.sprite.body.velocity.x !== 0){ this.player.sprite.body.velocity.x -= 10; if(this.player.movingLeft){ if(this.player.sprite.body.velocity.x > 0){ this.player.sprite.body.velocity.x = 0; this.player.movingLeft = null; } } if(this.player.movingRight){ if(this.player.sprite.body.velocity.x < 0){ this.player.sprite.body.velocity.x = 0; this.player.movingRight = null; } } } } //Set proper frame if(this.player.sprite.frame !== 0){ this.player.sprite.frame = 0; } //Stop any animations if(this.player.sprite.animations.currentAnim.isPlaying){ this.player.sprite.animations.stop(); } //Handle inputs if(this.player.controller_.cursor.left.isDown || this.player.controller_.cursor.right.isDown){ this.player.state = new Player.State.Walking(this.player); } if(this.player.controller_.cursor.up.isDown && this.player.sprite.body.onFloor()){ this.player.state = new Player.State.Jumping(this.player); } }};Player.State.Walking.prototype = { update : function(){ //Initialize flag and start timer upon entering state if(!this.isWalking){ //This is what seems to not make it in the update loop... //As you can see below, I destroy the timer object when changing states. //However, it only seems to happen 'sometimes', which obviously isn't //sufficient... this.player.timer = this.player.game.time.create(false); this.player.timer.start(); this.isWalking = true; } //Increment the player's walking speed based on time if(this.player.timer.ms % this.player.incrementSpeed === 0 && this.player.walkingSpeed <= this.player.maxSpeed){ this.player.walkingSpeed += this.player.incrementSpeedValue; } //Start animation if it hasn't already if(!this.player.sprite.animations.currentAnim.isPlaying){ this.player.sprite.animations.play('walk'); } //Increment the speed of the animation by how fast the player is moving this.player.sprite.animations.currentAnim.speed = this.walkingSpeed/5; //Walking left or right if(this.player.controller_.cursor.left.isDown){ //Set flag this.player.movingLeft = true; //Face left this.player.sprite.scale.x = -1; // Move the player to the left this.player.sprite.body.velocity.x = -this.player.walkingSpeed; } else if(this.player.controller_.cursor.right.isDown){ //Set flag this.player.movingRight = true; //Face left this.player.sprite.scale.x = 1; // Move the player to the left this.player.sprite.body.velocity.x = this.player.walkingSpeed; } //No input, stop what's going on else{ this.reset(); this.player.state = new Player.State.Standing(this.player); } //Jumping from walking if(this.player.controller_.cursor.up.isDown && this.player.sprite.body.onFloor()){ this.reset(); this.player.state = new Player.State.Jumping(this.player); } }, reset : function(){ this.isWalking = false; this.player.walkingSpeed = this.player.initialSpeed; this.player.timer.destroy(); }};Player.State.Jumping.prototype = { update : function(){ if(this.player.sprite.animations.currentAnim.isPlaying){ this.player.sprite.animations.stop(); } if(this.player.sprite.frame != 4){ this.player.sprite.frame = 4; } if(this.player.sprite.body.onFloor()){ if(!this.isJumping){ this.player.sprite.body.velocity.y = -this.player.jumpHeight; this.isJumping = true; } else{ this.isJumping = false; this.player.state = new Player.State.Standing(this.player); } } }};This seems pretty straight forward to me... but it's just not doing it, particularly the timer object that's created when entering Walking state. What am I missing? Why it's imporant to me: The state pattern makes a huge impact on how my game will work. It will be a fighting game, and like any fighting game, there will be a combination of different inputs that will determine the next move, and both state and timers will affect the subsequent moves. Rather than having one ridiculously large update function with n^n different flags, states seem like the best way to handle it. Link to comment Share on other sites More sharing options...
Recommended Posts