sprite walking over terrain/coll mask

Previous topic - Next topic

kaotiklabs


During the last LD I found a problem that coudnt solve properly.

I had a 2D terrain with a collision mask and just wanted to implement a sprite walking over it.
I just needed to use one point calculation (medium bottom) for the checks.

I thought about using setpixel but discarted for beeing slow.
I finally did it by adjusting up/down all the times the Y, but that obviously ends with a bit of flickering and another related things like an "elevator motion" when you move fast and the character goe trough the terrain. Im still thinking about a good solution without having to precalcullate the terrain heights.

Some sort of raycast collision calculation is possible in 2D?
Wich is the best way?

Vote Cthulhu! Because the stars are right!!!!
Ia Ia Cthulhu F' tang!

Kitty Hello

CREATESCREEN 0,1,8,8
USESCREEN 0
DRAWRECT RGB(255,0,128)
SETPIXEL(0,0,1)
USESCREEN -1

now you can SPRCOLL(1, x,y

kaotiklabs

Oh sorry, I mistyped SETPIXEL, wanted to write GETPIXEL.

I just need to know the upper pixel of a terrain/collider in a given X.
is possible?

now I have something like that (horrible coded)

Code (glbasic) Select
if sprcoll(character, terrain)
DEC Character.y, 1
else
INC Chracter.y, 1
endif


That obviously flickers and is ugly xD
Vote Cthulhu! Because the stars are right!!!!
Ia Ia Cthulhu F' tang!

Kitty Hello

you can use SPRCOLL with a single pixel sprite. Is that what you want?

kaotiklabs

I need a good method to follow the terrain (collision sprite) contour, so I must find the upper Y pixel of my collider.
Using SPRCOLL with a single pixel helps, but the problem still is wich method to use.

Maybe I could check for SPRCOLL from the bottom of the collision sprite to the coordinate Y where it stops colliding in order to find the top point. Dont know if this would be very CPU intensive thought.
Vote Cthulhu! Because the stars are right!!!!
Ia Ia Cthulhu F' tang!

kanonet

Or you use SPRITE2MEM? Of cause generete the array jjt one time (not every loop) and check it when you need it. Should use to much cpu power.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Slydog

#6
Quote from: kaotiklabs on 2012-Apr-24Maybe I could check for SPRCOLL from the bottom of the collision sprite to the coordinate Y where it stops colliding in order to find the top point. Dont know if this would be very CPU intensive thought.
This should work, and not be too slow. 
Depends on your min and max range you specify to search in.

If it's fairly large (>30px? just a guess if that is a worthy range!) you could use a narrowing algorithm such as:

Code (glbasic) Select
// min_y -> Don't check above this 'y' location
// max_y -> Don't check below this 'y' location
// px -> current 'x' location of character
// tx,ty -> the terrain sprite x and y
FUNCTION FindUpperY: min_y%, max_y%,  px%,  tx%, ty%
LOCAL cur_y%
cur_y = (min_y + max_y) / 2  // Half way between min and max

WHILE (max_y - min_y) > 1 // quit when they are one apart (or meet)
// If pixel is colliding, cut range in half, and search above
IF SPRCOL(sp_pixel, px, cur_y,   sp_terrain, tx, ty)
max_y = cur_y
// Else, cut range in half, and search below
ELSE
min_y = cur_y
ENDIF
cur_y = (min_y + max_y) / 2  // Half way between min and max
WEND
RETURN cur_y
ENDFUNCTION


Something like the above (I haven't written one in a long time!), where you just halve the previous range until you are left with two adjoining pixels, one NOT colliding and one that IS colliding.  There's a point when just looping 1 pixel at a time may require fewer checks, all depends on your requirements.  You could always check every forth pixel (or something) until you find a collision, then back off a bit to find the exact pixel.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Wampus

One way to do it is to include path information with your terrain, i.e. instead of looking at individual pixels use descriptive lines or polygons then run your collision detection against them. The advantage is its easier to do totally smooth movement transitions if you're between pixels


kaotiklabs

#8
Wampus, your idea is fine, I have used it many times in the past, but in this case terrain is beeing randomly generated and is really curved (beziers) so I must find a way to do it on the fly.
Eitherway I dont discard to try it also.
I will test some of the methods comented here and lets see the performance results.
Vote Cthulhu! Because the stars are right!!!!
Ia Ia Cthulhu F' tang!

fuzzy70

Seeing as you generate the beziers to create your terrain is there not a way for the routine to store the height in an array to check against it in your collision detection. Just a thought but without seeing your code or the output I may be barking up the wrong tree. :noggin:

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

kaotiklabs

Beziers are used in the artist program, I dont have this data, so I´m looking for something more generic.
I´m trying to do it on the fly with a barely good performance, if is not possible, I will look for precalculation, but directly from the texture, loading the image in memory and checking the rgbs.
I have something now, but must be optimized.
Vote Cthulhu! Because the stars are right!!!!
Ia Ia Cthulhu F' tang!

Hemlos

Dont know if this will help or not...but it is very versatile:

http://www.glbasic.com/forum/index.php?topic=3839.0
Bing ChatGpt is pretty smart :O

Marmor

maybe a second bitmap with the collisionsline is much better as spcol and other solution.