phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
36.94k stars 7.08k forks source link

Reset sprite frame when not overlap #1566

Closed wildfiremedia closed 9 years ago

wildfiremedia commented 9 years ago

A request for this feature with the ability for sprites itself to reset to original frame state when the overlap is false.

game.load.spritesheet('woodenplank', 'w.png', 200, 30);

game.physics.startSystem(Phaser.Physics.ARCADE) 
group = game.add.group()    
group.enableBody = true;
group.physicsBodyType = Phaser.Physics.ARCADE;

for(var i=3;i>0;i--){
    group.create(i*100, 100, 'woodenplank')
}

ccc=game.add.sprite(100, 100, 'dude')
game.physics.arcade.overlap(ccc, group, function(r, s){
    console.log("is overlap")
    s.frame=1
});
pnstickne commented 9 years ago

This is problematic to make generic and should be handled in game code.

  1. Doing this change requires that the sprite is then aware of its overlapping rules - ie. with whom is it overlapping? and why does it care?
  2. What happens if something different - eg. playing a sound - should happen when the sprite is no longer overlapping?

One way to detect when the overlap ends is to track a 'overlapping' flag with each sprite. Then, after each overlap update, check to see if this flag is [recently] set. To avoid having to clear the overlap flag the current time can be used / compared.

For example, in update:

var whence = game.time.now;

// Mark sprites that are currently overlapping
game.physics.arcade.overlap(ccc, group, function(r, s){
    console.log("is overlap");
    s.frame = 1;
    s.overlapToken = whence;
});

group.forEach(function (s) {
    if (s.overlapToken && s.overlapToken !== whence) {
        // was overlapping it is no longer overlapping
        s.frame = 0;
        s.overlapToken = 0;
    }
}, null, true);

There are other variations of approaches as well (this will check all the items in the group even if only have been overlapped), but this should hopefully solve your problem and also show why it shouldn't be handled generically.

wildfiremedia commented 9 years ago

Just thought Phaser demo line intersection was similar http://examples.phaser.io/_site/view_full.html?d=geometry&f=line+intersection.js&t=line%20intersection

The idea to have a characters/sprites aware of its surrounding which is done in 2D or top-view MMORPG when the player move near or overlap them, without having to write generic code that the characters can move around after the player do not approach them.

pnstickne commented 9 years ago

@wildfiremedia Notice how the linked demo really isn't "aware", but the check (for a single line-line intersection) is done each update and the appropriate color chosen based on the current intersection status. The code proposed above is generic across N sprites in the group. In both cases it is still game-specific logic.

Why the same code can't be done as is with the overlap is because overlap only detects when there is an overlap, but doesn't detect when there is no overlap - the approach above handles that, by remembering if there was a previous overlap and acting accordingly.

For specific games (and specific logic or restrictions placed upon it) different approaches can be used: but the approach depends on the specific game rules and physics/collision system being used.

photonstorm commented 9 years ago

Tend to agree this ought to be handled in userland code, sorry.