How to improve Pico-8 Collision?

137 Views Asked by At

Error: Attempt to index global 'W' (a nil value)

Hello! I am having trouble getting collision working with a different system that spawns sprites in from the map screen.

This is the collision tutorial I used: https://youtu.be/Recf5_RJbZI?si=Df6FbJ2FYfCN39Qx This is the sprite spawning tutorial I used: https://youtu.be/8jb8SHNS66c?si=233nn8z_S1R4R64n

I have watched TONS of tutorials on this and still can't wrap my head around it. A lot of tutorials create very basic collision that has issues, like only being able to work with certain speed values (1,2,4,8,16,etc.) or that don't let your character slide alongside a wall when holding a diagonal.

Can anyone help? I definitely want to use this spawning system in the future to spawn in different types of walls and enemies. I have a feeling that I am misunderstanding how to use the table variables properly, so any explanation would be appreciated!

-- game loop --

function _init()
    cls()
    walls={}
    make_player()
    make_walls()
    -- top-left and lower-right
    -- bounds of player area
    a1,b1=8,8
    a2,b2=112,112
end

function _update60()
    -- keep inside the play area
    move_player()
    p.x=mid(a1,p.x,a2)
    p.y=mid(b1,p.y,b2)
end

function _draw()
    cls()
    draw_map()
    draw_player()
    
    for w in all(walls) do
        spr(w.wsp,w.wx,w.wy)
    end 
end
-- map --

function draw_map()
    map(0,0,0,0,16,16)
end
-- player --

function make_player()
    p={
    x=40,
    y=40,
    w=8,
    h=8,
    speed=2,
    sprite=1,
    }
end

function move_player()
    --move player with buttons
    --interacts with wall collision
    if (btn(⬅️)) then
        for newx=p.x,p.x-p.speed,-1 
            do
                if not box_hit(newx,p.y,
                    p.w,p.h,
                    w.wx,w.wy,
                    w.ww,w.wh) 
                then
                    p.x=newx
            end
        end
    end
        
        if (btn(➡️)) then
        for newx=p.x,p.x+p.speed 
            do
                if not box_hit(newx,p.y,
                        p.w,p.h,
                        w.wx,w.wy,
                        w.ww,w.wh) 
                then
                    p.x=newx
            end
        end
    end
        
        if (btn(⬆️)) then
        for newy=p.y,p.y-p.speed,-1 
            do
                if not box_hit(p.x,newy,
                        p.w,p.h,
                        w.wx,w.wy,
                        w.ww,w.wh) 
                then
                    p.y=newy
            end
        end
    end
        
        if (btn(⬇️)) then
        for newy=p.y,p.y+p.speed 
            do
                if not box_hit(p.x,newy,
                        p.w,p.h,
                        w.wx,w.wy,
                        w.ww,w.wh) 
                then
                    p.y=newy
            end
        end
    end
end

--draw player
function draw_player()
    spr(p.sprite,p.x,p.y)
end
-- walls --

function make_walls()
    for x=0,15 do
        for y=0,15 do
            if mget(x,y)==65 then
                add(walls,{
                    wx=x*8,
                    wy=y*8,
                    ww=8,
                    wh=8,
                    wsp=66
                })
                mset(x,y,64)
            end
        end
    end
end

--wall collision calculations

function box_hit(x1,y1,
        w1,h1,
        x2,y2,
        w2,h2)

        local hit=false
        local xd=abs((x1+(w1/2))-(x2+w2/2))
        local xs=w1/2+w2/2
        local yd=abs((y1+(h1/2))-(y2+h2/2))
        local ys=h1/2+h2/2  
    
    if xd < xs and yd < ys then
        hit=true
    end
    
    return hit
    
end
0

There are 0 best solutions below