Log In  
Follow
rbndr
agametopassthetime
by rbndr
SHOW MORE

edit: forgot cart

Cart #nonmapbasedcollisions-0 | 2024-02-20 | Code ▽ | Embed ▽ | No License
2

edit: solved!
Cart #nonmapbasedcollisions-1 | 2024-02-20 | Code ▽ | Embed ▽ | No License
1

Can anyone advise me on where I am going wrong with my collission detection. I want to be able to use table objects instead of map tiles and flags as I want to be able to continuously scroll for wider than the map allows.

I have pieced the following together from various sources (omitted the init and draw parts of the code, they just set up the various objects, but are in the carts code). It is using the method of checking whether the distance between the midpoints of two objects are smaller than the sum of the halves of the objects for both dimensions.

When something affects the players movement, either buttons or gravity, the new Y and X positions are run through a collision detection which loops through every object, with y then x positions being checked within each loop, if a movement results in a collision the new X or Y position is adjusted to the max position that doesn't overlap and momentum is stopped. If there is no collision the new X and Y positions become the actual X and Y positions, if there is a collision the new X and Y positions are adjusted before becoming the actual X or Y positions.

It almost works except for on corners where the player can get stuck and it judders. I've set up the cart so that it is easy to recreate the problem by falling/jumping along the vertical side of the squares while pressing left or right.

I guess this is where within a loop both X and Y are adjusted putting them back to a position where it will keep happening while those directions are maintained. I assume I have to give priority to one axis but I can't figure out how to do this. I was wondering what the best approach is for this.

Also is this approach on collisions generally ok or is there an easier or more efficient way, will it use up too much processing to do an entire map this way? I have tried to figure this out but most of the collision guides seem to be either map tiles and flags, or simple one pixel by pixel movement, or comparing only two objects at a time.

thanks

here

--move objects
function _update()
move(pl)

end

--move and collission functions

function move(obj) 

 if (btn(0)) then 
 obj.dx-=obj.acc --move left amount
 end

 if (btn(1)) then 
 obj.dx+=obj.acc --move right amount
 end

 if (btnp(5)) then 
 obj.dy-=obj.boost --move up amount when jump
 end

 --reduce vertical movement by gravity each update
 obj.dy+=gravity
 --reduce horizontal movement by friction
 obj.dx*=friction

 --limit max speed in all directions
 obj.dy=mid(
 -obj.max_dy,
 obj.dy,
 obj.max_dy)

 obj.dx=mid(
 -obj.max_dx,
 obj.dx,
 obj.max_dx)

    --new locations if movement applied
 obj.newx=obj.x+obj.dx
 obj.newy=obj.y+obj.dy

 --check whether new locations collide with other objects
 --will adjust newx/newy positions to not overlap collided object

        for v in all(things) do
        if v!=pl then
        --check collision of new vertical
    box_hit(obj,v,"y")
    --check collision of new horizontal
    box_hit(obj,v,"x")
            --apply new positions (adjusted to stop before collide)
    end
    end

 obj.y=obj.newy 
 obj.x=obj.newx     

 obj.y=mid(0,obj.y,120)
 obj.x=mid(0,obj.x,120)

end

function box_hit(obj,obj2,axis)

--compares one object x/y/w/h to another  
--axis is which dimension of movement being checked
--hitbox different depending on direction

  if axis=="y" then
  y1=obj.newy
  x1=obj.x

  elseif axis=="x" then
  y1=obj.y  
  x1=obj.newx
  end

  w1=obj.w
  h1=obj.h
  x2=obj2.x
  y2=obj2.y
  w2=obj2.w
  h2=obj2.h

  --collision check method 
  --if distance between midpoints greater than 
  --the sum of the two box halves

  --distance mid points
  local xd=abs((x1+(w1/2))
  -(x2+(w2/2)))
  --sum of box widths/2
  local xs=w1*0.5+w2*0.5
  --distance mid points
  local yd=abs((y1+(h1/2))
  -(y2+(h2/2)))
  --distance mid points
  local ys=h1/2+h2/2

if xd<xs and 
   yd<ys then 

--is a collission    

  if axis=="y" then
    --kill vertical momentum
                obj.dy=0
    if y1<y2 then
    --if collide from above limit movement to last non collide point 
    obj.newy=flr(y1-(ys-yd)) 
    else 
    --if collide from below limit to lowest point of 2nd object
    obj.newy=ceil(y2+h2) end

  else
    --kill horizontal momentum
                obj.dx=0

    if x1<x2 then
    --if colliding from left
    obj.newx=flr(x2-obj.w) 
    else 
    --if colliding from right
    obj.newx=ceil(x2+w2) end

 end
 end 
P#141692 2024-02-20 19:36 ( Edited 2024-02-20 22:18)

SHOW MORE

this is my first attempt at doing anything in pico 8, or any game. there isn't much game play yet though.

updated idle animation in v2

Cart #agametopassthetime-2 | 2023-11-01 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
30

P#136700 2023-10-31 20:25 ( Edited 2023-11-01 14:55)

Follow Lexaloffle:          
Generated 2024-03-03 19:11:41 | 0.067s | Q:18