Collisions with the landscape

ZXNet echo conference «code.zx»

From Valery Grigoriev To All 14 January 2006

Hello new art Usually such problems are solved mathematically, and not head-on. I didn’t quite understand from the problem statement what was needed - graphically (by pixels per screen) determine collision with terrain or mathematically? If the direction is known, the position is known, it is known in which direction it should If the character moves, then mathematically this problem can be solved very simply. First, an analysis is made to determine whether movement is possible, in principle, since the motion vector is known, you can see what obstacles are nearby, write an ordinary equation and make a comparison if the result is If we get an excess, then we don’t go/roll/fly any further. If not exceeding - we continue to move. The object/character itself will be characterized by dimensions - height and width. The starting point will be taken from anywhere (be it from the bottom or from the top). Then you need to evaluate the leftmost edge when moving the character to the left, when moving to the right, on the far right, down, respectively, on the bottom, up top. When combined movement, evaluate in two directions at once. The obstacles themselves can also be assessed by their size. Then they automatically will become as if convex - i.e. if there is an obstacle, then it is on the left and on the right and below and above will be impenetrable to the character. There is a Basic frame of reference - for example, the upper left corner of the screen.The counting is carried out along the X axis to the right and down the Y axis. There is a character who is famous: X1 - position X - the extreme left upper corner of the character is also taken Y1 - Y position deltaX1 - character width in X deltaY1 - Y height Likewise for obstacles: X2, Y2, deltaX2, deltaY2. It is known that the character should move N pixels to the right. Is it possible to move? If ( (Y1>Y2 and Y1Y2 and Y1+DeltaY1X1) [horizontal check] then it is impossible carry out the movement (there will be a collision). In all other cases, you can move to the right as much as you like. The mathematics is very simple - in the sense that there is no need to use calculator, etc., you can write all the procedures ready-made yourself.

From lvd To All 14 January 2006

Hello new art new> While making the game I came across a small problem. new> The hero and enemies moving across the landscape must new> smoothly go around it (as in Dizzy 7). As for landscape sprites, you can simply mark it as passable/impassable. And in the second layer, accordingly, draw/not draw it. A As for movements of several pixels at once, you can release “tentacles” length equal to the movement step, and if they encounter an obstacle, then accordingly, decide whether the hero was killed against the wall, or jumped 1 pixel and did not noticed, etc. Another radical option is to spend half a day picking the hole in the same disze. =)

From lvd To All 14 January 2006

Hello new art new> You misunderstood a little. The second layer is not drawn to the screen, it only new> is intended for checking collisions. If the sprite is 0 then it is empty new> that is, we go through the whole thing. new> You didn't understand this a bit. I'm telling you - if we see the sprite but we pass through, then we don't draw it to that layer, and if it’s impassable, then draw the same one as to the screen (possibly with post-return such as filling or thickening). > As for "tentacles", how is this different from my method? The fact that 1 time for each arbitrary change in coordinates is done.

From rasmer To All 14 January 2006

Hello, lvd lvd> Another radical option is to spend half a day picking the hole in that lvd> dizze. =) Better yet, disassemble the engine from the VAV demodizzy - it’s not like that it already weighs a lot - and to recycle it...

From Alexander Shushkov To All 14 January 2006

Hello new art new> The only way out that I have found so far is to call a subroutine new> check for collisions as many times as you need to move the sprite new> but this is clearly not the optimal method, especially if there is a lot on the screen new> enemies that work on the same principle. Since all the action takes place on one screen, there shouldn’t be very many enemies. a lot, so the speed should be enough. After all, you won’t have a hundred heroes run there at the same time. In general, you have Gogin nearby. Ask him, he already has experience.

From Vyacheslav Kalinin To All 14 January 2006

