11-07-2024, 10:47 AM
What I've learned so far :
1. The 2D polyline can be transformed to 3D race track
2. Control key modification
- Display control key indication : on/off
- If UP is on, the car moves forward until SPACEBAR is on
I haven't still succeeded to show the car position on the little 2D polyline race track
Don't worry, it is just my curiousity. I am amazed that 2D polyline can be transformed to 3D race track.
Code:
'=====================================
' Some modification on Futuracer
'
' Resources :
' * Futuracer, original code by Marcus
'
'=====================================
'----------------
' INITIALIZATION
'----------------
'library
include "s3d.n7"
include "polyline.n7"
'screen size
visible vRes = 480
set window "Futuracer", vRes*screenw()/screenh(), vRes, false
set redraw off
'color definition
black = [0,0,0]
white = [255,255,255]
green = [0,255,0]
'create road and white strips image
texture = createimage(128, 128)
set image texture 'road
for y = 0 to 127 for x = 0 to 127
i = 16 + rnd(64)
set color i, i, i
set pixel x, y
next
set image primary
BoxBlur(texture, 2, 2)
set image texture 'white strips
set color white
draw rect 60, 0, 8, 64, true
set image primary
BoxBlur(texture, 1, 1)
'race track
points = [[-50, 50], [50, 50], [50, -50], [-50, -50]]
p = PolyLine(points, true) 'true = closed loop
'draw race track in 3D
mesh = S3D_BeginMesh()
S3D_Begin(S3D_QUADS)
hrw = 8
stp = 15
i = 0
while i < p.GetLength()
pos = p.GetPoint(i, true)
dir = p.GetDirection(i, true)
x0 = pos[0]; y0 = pos[1]
tx0 = dir[1]; ty0 = -dir[0]
j = i + stp
if j > p.GetLength() j = 0
pos = p.GetPoint(j, true)
dir = p.GetDirection(j, true)
x1 = pos[0]; y1 = pos[1]
tx1 = dir[1]; ty1 = -dir[0]
S3D_Vertex(x0 - tx0*hrw, 0, y0 - ty0*hrw, 0, 1)
S3D_Vertex(x1 - tx1*hrw, 0, y1 - ty1*hrw, 0, 0)
S3D_Vertex(x1 + tx1*hrw, 0, y1 + ty1*hrw, 1, 0)
S3D_Vertex(x0 + tx0*hrw, 0, y0 + ty0*hrw, 1, 1)
i = i + stp
wend
S3D_End()
S3D_EndMesh()
'--------------
' MAIN PROGRAM
'--------------
S3D_SetView(primary, rad(74), 0.1, 100)
'initial values
x = -70
z = 0
a = 0
lastTick = clock()
toggleUp = 0
toggleDown = 0
infoLeft = "OFF"
infoRight = "OFF"
infoUp = "OFF"
infoDown = "OFF"
infoBrake = "OFF"
while not keydown(KEY_ESCAPE, true)
'delta time
t = clock()
dt = (min(t - lastTick, 100))/1000
lastTick = t
'control keys
if keydown(KEY_LEFT)
a = a - 90*dt
infoLeft = "ON"
else
infoLeft = "OFF"
endif
if keydown(KEY_RIGHT)
a = a + 90*dt
infoRight = "ON"
else
infoRight = "OFF"
endif
if keydown(KEY_UP) or toggleUp = 1
x = x + sin(rad(a))*10*dt
z = z + cos(rad(a))*10*dt
toggleUp = 1 'keep forward
toggleDown = 0
infoUp = "ON"
infoDown = "OFF"
infoBrake = "OFF"
endif
if keydown(KEY_DOWN) or toggleDown = 1
x = x - sin(rad(a))*10*dt
z = z - cos(rad(a))*10*dt
toggleUp = 0 'stop
toggleDown = 1 'keep backward
infoUp = "OFF"
infoDown = "ON"
infoBrake = "OFF"
endif
if keydown(KEY_SPACE)
toggleUp = 0 'stop
toggleDown = 0 'stop
infoUp = "OFF"
infoDown = "OFF"
infoBrake = "ON"
endif
'clear background
set color black; cls
'draw race track in 2D
shiftX = 320
shiftY = 90
set color green
for i = 0 to sizeof(points) - 1
j = (i + 1)%sizeof(points)
draw line shiftX+points[i][0], shiftY+points[i][1], shiftX+points[j][0], shiftY+points[j][1]
next
set caret 270,10 ; write "Race Track"
d = d + 1
pos = p.GetPoint(d, true)
dir = p.GetDirection(d, true)
draw line pos[0] - dir[0]*16+shiftX, pos[1] - dir[1]*16+shiftY, pos[0]+shiftX, pos[1]+shiftY
'S3D rendering process
S3D_Clear()
S3D_RotateY(-rad(a))
S3D_Translate(-x, 2, -z)
S3D_Texture(texture)
S3D_Mesh(mesh, 0)
S3D_Render()
S3D_RenderFog(0, 0, 0, false)
'FPS info
set caret 10,10
set color green
wln "FPS: " + str(round(1/dt))
wln ""
wln "Control keys : "
wln " Left (Left) : "+infoLeft
wln " Right (Right) : "+infoRight
wln " Forward (Up) : "+infoUp
wln " Backward (Down) : "+infoDown
wln " Brake (Space Bar) : "+infoBrake
redraw
wait 1
wend
'-----------
' FUNCTIONS
'-----------
' BoxBlur
' -------
function BoxBlur(img, rx, ry)
rx = max(int(rx), 0); ry = max(int(ry), 0)
set image img
w = width(img); h = height(img)
data = dim(w, h)
' Blur vertically
for y = 0 to h - 1 for x = 0 to w - 1 data[x][y] = pixeli(img, x, y)
count = ry*2 + 1
for x = 0 to w - 1
sr = 0; sg = 0; sb = 0; sa = 0
for y = -ry to ry
p = data[x][y%h];
sr = sr + Red(p); sg = sg + Green(p); sb = sb + Blue(p); sa = sa + Alpha(p)
next
for y = 0 to h - 1
set color sr/count, sg/count, sb/count, sa/count
set pixel x, y
p = data[x][(y - ry)%h]
sr = sr - Red(p); sg = sg - Green(p); sb = sb - Blue(p); sa = sa - Alpha(p)
p = data[x][(y + ry + 1)%h]
sr = sr + Red(p); sg = sg + Green(p); sb = sb + Blue(p); sa = sa + Alpha(p)
next
next
' Blur horizontally.
for y = 0 to h - 1 for x = 0 to w - 1 data[x][y] = pixeli(img, x, y)
count = rx*2 + 1
for y = 0 to h - 1
sr = 0; sg = 0; sb = 0; sa = 0
for x = -rx to rx
p = data[x%w][y]
sr = sr + Red(p); sg = sg + Green(p); sb = sb + Blue(p); sa = sa + Alpha(p)
next
for x = 0 to w - 1
set color sr/count, sg/count, sb/count, sa/count
set pixel x, y
p = data[(x - rx)%w][y]
sr = sr - Red(p); sg = sg - Green(p); sb = sb - Blue(p); sa = sa - Alpha(p)
p = data[(x + rx + 1)%w][y]
sr = sr + Red(p); sg = sg + Green(p); sb = sb + Blue(p); sa = sa + Alpha(p)
next
next
set image primary
' Pixeli helpers.
function Alpha(c); return int(c/16777216); endfunc
function Red(c); return int((c/65536))%256; endfunc
function Green(c); return int((c/256))%256; endfunc
function Blue(c); return c%256; endfunc
endfunc