The program requires these two images to be downloaded and resaved as bitmaps ambulance4.bmp and top2.bmp respectively.
The list of 3d points abs3D() are rotated by some angle into the rot3D() array and then projected onto a 2d bitmap image.
This bitmap image is then PUT onto the display at the isometric position of the ambulance's 2D position.
The two ambulances use the same set of absolute points to create an image but are rotated by their own angles and have their own 2d positions.
One ambulance is controlled by the arrow keys and the other is controlled by the ASDW keys.
The reason for the TANK label is because it was going to be a tank vehicle but I haven't got around to writing the code to draw a tank.
So it is meant to be a tank image which I will hopefully remedy later.
EDIT: Code modified with suggestions made in next two posts.
Code: Select all
const ScrW = 1280
const ScrH = 480
const imgW = 100
const imgH = 100
'some useful defines
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
screenres ScrW,ScrH,32
color rgb(0,0,0),rgb(155,155,255):cls
'=========== make cube ========================
dim shared as any ptr cube1
cube1 = imagecreate(32,33,rgb(255,0,255))
dim as integer x1,y1,x2,y2
for i as integer = 1 to 9
read x1,y1,x2,y2
line cube1,(x1,y1)-(x2,y2),rgb(0,0,0)
next i
paint cube1,(10,7),rgb(204,167,98),rgb(0,0,0)
paint cube1,(23,20),rgb(98,49,49),rgb(0,0,0)
paint cube1,(8,19),rgb(158,98,68),rgb(0,0,0)
data 16,0,31,8, 31,8,16,15, 15,16, 0,8, 0,8,15,0
data 31,24,16,32, 15,32,0,24, 31,8, 31,24, 15,16,15,32, 0,8,0,24
'======================================================
dim shared as any ptr ambulance
ambulance = imagecreate(61,47)
bload "ambulance4.bmp",ambulance
dim shared as any ptr top
top = imagecreate(110,31)
bload "top2.bmp",top
dim shared as any ptr image 'hold a image of rotated points
image = imagecreate(imgW,imgH)
type Point3D
x as single
y as single
z as single
c as ulong
end type
sub plot3D(x as single,y as single,z as single, c as ulong)
'circle ( (x-y) + imgW/2, (x+y)/2 + z + imgH/2 ),1,c,,,,f
pset image,( (x-y) + imgW/2, (x+y)/2 + z + imgH/2 ),c
end sub
'dodicat's fast qsort of points according to distance
Sub QsortZ(array() As Point3D,begin As Long,Finish As Ulong)
Dim As Long i=begin,j=finish
Dim As Point3D x =array(((I+J)\2))
While I <= J
While array(I).z > X .z:I+=1:Wend
While array(J).z < X .z:J-=1:Wend
If I<=J Then Swap array(I),array(J): I+=1:J-=1
Wend
If J >begin Then QsortZ(array(),begin,J)
If I <Finish Then QsortZ(array(),I,Finish)
End Sub
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 angle 'direction in degrees
end type
dim shared as integer MAX_DOTS
dim shared as integer TOT_DOTS
MAX_DOTS = 50000
dim shared as TANK t1,t2
t1.x = 0
t1.y = 0
t1.angle = 0
t2.x = 100
t2.y = 200
t2.angle = 0
'now dimension array of absolute position of points and array of rotated points
dim shared as Point3D abs3D(MAX_DOTS) 'absolute positions
dim shared as Point3D rot3D(MAX_DOTS) 'relative positions after any rotation
dim as ulong v,v2
dim as integer flag,x,y,z
' ============ create absolute point positions for ambulance ==========
'edge data to draw back,top and bottom pixels of object
dim as integer edgeX(0 to 110),edgeY(0 to 110)
for i as integer = 0 to 110
read edgeX(i),edgeY(i)
next i
for j as integer = 1 to 46
flag = 0
for i as integer = 0 to 60
v = point(i,j,ambulance)
if v <> rgb(255,0,255) then
abs3D(TOT_DOTS).x = i - imgW/4
abs3D(TOT_DOTS).y = 15
abs3D(TOT_DOTS).z = j
abs3D(TOT_DOTS).c = v
if TOT_DOTS < MAX_DOTS then TOT_DOTS = TOT_DOTS + 1
end if
next i
next j
for j as integer = 0 to 46
for i as integer = 0 to 60
v = point(i,j,ambulance)
if v <> rgb(255,0,255) then
abs3D(TOT_DOTS).x = i - imgW/4
abs3D(TOT_DOTS).y = -15
abs3D(TOT_DOTS).z = j
abs3D(TOT_DOTS).c = v
if TOT_DOTS < MAX_DOTS then TOT_DOTS = TOT_DOTS + 1
end if
next i
next j
for i as integer = 0 to 109
for y as integer = -15 to 15
abs3D(TOT_DOTS).x = edgeX(i) -imgW/4
abs3D(TOT_DOTS).y = y
abs3D(TOT_DOTS).z = edgeY(i)
abs3D(TOT_DOTS).c = point(i,y+15,top)
if TOT_DOTS < MAX_DOTS then TOT_DOTS = TOT_DOTS + 1
next y
next i
'=====================================================================
sub moveTank(t as TANK)
t.dx = cos(t.angle*DtoR) * t.v
t.dy = sin(t.angle*DtoR) * t.v
t.x = t.x + t.dx
t.y = t.y + t.dy
end sub
sub rotatePoints(tt as TANK) 'rotates points by tt.angle
dim as single x,y,z,scale
'rotate
dim as single cosAngleX,sinAngleX,angleX
dim as single cosAngleY,sinAngleY,angleY
dim as single cosAngleZ,sinAngleZ,angleZ
angleZ = tt.angle*DtoR 'angle to rotate points
cosAngleZ = cos(angleZ)
sinAngleZ = sin(angleZ)
scale = 1/sqr(2)
for i as integer = 0 to TOT_DOTS - 1 'rotate each point
'rotate z axis
x = abs3D(i).x
y = abs3D(i).y
z = abs3D(i).z
rot3D(i).x = ((cosAngleZ * x) - (sinAngleZ * y))*scale
rot3D(i).y = ((sinAngleZ * x) + (cosAngleZ * y))*scale
rot3D(i).z = z*0.5
rot3D(i).c = abs3D(i).c
next i
'sort by distance along z axis
'***dodisort***
Qsortz(rot3D(),Lbound(rot3D),TOT_DOTS - 1)
'Qsortz(rot3D(),Lbound(rot3D),Ubound(rot3D))
end sub
sub drawSprite(t as TANK)
'clear image
line image,(0,0)-(imgW-1,imgH-1),rgb(255,0,255),bf
line image,(0,0)-(imgW-1,imgH-1),rgb(0,0,0),b 'show edge of image
rotatePoints(t) 'rotate abs3D() points by t.angle to produce rot3D() points
'draw rotated points onto image bitmap
for i as integer = 0 to TOT_DOTS - 1
plot3D(rot3D(i).x, rot3D(i).y, rot3D(i).z, rot3D(i).c)
next i
'cartesian to isometric coordinates of image
dim as single tempX = (t.x - t.y) + 640 - imgW/2
dim as single tempY = (t.x + t.y) / 2 + 30 - imgH/2
'put rotated image on display
put (tempX,tempY),image,trans
end sub
sub drawPoints()
screenlock
cls
'draw isometric cubes
for y as integer = 0 to 24
for x as integer = 0 to 24
put ( (x*16-y*16) + SCRW/2 - 16, (x*16+y*16)/2 + 0 + 30 ),cube1,trans
next x
next y
moveTank(t1)
drawSprite(t1) 'draw rotated pixels onto image and place on screen
moveTank(t2)
drawSprite(t2) 'draw rotate pixels onto image and place on screen
locate 2,2
print t1.angle,t2.angle,TOT_DOTS
screenunlock()
end sub
dim as double now1
now1 = timer
do
if timer - now1 > 0.01 then
now1 = timer
drawPoints()
'==================================================
'cursor keys to control tank1
t1.v = 0
if multikey(&H50) then t1.v = -2 'REVERSE
if multikey(&H48) then t1.v = 2 'FORWARD
'rotate around z axis
if multikey(&H4D) then
t1.angle = t1.angle + 1
if t1.angle > 360 then t1.angle = t1.angle - 360
end if
if multikey(&H4B) then
t1.angle = t1.angle - 1
if t1.angle < 0 then t1.angle = t1.angle + 360
end if
'==================================================
'ASDW keys to control tank2
t2.v = 0
if multikey(&H1F) then t2.v = -2 'REVERSE
if multikey(&H11) then t2.v = 2 'FORWARD
'rotate around z axis
if multikey(&H20) then
t2.angle = t2.angle + 1
if t2.angle > 360 then t2.angle = t2.angle - 360
end if
if multikey(&H1E) then
t2.angle = t2.angle - 1
if t2.angle < 0 then t2.angle = t2.angle + 360
end if
end if
sleep 2
loop until multikey(&H01)
sleep
'coordinates of back, top and front of side edge of ambulance image to join using colors in top2 bitmap
data 0,30, 0,29, 0,28, 0,27, 1,27, 1,26, 1,25, 1,24, 1,23, 1,22, 1,21, 1,20, 1,19, 1,18, 1,19, 1,18, 1,17, 1,16
data 1,15, 1,14, 1,13, 1,12, 1,11, 1,10, 1,9, 1,8, 1,7, 1,6, 1,5, 1,4, 1,3, 1,2, 2,1, 3,0
data 4,0, 5,0, 6,0, 7,0, 8,0, 9,0, 10,0, 11,0, 12,0, 13,0, 14,0, 15,0, 16,0, 17,0, 18,0, 19,0, 20,0, 21,0
data 22,0, 23,0, 24,0, 25,0, 26,0, 27,0, 28,0, 29,0, 30,0, 31,0, 32,0, 33,0, 34,0, 35,0, 36,0, 37,0, 38,0, 39,0
data 40,0, 41,0, 42,0, 43,0, 44,0
data 44,1, 45,2, 45,3, 46,4, 46,5, 47,6, 47,7, 48,8, 48,9, 49,10, 49,11, 50,12, 51,13, 52,14, 53,14, 54,15, 55,15
data 56,16, 57,16, 58,17, 58,18, 58,19, 58,20, 58,21, 58,22, 58,23, 58,24, 58,25, 58,26, 58,27, 59,27, 60,27, 60,28, 60,29, 60,30