That's cool and inspired me to do the same basic thing in pygame (python 2.7). The next step would be to make a second "animation" that is really just flat and stationary, then "blend" both animations weighted more toward the stationary one on the endcaps (so the head/tail are more still like yours, I also just used blocks not letters, but they rotate to stay in line with snake body as well).
import pygame,random,time,math
class Spot(object):
def __init__(ss,x,y,ang,leti):
ss.x=x
ss.y=y
ss.ang=ang
ss.leti=leti
def makesnake(startang,rot,rad,wordreps,w,h):
step=w/(wordreps*6.0)
nsteps=wordreps*6
spots=[]
ang=startang
x=0
leti=0
for i in range(nsteps):
y=(h/2)+(math.sin(math.radians(ang))*rad)
s=Spot(x,y,None,leti)
spots.append(s)
x+=step
ang=(ang+rot)%360
leti=(leti+1)%6
return spots
def makesnakeanim(ang,angstep,rot,rotstep,rotmax,rotmin,rad,radstep,radmax,radmin,wordreps,w,h,frames):
snakeanim=[]
for i in range(frames):
spots=makesnake(ang,rot,rad,wordreps,w,h)
setspotangs(spots)
snakeanim.append(spots)
ang+=angstep
rot+=rotstep
if rot>rotmax or rot<rotmin:
rotstep*=-1
rot+=rotstep*2
rad+=radstep
if rad>radmax or rad<radmin:
radstep*=-1
rad+=radstep*2
return snakeanim
def drawsnake(spots):
for s in spots:
roted=pygame.transform.rotate(letrs[s.leti],s.ang)
screen.blit(roted,(s.x,s.y))
def setspotangs(spots):
for i in range(len(spots)-1):
x1=spots[i].x
y1=spots[i].y
x2=spots[i+1].x
y2=spots[i+1].y
spots[i].ang=math.atan2(y2-y1,x2-x1)*-180.0/math.pi
x1=spots[-1].x
y1=spots[-1].y
x2=spots[-2].x
y2=spots[-2].y
spots[-1].ang=math.atan2(y2-y1,x2-x1)*-180.0/math.pi
#spots[-1].ang=0
letrs=[]
for i in range(6):
s=pygame.Surface((12,12))
s.set_colorkey((1,1,1))
s.fill((random.randint(0,255),random.randint(0,255),random.randint(0,255)))
letrs.append(s)
sw=512
sh=512
screen=pygame.display.set_mode((sw,sh))
#startang=0
#rot=10
#rad=5
#anim1=makesnakeanim(0,8,5,1,20,1,32,3,96,16,6,512,512,100)
ang=0
angstep=8
rot=20
rotstep=1
rotmax=40
rotmin=10
rad=32
radstep=8
radmax=64
radmin=16
wordreps=6
w=512
h=512
frames=500
anim1=makesnakeanim(ang,angstep,rot,rotstep,rotmax,rotmin,rad,radstep,radmax,radmin,wordreps,w,h,frames)
cc=0
running=True
while running:
for e in pygame.event.get():
if e.type==pygame.QUIT:
running=False
screen.fill((255,255,255))
#spots=makesnake(startang,rot,rad,6,512,512)
#setspotangs(spots)
#drawsnake(spots)
drawsnake(anim1[cc])
pygame.display.flip()
time.sleep(0.1)
#startang+=4
#rad+=0.1
cc=(cc+1)%len(anim1)
pygame.quit()