If you haven't played wormzone.io or snake.io then check them out if you're unfamiliar. The mechanics, though I thought would be simple, is giving me a bit of trouble. My snake moves more like a rope in that the tail doesn't move unless I've fully extended its length. What I want is each segment of the snake to continuously move along the path the head of the snake has taken. The coordinates of the snake and it's body segments are in world coordinates, not screen. The head is locked at the center (512,384 in my example) and the background map is offset based on the snake's position to make it look like you're moving. I just can't for the life of me get the body segments to move the way I want.
// Project: snakey
// Created: 2021-01-08
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "wormzone" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 60, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
Type Point
x as float
y as float
EndType
segs = 20
Type Worm
segs as Point[20]
EndType
w as Worm
w.segs[1].x = 512
w.segs[1].y = 384
for i = 2 to segs
w.segs[i].x = 512 + i*20
w.segs[i].y = 384
next i
c = makeColor(255,128,0)
c1 = makeColor(255,0,0)
map as integer[10,10]
f = makeColor(255,255,255)
drawBox(1, 1, 128, 128, f,f,f,f, 1)
drawBox(128, 128, 256, 256, f,f,f,f, 1)
b = getImage(1,1,256,256)
b1 = createSprite(b)
//b1 = createSprite(loadImage("back.png"))
for x = 0 to 9
for y = 0 to 9
map[x,y] = cloneSprite(b1)
next y
next x
setSpriteVisible(b1, 0)
mapX = 0
mapY = 0
do
// Update body segments
for i = segs to 2 step -1
x# = w.segs[i-1].x - w.segs[i].x
y# = w.segs[i-1].y - w.segs[i].y
d2 = x#^2 + y#^2
if d2 >= 400 // keeps segments at 20px apart
d# = sqrt(d2)
x# = x# / d#
y# = y# / d#
w.segs[i].x = w.segs[i].x + x# * 3
w.segs[i].y = w.segs[i].y + y# * 3
endif
drawEllipse(w.segs[i].x+mapX, w.segs[i].y+mapY, 10, 10, c1, c1, 1)
next i
// Direction of head
x# = getRawMouseX() - 512
y# = getRawMouseY() - 384
d# = sqrt(x#^2 + y#^2)
if d# < 1 then d# = 1
x# = x# / d#
y# = y# / d#
// Update head position
w.segs[1].x = w.segs[1].x + x#*3
w.segs[1].y = w.segs[1].y + y#*3
// Head position fixed at [512,384], offset map instead to show movement
mapX = 512 - w.segs[1].x
mapY = 384 - w.segs[1].y
// Draw head
drawEllipse(512, 384, 10, 10, c, c, 1)
// Draw body segments
for x = 0 to 9
for y = 0 to 9
setSpritePosition(map[x,y], mapX+x*252, mapY+y*250)
next y
next x
Sync()
loop