snake by lines

Hi, can anybode help me code snake controled by 2 arrows moving in 360 degrees? what about drawing style? it is better to use lines or ellipse? thanks

Hi @Cabernet there are a few snake examples already shared on the forum. Just search for snake or look through the Code Sharing Category (look over here →

yes but all of them have only 4 way movement on grid… I want to now how to figure out with snake moving in 360 degrees

Hey @Cabernet, I saw you commented on my snake project, so what you intend is to have a snake game which can go in any direction? I have a few comments on that:
###One:
Nice twist on the classic game! My greatest change from the classic game that I thought of was shooting fireballs :wink:
###Two:
I hope you have previous programming experience, as this idea has many complicated parts

1. The speed and direction of the snake would be tricky, with no grid
2. The gameplay (I think) would be tricky, because you could double back on yourself (nearly) and twist your snake in odd angles.
3. The control style would be tricky! Swipes? Turning by the arrows (like a car)

###Three
I am thinking lines, I tried ellipses, and although looking cool, it was quite hard to see.
###Four
I wouldn’t mind cooking something up for you…

@Cabernet @Jordan you guys made me reminisce of a game i used to play. here’s a link
http://www.neopets.com/games/game.phtml?game_id=500&size=regular&quality=high&play=true

I like the idea and started to code a bit to find out how this could be solved. I came across some problems which would be interesting to see if somebody has a solution for.

First i made the controls: Touching the screen on the left side turns left and touching right turns right. This just increases or decreases a number which is used as radians input for sin/cos to calculate the movement vector. Simply uses currenttouch, which is not perfect. Shold be done with touched function.

Then I tried to create a display sized image and render an ellipse into it at the new location to get the trail. But that was very slow, I got only 3 fps or so. This happened when I called setContext(), so my first question is, if this can be made faster? The drawing of that large image every frame was fast enough.
To avoid setContext() I tried the set function on the image, but even setting one pixel drops the frame rate from 60 to 10. Is there some trick to do that faster? Because having the playground in an image would make it easy to check the collision → just call image:get on the location of the head of the snake to see if there is a trail.

Finally I used the retained mode to draw the trail. That works fast, but I cant find a collision. So my final question is: Can I read the content of the current display (ogl color buffer) to check if there is a trail?

Why did I use this approach? I have no grid and want to move freely. But I did not want to save the whole trail as polyline and render it each frame and also check the whole polyline for a collision. So this seems a simple solution… if the collision could be solved.

Below you find the simple code for the retained mode approach. Of course, the touch handling should be done more stable and there are no borders. But it shows the concept:

-- Snake360
backingMode(RETAINED)

direction = 0    -- Degrees in radians.
curPos = vec2(WIDTH/2, HEIGHT/2)

-- Use this function to perform your initial setup
function setup()
    background(25, 25, 44, 255)
end

function draw()
    -- Change direction by touch:
    if CurrentTouch.tapCount >= 1 and (CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING) then
        if CurrentTouch.x < WIDTH/2 then
            direction = direction - DeltaTime * 2
        elseif CurrentTouch.x > WIDTH/2 then
            direction = direction + DeltaTime * 2
        end
    end

    local oldPos = vec2(curPos.x, curPos.y)

    curPos.x = curPos.x + math.sin(direction) * DeltaTime * 150
    curPos.y = curPos.y + math.cos(direction) * DeltaTime * 150

    -- Draw into playground image:
    pushStyle()
        smooth()
        strokeWidth(10)
        stroke(255, 109, 0, 255)
        line(oldPos.x, oldPos.y, curPos.x, curPos.y)
    popStyle()
end

BTW, there is a game in the store which has 360 freedom, it is called “Achtung”.

This is exactly what I was looking for. Description is very good too. Thanks

A solution for collision checking is to create an array with smaller resolution than the display. I tried with 1/4 of size and it works nicely :slight_smile: I’m still interested, if this could be solved in other ways like I tried above, but it was too slow… it is a bit different to work in retained mode and it doesnt work on ipad3, so other solutions would be nicer for me.

Try this code for controlling the speed and direction of your object. See comments at the beginning of the code to use either variable or constant speed. You can change the values of speedVariable or speedFixed to get the overall speed you want to use.


-- Here is a routine to control the direction 
-- of an object based on where you touch the 
-- screen or drag your finger.

-- set fixedSpeed to true to move the object at a 
-- constant speed.

-- set fixedSpeed to false to move the object at a 
-- speed thats faster the farther you touch 
-- from the object.

function setup()
    displayMode(FULLSCREEN)
    x=WIDTH/2
    y=HEIGHT/2
    sx=0
    sy=0
    speedVariable=50
    speedFixed=3
    fixedSpeed=true
end

function draw()
    background(40,40,50)
    fill(255,0,0)
    ellipse(x,y,10,10)
    x = x + sx
    y = y + sy
end

function getDirection()
    dx=CurrentTouch.x-x
    dy=CurrentTouch.y-y
    h=math.sqrt(dx*dx+dy*dy)
    if fixedSpeed then
        sx=dx*speedFixed/h
        sy=dy*speedFixed/h
    else
        sx=dx/speedVariable
        sy=dy/speedVariable
    end
end

function touched(t)
    getDirection()
end

Hello @Cabernet. My contribution to coding freely-moving snakes, inspired by your question and this discussion, is here.

@KilamMalik taking your code as a starting point I’ve implemented a version with images.
My solution was essentially to store the coordinates (or poly line as you said) and check the head position against the previous locations. I found interacting with images directly using get and set quite slow(well actually set rather than get), and though would give pixel point accuracy it’s overkill here.

I also got a wee bit carried away and implemented a eat the food to grow the snake function. I too haven’t implemented screen boundary detection and the screen only flashes when a collision with itself occurs

-- Snake360
--backingMode(RETAINED)
displayMode(FULLSCREEN)

-- Use this function to perform your initial setup
function setup()
    direction = 0    -- angle in radians.
    curPos = vec2(WIDTH/2, HEIGHT/2) -- position of snake head
    posArray={}-- table for coordinates
    snake=mesh()
    snakeimg=readImage("Cargo Bot:Star Filled")
    snake.texture=snakeimg
    food=mesh()
    foodimg=readImage("Cargo Bot:Smoke Particle")
    food.texture=foodimg
    foodPos =vec2(math.random(WIDTH-200)+100,math.random(HEIGHT-200)+100) -- initial position of food
    maxSize=50
end

function draw()
    snake:clear()
    food:clear()
    background(25, 25, 44, 255)
    -- Change direction by touch:
    if CurrentTouch.tapCount >= 1 and (CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING) then
        if CurrentTouch.x < WIDTH/2 then
            direction = direction - DeltaTime * 2
        elseif CurrentTouch.x > WIDTH/2 then
            direction = direction + DeltaTime * 2
        end
    end
--    store the previous position in a tableinserting it at the front
        local oldPos = vec2(curPos.x, curPos.y)
        table.insert(posArray,1,oldPos)
        --drop the tail off the snake according it the max size
        if #posArray>maxSize then
            table.remove(posArray)        
        end
--        calculate the new head position
    curPos.x = curPos.x + math.sin(direction) * DeltaTime * 150
    curPos.y = curPos.y + math.cos(direction) * DeltaTime * 150

    --detect collision between head and food
    -- very rough - calculate straight line distance between head and food
        if math.sqrt((foodPos.x-curPos.x)^2+(foodPos.y-curPos.y)^2)<15 then
            --increase the snake size
            maxSize = maxSize + 30
            --create food in a new random location
            foodPos =vec2(math.random(WIDTH-200)+100,math.random(HEIGHT-200)+100)
        end
    -- position the food
    local foodid=food:addRect(foodPos.x,foodPos.y,20,20)
    food:setRectTex(foodid,0,0,1,1)
 
    --miss out last 10 as it won't be possible to turn that quick and stops collision with immediate neighbour
        for i=10,#posArray do
            local idx=snake:addRect(posArray[i].x,posArray[i].y,20,20)
            snake:setRectTex(idx,0,0,1,1)
            -- fade out the tail
            snake:setRectColor(idx,255,255,255,255-(255*i/#posArray))
            if math.sqrt((posArray[i].x-curPos.x)^2+(posArray[i].y-curPos.y)^2)<5 then
                 --game over, but at the moment flash a random background colour
                 background(math.random(255),math.random(255),math.random(255), 255)
            end
        end
    food:draw()
    snake:draw()
end

Thanks @West for looking into that. I like that approach of using meshes and it is pretty fast even though you build up the rectangles each frame. I think thats the solution for @Cabernet question.

I think I did not write that in detail, but I wanted to have an endless trail. Then you have to live as long as possible in one or multiplayer environment (like tron). Thats why I chose the approaches in my comments above. But I dont like the retained mode when it comes to e.g. picking up items.

BTW, The star looks great when turning around corners… I will try that with retained mode :slight_smile:

@Cabernet, I hope you dont mind if I create a game like that. Your idea seems a bit different but your post lead me to ideas for some gameplay… well, maybe more a game like “Achtung”, but with some single player levels. its a small game so this could be the optimal first project for the app store for me… my mac mini arrived today :slight_smile: I hope retained mode works when compiled as ipa…

@KilamMalik Sound great! I am looking forward to your game… I want to develop some snake game but when i saw Achtung(thank you for this reminder) I decide to focus on something else… I am also looking for some mac mini or another mac device to start real developing for iOS. When your game will be in App store make sure to post about it.

Sorry for my English :wink: Cabernet

@West, finally I’m using your approach with meshes. I thought it would be too slow as I simply set the maximum length in your code higher. But I have missed, that you recreate the whole mesh each frame. you do that to cut the end, but I cluld just add rects as i want to keep the trail. thats now fast enough and I can have a trail of a few thousand rectangles :slight_smile: