Discord
Login
Community
DARK THEME

Collision

Can someone please teach me how to do map and sprite collisions? What functions are supposed to be used and what is the math behind it?

im working on some code, one second

Ok, here is the starter code project, https://microstudio.dev/i/TedCodes/quickenginesamplecode/ The box is solid but it has properties like, solid, fixed (states in place), and other things,

In QuickEngine, a function called "Quick.spriteMapCollision" is responsible for detecting Sprite collisions with Maps.

When a Sprite has the solid field set to true, the solid surrounding the Sprite is determined so that it is larger than the Sprite. The area of ​​this solid will be tested (the edges of this solid).

For example: If a sprite moves to the right, tiles are tested on its right side along the entire height of the sprite.

If a collision occurs (there is a tile on the right side) - a new position of sprite.x will be calculated so that the edge of the sprite is next to the edge of the tile, the sprite.vx variable is set to zero (the sprite will not move further).

The same is done for the second coordinate axis.

ok i got it, but i wanted to know:

what is "s", "m" and "c"?

what is "break"?

what is the maths behind it?

s - this is Sprite

m - to Map ( Tilemap ) .

It's best if you consider the simplest case.

The map has 1x1 tiles.

The sprite has dimensions of 1x1 and can always move by an integer amount.

Now, to detect a collision, just call the map.get(x, y) method - which returns the name of the Sprite that is in this position (zero - if the space is empty).

You want to move the sprite to a specific position - you check whether all fields are empty along the way.

In QuickEngin it is more extensive because the Sprite can be larger than the tiles, so you have to check more than one place.

ok thank you so much!

but I still don't understand what "c" and "break" is.

break - is a keyword of the language. Reserved and cannot be used as e.g. a variable. Break - means that after encountering this word in the code, the program will stop executing the current loop (for or while), the next code that will be executed is the one after the loop.

Add this method to the engine, you will understand when you see.

Quick Engine file >>

Quick.drawSpriteMapCollision = function(s,m)

  if m.solid and s.solid then
    local x1 = s.x-s.width*.5
    local x2 = s.x+s.width*.5
    local y1 = s.y-s.height*.5
    local y2 = s.y+s.height*.5
    local cx1 = floor((x1-m.x+m.width/2)/m.width*m.map.width)
    local cx2 = floor((x2-m.x+m.width/2)/m.width*m.map.width)
    local cy1 = floor((y1-m.y+m.height/2)/m.height*m.map.height)
    local cy2 = floor((y2-m.y+m.height/2)/m.height*m.map.height)
    
    local scx1 = floor((s.x-s.width*.3-m.x+m.width/2)/m.width*m.map.width)
    local scx2 = floor((s.x+s.width*.3-m.x+m.width/2)/m.width*m.map.width)
    local scy1 = floor((s.y-s.height*.3-m.y+m.height/2)/m.height*m.map.height)
    local scy2 = floor((s.y+s.height*.3-m.y+m.height/2)/m.height*m.map.height)

    local ratioX = m.width/m.map.width
    local ratioY = m.height/m.map.height
    screen.drawRect( s.x, s.y, x2-x1, y2-y1, "rgb(255,255,255" )
    print( "x1: " + x1 + " y1: "+ y1)
    print( "cx1: " + cx1 + " cx2: " + cx2 )
    print( "cy1: " + cy1 + " cy2: " + cy2 )
    print( "scx1: " + scx1 + " scx2: " + scx2 )
    print( "scy1: " + scy1 + " scy2: " + scy2 )
    screen.setScale( camera.zoom,camera.zoom)
    screen.setColor("rgb(255,0,0)")
    screen.drawRect(
      ((cx2+cx1)/2 - m.map.width/2 ) * ratioX + ratioX/2, 
      ((cy2+cy1)/2 - m.map.height/2 ) * ratioY + ratioY/2, 
      (cx2-cx1+1) * ratioX, 
      (cy2-cy1+1) * ratioY)
    screen.setColor("orange")
    screen.drawRect( 
      ((scx2+scx1)/2 - m.map.width/2 ) * ratioX + ratioX/2, 
      ((scy2+scy1)/2 - m.map.height/2 ) * ratioY + ratioY/2, 
      (1+scx2-scx1) * ratioX, 
      (1+scy2-scy1) * ratioY) 
 
    for i=scx1 to scx2
      if s.vy<=0 then
        if isMapCellSolid(m,i,cy1) and not isMapCellSolid(m,i,cy1+1) then
          s.vy = 0
          s.y = m.y-m.height*.5+(cy1+1)*m.height/m.map.height+s.height/2-.01
          s.grounded = 1
          break
        end
      elsif s.vy>0 then
        if isMapCellSolid(m,i,cy2) and not isMapCellSolid(m,i,cy2-1) then
          s.vy = 0
          s.y = m.y-m.height*.5+cy2*m.height/m.map.height-s.height/2
          break
        end
      end
    end
    
    for i=scy1 to scy2
      if s.vx<0 then
        if isMapCellSolid(m,cx1,i) and not isMapCellSolid(m,cx1+1,i) then
          s.vx = 0
          s.x = m.x-m.width*.5+(cx1+1)*m.width/m.map.width+s.width/2
          break
        end
      end
      if s.vx>0 then
        if isMapCellSolid(m,cx2,i) and not isMapCellSolid(m,cx2-1,i) then
          s.vx = 0
          s.x = m.x-m.width*.5+cx2*m.width/m.map.width-s.width/2
          break
        end
      end
    end
  end
end

main file

draw = function()
 Quick.draw()
 Quick.drawSpriteMapCollision(test,map)
end

thank you so much @Loginus and @TedCodes for your help

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community