Hotspots

Creating entities is no good without a map to walk them around on. But that's another tutorial. However, the relation is an important one, as you will most likely have areas of the map you don't want an entity to be able to move over, such as walls, water, wastepaper bins, whatever. For this the map has an obstruction layer that defines all the areas entities cannot cross.

However, an entity frame can be much larger than the area of the ground it appears to be standing on, so rather than preventing the frame from touching the map obstructions at all, you can define a hotspot area. This is simply a portion of the frame that cannot overlap with obstructions in the game. So for this sprite, we can set only the feet area as the hotspot area, making closer more accurate collision detection.



 hotspot_x 8
 hotspot_y 16
 hotspot_w 16
 hotspot_h 16

So, here is the hot spot defined, it starts at the coordinates 8,16 on the sprite (so 9th pixel in from the left, and 17th down), and is 16 pixels square.

This one hotspot is used for all entity frames (though it can be disabled, see below). In addition it is not possible to define runtime, you have to set the hotspot details in the MAK file. This may change in the future, but at the moment you'd have to load an entirely different CHR file to use a different hotspot configuration.

In these screenshots the white shading shows the map obstructions, and the coloured boxes over the entities are their hotspot areas. Look on the left here that it's possible to walk right up to an obstruction, but the entity stops and the borders do not overlap. See how the actual frame area is irrelevant, collisions only look at the hotspot area defined in the MAK file.

Note that collisions are pixel perfect as well, to the right it may look like the entity could move upwards, but in fact there is a slight overlap, so the pillar is blocking movement. It is possible to draw map obstruction tiles with sloped or rounded corners so that an entity will adjust it's move to slide past diagonally rather than being blocked - but the zones will never overlap.

Collisions between entities works in a similar way, but depends on how the entity.obstructable[] and entity.obstruct[] variables are set. If obstructable is true the entity can be obstructed by the map and other entities, if it is false then it will walk through everything. If obstruct is true the entity's hotspot will act as an obstruction to other entities, otherwise it will pass straight through. On the left the wandering entity with the purple box is trying to move, but the other entity has obstruct set and is blocking them. On the right the other entity does not have obstruct set, so the purple box entity has walked over them.

Note that for the 'player' entity being moved things are slightly different. When being moved by the user with arrow keys the entity is always obstructable, so is stopped by walls and any obstructing entities. When moved by the game with PlayerMove() is never obstructed by anything, to prevent the game hanging if the player can't move. The player entity will still obstruct other entities as normal though.

The various verge variables that state the positions of things in relation to each other in the game can get rather confusing. In general most map locations are given as an x,y coord in pixels, not map squares. Most map functions however require the map square coords, and to draw an image requires screen coords. The diagram on the left might help clarify a few things. Notably, the x,y value of an entity refers to the top left corner of their hotspot, rather that the sprite.

As often we can get a map coord (x,y) or an entity number (ent) know how to convert this to useful information is useful. Here are a list of common things you might want to do:

Get the map tile coord:
(x / 16),(y / 16)
To use GetTile(), SetTile() or other map functions to modify the map at runtime

Top left map coord of a tile:
(x - (x % 16)),(y - (y % 16))
Position of this on the screen:
(x - (x % 16) - xwin),(y - (y % 16) - ywin)
So you can blit a tile to the screen with BlitTile()

Position of entity frame on screen:
(entity.x[ent] - entity.hotx[ent] - xwin),(entity.y[ent] - entity.hoty[ent] - ywin)
So you can manually blit an entity with BlitEntityFrame()

Examples are from Parallel Seven, and game screenshots use Overkill's console utility to show the obstructions and entity hotspots.

Talkback

There are no talkbacks on this documentation page yet. Post the first?

Post a new comment?

Doc Nav

Your docs
View All Docs

If you log in, you can edit the documentation, or create your own documents and tutorials!

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.