Jump to content

Trigger an action on overlapping just one time


Pau
 Share

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

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
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!!

Link to comment
Share on other sites

  • 6 months later...

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

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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