Help Please! :)

I have been working on this snake game for a day, and i just realized a massive bug. When i eat the food, my snake dies, any suggestions? :slight_smile: CODE =

function touched(touch) if touch.state == BEGAN then inTouch = true elseif touch.state == ENDED then inTouch = false end end

function setup() displayMode(FULLSCREEN) Grid = {} – The table which holds all the squares of the game size = 32 inTouch = false ------------- – Variables for the colours of the grid EMPTY = 1 BODY = 2 HEAD = 3 FOOD = 4 -------------- for x = 1,32 do – I decided the perfect size for each block would be 32 X 32, so this fills for y = 1,24 do – up the screen (1024 X 768) so thats a 32 X 24 grid table.insert(Grid,Square(x,y)) end end fps = 5 frame = 0 Snake = {Head(),Body(17,13,2),Body(16,13,3)} food = Food() queue = 0 end

function draw() background(0) if frame < fps then frame = frame + 1 else frame = 0 end food:draw() for i = 0,#Snake - 1 do Snake[#Snake - i]:draw() end for k,b in ipairs(Grid) do b:draw() end end

function gval(v) – function to take a vector and convert it to a place in the grid return ((v.x-1) * 24 + v.y) end

function stog(v) – function to take a location on the screen and translate it to the grid return vec2(math.ceil(v.x/32),math.ceil(v.y/32)) end

Body = class()

function Body:init(x,y,n) self.pos = vec2(x,y) self.n = n end

function Body:draw() Grid[gval(self.pos)]:body() if frame == 0 then self.pos = Snake[self.n-1].pos end if self.n == #Snake and queue > 0 then Snake[self.n+1] = Body(self.pos.x,self.pos.y,self.n+1) end end

Food = class()

function Food:init() self.pos = vec2(math.random(1,32),math.random(1,24)) while Grid[gval(self.pos)].occupied == true do self.pos = vec2(math.random(1,32),math.random(1,24)) end
end

function Food:draw() if Snake[1].pos == self.pos then Snake[1].pos = self.pos queue = queue + 1 fps = fps - 0.5 self:init() end Grid[gval(self.pos)]:food() end

Head = class()

function Head:init() self.pos = vec2(18,13) self.speed = vec2(1,0) L = vec2(-1,0) R = vec2(1,0) U = vec2(0,1) D = vec2(0,-1) end

function Head:draw() --if Grid[gval(self.pos)].occupied == true then close() end Grid[gval(self.pos)]:head() if frame == 0 then Snake[2].pos = self.pos self.pos = self.pos + self.speed if self.pos.x > 32 then self.pos.x = 1 end if self.pos.y > 24 then self.pos.y = 1 end if self.pos.x < 1 then self.pos.x = 32 end if self.pos.y < 1 then self.pos.y = 24 end end self:move() end

function Head:move() if inTouch == true and frame == 0 then smalltouch = stog(vec2(CurrentTouch.x,CurrentTouch.y)) dist = vec2(smalltouch.x - self.pos.x,smalltouch.y - self.pos.y)

axis = math.max(math.abs(dist.x),math.abs(dist.y))
if axis == math.abs(dist.x) then
    if dist.x > 0 then self:right() end
    if dist.x < 0 then self:left() end
else
    if dist.y > 0 then self:up() end
    if dist.y < 0 then self:down() end
end

end
end

function Head:left() if not (self.speed == L or self.speed == R) then self.speed = L end end

function Head:right() if not (self.speed == L or self.speed == R) then self.speed = R end end

function Head:up() if not (self.speed == U or self.speed == D) then self.speed = U end end

function Head:down() if not (self.speed == U or self.speed == D) then self.speed = D end end Square = class()

function Square:init(x,y) self.pos = vec2(x,y) self.colors = { – The colours that will be present on the screen/grid color(100, 100, 100, 255), – Grey, for a blank square color(255, 255, 255, 255), – White, for the body of the snake color(255, 0, 0, 255), – Red, for the head of the snake color(0, 255, 0, 255) – Green, for the apples } self.state = EMPTY self.occupied = false end

function Square:draw() fill(self.colors[self.state]) ellipseMode(CENTER) ellipse(-16 + self.pos.x32,-16 + self.pos.y32,size,size) self.state = EMPTY self.occupied = false end

function Square:head() self.state = HEAD self.occupied = true end

function Square:body() self.occupied = true self.state = BODY end

function Square:food() self.occupied = false self.state = FOOD end

You need to edit this post and put 3 tildes before and after the code, like

~.~~
Code
~.~~

But remove those periods. Then we can read the code properly.

Hello @Jordan. Help can be found here, but to get the most out of the forum you have to help people to help you. Unformatted code is hard to read. General questions are harder to answer than specific ones.

Oh, sorry, newbies mistake. I fixed this bug (It was a problem with the order of the draw calls :slight_smile: )and continued with my program, but now I have one more bug, and then I am done the game (minus a start screen and a pause menu)


-- Jordan 17 June 2012

function touched(touch)
    if touch.state == BEGAN then
        inTouch = true
    elseif touch.state == ENDED then
        inTouch = false
    end
end

