GR.OPEN 255,0,0,0,1 GR.ORIENTATION 0 PAUSE 1000 BUNDLE.CREATE global % *global* bundle pointer = #1 GR.SCREEN x, y, density sbh=5*density/32 % status bar height w=16 h=9 tempo=40 % ms nx=x/(w*21) ny=(y-sbh)/(h*21) GR.SCALE nx, ny y0=sbh/ny BUNDLE.PUT global, "y0", y0 % status bar height offset in new coordinate system r=250*RND()+5 % define background main color v=250*RND()+5 b=250*RND()+5 DIM boardCol[w,h], boardDir[w,h] GR.BITMAP.CREATE bgnBmp, w*21, h*21 % bgnBmp is bitmap pointer #1 GR.BITMAP.DRAWINTO.START bgnBmp FOR y=1 TO h FOR x=1 TO w boardCol[x,y]=ROUND(200+55*RND()) GR.COLOR boardCol[x,y],r,v,b,1 GR.RECT nul,21*(x-1),21*(y-1),21*x,21*y boardDir[x,y]=0 NEXT NEXT GR.BITMAP.DRAWINTO.END GR.COLOR 255,0,0,0,1 GR.BITMAP.DRAW bgnPtr, bgnBmp, 0, y0 FN.DEF CROP(src_bmp, col, row) GR.BITMAP.CROP dst_bmp, src_bmp, 21*(col-1), 21*(row-1), 21, 21 FN.RTN dst_bmp FN.END FN.DEF HFLIP(src_bmp) % horizontal flip of image (left to right) GR.BITMAP.SIZE src_bmp, w, h GR.BITMAP.SCALE dst_bmp, src_bmp, -w, h FN.RTN dst_bmp FN.END FN.DEF VFLIP(src_bmp) % vertical flip of image (upside down) GR.BITMAP.SIZE src_bmp, w, h GR.BITMAP.SCALE dst_bmp, src_bmp, w, -h FN.RTN dst_bmp FN.END FN.DEF DRAW(bmp, col, row) GR.BITMAP.DRAWINTO.START 1 GR.BITMAP.DRAW ptr, bmp, 21*(col-1), 21*(row-1) GR.BITMAP.DRAWINTO.END FN.END FN.DEF RENDER(bmp, col, row) BUNDLE.GET 1, "y0", y0 GR.BITMAP.DRAW ptr, bmp, 21*(col-1), 21*(row-1)+y0 FN.RTN ptr FN.END FN.DEF FILL(bmp, a, r, v, b) GR.BITMAP.SIZE bmp, w, h GR.BITMAP.DRAWINTO.START bmp GR.COLOR 255,0,0,0,1 GR.RECT nul,0,0,w,h GR.COLOR a,r,v,b,1 GR.RECT nul,0,0,w,h GR.BITMAP.DRAWINTO.END GR.COLOR 255,0,0,0,1 FN.END ! Load and prepare graphics GR.BITMAP.LOAD bmp, "dog.png" bone=CROP(bmp,1,1) GR.BITMAP.CROP horneck, bmp, 42, 0, 3, 21 GR.BITMAP.CROP verneck, bmp, 42, 0, 21, 3 GR.BITMAP.CREATE horbar, 21, 3 GR.BITMAP.CREATE verbar, 3, 21 GR.BITMAP.CREATE square, 21, 21 DIM foot[4,2], head[4,2] % 4 directions + 2 animations DIM turn[4,4] % turning from 1 out of 4 directions to 1 out of 4 directions ! Note: East=1 / South=2 / West=3 / North=4 foot[1,1]=CROP(bmp,2,1) foot[3,1]=HFLIP(foot[1,1]) foot[4,1]=CROP(bmp,1,3) foot[2,1]=VFLIP(foot[4,1]) foot[1,2]=CROP(bmp,2,2) foot[3,2]=HFLIP(foot[1,2]) foot[4,2]=HFLIP(foot[4,1]) foot[2,2]=VFLIP(foot[4,2]) head[1,1]=CROP(bmp,4,1) head[1,2]=CROP(bmp,4,2) head[2,1]=CROP(bmp,3,3) head[2,2]=HFLIP(head[2,1]) % CROP(bmp,4,3) head[3,1]=HFLIP(head[1,1]) head[3,2]=HFLIP(head[1,2]) head[4,1]=VFLIP(head[2,1]) head[4,2]=VFLIP(head[2,2]) turn[1,4]=CROP(bmp,1,2) turn[2,3]=turn[1,4] turn[1,2]=CROP(bmp,3,2) turn[4,3]=turn[1,2] turn[3,4]=HFLIP(turn[1,4]) turn[2,1]=turn[3,4] turn[3,2]=HFLIP(turn[1,2]) turn[4,1]=turn[3,2] GR.BITMAP.DELETE bmp ! Initialize and draw full dog length=3 % original dog length anim=1 % current step of the dog hgo=1 % current direction of dog head (E1/S2/W3/N4) hx=w-2 % INT((w-length)*RND()+length+1) % head X hy=INT(h/2)+2 % INT(h*RND()+1) % head Y oldhgo=hgo tgo=1 % current direction of dog tail (E1/S2/W3/N4) oldtgo=1 % old direction of dog tail tx=hx-2 % tail X ty=hy % tail Y tdir=1 % tail direction is > 0 tEW=1 % tail is going East/West (not South/North) head=RENDER(head[hgo,anim],hx,hy) % dog head (foreground) boardDir[hx,hy]=hgo GR.BITMAP.DRAWINTO.START bgnBmp FOR x=1 TO 7 % draw dog body (merged with background) GR.BITMAP.DRAW nul, horneck, 21*(hx-2)+3*(x-1), 21*(hy-1) NEXT GR.BITMAP.DRAWINTO.END boardDir[hx-1,hy]=hgo tail=RENDER(foot[tgo,anim],tx,ty) % dog tail (foreground) boardDir[tx,ty]=tgo body=RENDER(turn[1,4],hx-1,hy) % piece of dog body (top foreground, used for animation) GR.HIDE body !' DIM txtDir[w,h] !' GR.TEXT.SIZE 10 !' GR.COLOR 255,255,255,255,1 !' FOR y=1 TO h !' FOR x=1 TO w !' GR.TEXT.DRAW txtDir[x,y],21*(x-1)+5,21*y+y0,INT$(boardDir[x,y]) !' NEXT !' NEXT !' GR.TEXT.DRAW txtMain, 2, 10+y0, "" GR.RENDER PAUSE 500 GOTO MAINLOOP ! BEGINNING OF SUB-PROCEDURES: !'---------------------------------------------------------------------- WALKINIT: c=CLOCK() ! 1) Init head movement xh=21*(hx-1) % X pixel-position of head yh=21*(hy-1) % Y pixel-position of head hEW=MOD(hgo,2) % head going E1 or W3 (= horizontal movement) hdir=3-hEW-hgo % head direction E1/S2=+1 ; W3/N4=-1 ! 2) Init tail movement xt=21*(tx-1) % X pixel-position of tail yt=21*(ty-1) % Y pixel-position of tail IF oldtgo<>tgo THEN % special piece of body for animation of pivoting tail GR.MODIFY body, "bitmap", turn[oldtgo,tgo] GR.MODIFY body, "x", xt+21*tEW*tdir GR.MODIFY body, "y", yt+21*(1-tEW)*tdir+y0 GR.SHOW body END IF a=boardCol[tx+tEW*tdir,ty+(1-tEW)*tdir] % used to erase the body (re-paint background on top of it) oldtdir=tdir tEW=MOD(tgo,2) % tail going E1 or W3 (= horizontal movement) tdir=3-tEW-tgo % tail direction E1/S2=+1 ; W3/N4=-1 IF oldtgo<>tgo THEN FILL(square,a,r,v,b) ELSEIF tEW THEN FILL(verbar,a,r,v,b) ELSE FILL(horbar,a,r,v,b) ELSE END IF boardDir[tx,ty]=0 !' GR.MODIFY txtDir[tx,ty],"text",INT$(boardDir[tx,ty]) RETURN !'---------------------------------------------------------------------- WALKANIM: IF dz=1 THEN RETURN c=CLOCK() IF dz=3 | dz=7 THEN anim=3-anim GR.MODIFY head, "bitmap", head[hgo,anim] GR.MODIFY tail, "bitmap", foot[oldtgo,anim] END IF RETURN !'---------------------------------------------------------------------- RENDER: IF BACKGROUND() THEN EXIT GR.RENDER c=tempo+c-CLOCK() IF c>0 THEN PAUSE c RETURN !'---------------------------------------------------------------------- WALKEND: ! 1) End head movement IF oldhgo<>hgo THEN % if pivoting, direction of the turn is *new* direction boardDir[hx,hy]=hgo !' GR.MODIFY txtDir[hx,hy],"text",INT$(boardDir[hx,hy]) END IF hx+=hEW*hdir hy+=(1-hEW)*hdir boardDir[hx,hy]=hgo !' GR.MODIFY txtDir[hx,hy],"text",INT$(boardDir[hx,hy]) oldhgo=hgo ! 2) End tail movement tx+=tEW*tdir ty+=(1-tEW)*tdir oldtgo=tgo tgo=boardDir[tx+tEW*tdir,ty+(1-tEW)*tdir] % tails next direction is dictated by the body RETURN !'---------------------------------------------------------------------- ONBACKKEY: EXIT !'---------------------------------------------------------------------- MAINLOOP: DO ! Initialize movement variables GOSUB WALKINIT ! Update head and/or tail upon new direction IF oldhgo<>hgo THEN % dog is changing direction GR.MODIFY head, "bitmap", head[hgo,anim] IF hEW THEN GR.MODIFY head, "y", yh+y0 % going from S2/N4 to E1/W3 END IF ! Do head and tail movement animations (in 7 steps) FOR dz=1 TO 7 GOSUB WALKANIM ! H-1) Dog is going straight -> head goes to next board square in 7 steps IF oldhgo=hgo THEN IF hEW THEN % going E1/W3 GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, horneck, xh+hdir*(dz-1)*3+(1-hdir)*9, yh GR.BITMAP.DRAWINTO.END GR.MODIFY head, "x", xh+hdir*3*dz ELSE % going S2/N4 GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, verneck, xh, yh+3*hdir*dz+19*hgo/2-20 GR.BITMAP.DRAWINTO.END GR.MODIFY head, "y", yh+hdir*(2+3*dz)+y0 END IF ! H-2) Dog is changing direction -> head pivots in 7 steps ELSE DRAW(turn[oldhgo,hgo],hx,hy) IF hEW THEN % turning to E1/W3 IF MOD(dz,2)=1 THEN % speed-up this specific movement GR.MODIFY head, "x", xh+hdir*(dz+17) IF dz=5 THEN GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, horneck, xh-12*hgo+33, yh GR.BITMAP.DRAWINTO.END END IF END IF ELSE % turning to S2/N4 GR.MODIFY head, "y", yh+hdir*(2+3*dz)+y0 IF dz=7 THEN GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, verneck, xh, yh+hdir*(37-17*hgo/2) GR.BITMAP.DRAWINTO.END END IF END IF END IF ! T-1) Tail and body are aligned -> tail goes straight in 7 steps IF oldtgo=tgo THEN IF tEW THEN % going E1/W3 -> verbar xtt=xt+tdir*3*dz GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, verbar, xtt+9*(tdir+1), yt GR.BITMAP.DRAWINTO.END GR.MODIFY tail, "x", xtt ELSE % going S2/N4 -> horbar ytt=yt+oldtdir*3*dz+y0 GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul,horbar,xt,ytt+9*(tdir+1)-y0 GR.BITMAP.DRAWINTO.END GR.MODIFY tail, "y", ytt END IF ! T-2) Tail and body make a right angle -> tail pivots in 7 steps ELSE IF tEW THEN % turning to E1/W3 -> square IF MOD(dz,2)=1 THEN % speed-up this specific movement IF dz=7 THEN tx-=tdir ty+=oldtdir ytt=yt+oldtdir*21 GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, square, xt, ytt GR.BITMAP.DRAWINTO.END GR.MODIFY tail, "bitmap", foot[tgo,anim] GR.MODIFY tail, "y", ytt+y0 GR.HIDE body ELSE GR.MODIFY tail, "y", yt+oldtdir*dz+y0 END IF END IF ELSE % turning to S2/N4 -> square IF dz=7 THEN tx+=oldtdir ty-=tdir xtt=xt+oldtdir*21 GR.BITMAP.DRAWINTO.START bgnBmp GR.BITMAP.DRAW nul, square, xtt, yt GR.BITMAP.DRAWINTO.END GR.MODIFY tail, "bitmap", foot[tgo,anim] GR.MODIFY tail, "x", xtt GR.HIDE body ELSE GR.MODIFY tail, "x", xt+oldtdir*2*dz END IF END IF END IF IF dz=7 THEN GOSUB WALKEND % Finalize movement. Store new position GOSUB RENDER % Refresh graphics NEXT ! Handle user input to change direction. Or bounce off walls GR.TOUCH touched,x,y IF touched THEN x/=(21*nx) y/=(21*ny) IF x>=w/4 & x<=w*3/4 & y<=h/3 & hgo<>2 THEN hgo=4 % go North IF x>=w/4 & x<=w*3/4 & y>=2*h/3 & hgo<>4 THEN hgo=2 % go South IF y>=h/4 & y<=h*3/4 & x<=w/3 & hgo<>1 THEN hgo=3 % go West IF y>=h/4 & y<=h*3/4 & x>=2*w/3 & hgo<>3 THEN hgo=1 % go East END IF IF !crashonwalls THEN IF hgo=1 & hx=w THEN % bounce off East wall IF hy>h/2 THEN hgo=4 ELSE hgo=2 ELSE IF hgo=4 & hy=1 THEN % bounce off North wall IF hx>w/2 THEN hgo=3 ELSE hgo=1 ELSE IF hgo=3 & hx=1 THEN % bounce off West wall IF hy>h/2 THEN hgo=4 ELSE hgo=2 ELSE IF hgo=2 & hy=h THEN % bounce off South wall IF hx>w/2 THEN hgo=3 ELSE hgo=1 END IF END IF !' GR.MODIFY txtMain, "text", "head @"+INT$(hx)+","+INT$(hy)+"("+INT$(oldhgo)+"->"+INT$(hgo)+") ; tail @"+INT$(tx)+","+INT$(ty)+"("+INT$(oldtgo)+"->"+INT$(tgo)+")" GR.RENDER UNTIL 0