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

1 decade ago by SnakePlissken

Ok so been wondering how turn based games work in this engine. So far I am having trouble manipulating the tiles and entities how I would like. Think of a game like advanced wars for the DS is what I am looking for. I have implemented this in regular javascript via dynamic onclick events via images set on a canvas but wondering how this would work in this engine. The problem I seem to have is that placing functions in the update portion of the code causes the function to fire constantly (obviously sinces its constantly updating) so where else can I put functions in order for them to be fired up later in the code by an entity or tile click?

Thanks,

Snake

1 decade ago by Xander

Advance Wars rules. Great choice.

The update function may still work for you, but what you need is a boolean variable in your entity that you can set on/off depending if you want the update to fire.

update: function() {
     if (booleanCheck) {
          //do stuff
     }
}

Then just set that boolean to true whenever, ie. when something is clicked.

If it is an entity, for example:

ig.game.getEntitiesByType( EntityPlayer )[0].booleanCheck = true;

Is that any help?

1 decade ago by SnakePlissken

Thanks for the quick reply. I was figuring I would have to use something like what you are saying but wanting to know I am using best practice or not trying to reinvent the wheel. Would you place your Boolean check in the game scope rather than the entity scope?

Another problem I am running into is figuring out how to work with tiles and allowing highlighting of adjacent tiles when the entity is clicked to show movement range. I can get the tiles range but in order to find tiles must i just add z number of pixels on x plane and z number of pixels on y plane? And then how do i attach events to these tiles (would I need to create an entity on the fly)?

Sorry I am getting windy here but excited about getting started and wanting to understand the basics before I go to far.

1 decade ago by Xander

I am just a beginner myself, but I have a decent grasp of thins so far, I think. As far as best practices go, I don't know! I only know what I have been able to get working for myself.

The boolean could be global or local to the entity, depends on functionality, really. If you have the Troop entity, you aren't going to want to move him until a move order has been issued. So in the update function you might check for a move order, and if issued, increase the the Troop's position (in either x or y) in the update (and do so each update until the Troop is inside the target tile).

As for tile highlighting, I would spawn new entities for this. I wouldn't try rewriting map data, myself (but what do I know!). I assume you are using 16x16 tiles, so I would just spawn those at 16*numOfTile away from the center tile. That's what I'd do, but I don't know what the best strategy would be, per se.

My best advice is to just make it work, anyway you can, just to learn how Impact works. Once you have a working model, you will know how to do things better just through your own experience.

I am super excited by Impact as well and I am working on a Metroidvania style game. If you have google chat or something, we should exchange info, if you like, for chatting.

1 decade ago by Arantor

Honestly, I don't think I'd use Impact for stuff that isn't time sensitive... the amount of stuff required to make it fit into the model of canvas refreshing 60 times a second, and all the interface mashing that goes in with interacting with a canvas, personally seems to me to be the wrong way to do it.

1 decade ago by SnakePlissken

Yea I hear you Arantor but it seems like I am missing something or maybe its the engine itself but what I am seeking is the functionality like switching the image source of a tile on click of another image. Is it really that hard to accomplish in this engine? As for dealing with the update it seems pretty straight forward with the boolean value. However there should be a way to only fire a function once per event without the update function looping through it multiple times.

Xander I am more than willing to chat with you would be nice to chat with a fellow coder. However I would prefer not to place my email address on a public forum for fear of spam.

Thanks,

Snake

1 decade ago by Xander

Cool. I use Google's email service, username: davidjclarke

;)

1 decade ago by SnakePlissken

added currently testing out creating a ig.game bool variable to make sure the function inside update fires only once. Still looking into how to manage tiles onclick. seems like using an entity is an option I will have to test out to work my highlight functions.

Snake

1 decade ago by Arantor

Consider what you're asking. A canvas is essentially a black box; the click handler has no idea what's on the canvas, because it's just a rectangle of pixels.

It's notionally similar to clicking (once) on a block of text and getting the character back that you've clicked on - there's no functionality to support this in the web standards, but you can receive the click, receive its co-ordinates then figure out what is under them by going through what you have and figuring out what must be there.

It's not like the DOM when you have a collection of elements and are receiving a click on one which has a discrete level of existence of its own, its own element handling, etc.

1 decade ago by alexandre

A dichotomy then because ImpactJS is labeled as a game engine, which almost by definition implies input handling support.

1 decade ago by

So you are saying there is no way to make Ids to tiles? I think you could loop a x y coord function to set a name to each tile or is there no other way to distinguish it ?

1 decade ago by Arantor

Yes, it's a game engine but that doesn't immediately imply that it's suited to every kind of game that you can possibly make. Just as the Quake engine is also a game engine but again, it's not suited to every kind of game you can possibly make. Or Unity, or... whatever. It's an engine that suited to a rather versatile set of things, but less so for turn based stuff.

There's no way to apply an id to a tile itself, just as you can't readily apply an id to a single character in a div without wrapping it in a span (in which case it stops being a character in a div)

That's not to say you can't identify what tile the character is on; a collision map absolutely requires this by definition. But there's no magic methodology to it, you have to do some legwork.

