Pau

Trigger an action on overlapping just one time

Recommended Posts

Hello,

I want to trigger the "goal" function just one time, when one of the elements of the "players" group enter in the the overlappingArea. Now, the "goal" function is triggering multiple times, while one of the player's group is over the overllapping area. How can i trigger just one time, when the player enter in the zone?

this.physics.add.overlap(players, overlappingArea, goal);

Thank you in advance

Share this post


Link to post
Share on other sites

Hi Pau,

This is a way to do that (tested on phaser 3 sandbox):

var overlapCollider;
var overlapTriggered = false;

/* ...... */

function create(){

    /* ..... */

    overlapCollider = this.physics.add.overlap(players, overlappingArea, goal.bind(this));

};

function goal(){

    if(overlapTriggered){
      this.physics.world.removeCollider(overlapCollider);
      return;
    };

    console.log('overlap');
    overlapTriggered=true;
};

Without using the variable overlapTriggered, goal() would be executed 2 times.

Regards.

Share this post


Link to post
Share on other sites

Ah!

Sorry about my wrong explanation :(

I want  the event to trigger each time the car pass across the goal zone. With your code it only trigger one time.

Thank you

 

s.png

Share this post


Link to post
Share on other sites

Hi again @Pau,

I think you can use something like this (I'm sure you can improve this code 😁 , I usually use Phaser CE)  :

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: {
        default: 'arcade',
        arcade: {
            debug: true,
            gravity: { y: 200 }
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var zone1;
var zone2;
var group;

new Phaser.Game(config);

function preload ()
{
    this.load.image('space', 'assets/skies/space.jpg');
    this.load.image('block', 'assets/sprites/bikkuriman.png');
}

function create ()
{
    this.add.image(400, 300, 'space');

    /* Creating group with 2 elements */
    var group = this.add.group(this);

    /******************** Adding two cars to the group*/

    /**************************** CAR1 */
    var car = group.create(50,150,'block');
    this.physics.world.enable(car);
    car.body.setVelocity(50,0);
    car.body.setAllowGravity(false);
    /* Custom properties for CAR1 */
    car.name = 'car1';
    car.triggered = false;

    car.overlapIn = function (){
    this.triggered=true;
    }
    car.overlapOut = function (){
    if(this.triggered){
    console.log(this.name +' crossing goal');
    }
    this.triggered=false;
    }

    /******************* CAR2 */
    car = group.create(50,300,'block');
    this.physics.world.enable(car);
    car.body.setVelocity(100,0);
    car.body.setAllowGravity(false);
    /* Custom properties for CAR2 */
    car.name = 'car2';
    car.triggered = false;
    car.overlapIn = function (){
    this.triggered=true;
    }
    car.overlapOut = function (){
    if(this.triggered){
    console.log(this.name +' crossing goal');
    }
    this.triggered=false;
    }




    /* zone1 enable sprite to cross zone2 ("triggered" property is set to false)*/
    zone1 = this.add.zone(300, 50).setSize(5, 500);
    zone2 = this.add.zone(370, 50).setSize(5, 500);

    this.physics.world.enable(zone1);
    this.physics.world.enable(zone2);
    zone1.body.setAllowGravity(false);
    zone1.body.moves = false;
    zone2.body.setAllowGravity(false);
    zone2.body.moves = false;

    

    this.physics.add.overlap(group, zone1, overlapAction1.bind(this));
    this.physics.add.overlap(group, zone2, overlapAction2.bind(this));
}

function overlapAction1(objectCar,objectZone1){
    objectCar.overlapIn();
}

function overlapAction2(objectCar,objectZone2){
    objectCar.overlapOut();
}

function update ()
{
    zone1.body.debugBodyColor = zone1.body.touching.none ? 0x00ffff : 0xffff00;
    zone2.body.debugBodyColor = zone2.body.touching.none ? 0x00ffff : 0xffff00;
}

The two cars in the group have 2 custom properties ("name" and "triggered") and two custom methods ("overlapIn" and "overlapOut").

The goal line have 2 zones: When car overlaps zone1 "triggered is set to true (this enable the zone2 where is executed the goal action), and when car overlaps zone2 "triggered" is set to false after execute an action, in this case print in console the car name and "crossing goal".

The code can be tested editing the code in this example: https://labs.phaser.io/edit.html?src=src\physics\arcade\overlap zone.js   .

If you want to avoid cheats then you need place some check points in the track.

Regards.

Share this post


Link to post
Share on other sites

Hello onlycape,
Thank you very much for your help, and for your fast reply :).

I tried to integrate your code in mine, but it is giving me the next error:
"objectCar.entraEnArea1 is not a function".

I tried to give the car object (coche)  a property name called "love", but it says that the value is undefined.
If i try to make it without a group, it gives to me the same error. I would like to make it with a group, anyways.

function create() {
	map = this.make.tilemap({key:'level1'});	
	tileset = map.addTilesetImage('nombreDelTilesetEnTiled', 'nombreDelTilesetEnPhaser');
	carreteraLayer = map.createDynamicLayer('carreteraLayer', tileset,0,0);
	alrededoresLayer = map.createDynamicLayer('alrededoresLayer', tileset,0,0);	

	var players = findObjectsByType('player', map, 'objectsLayer');
	var metaIN = findObjectsByType('meta', map, 'objectsLayer')[0];
	var metaOUT = findObjectsByType('meta2', map, 'objectsLayer')[0];

	var metaObjIN = this.add.zone(metaIN.x, metaIN.y+32, metaIN.width, metaIN.height).setOrigin(0,0)
	this.physics.world.enable(metaObjIN);

	var metaObjOUT = this.add.zone(metaOUT.x, metaOUT.y+32, metaOUT.width, metaOUT.height).setOrigin(0,0)
	this.physics.world.enable(metaObjOUT);

        cursors = this.input.keyboard.createCursorKeys();

        coches = this.physics.add.group(this);

        player1 = coches.create(players[0].x, players[0].y,'car1');
        player2 = coches.create(players[1].x, players[1].y,'car2');
        player3 = coches.create(players[2].x, players[2].y,'car3');
        player4 = coches.create(players[3].x, players[3].y,'car4');

        Phaser.Actions.Call(coches.getChildren(), function(coche) {
        	coche.setDrag(100,100)
        	coche.parametros = {}
        	coche.love= 2
        	coche.entraEnArea1 = function (){
        		this.triggered=true;
        		console.log(this.name +' crossing goal');
        	}
        	coche.entraEnArea2 = function (){
        		if(this.triggered){
        		}
        		this.triggered=false;
        	}
        })
        this.physics.add.overlap(coches, metaObjIN, entra1.bind(this));
        this.physics.add.overlap(coches, metaObjOUT, entra2.bind(this));

        alrededoresLayer.setCollisionBetween(0, 500);
        this.physics.add.collider(coches, coches);
        this.physics.add.collider(coches, alrededoresLayer);
}

function entra1(objectCar,objectZone1){
    	console.log(objectCar)
    	console.log(objectCar.love)
    	objectCar.entraEnArea1();
}

function entra2(objectCar,objectZone2){
    	objectCar.entraEnArea2();
}

Thank you in advance.

Share this post


Link to post
Share on other sites

Hi @Pau,

Now it works, but is very strange for me . I don't know why, but with your code, the params of "entra1" and "entra2" are in other order (the car is the second parameter, not the first, thats the reason of the errors).The "if" of entraArea2 is the location to execute the crossing action.

Here the tested code in  https://labs.phaser.io/edit.html?src=src\physics\arcade\overlap zone.js :

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: {
        default: 'arcade',
        arcade: {
            debug: true,
            gravity: { y: 200 }
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var metaIn;
var metaOut;
var coches;

new Phaser.Game(config);

function preload ()
{
    this.load.image('space', 'assets/skies/space.jpg');
    this.load.image('block', 'assets/sprites/bikkuriman.png');
}

function create ()
{
    this.add.image(400, 300, 'space');

    



    /* metaIn enable sprite to cross metaOut ("triggered" property is set to false)*/
    metaIn = this.add.zone(300, 50).setSize(5, 500);
    metaOut = this.add.zone(370, 50).setSize(5, 500);

    this.physics.world.enable(metaIn);
    this.physics.world.enable(metaOut);
    metaIn.body.setAllowGravity(false);
    metaIn.body.moves = false;
    metaOut.body.setAllowGravity(false);
    metaOut.body.moves = false;

    /* GRUPO DE COCHES (2) */
    var coches = this.physics.add.group(this);

    player1 = coches.create(50, 150,'block');
    player2 = coches.create(50,300,'block');

        Phaser.Actions.Call(coches.getChildren(), function(coche) {
        	coche.body.setVelocity(100,0);
            coche.body.setAllowGravity(false);
        	coche.parametros = {};
        	coche.love= 2;           
        	coche.entraEnArea1 = function (){
        		this.triggered=true;
        	}
        	coche.entraEnArea2 = function (){
        		if(this.triggered){
                    //// Aquí pones la acción que quieres ejecutar al cruzar la meta ////
                    console.log('el coche con love '+ this.love + ' cruza por meta');
        		}
        		this.triggered = false;
        	}
        });  

        
    

    this.physics.add.overlap(coches, metaIn, entra1.bind(this));
    this.physics.add.overlap(coches, metaOut, entra2.bind(this));
}

function entra1(objectmetaIn,coche){    
    //console.log(objectmetaIn.love);
    coche.entraEnArea1();
}

function entra2(objectmetaOut,coche){
    //console.log(objectmetaOut);
    coche.entraEnArea2();
}

function update ()
{
    metaIn.body.debugBodyColor = metaIn.body.touching.none ? 0x00ffff : 0xffff00;
    metaOut.body.debugBodyColor = metaOut.body.touching.none ? 0x00ffff : 0xffff00;
}

Good luck!!

Share this post


Link to post
Share on other sites

Sorry if necro post, but I want to share for this solution that need little effort to code.
 

function update ()
{
    // Need to capture current state
    var currentTrigger = zone.body.touching.none;
    
    zone.body.debugBodyColor = zone.body.touching.none ? 0x00ffff : 0xffff00;

    // if there is the difference, then active! Just like that
    if ((this.lastOnTrigger == true) && (currentTrigger == false)){
       window.alert("ACTIVE!");
    }
    // Also need capture the latest state touch status
    this.lastOnTrigger = zone.body.touching.none;
}

Reference: Phaser 3 Example Overlap zone

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.