Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

goomba move


mrdotb
 Share

Recommended Posts

Hi everyone,

I want to move my enemy like this

1402059532-question.png

 

For the moment i use:

function create_enemy() {    APP.enemy = game.add.group();    tabEnemy = [];    tabEnemy[0] = APP.enemy.create(2477, 1938, 'enemy');    tabEnemy[1] = APP.enemy.create(2813, 1842, 'enemy');    tabEnemy[2] = APP.enemy.create(3019, 1746, 'enemy');    tabEnemy[3] = APP.enemy.create(3551, 1650, 'enemy');    for (var i = 0; i < tabEnemy.length; i++) {        game.physics.enable(tabEnemy[i]);    }};function update_enemy() {    game.physics.arcade.collide(APP.layer, APP.enemy);    //enemy1    if (bow(tabEnemy[0].position.x) == bow(2477)) {        tabEnemy[0].body.velocity.x = -100;    };    if (bow(tabEnemy[0].position.x) == bow(1968)) {        tabEnemy[0].body.velocity.x = 100;    };    //enemy2    if (bow(tabEnemy[1].position.x) == bow(2813)) {        tabEnemy[1].body.velocity.x = -100;    };    if (bow(tabEnemy[1].position.x) == bow(2694)) {        tabEnemy[1].body.velocity.x = 100;    };    //enemy3    if(bow(tabEnemy[2].position.x) == bow(3200)) {        tabEnemy[2].body.velocity.x = -100;    };    if(bow(tabEnemy[2].position.x) == bow(3019)) {        tabEnemy[2].body.velocity.x = 100;    };    //enemy4    if(bow(tabEnemy[3].position.x) == bow(3551)) {        tabEnemy[3].body.velocity.x = 100;    };    if(bow(tabEnemy[3].position.x) == bow(3773)) {        tabEnemy[3].body.velocity.x = -100;    };};function bow(value){   var calcul = Math.ceil(value / 10) *10;    return calcul;}

Do you have a better way to do it ?

 

Thank you.

Link to comment
Share on other sites

I guess the issue is you're having to manually set the patrol routes of the enemies rather than have them detect the edges and turn around. There are many different ways of doing this but most depend on the enemy having some basic way of 'seeing' the world in front of it. You could extend the sprite and add a second smaller detection body in front of the enemy which is lowered into the ground slightly. You would then check this body on every update of the sprite to see if it was overlapping the ground. If it doesn't overlap the ground, you change the enemy's direction and move the detection body so that it is in front of the enemy.

 

Other methods include using ray casts to do the same thing, triggers built into the map at the edges which when collided with, tell the enemy to turn around, the enemy checking the size of the floor when it first spawns/lands on it (if each floor section is individual) and setting its bounds dynamically based on that check, and probably many other smarter ways I can't think of right now!

Link to comment
Share on other sites

I would stick with the trigger method. At each edge that you want the enemies to turn around on, add an invisible sprite (game.add.sprite(0, 0, null); will create a sprite at x = 0, y =0 with no visible texture - enable the body on it and you have an invisible sprite with a body to check against) and when the enemy overlaps that sprite, reverse its velocity.x (you can do sprite.body.velocity.x *= -1; to switch its direction regardless of whether it's going left or right). Put all of your triggers in a group and you can do all of this fairly simply.

// Create a group for all triggersvar reverseEnemyTriggers = game.add.group();// Ensure all triggers added to group have an arcade physics bodyreverseEnemyTriggers.enableBody = true;reverseEnemyTriggers.physicsBodyType = Phaser.Physics.ARCADE;// Add the left trigger to the group and set its size manually to 4 pixels wide by// 32 pixels high - tweak this to suit your game.var leftTrigger = game.add.sprite(0, 0, null, 0, reverseEnemyTriggers);leftTrigger.body.setSize(4, 32, 0, 0);// And again for the right triggervar rightTrigger = game.add.sprite(100, 0, null, 0, reverseEnemyTriggers);rightTrigger.body.setSize(4, 32, 0, 0);// Add an enemy to the enemies groupvar enemy = game.add.sprite(50, 0, 'enemy', 0, enemiesGroup);game.physics.enable(enemy, Phaser.Physics.ARCADE);enemy.body.velocity.x = 100;function update() {  game.physics.arcade.overlap(enemiesGroup, reverseEnemyTriggers, function(enemy, trigger) {    // Do a simple check to ensure the trigger only changes the enemy's direction    // once by storing it in a property on the enemy. This prevents enemies getting    // 'stuck' inside a trigger if they overlap into it too far.    if (enemy.lastTrigger !== trigger) {      // Reverse the velocity of the enemy and remember the last trigger.      enemy.body.velocity.x *= -1;      enemy.lastTrigger = trigger;    }  }}

The idea would be to place these triggers either manually or via the same routine that generates your maps so they exist wherever an enemy should 'patrol'. By adding a final check to the enemies in the collision callback to reverse their direction if they're touching/blocked on the left or the right, you should have all bases covered - enemies will not walk off ledges unless you let them, and they will change direction if they walk into a wall.

Link to comment
Share on other sites

just my 2 cents to the trigger method..   i use it in my own game and it is a very easy way to go..  i am using tilemaps i create with tiled and i think the simplest way to do this is to add an extra layer (i call it "enemybounds") and on this layer i place little traffic cones at those points where i want my enemies to stop/turnaround..   the rest is really easy.. i initialize the layer like every other layer, then assign a collision group to that layer that only collides with enemies and then i set this layer to visible = false; so i don't get distracted from the traffic cones :)

view-source:http://test.xapient.net/phaser/ALL/

have a look at the function (setupLayers)

 

of course the enemymovement in p2 is not that easy..  i am making use of two other custom functions (touchingLeft / touchingRight )  and use a separate funciton (moveAliveEnemy)  to move the enemies..  so maybe it's not that easy after all ^^

 

i really like the idea with sensors..  it seems easier when i think about it..   in p2 everything can have several shapes ..  adding a shape is easy..    mynewshape= player.body.addCircle(22, 10, 20);   [radius,offsetx,offsety]  and this shape can then act as sensor to "sense" ground and the moment it is not colliding you would turn around the enemy...

Link to comment
Share on other sites

Sensors is certainly the more dynamic and interesting way to go. Usually modern games employ a mixture of the two - the AI has rudimentary senses so it can make dynamic decisions, and the worlds have triggers and zoning that helps the AI along and makes the game more predictable and thus easier to get working the way you want it.

 

I personally find this part of games programming very interesting and enjoyable :)

Link to comment
Share on other sites

It's working you can see it here http://s475613576.onlinehome.fr/portfolio/jeu/triggers/index.html

APP.enemy = game.add.group();    tabEnemy = [];    tabEnemy[0] = APP.enemy.create(2477, 1938, 'enemy');    game.physics.enable(APP.enemy);    for(i=0;i<tabEnemy.length;i++){    tabEnemy[i].body.velocity.x = -100;}    APP.reverseEnemyTriggers = game.add.group();    tabTriggers = [];    tabTriggers[0] = APP.reverseEnemyTriggers.create(1968, 1936, 'trigger');    tabTriggers[1] = APP.reverseEnemyTriggers.create(2492, 1936, 'trigger');    game.physics.enable(APP.reverseEnemyTriggers);};function update_enemy() {    game.physics.arcade.overlap(APP.enemy, APP.reverseEnemyTriggers, function(enemy, trigger) {        // Do a simple check to ensure the trigger only changes the enemy's direction        // once by storing it in a property on the enemy. This prevents enemies getting        // 'stuck' inside a trigger if they overlap into it too far.        if (enemy.lastTrigger !== trigger) {            // Reverse the velocity of the enemy and remember the last trigger.            enemy.body.velocity.x *= -1;            enemy.lastTrigger = trigger;        }    });};

I have last one answer when i do APP.enemy.body.velocity.x it's not working i have to do set the velocity one by one with a for loop. Any idea ?

Link to comment
Share on other sites

Just as a little note, rather than explicitly setting the key of each item in the array (i.e. doing tabTriggers[0] = ...) you can simply do tabTriggers.push(...) which will just add an item to the array at the next available index.

 

As for setting a property on all items in the group, you can either do it by the loop, Group.forEach or most easily for your specific need, using the Group.setAll method in place of your for loop, like so:

// set the body.velocity.x of every child in this group that is alive to -100APP.enemy.setAll('body.velocity.x', -100, true);
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...