fubeca6 Posted June 21, 2014 Share Posted June 21, 2014 Hi all, I'm very very new to Phaser and game dev in general. To teach myself the basics, I've been working on a few different prototypes that implement various physics mechanics, or address some other specific challenge. Recently I created a prototype in which a rogue-like char has to avoid a few moving columns and get to a "win" sprite (...physics.arcade.overlap) to finish the level. To make things more interesting I tried to implement some tiles where, on ...arcade.overlap the tiles would manipulate the players movement - essentially creating a water-like current, so that the players movement was lightly restricted in one direction, but enhanced in the other direction. Here's the code: Under create(): // configure the water blocks waters = game.add.group(); waters.enableBody = true; water1 = waters.create(0, 96, 'water'); water2 = waters.create(game.world.width - 256, 224, 'water'); water1.body.immovable = true; water2.body.immovable = true;Under update(): game.physics.arcade.overlap(player,water1, water1Flow, null, this); game.physics.arcade.overlap(player,water2, water2Flow, null, this);water1Flow (since the two functions are nearly identical):function water1Flow() { player.body.velocity.x = 100;}I expected that this would have an impact on the player sprite's movement, but it hasn't done ANYTHING. I put a "console.log(player.body.velocity.x);" line in the function, and it showed that the velocity was 100, but in actual gameplay, that doesn't seem to be the case. Any help or ideas would be greatly appreciated! Thanks Link to comment Share on other sites More sharing options...
marvster Posted June 22, 2014 Share Posted June 22, 2014 Is the player under the context of "this"? If not try to pass the player directly to the function: game.physics.arcade.overlap(player, water1, water1Flow, null, player);function water1Flow() { this.body.velocity.x = 100;} Link to comment Share on other sites More sharing options...
fubeca6 Posted June 22, 2014 Author Share Posted June 22, 2014 marvster, thanks for the reply! I made the change but unfortunately had the same end result. Here I included:function water1Flow() { player.body.velocity.x = 100; console.log(player.body.velocity.x);}The result is, that as soon as I hit the "water" tile, the console begins printing out "100"'s like crazy. However, the player sprite remains still... Perhaps it's something in the way I'm defining movement? if (keyboard.isDown(Phaser.Keyboard.A)) { player.body.velocity.x = -150; } else if (keyboard.isDown(Phaser.Keyboard.D)) { player.body.velocity.x = 150; } else { player.body.velocity.x = 0; } if (keyboard.isDown(Phaser.Keyboard.W)) { player.body.velocity.y = -150; } else if (keyboard.isDown(Phaser.Keyboard.S)) { player.body.velocity.y = 150; } else { player.body.velocity.y = 0; }Any ideas are appreciated! Link to comment Share on other sites More sharing options...
fubeca6 Posted June 22, 2014 Author Share Posted June 22, 2014 (Update) I tried function water1Flow() { player.body.gravity.x = 100;}but without luck. The player sprite moves, but negligibly. I believe that the " } else { player.body.velocity.x = 0; } " is inhibiting movement in the case of using the body.gravity property, but I'm not sure how to alleviate that. Link to comment Share on other sites More sharing options...
lewster32 Posted June 22, 2014 Share Posted June 22, 2014 I think the issue is due to you setting, rather than adding, velocity. Typically when moving via velocity, you want to set the initial velocity, and then add to or subtract from that velocity to change it - otherwise you may as well set body.moves = false and handle the positioning yourself. What you could do if you want to keep this way of doing it is add a new Phaser.Point to your player called 'externalForce' and add another called 'force' on any tiles that you want to impart a force on the player, then change the externalForce when the player is touching a tile which has a force property, then finally you can add the externalForce to the player's normal movement velocities. So where you create your player, do this:player.externalForce = new Phaser.Point(0, 0);Ensure all of your force-imparting tiles are in a single group or array called something like 'forceTiles' and on each do the following:// this tile adds a velocity of 100 to the x axis of the player, moving it right;// use -100 to move the player left insteadtile.force = new Phaser.Point(100, 0); Then change your movement loop to this: if (keyboard.isDown(Phaser.Keyboard.A)) { player.body.velocity.x = -150 + player.externalForce.x; } else if (keyboard.isDown(Phaser.Keyboard.D)) { player.body.velocity.x = 150 + player.externalForce.x; } else { player.body.velocity.x = 0 + player.externalForce.x; } if (keyboard.isDown(Phaser.Keyboard.W)) { player.body.velocity.y = -150 + player.externalForce.y; } else if (keyboard.isDown(Phaser.Keyboard.S)) { player.body.velocity.y = 150 + player.externalForce.y; } else { player.body.velocity.y = 0 + player.externalForce.y; }Then instead of separate waterFlow functions just create one called applyForceTile:function applyForceTile(player, tile) { // does this tile have a force? if (tile.force) { // if so, add its x and y values to the player's externalForce player.externalForce.add(tile.force.x, tile.force.y); }}Finally you need to ensure you zero the externalForce when the player isn't touching anything: // if we're not overlapping a force tile, zero the external force if (!game.physics.arcade.overlap(player, forceTiles, applyForceTile, null, this)) { player.externalForce.setTo(0, 0); };The above gives you a clean way of applying arbitrary forces per tile with a single overlap loop, and you can make your forces go in any direction, so you can have things like gravity lifts, boost pads and so on. Link to comment Share on other sites More sharing options...
fubeca6 Posted June 22, 2014 Author Share Posted June 22, 2014 Woot! Thank you lewster32! I won't have time to try today, but should tomorrow - I'll let you know how it goes! Link to comment Share on other sites More sharing options...
fubeca6 Posted June 24, 2014 Author Share Posted June 24, 2014 Hey lewster32, Thank you again for your help. However, the mechanics did not quite work as I would have liked. Instead of applying a static velocity when the player and the tile sprites overlap, the velocity is compounded. So that, although it starts out at the desired value, it quickly accelerates, giving the player no hope of "swimming up-stream" as it were. For instance, with the initial force set to 150, and adding a console.log() line in the function, the results are:150150170170190190210210230230...and so on. Link to comment Share on other sites More sharing options...
lewster32 Posted June 24, 2014 Share Posted June 24, 2014 Oops, the bug is in applyForce, which is adding the velocity every frame - instead it should be setting it:function applyForceTile(player, tile) { // does this tile have a force? if (tile.force) { // if so, set the externalForce values to be the same as the tile's force values player.externalForce.copyFrom(tile.force); }} Link to comment Share on other sites More sharing options...
fubeca6 Posted June 24, 2014 Author Share Posted June 24, 2014 Hey Lewster32 - I will try again a bit later, and update this post. I really appreciate your help though! The Phaser examples that are included with the framework are wonderful, and usually succeed in getting me over these little humps and on my way - but this one has been a stumper. Being new to all of this, I really appreciate your willingness to show how it's done! Link to comment Share on other sites More sharing options...
fubeca6 Posted June 26, 2014 Author Share Posted June 26, 2014 Lewster32, I marked your latest answer as the solution. Thanks again for the help! It's working how I want! lewster32 1 Link to comment Share on other sites More sharing options...
lewster32 Posted June 26, 2014 Share Posted June 26, 2014 No problem, glad I could help Link to comment Share on other sites More sharing options...
Recommended Posts