function setup()
    displayMode(FULLSCREEN)
    Grid = {} -- The table which holds all the squares of the game
    size = 32
    inTouch = false
    -------------
    -- Variables for the colours of the grid
    EMPTY = 1
    BODY = 2
    HEAD = 3
    FOOD = 4
    --------------
    for x = 1,32 do -- I decided the perfect size for each block would be 32 X 32, so this fills
        for y = 1,24 do -- up the screen (1024 X 768) so thats a 32 X 24 grid
            table.insert(Grid,Square(x,y))
        end
    end
    fps = 15
    frame = 0
    Snake = {Head(),Body(17,13,2),Body(16,13,3),Body(15,13,4),Body(14,13,5)}
    food = Food(vec2(1,0))
    queue = 0
    dist = vec2(1,0)
    gameover = false
end

function draw()
    background(0)
    if gameover == false then
    if frame < fps then
        frame = frame + 1
    else
        frame = 0
    end
    food:draw()
    for i = 0,#Snake - 1 do
        Snake[#Snake - i]:draw()
    end
    for k,b in ipairs(Grid) do
        b:draw()
    end
    else
        for k,b in ipairs(Grid) do
        b:draw()
        end
        fill(255, 255, 255, 255)
        fontSize(40)
        text("GAMEOVER",WIDTH/2,HEIGHT/2 + 20)
        text("SCORE = "..#Snake,WIDTH/2,HEIGHT/2 - 40)
    end
        
end

function gval(v) -- function to take a vector and convert it to a place in the grid
    return ((v.x-1) * 24 + v.y)
end

function stog(v) -- function to take a location on the screen and translate it to the grid
    return vec2(math.ceil(v.x/32),math.ceil(v.y/32))
end

Body = class()

function Body:init(x,y,n)
    self.pos = vec2(x,y)
    self.n = n
end

function Body:draw()
    Grid[gval(self.pos)]:body()
    if frame == 0 then
        self.pos = Snake[self.n-1].pos
    end
    if self.n == #Snake and queue > 0 then
        table.insert(Snake,Body(self.pos.x,self.pos.y,self.n+1))
        queue = queue - 1
    end
end

Food = class()

function Food:init(eatspeed)
    Snake[1].speed = eatspeed
    self.pos = vec2(math.random(1,32),math.random(1,24))
    while Grid[gval(self.pos)].occupied == true do
        self.pos = vec2(math.random(1,32),math.random(1,24))
    end
    
end

function Food:draw()
    Grid[gval(self.pos)]:food()
    self.eatspeed = Snake[1].speed
    if Snake[1].pos == self.pos and frame == 0 then
        Grid[gval(self.pos)]:head()
        queue = queue + 1
        fps = fps - 0.5
        self:init(self.eatspeed)
    end
    
end

Head = class()

function Head:init()
    self.pos = vec2(18,13)
    self.speed = vec2(1,0)
    L = vec2(-1,0)
    R = vec2(1,0)
    U = vec2(0,1)
    D = vec2(0,-1)
end

function Head:draw()
    if Grid[gval(self.pos)].occupied == true then gameover = true end
    Grid[gval(self.pos)]:head()
    if frame == 0 then
        Snake[2].pos = self.pos
        self.pos = self.pos + self.speed
        text("Hallelujiah!",100,60)
        if self.pos.x > 32 then self.pos.x = 1 end
        if self.pos.y > 24 then self.pos.y = 1 end
        if self.pos.x < 1 then self.pos.x = 32 end
        if self.pos.y < 1 then self.pos.y = 24 end
    end
    self:move()
end

function Head:move()
    if inTouch == true  then
        smalltouch = stog(vec2(CurrentTouch.x,CurrentTouch.y))
        dist = vec2(smalltouch.x - self.pos.x,smalltouch.y - self.pos.y)
    end
    if frame == 0 then
        axis = math.max(math.abs(dist.x),math.abs(dist.y))
        if axis == math.abs(dist.x) then
            if dist.x > 0 then self:right() end
            if dist.x < 0 then self:left() end
        else
            if dist.y > 0 then self:up() end
            if dist.y < 0 then self:down() end
        end
    end
end

function Head:left()
    if not (self.speed == L or self.speed == R) then self.speed = L end
end

function Head:right()
    if not (self.speed == L or self.speed == R) then self.speed = R end
end

function Head:up()
    if not (self.speed == U or self.speed == D) then self.speed = U end
end

function Head:down()
    if not (self.speed == U or self.speed == D) then self.speed = D end
end
Square = class()

function Square:init(x,y)
    self.pos = vec2(x,y)
    self.colors = { -- The colours that will be present on the screen/grid
    color(100, 100, 100, 255), -- Grey, for a blank square
    color(255, 255, 255, 255), -- White, for the body of the snake
    color(255, 0, 0, 255),     -- Red, for the head of the snake
    color(0, 255, 0, 255)      -- Green, for the apples
    }
    self.state = EMPTY
    self.occupied = false
end

function Square:draw()
    fill(self.colors[self.state])
    rectMode(CENTER)
    rect(-16 + self.pos.x*32,-16 + self.pos.y*32,size,size)
    self.state = EMPTY
    self.occupied = false
end

function Square:head()
    self.state = HEAD
    self.occupied = false
end

function Square:body()
    self.occupied = true
    self.state = BODY
end

function Square:food()
    self.occupied = false
    self.state = FOOD
end