Cutu Posted January 2, 2017 Share Posted January 2, 2017 Hey guys this is a quick question, I was trying to make an sprite move left or right with the input.onDown/Up() event, but I'm getting "Cannot read property 'body' of undefined. Here's the code of my Main state. var xSpeed = 600, moveDirection = 0; var Main = function(game) { }; Main.prototype = { create: function() { this.createPlayer(); //Testing if it works on PC and it does. this.cursors = this.game.input.keyboard.createCursorKeys(); //Added the touch events (So it can be played in mobile devices) and it doesn't work :( this.game.input.onDown.add(function(e) { if(e.position.x < this.game.width/2) { moveDirection = -1; } else { moveDirection = 1; } this.player.body.velocity.x = xSpeed * moveDirection; }); //This one is to stop the player from moving. this.game.input.onUp.add(function(e) { this.player.body.velocity.x = 0; }); }, update: function() { this.movePlayerCursors(); }, gameOver: function() { this.game.state.start("GameOver"); }, createPlayer: function() { this.player = this.game.add.sprite(this.game.world.width/2,this.game.world.height*0.8, "player"); this.player.anchor.setTo(0.5, 0.5); this.game.physics.arcade.enable(this.player); this.player.checkWorldBounds = true; this.player.body.collideWorldBounds = true; /*I tried adding xSpeed property to player but it doesn't work neither :/ this.player.xSpeed = 600; */ }, movePlayerCursors: function() { this.player.body.velocity.x = 0; if(this.cursors.right.isDown) { //this.player.body.velocity.x += this.player.xSpeed; this.player.body.velocity.x += xSpeed; } else if(this.cursors.left.isDown) { //this.player.body.velocity.x -= this.player.xSpeed; this.player.body.velocity.x -= xSpeed; } }, }; What am I doing wrong? I hope you guys can help me, thanks in advance! Link to comment Share on other sites More sharing options...
Théo Sabattié Posted January 2, 2017 Share Posted January 2, 2017 this.game.input.onDown.add(function(e) { if(e.position.x < this.game.width/2) { moveDirection = -1; } else { moveDirection = 1; } this.player.body.velocity.x = xSpeed * moveDirection; }); In callback, or event callback, object is often bind in function (as this); function explanationBind(){ console.log(this); } var lObject = {a:"hello"}; explanationBind.bind(lObject)(); // lObject in console explanationBind(); // Window object in console If you want your object in this method (as this), you have ton bind your object: this.game.input.onDown.add((function(e) { if(e.position.x < this.game.width/2) { moveDirection = -1; } else { moveDirection = 1; } this.player.body.velocity.x = xSpeed * moveDirection; }).bind(this)); Link to comment Share on other sites More sharing options...
Cutu Posted January 3, 2017 Author Share Posted January 3, 2017 Thanks @Théo Sabattié, I tried before binding this to the object but it didn't work (got a "bind is not a defined method" error), but now that I saw your suggestion I noticed that you added the callback inside parenthesis, what's the difference? This was how I did it, and one last question which object does it refers when we bind "this"? The Main object? This was how I did it and didn't work: this.game.input.onDown.add(function(e) { if(e.position.x < this.game.width/2) { moveDirection = -1; } else { moveDirection = 1; } this.player.body.velocity.x = xSpeed * moveDirection; }).bind(this); *Notice that I didn't wrap the anonymous function in ( )* Link to comment Share on other sites More sharing options...
Théo Sabattié Posted January 3, 2017 Share Posted January 3, 2017 I doubted so I set parenthesis, but you can remove them for that: this.game.input.onDown.add(function(e) { if(e.position.x < this.game.width/2) { moveDirection = -1; } else { moveDirection = 1; } this.player.body.velocity.x = xSpeed * moveDirection; }.bind(this)); In your case, you apply the bind on the add returnment this.game.input.onDown.add( function(e) { /* ... */} ).bind(this); I don't know if add method returns something, but that is not the place to use bind. You have to bind your own object on the callback : this.game.input.onDown.add( function(e) { /* ... */ }.bind(yourObject) ); In this case, this is the Main instance. But if you want, you can bind directly this.player.body.velocity and update x inside callback: this.x += /*..*/ But it will become hard when you will proofread your code to know what "this" represents. Link to comment Share on other sites More sharing options...
Cutu Posted January 3, 2017 Author Share Posted January 3, 2017 Ohh I see, thank you so much for your help, but now I have one last question, in the Update method I have the movePlayerCursors which moves the player Horizontally using the left and right keys, this works properly but it makes conflict with the touch inputs because I had to set the player.body.velocity.x to 0 making the user tap like crazy to move the player sprite, but if I don't set this velocity to 0 when they use the keyboard inputs the sprite won't stop moving, I'm sorry if its difficult to understand but English is not my native language, if you can help me with this I would appreciate it. Thank you one more time @Théo Sabattié this is the part of the code I'm talking about: movePlayerCursors: function() { this.player.body.velocity.x = 0; //If I remove this line the sprite won't stop moving using the right and left keys, but if I leave it there the user will have to tap like crazy the phone to move pixel per pixel the sprite. if(this.cursors.right.isDown) { this.player.body.velocity.x += this.player.xSpeed; } else if(this.cursors.left.isDown) { this.player.body.velocity.x -= this.player.xSpeed; } } Link to comment Share on other sites More sharing options...
Théo Sabattié Posted January 3, 2017 Share Posted January 3, 2017 Quote English is not my native language Don't be worry, that is not mine too. I am not sure to understand Why don't you update directly the position ? I don't understand where the conflict come from. Link to comment Share on other sites More sharing options...
Cutu Posted January 3, 2017 Author Share Posted January 3, 2017 3 hours ago, Théo Sabattié said: Don't be worry, that is not mine too. I am not sure to understand Why don't you update directly the position ? I don't understand where the conflict come from. You mean using body.position instead of velocity? I didn't tried that because I was following one of those flappy bird tutorial, but now I tried and if I use the position in the touch events the sprite won't move I don't know why. What I just did it was to add another property to the player "xMove" to use it with the keyboard inputs and the xSpeed with touch inputs like this: //Touch Inputs this.game.input.onDown.add((function(e) { if(e.position.x < this.game.width/2) { this.player.moveDirection = -1; } else { this.player.moveDirection = 1; } this.player.body.velocity.x = this.player.xSpeed * this.player.moveDirection; }).bind(this)); this.game.input.onUp.add((function(e) { this.player.body.velocity.x = 0; }).bind(this)); //Keyboard Inputs movePlayerCursors: function() { if(this.cursors.right.isDown) { this.player.body.position.x += this.player.xMove; } else if(this.cursors.left.isDown) { this.player.body.position.x -= this.player.xMove; } } //And the createPlayer function createPlayer: function() { this.player = this.game.add.sprite(this.game.world.width/2,this.game.world.height*0.8, "player"); this.player.anchor.setTo(0.5, 0.5); this.game.physics.arcade.enable(this.player); this.player.checkWorldBounds = true; this.player.body.collideWorldBounds = true; this.player.xSpeed = 500; //added this for Touch this.player.xMove = 10; //this one for keys this.player.moveDirection = 0; } I'm not sure if this is how it has to be but it works, still don't know why if I use body.position in the touch event the sprite doesn't move D: Thank you anyways! Link to comment Share on other sites More sharing options...
Recommended Posts