Hello, All While making the game I came across a small problem. The hero and enemies moving across the landscape must smoothly go around it (as in Dizzy 7). Vertical jumps are also possible during for whom the landscape overhead is not an obstacle, that is, the hero can seem to pass through it vertically fly over. Since there will be grass and other decorations on the landscape, I decided to create an additional set of sprites with outlines landscape. That is, the level map consists of two layers. When jumping while the hero is flying upward, collisions are generally possible do not process. But when the hero starts to fall after the jump how to distinguish vertical ones (I marked them in blue) obstacles (which serve to limit left-right movement)? In principle, you can allocate 2 bits per pixel (as in the example red (1) horizontal, blue (2) vertical, and 0 off pixel. Since there are quite a few obstacle sprites, you can It doesn’t even bother with bits, but allocate one byte per pixel. But there is one more problem, let’s say the hero falls after the jump, well, or even just runs, and the discreteness of movement a few pixels is acceptable 4. It’s easy to guess what’s in this In this case, the hero can simply slip through the obstacle. After all, not all the heroes are checked for conflicts with the landscape, but only a few pixels (in the middle near the legs). The only way out that I have found so far is to call a subroutineCheck for collisions as many times as you need to move the sprite, but this is clearly not the optimal method, especially if there is a lot of enemies that work on the same principle. Can you recommend anything? Perhaps my method is fundamentally wrong? I'm not much of a hacker, so I didn't pick games and see how it's done there. File: collision.png http://zx.pk.ru/attachment.php?attachmentid=2218

From Vyacheslav Kalinin To All 14 January 2006

Hello, lvd lvd> Because it is done once for every arbitrary change in coordinates. I'm confused, please explain in more detail. For example, it is known that a sprite must move into a given frame (at a time) by 4 pixels. What are the actions?

From Vyacheslav Kalinin To All 14 January 2006

Hello, lvd lvd> As for landscape sprites, you can simply mark what it is lvd> passable/impassable. And in the second layer, accordingly, draw/not lvd> draw it. And as for movements of several pixels at once - lvd> you can release "tentacles" with a length equal to the movement step, and if lvd> they come across an obstacle, then decide accordingly whether the hero is killed lvd> against the wall, or jumped 1 pixel and didn’t notice, etc. lvd> lvd> Another radical option is to spend half a day picking the hole in that lvd> dizze. =) You don't understand a bit. The second layer is not drawn on the screen, it is only for collision checking is intended. If the sprite is 0 then it is empty, that is, entirely let's pass. Regarding "tentacles", how is this different from my method? And in Dizi, it seems like the screen is being scanned.

From Vyacheslav Kalinin To All 14 January 2006

Hello, lvd lvd> You misunderstood a little. I'm telling you - if the sprite is visible but lvd> we pass, then don’t draw it to that layer, and if it’s impassable, then lvd> draw the same as on the screen (possibly with post-return type lvd> fill or thicken). How to draw the same if the sprite often has collisions and what They look completely different on the screen. Therefore, collision sprites are drawn manually. The collision map is created automatically using the correspondence table, but in the editor it is possible to change blocks manually (for cases when you need to for example, walk through a wall, like in dizi).

From Vyacheslav Kalinin To All 14 January 2006

Hello, rasmer ras> Or better yet, disassemble the engine from the VAV demodizzi - it ras> Tama doesn't weigh that much - so recycle it... He has nothing in common with what I do. My map sprite size is fixed and the map is screen sized.

From aprisobal To All 15 January 2006

Hello new art newart, maybe the following scheme will suit you: 1. There is a buffer (let’s call it a “collision buffer”) of 6144 bytes, into which, when entering location, special ones are drawn. location sprite masks. Like in your screenshot. 2. There is also a second collision buffer. The format should be similar to that of screen attributes, size 768 bytes. Depending on the type of sprite, it is entered into 4 bytes (if the sprite is 16x16px) data: 0 - empty, 1 - horizontal. shelf, 2 - vertical. wall. This buffer is also filled only when entering a location. 3. When jumping (no need to redraw anything in collision buffers, like here advised) disable the collision checking procedure with the horizon. shelves, but how As soon as the hero starts to fall, you turn it on. This procedure is horizontal. collisions should be the following: 1) add 1 pixel to the object in Y. If you need to move by 4 px, then We call this procedure 4 times. There is no other way - a flight is possible or you will have to constantly raise the hero to the height of the sprite, and in your case it’s is equivalent to calling this collision procedure. 2) recalculate pixel coordinates into familiar place coordinates and check the second collision buffer is the presence of a horizontal shelf. 3) check for collisions in the first buffer with instructions like: LD A,(IX):OR A:JR Z,sleduyschiybayt:LD A,(HL):AND E:CP (HL):JR NZ,chtotoest:INC HL:INCIX.... (and so on three times for a 16px sprite) where HL is the coordinate address (X of the hero + offset to the bottom line of the hero sprite) in the first collision buffer, E,... - masks (already called) of the bottom line of the hero's sprite. 4) obsessing..... The maximum per object will be 1000 ticks. 10x1000=10000 cycles.