You know the x,y position that the mouse is at, you can - if you do the work yourself - figure out what tile is under that square and any other entities drawn there too. But it's less an engine limitation and more a limitation of the canvas element that you can't magically identify what's there.

Folks, it's a canvas. It's a single element. Tiles and entities are - to the canvas - totally irrelevant. An entity is just a construct, it gets drawn to the canvas, but the canvas doesn't record there's an entity there, nor does it record what was drawn where, it just records the final state of drawing - it is just like a paint canvas.

Can you take a paint canvas, press it and magically be told what person was painted on the landscape? No, you can't. But you can keep a list of who was painted in a painting, and where, and do the legwork yourself.

1 decade ago by SnakePlissken

Sorry was I coming off like I thought I was owed something in the game engine? I just had a questions about the tools that were available to me in this engine. I am more than happy to do the legwork but wanted to make sure thats what had to be done before possibly reinventing the wheel.

1 decade ago by monkeyArms

I would probably create a click handler function which would do the required math to figure out which tile had been clicked. For example, if your tiles are 64x64, and your game map is 100 tiles x 100 tiles (6400 x 6400), you could do something like this (untested):



// in game init method:
ig.input.bind( ig.KEY.MOUSE1, 'click' );

// in game update method:
if( ig.input.pressed( 'click' ) ) {

	var tileSize = 64, // configure here
		numMapColumns = 100, // configure here
		x = ig.game._rscreen.x + ig.input.mouse.x,
		y = ig.game._rscreen.y + ig.input.mouse.y,
		row = Math.floor(x/tileSize),
		col = Math.floor(y/tileSize),
		index = (row*numMapColumns) + col;
		
	// now you know the row, column, and array index of the tile

}

1 decade ago by Arantor

Sorry for snapping, SnakePlissken. It's just that this question comes up a lot and it's because people are expecting the system to magically do everything for them. Impact does an awful lot but it's like any other tool: it's just that, a tool.

So many of the questions that arise here do so because very few people actually seem to understand the difference between normal HTML and the canvas element, and wonder why what should be obvious just doesn't work. I know I've explained it at least 3 times on the forum before now :/

The structure of the above is good, though it depends what you're trying to click on - if it's a tile, yes, the above will mostly do the job (though, note, you don't need the index generated at the end, the tile map is an array of arrays, so you could access it via row/column... then, which tile do you look at? The background map is not necessarily just one map...)

As far as determining a click on entity, you'd have to go through the list of entities and examine their pos.x, pos.y and whether the mouse click was within (pos.x <= mouse.x <= pos.x + size.x) && (pos.y <= mouse.y <= pos.y + size.y) or not, for each entity.

This is the sort of thing that references my above comment: if you're doing stuff that isn't time critical, Impact is probably the wrong tool for the job, because it's expecting to cope with redrawing the screen at 60 FPS. Whereas in a more conventional tile-based approach, you can set up all the things you want (and not even need a canvas, depending on what you're doing) and manage changes that way. The logic is basically the same but you don't have to get into event management and redrawing the screen every 1/60 seconds, you can set up a movement and apply a callback in a way that makes sense.

1 decade ago by SnakePlissken

Thanks for the replies all very good discussion going on here. The reason I am using impactjs is because I have animations and time sensitive like processes also in store for this application. So this is just one piece to the puzzle and sounds like there is defiantly ways to implement this in impact and hey who knows while coding this I may learn a few things which is mainly what I am interested in.

1 decade ago by alexandre

@Snake
I would delegate input handling to some SelectionManager non-entity class, a subscriber of entity selection events (see this).

In ig.game, every spawned game entity would have the selection manager as subscriber of "selection changed" events.

I would also create a SelectionCursorEntity object, the checkAgainst prop of which would look for overlaps with type A entities (your units' collision type).

As for the actual selection of game entities, I would try something like this:
1. in ig.game.update()
a. if (mouse.pressed('MOUSE1')), determine row/col from mouse.x and mouse.y
b. move the selection cursor to that location
2. in SelectionCursor.check(other), call other.select()
3. in Unit.select(), fire a "selection changed" event
4. in SelectionManager.selectionChanged(other)...
a. update selectedUnit(s) property,
b. then, calculate allowed move coordinates
c. then, ig.game.spawnEntity(DestinationCursor) for each allowed destination

Anyway, something like that.

1 decade ago by monkeyArms

One other way to approach the problem would be to use daveb's Events plugin. Then in your loadLevel() method, you could spawn an invisible 'tile' entity for every grid point on the map. The advantage to this is that there would be a physical entity on every grid position, and if you made the tile entity extended from ClickableEntity (through the Events plugin), the clicking is a lot easier to handle. It also would allow you to add hover effects when moused over a tile, etc. It shouldn't really affect performance much if you override the draw() call within the entity to only draw on hover or on click (so that only one entity is ever "drawn").

It's a bit of a complicated solution, but it does give you a lot of flexibility....just another thought ;)
Page 1 of 1
« first « previous next › last »