It makes use of Joshy's multiput.bi program to rotate the images.
In this example the turret just keeps slowly turning while randomly firing a bullet if one is available. When a tank hits an obstacle (another tank or a wall) it does a random turn away from the obstacle. When a bullet hits a brown tile (building) the tile is removed. When a bullet hits another tank the collision circle's color turns magenta.
Edit: changed multiput.bi to latest version
'multiput.bi
Code: Select all
#ifndef __MULTIPUT_BI__
#define __MULTIPUT_BI__
' Multiput by D.J.Peters (Joshy)
' MultiPut [destination],[xmidpos],[ymidpos], source,[xScale],[yScale],[Trans]
type FP16 ' fixed point 16:16
union
type
as ushort l
as short h
end type
as integer v
end union
end type
#define _ADD_ 0 ' increment a value
#define _CMP_ 1 ' compare values
#define _SET_ 2 ' set a value
#define _XScreen_ 0
#define _YScreen_ 1
#define _UTexture_ 2
#define _VTexture_ 3
#define _LeftIndex_ 0
#define _RightIndex_ 1
#define _CurrentIndex_ 0
#define _NextIndex_ 1
#define _EdgeXStart_ 0
#define _EdgeUStart_ 1
#define _EdgeVStart_ 2
#define _EdgeXStep_ 3
#define _EdgeUStep_ 4
#define _EdgeVStep_ 5
'#define UseRad 'if not then Rotate are in degrees
Sub MultiPut(Byval pTarget As Any Ptr= 0, _
Byval xMidPos As Integer= 0, _
Byval yMidPos As Integer= 0, _
Byval pSource As Any Ptr , _
Byval xScale As Single = 1, _
Byval yScale As Single = 1, _
Byval Rotate As Single = 0, _
Byval Transparent As boolean = false)
Dim As Integer SourceWidth=any,SourceHeight=any,SourceBytes=any,SourcePitch=any
Dim as Integer TargetWidth=any,TargetHeight=any,TargetBytes=any,TargetPitch=any
Dim As Integer i=any,yStart=any,yEnd=any,xStart=any,xEnd=any
Dim As Integer CNS(1,1)=any 'Counters
Dim As Integer ACS(1,2)=any '_ADD_ compare and _SET_
Dim As Single fPoints(3,3)=any,fEdges(2,6)=any,fLength=any,fUSlope=any,fVSlope=any
Dim As FP16 U=any,V=any,US=any,VS=any
Dim As boolean MustRotate = iif(Rotate<>0,true,false)
If (ScreenPtr()=0) Or (pSource=0) Then Exit Sub
If xScale < 0.001 Then xScale=0.001
If yScale < 0.001 Then yScale=0.001
If pTarget=0 Then
ScreenInfo _
TargetWidth , _
TargetHeight,, _
TargetBytes , _
TargetPitch
pTarget=ScreenPtr()
Else
ImageInfo _
pTarget , _
TargetWidth , _
TargetHeight, _
TargetBytes , _
TargetPitch , _
pTarget
End If
If (TargetWidth<4) Or (TargetHeight<4) Then Exit Sub
ImageInfo _
pSource , _
SourceWidth , _
SourceHeight, _
SourceBytes , _
SourcePitch , _
pSource
Select Case as const TargetBytes
case 1 ' TargetPitch shr=0 : SourcePitch shr=0
case 2 : TargetPitch shr=1 : SourcePitch shr=1
case 4 : TargetPitch shr=2 : SourcePitch shr=2
case else : exit sub
end select
fPoints(0,_XScreen_)=-SourceWidth/2 * xScale
fPoints(1,_XScreen_)= SourceWidth/2 * xScale
fPoints(2,_XScreen_)= fPoints(1,_XScreen_)
fPoints(3,_XScreen_)= fPoints(0,_XScreen_)
fPoints(0,_YScreen_)=-SourceHeight/2 * yScale
fPoints(1,_YScreen_)= fPoints(0,_YScreen_)
fPoints(2,_YScreen_)= SourceHeight/2 * yScale
fPoints(3,_YScreen_)= fPoints(2,_YScreen_)
fPoints(0,_UTexture_)=0
fPoints(1,_UTexture_)= SourceWidth
fPoints(2,_UTexture_)= fPoints(1,_UTexture_)
fPoints(3,_UTexture_)=0
fPoints(0,_VTexture_)=0
fPoints(1,_VTexture_)=0
fPoints(2,_VTexture_)= SourceHeight
fPoints(3,_VTexture_)= fPoints(2,_VTexture_)
If MustRotate=true Then
#ifndef UseRad
Rotate*=0.017453292 'deg 2 rad
#endif
var co = cos(rotate)
var si = sin(rotate)
For i=0 To 3
var x = fPoints(i,_XScreen_)*co - fPoints(i,_YScreen_)*si
var y = fPoints(i,_XScreen_)*si + fPoints(i,_YScreen_)*co
fPoints(i,_XScreen_) = x
fPoints(i,_YScreen_) = y
Next
End If
yStart=30^2:yEnd=-yStart:xStart=yStart:xEnd=yEnd
' get min max
For i=0 To 3
fPoints(i,_XScreen_)=Int(fPoints(i,_XScreen_)+xMidPos)
fPoints(i,_YScreen_)=Int(fPoints(i,_YScreen_)+yMidPos)
If fPoints(i,_YScreen_)<yStart Then yStart=fPoints(i,_YScreen_):CNS(_LeftIndex_,_CurrentIndex_)=i
If fPoints(i,_YScreen_)>yEnd Then yEnd =fPoints(i,_YScreen_)
If fPoints(i,_XScreen_)<xStart Then xStart=fPoints(i,_XScreen_)
If fPoints(i,_XScreen_)>xEnd Then xEnd =fPoints(i,_XScreen_)
Next
If yStart = yEnd Then Exit Sub
If xStart = xEnd Then Exit Sub
If yEnd < 0 Then Exit Sub
If xEnd < 0 Then Exit Sub
If yStart>=TargetHeight Then Exit Sub
If xStart>=TargetWidth Then Exit Sub
ACS(_LeftIndex_ ,_ADD_)=-1:ACS(_LeftIndex_ ,_CMP_)=-1:ACS(_LeftIndex_ ,_SET_)=3
ACS(_RightIndex_,_ADD_)= 1:ACS(_RightIndex_,_CMP_)= 4:ACS(_RightIndex_,_SET_)=0
' share the same highest point
CNS(_RightIndex_,_CurrentIndex_)=CNS(_LeftIndex_,_CurrentIndex_)
' loop from Top to Bottom
While yStart<yEnd
'Scan Left and Right edges together
For i=_LeftIndex_ To _RightIndex_
' bad to read but fast and short ;-)
If yStart=fPoints(CNS(i,_CurrentIndex_),_YScreen_) Then
CNS(i,_NextIndex_)=CNS(i,_CurrentIndex_)+ACS(i,_ADD_)
If CNS(i,_NextIndex_)=ACS(i,_CMP_) Then CNS(i,_NextIndex_)=ACS(i,_SET_)
While fPoints(CNS(i,_CurrentIndex_),_YScreen_) = fPoints(CNS(i,_NextIndex_),_YScreen_)
CNS(i,_CurrentIndex_)=CNS(i,_NextIndex_)
CNS(i,_NextIndex_ )=CNS(i,_CurrentIndex_)+ACS(i,_ADD_)
If CNS(i,_NextIndex_)=ACS(i,_CMP_) Then CNS(i,_NextIndex_)=ACS(i,_SET_)
Wend
fEdges(i,_EdgeXStart_) = fPoints(CNS(i,_CurrentIndex_),_XScreen_)
fEdges(i,_EdgeUStart_) = fPoints(CNS(i,_CurrentIndex_),_UTexture_)
fEdges(i,_EdgeVStart_) = fPoints(CNS(i,_CurrentIndex_),_VTexture_)
fLength = fPoints(CNS(i,_NextIndex_),_YScreen_) - fPoints(CNS(i,_CurrentIndex_),_YScreen_)
If fLength <> 0.0 Then
fLength=1/fLength
fEdges(i,_EdgeXStep_) = fPoints(CNS(i,_NextIndex_),_XScreen_ )-fEdges(i,_EdgeXStart_):fEdges(i,_EdgeXStep_)*=fLength
fEdges(i,_EdgeUStep_) = fPoints(CNS(i,_NextIndex_),_UTexture_)-fEdges(i,_EdgeUStart_):fEdges(i,_EdgeUStep_)*=fLength
fEdges(i,_EdgeVStep_) = fPoints(CNS(i,_NextIndex_),_VTexture_)-fEdges(i,_EdgeVStart_):fEdges(i,_EdgeVStep_)*=fLength
End If
CNS(i,_CurrentIndex_)=CNS(i,_NextIndex_)
End If
Next
If (yStart<0) Then Goto NextScanLine
xStart=fEdges(_LeftIndex_ ,_EdgeXStart_):If xStart>=TargetWidth Then Goto NextScanLine
xEnd =fEdges(_RightIndex_,_EdgeXStart_):If xEnd < 0 Then Goto NextScanLine
If (xStart=xEnd) Then Goto NextScanLine
if xEnd <xStart Then goto NextScanLine
fLength=1/(xEnd-xStart)
fUSlope=fEdges(_RightIndex_,_EdgeUStart_)-fEdges(_LeftIndex_,_EdgeUStart_):fUSlope*=fLength
fVSlope=fEdges(_RightIndex_,_EdgeVStart_)-fEdges(_LeftIndex_,_EdgeVStart_):fVSlope*=fLength
If xStart<0 Then
fLength=-xStart
U.v=(fEdges(_LeftIndex_,_EdgeUStart_)+fUSlope*fLength)*&HFFFF
V.v=(fEdges(_LeftIndex_,_EdgeVStart_)+fVSlope*fLength)*&HFFFF
xStart = 0
Else
U.v=fEdges(_LeftIndex_,_EdgeUStart_)*&HFFFF
V.v=fEdges(_LeftIndex_,_EdgeVStart_)*&HFFFF
End If
If u.v<0 Then u.v=0
If v.v<0 Then v.v=0
US.v=fUSlope*&HFFFF
VS.v=fVSlope*&HFFFF
If xEnd>=TargetWidth Then xEnd=TargetWidth-1
Select Case as const TargetBytes
Case 1
var s=cptr(ubyte ptr,pSource)
var t=cptr(ubyte ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ubyte c=*(s+V.h*SourcePitch+U.h)
If c Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
Case 2
var s=cptr(ushort ptr,pSource)
var t=cptr(ushort ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ushort c=*(s+V.h*SourcePitch+U.h)
If c<>&HF81F Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
Case 4
var s=cptr(ulong ptr,pSource)
var t=cptr(ulong ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ulong c=*(s+V.h*SourcePitch+U.h)
If c<>&HFFFF00FF Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
End Select
NextScanLine:
yStart+=1 : If yStart=TargetHeight Then exit while
fEdges(_LeftIndex_ ,_EdgeXStart_)+=fEdges(_LeftIndex_ ,_EdgeXStep_)
fEdges(_LeftIndex_ ,_EdgeUStart_)+=fEdges(_LeftIndex_ ,_EdgeUStep_)
fEdges(_LeftIndex_ ,_EdgeVStart_)+=fEdges(_LeftIndex_ ,_EdgeVStep_)
fEdges(_RightIndex_,_EdgeXStart_)+=fEdges(_RightIndex_,_EdgeXStep_)
fEdges(_RightIndex_,_EdgeUStart_)+=fEdges(_RightIndex_,_EdgeUStep_)
fEdges(_RightIndex_,_EdgeVStart_)+=fEdges(_RightIndex_,_EdgeVStep_)
Wend
End Sub
#endif ' __MULTIPUT_BI__
Code: Select all
#include "multiput.bi"
const Pi = 4 * Atn(1)
Dim Shared As single TwoPi = 8 * Atn(1)
Dim Shared As single RtoD = 180 / Pi ' radians * RtoD = degrees
Dim Shared As single DtoR = Pi / 180 ' degrees * DtoR = radians
'======== SET SCREEN SIZE, INK AND PAPER COLOR ====================
const SCRW = 1024
const SCRH = 480
screenres SCRW,SCRH,32
color rgb(0,0,0),rgb(100,255,100):cls
'bitmaps used
dim shared as any ptr TB,TT
TB = imagecreate(35,35)
' bload "tankBody.bmp",TB
TT = imagecreate(35,35)
' bload "tankTurret.bmp",TT
dim shared as any ptr backGround
backGround = imagecreate(1024,480)
' bload "backGround2.bmp",backGround
dim as ulong colors( 6)
colors(0)=RGB(255,0,255)
colors(1)=RGB(0,0,0)
colors(2)=RGB(166,202,240)
colors(3)=RGB(0,160,192)
colors(4)=RGB(192,192,192)
colors(5)=RGB(128,128,128)
dim as integer n
for j as integer = 0 to 34
for i as integer = 0 to 34
read n
pset TT,(i,j),colors(n)
next i
next j
for j as integer = 0 to 34
for i as integer = 0 to 34
read n
pset TB,(i,j),colors(n)
next i
next j
'create background bitmap from world tile id array
for j as integer = 0 to 14
for i as integer = 0 to 31
read n
if n = 1 then
line backGround,(i*32,j*32)-(i*32+31,j*32+31),rgb(128,64,0),bf
else
line backGround,(i*32,j*32)-(i*32+31,j*32+31),rgb(255,255,255),bf
end if
next i
next j
const TOTAL_TANKS = 8 'number of tanks on the field
type BULLET
as single x 'x position of center of disc
as single y 'y position of center of disc
as single dx 'change in x position per cycle
as single dy 'change in y position per cycle
as single v 'speed restricted to -1.0 to +1.0
as single rad 'radius of bullet image
as single angle 'direction in degrees
as ulong c 'color of bullet image
as integer alive 'bullet exists or not
end type
type TANK
as single x 'x position of center of disc
as single y 'y position of center of disc
as single dx 'change in x position per cycle
as single dy 'change in y position per cycle
as single v 'speed restricted to -1.0 to +1.0
as single rad 'radius of collision circle around center of image
as single angle1 'direction in degrees
as single angle2 'direction of turret
as ulong c 'color of DISC
as integer task 'current task being done by agent
as integer ID 'ID of agent
as integer lastAngle 'memory for agent during collision evasion
as integer hitWall 'memory for agent
as integer hittank 'memory for agent
end type
dim shared as TANK r(1 to TOTAL_TANKS)
'initialize tanks
for i as integer = 1 to 4
r(i).x = 42
r(i).y = i*42+140+50
r(i).v = 1 'moving forward
r(i).angle1 = int(rnd(1)*360) 'random direction of travel
r(i).angle2 = int(rnd(1)*360) 'random direction of turret
r(i).rad = 18
r(i).ID = i
'r(i).c = rgb(int(rnd(1)*256),int(rnd(1)*256),int(rnd(1)*256))
r(i).c = rgb(100,255,100)
next i
for i as integer = 5 to 8
r(i).x = SCRW-42
r(i).y = (i-4)*42+140+50
r(i).v = 1 'moving forward
r(i).angle1 = int(rnd(1)*360) 'random direction of travel
r(i).angle2 = int(rnd(1)*360) 'random direction of turret
r(i).rad = 18
r(i).ID = i
'r(i).c = rgb(int(rnd(1)*256),int(rnd(1)*256),int(rnd(1)*256))
r(i).c = rgb(100,100,255)
next i
dim shared as BULLET b1(1 to TOTAL_TANKS)
for i as integer = 1 to TOTAL_TANKS
b1(i).v = 0
b1(i).rad = 3
b1(i).c = r(i).c
b1(i).alive = 0 'not fired
next i
sub display()
screenlock
cls
put (0,0),backGround,trans
for i as integer = 1 to TOTAL_TANKS
circle (r(i).x,r(i).y),r(i).rad,r(i).c,,,,f
circle (r(i).x,r(i).y),r(i).rad,rgb(0,0,0)
line (r(i).x,r(i).y)-(r(i).x + cos(r(i).angle1 * DtoR)*r(i).rad,r(i).y + sin(r(i).angle1 * DtoR)*r(i).rad),rgb(0,0,0)
draw string (r(i).x-r(i).rad,r(i).y-r(i).rad),str(i)
multiput 0,r(i).x,r(i).y,TB,1,1,r(i).angle1,1
multiput 0,r(i).x,r(i).y,TT,1,1,r(i).angle2+r(i).angle1,1
if b1(i).alive = 1 then
circle (b1(i).x,b1(i).y),b1(i).rad,b1(i).c,,,,f
circle (b1(i).x,b1(i).y),b1(i).rad,rgb(0,0,0)
end if
next i
screenunlock
end sub
dim as single frameTimer
frameTimer = timer
dim as integer count = 1
do
if timer > frameTimer + 0.005 then
frameTimer = timer
'TEST FOR COLLISIONS
for i as integer = 1 to TOTAL_TANKS
'compute value to add to dx,dy for a given speed and direction
b1(i).dx = cos(b1(i).angle * DtoR) * b1(i).v
b1(i).dy = sin(b1(i).angle * DtoR) * b1(i).v
'move BULLET
b1(i).x = b1(i).x + b1(i).dx
b1(i).y = b1(i).y + b1(i).dy
'compute value to add to dx,dy for a given speed and direction
r(i).dx = cos(r(i).angle1 * DtoR) * r(i).v
r(i).dy = sin(r(i).angle1 * DtoR) * r(i).v
'move tank
r(i).x = r(i).x + r(i).dx
r(i).y = r(i).y + r(i).dy
'was there any contact with another tank?
for j as integer = 1 to TOTAL_TANKS
if i<>j then 'don't compare with self
if sqr( (r(i).x - r(j).x)^2 + (r(i).y - r(j).y)^2) <= r(i).rad*2 then
r(i).x = r(i).x - r(i).dx
r(i).y = r(i).y - r(i).dy
r(i).angle1 = r(i).angle1 + 1
if r(i).angle1 > 360 then r(i).angle1 = r(i).angle1-360
r(i).hittank = 1 'flag it hit a tank
end if
end if
next j
'scan around tank for background hit
dim as integer hit
dim as single dx,dy
hit = 0
for ca as single = 0 to 359 step 10
dx = cos(ca*DtoR) * 17
dy = sin(ca*DtoR) * 17
if point(r(i).x + dx, r(i).y + dy, backGround)<>rgb(255,255,255) then
hit = 1
end if
next ca
if hit = 1 then
'set exit angle, lastAngle, if first hit
if r(i).hitWall = 0 then
r(i).lastAngle = r(i).angle1 +160
if r(i).lastAngle > 360 then r(i).lastAngle = r(i).lastAngle-360
end if
r(i).x = r(i).x - r(i).dx
r(i).y = r(i).y - r(i).dy
r(i).v = 0 'turn off motors
r(i).hitWall = 1 'flag it hit a wall
end if
'was there any contact with screen boundary?
if r(i).x <= r(i).rad or r(i).x >= SCRW-r(i).rad or r(i).y <= r(i).rad or r(i).y >= SCRH-r(i).rad then
'set exit angle, lastAngle, if first hit
if r(i).hitWall = 0 then
r(i).lastAngle = r(i).angle1 +160
if r(i).lastAngle > 360 then r(i).lastAngle = r(i).lastAngle-360
end if
r(i).x = r(i).x - r(i).dx
r(i).y = r(i).y - r(i).dy
r(i).v = 0 'turn off motors
r(i).hitWall = 1 'flag it hit a wall
end if
if r(i).hitWall = 1 then
if r(i).angle1 <> r(i).lastAngle then
r(i).angle1 = r(i).angle1 + 1
if r(i).angle1 > 360 then r(i).angle1 = r(i).angle1 - 360
else
r(i).hitWall = 0
r(i).v = 1 'start up motors
end if
end if
r(i).angle2 = r(i).angle2 + .1 'rotate turret
'if bullet not in use random fire bullet
if int(rnd(1)*550)=1 and b1(i).alive = 0 then
b1(i).alive = 1
b1(i).v = 2
b1(i).angle = r(i).angle1 + r(i).angle2
'if b1(i).angle > 359 then b1(i).angle = b1(i).angle - 360
b1(i).x = r(i).x + cos(b1(i).angle * DtoR)*18 'end of turret
b1(i).y = r(i).y + sin(b1(i).angle * DtoR)*18
end if
'did bullet hit a tile?
dim as ulong v
dim as integer tileX,tileY
if b1(i).alive = 1 then
v = point(b1(i).x,b1(i).y,backGround)
if b1(i).x>SCRW or b1(i).x<0 or b1(i).y>SCRH or b1(i).y<0 or point(b1(i).x,b1(i).y,backGround) <> rgb(255,255,255) then
b1(i).alive = 0
if v = rgb(128,64,0) then
tileX = b1(i).x\32
tileY = b1(i).y\32
line backGround,(tileX*32,tileY*32)-(tileX*32+31,tileY*32+31),rgb(255,255,255),bf
'circle backGround,(b1(i).x,b1(i).y),13,rgb(255,255,255),,,,f
end if
end if
end if
'bullet connect with tank?
for j as integer = 1 to TOTAL_TANKS
if j<>i then 'not bullet of this tank
if sqr( (b1(i).x - r(j).x)^2 + (b1(i).y - r(j).y)^2) <= r(i).rad*2 then
r(j).c = rgb(255,0,255)
b1(i).alive = 0
end if
end if
next j
next i
display()
end if
sleep 2
loop until multikey(&H01)
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,1,1,2,2,2,2,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,0,0,0,0,0,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,2,1,3,3,1,1,1,1,1,1,3,3,1,0,0
DATA 0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,1,1,2,2,2,1,3,3,3,3,3,3,3,3,3,3,1,0,0
DATA 0,0,0,0,0,0,0,0,0,1,2,2,2,2,1,1,1,1,1,2,2,1,3,3,1,1,1,1,1,1,3,3,1,0,0
DATA 0,0,0,0,0,0,0,0,0,1,2,2,2,2,1,1,1,1,1,2,2,1,1,1,1,0,0,0,0,0,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,1,1,1,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,1,1,2,2,2,2,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
DATA 0,0,0,0,0,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,1,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,0,0
DATA 0,0,0,0,0,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,1,0,0,0,0,0
DATA 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,1,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,4,5,4,1,0,0,0,0
DATA 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
'tile id data 32x15 for world array
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0