Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

8 years ago by MikeL

I turned some work I did earlier into an official plugin to extend Impact. For games that could be described as 2.5D, whereby you need certain entities to appear in front of others, there are 2 new functions which can be helpful:

ig.Game.swapzIndex - for directly swapping 2 entities' zIndex without having to sort.

ig.Entity.moveToFront - for ensuring that an entity is always "in front" of all other entities, such as a specialized pointer or, in my current game, a scope entity.

More info is at Graphikos nice Point of Impact site.

8 years ago by Graphikos

Thanks for the contribution MikeL!

8 years ago by quidmonkey

Awesome!

Any reason you didn't use .splice() & .push() for ig.Entity.moveToFront()?

You could also add a ig.Entity.movezIndex:
//untested
//assume ig.game.entities is sorted
function: movezIndex( ent ){
	var ents = ig.game.entities, i = ents.length - 1;
	ents.splice( ents.indexOf( ent ), 1 );
	while( ents[--i].zIndex > ent.zIndex ){}
	ents.splice( i + 1, 0, ent );
}

8 years ago by MikeL

Thanks quidmonkey. I'll be able to show it in action once I get my game in a working state in the next week or two.

To answer your question Entity.zIndex does not (as far as my experiments and view of the Impact code) represent the entity's actual position in the array. Rather it is a tool used for sorting only. So setting it directly does nothing, unless you do a sort afterwards. Also after the sort, the ordering of entities may be quite different - which is fine in most cases.

What I am working on is a 2.5D (maybe more like 2.1D once you see it) game. In the game the player is looking down a street, with 3 rows of buildings each behind the other. Entities can land and collapse down with different buildings. In order to give the appearance of some entities being "behind" others, I had to be careful to never sort the entities. Instead I would just "swap" positions within the entity array (the actual z index).

Finally, I have a scope entity which always needs to be "in front" of the other entities. The simplest way to do it (without reordering) was to just do a swap with the last entity. Your idea of using splice is a good one and I may change it if needed. But so far this has been working, so I'm hesitant to change it for now. You know how that goes :)

8 years ago by quidmonkey

Hey, if it ain't broke. =)

I guess I was confused because sortEntities() does occur during the loadLevel() (line 48 of game.js). Thus, the ordering of ig.game.entities = zIndex ordering @ initialization. If you splice() it, you should be able retain an zIndex-ordered ig.game.entities without having to call sortEntities() again.

On the way home I thought of two improvements to movezIndex():

//untested
//assume ig.game.entities is sorted
function: movezIndex( ent ){
    var ents = ig.game.entities, i = ents.length - 1, z = ents.zIndex;
    ents.splice( ents.indexOf( ent ), 1 );
    while( i-- ){
    	if( ents[i].zIndex <= z ){
    		ents.splice( i + 1, 0, ent );
    		break;
    	}
    }
}

Again, untested, but should prevent Index Out-of-Bounds exceptions.

8 years ago by quidmonkey

Hmm...I should do some benchmarking, but I wonder if .sort() is still faster than my movezIndex() would be due to it being compiled vs interpreted.

But I had one more idea: what if you really did force zIndex to equal an Entity's index in ig.game.entities. You could override sortEntities() like so:

sortEntities: function() {
		this.entities.sort( function(a,b){ return a.zIndex - b.zIndex; } );
		for( var i = this.entities.length; i--; i ){
			this.entities[i].zIndex = i;
		}
	},

You'd then have to limit .zIndex to be within ig.game.entities.length during runtime. From there you could do this for movezIndex:

setzIndex: function( newZ ){
		newZ = newZ.limit(0, ig.game.entities.length - 1 );
		ig.game.entities.splice( this.zIndex, 1 );
		ig.game.entities.splice( newZ, 0, this );
		this.zIndex = newZ;
}

8 years ago by MikeL

If you splice() it, you should be able retain an zIndex-ordered ig.game.entities without having to call sortEntities() again.

I do agree with you, but of course lets say you splice out entity 20 of 50 and move it to then end. Then #20 becomes #50. But all other entities from the orginial 21-50 will move down one position in the array. The main reason I didn't want to do that is to avoid changing the position of a bunch of entities and perhaps(?) creating unwanted side effects during the frame cycle. Test it out and let me know though. I'd be glad to modify the plugin.

As to the setzIndex, it seems as though it would work. One issue though, is that you would also need to set the "actual" zIndex for any new entities that are spawned after the level has begun. It could get messy.

It's an interesting topic anyhow. What I've wanted to do, but haven't had the time, is to create multiple entity layers. I've thought of a couple of different ways. That could be potentially one very useful plugin.

8 years ago by quidmonkey

Good call on not updating ig.game.entities until after the frame. I forked your plugin. Let me know what you think.

I'd be interested in seeing the multiple layers.

8 years ago by MikeL

Interesting work quidmonkey. Have you tested it out in any games yet? When I get a chance, I'll try it out in my game. My approach was to basically leave a minimal "footprint" if you will to avoid side effects and debugging.

If you're interested in the multiple entity layers, one potential idea I had was to have an array of entity arrays in ig.Game. Update could cycle through each block of entities and then call each individual entity's update. Of course one would have to consider how each block would interact with the background collision layer. I would think probably just the "bottom-most" layer would be able to.

Also you would have to cycle through each block of entities during .checkEntities in ig.Game.

8 years ago by quidmonkey

I haven't tested it yet, but outside of syntax errors, I feel confident it'll work. My one qualm is the garbage collection on this.zEntities.

A 2d entity array for layers also occurred to me. You'll have to worry about performance if you're running frames for numerous layers, and then you'll also have to ensure collision detection is occurring on the proper frame. How would you assign entities to each layer? How would you deal with weltmeister?

8 years ago by MikeL

I put a link to your fork at the Point of Impact site.

As far as the 2d (or even more entity layers) goes, it should be relatively easy to do a check on entity-entity collision within each layer. Again, because only the "bottom" layer would interact with the background, it may actually speed things up a tad. Good point on Weltmeister and assigning entities. Hadn't thought about that part. They would need to be assigned, maybe within Welmeister as an entity variable. Then loadLevel would have to place each entity in it's proper layer.

8 years ago by PartTimeJohnny

Thanks for the plugin MikeL, works like a champ.

8 years ago by MikeL

That's great Johnny. I went ahead and pushed new changes to the moveToFront method based on quidmonkey's work. It works better if you need to move multiple entities to the front.

8 years ago by sunnybubblegum

Could you show a working example of the 'swap z-index' feature?

I don't know what to put in place of 'entityA' and 'entityB'.
Page 1 of 1
« first « previous next › last »