Posts: 721
Threads: 95
Joined: Nov 2023
Reputation:
7
Added some targets to determine how difficult it is to aim. But it doesn't feel hard at all, so I'm sure it'll be fine even with moving targets.
Your browser does not support the video tag.
I'll upload the new n7 version as soon as I can, so that you can try this out.
Posts: 721
Threads: 95
Joined: Nov 2023
Reputation:
7
Dirty code, needs cleaning and requires the latest n7 version!
Code:
' flight_test.n7
' --------------
include "s3d.n7"
include "qsort.n7"
#win32
constant RES = 480
' Shadow settings.
constant SHD_OFFS = 0.01
constant SHD_ALPHA = 64
constant SHD_RES = 16
' Set to 1 for non-inverted y-axis. I can only play inverted ...
ctrlYScale = -1
visible vRenderDepth = 50
winAspect = min(screenw()/screenh(), 2)
randomize 382
set window "flight test", RES*winAspect, RES, true
set redraw off
'while not mousebutton(0, true) wait 100
S3D_SetView(primary, rad(60), 0.1, vRenderDepth)
visible vRedObstacleMesh = BoxMesh(5, 2.5, 5, 208, 16, 0)
visible vGreenObstacleMesh = BoxMesh(4, 5, 4, 16, 208, 0)
visible vBlueObstacleMesh = BoxMesh(2, 13, 2, 16, 0, 208)
' Create player ship model.
shipMesh = S3D_BeginMesh()
hw = 0.5
S3D_Begin(S3D_TRIANGLES)
S3D_Color3(208, 208, 208)
' right side.
S3D_Vertex3(0, 0, 2)
S3D_Vertex3(0.5, 0.125, -1.25)
S3D_Vertex3(0, -0.25, -1)
' left side.
S3D_Vertex3(0, 0, 2)
S3D_Vertex3(0, -0.25, -1)
S3D_Vertex3(-0.5, 0.125, -1.25)
' back.
S3D_Color3(255, 160, 0)
S3D_Vertex3(0, -0.25, -1)
S3D_Vertex3(0.5, 0.125, -1.25)
S3D_Vertex3(-0.5, 0.125, -1.25)
' bottom.
S3D_Color3(128, 128, 128)
S3D_Vertex3(0, 0, 2)
S3D_Vertex3(-0.5, 0.125, -1.25)
S3D_Vertex3(0.5, 0.125, -1.25)
' right wing.
S3D_Color3(64, 128, 208)
S3D_Vertex3(0.5, 0, 0.25)
S3D_Vertex3(2.0, 0.25, -2)
S3D_Vertex3(0.5, 0, -1.5)
S3D_Vertex3(0.5, 0, 0.25)
S3D_Vertex3(0.5, 0, -1.5)
S3D_Vertex3(2.0, 0.25, -2)
' left wing.
S3D_Color3(64, 128, 208)
S3D_Vertex3(-0.5, 0, 0.25)
S3D_Vertex3(-2.0, 0.25, -2)
S3D_Vertex3(-0.5, 0, -1.5)
S3D_Vertex3(-0.5, 0, 0.25)
S3D_Vertex3(-0.5, 0, -1.5)
S3D_Vertex3(-2.0, 0.25, -2)
S3D_End()
S3D_EndMesh()
' Player bullet model, probably needs volume ...
bulletMesh = S3D_BeginMesh()
S3D_Color3(255, 208, 96)
S3D_Begin(S3D_QUADS)
S3D_Vertex3(0, 0, 0.5)
S3D_Vertex3(0.5, 0, 0)
S3D_Vertex3(0, 0, -1.5)
S3D_Vertex3(-0.5, 0, 0)
S3D_Vertex3(-0.5, 0, 0)
S3D_Vertex3(0, 0, -1.5)
S3D_Vertex3(0.5, 0, 0)
S3D_Vertex3(0, 0, 0.5)
S3D_End()
S3D_EndMesh()
' Something to shoot at.
visible vTargetMesh = S3D_BeginMesh()
xz = []
res = 6; r = 2; h = 3
for i = 0 to res - 1 xz[sizeof(xz)] = [sin(i*2*PI/res)*r, cos(i*2*PI/res)*r]
S3D_Begin(S3D_TRIANGLES)
for i = 0 to res - 1
j = (i + 1)%res
if i%2 = 0 S3D_Color3(192, 192, 192)
else S3D_Color3(224, 32, 0)
S3D_Vertex3(0, -h*0.5, 0)
S3D_Vertex3(xz[i][0], 0, xz[i][1])
S3D_Vertex3(xz[j][0], 0, xz[j][1])
if i%2 = 1 S3D_Color3(192, 192, 192)
else S3D_Color3(224, 32, 0)
S3D_Vertex3(0, h*0.5, 0)
S3D_Vertex3(xz[j][0], 0, xz[j][1])
S3D_Vertex3(xz[i][0], 0, xz[i][1])
next
S3D_End()
S3D_EndMesh()
' Player.
ship = []
ship.mesh = shipMesh
ship.pos = []
ship.pos[0] = 0
ship.pos[1] = -2
ship.pos[2] = 0
ship.box = dim(6)
ship.rot = []
ship.rot.yaw = 0
ship.rot.pitch = 0
ship.rot.roll = 0
ship.dir = [0, 0, 0, 0]
ship.push = fill(0, 3)
ship.shd = []
ship.shd.img = createimage(5.75*SHD_RES, 5.75*SHD_RES)
ship.shd.scale = 0.78
ship.shd.size = 5.75
ship.shootTimer = 0
set image ship.shd.img
set color 0, 0, 0, 0
cls true
set image primary
' Player bullets.
bullets = []
' Camera.
cam = []
cam.pos = []
cam.pos[0] = 0
cam.pos[1] = 0
cam.pos[2] = 0
cam.rot = []
cam.rot.yaw = 0
cam.rot.pitch = 0
cam.rot.roll = 0
cam.followX = 0.75
' X and y limitations of player.
xMin = -15
xMax = 15
yMin = -15
yMax = -1
' Add 1000 obstacles and sort by z.
visible vObstacles = []
for i = 1 to 1000
select rnd(3)
case 0 vObstacles[sizeof(vObstacles)] = RedObstacle(rnd()*40 - 20, 5 + rnd()*2000)
case 1 vObstacles[sizeof(vObstacles)] = GreenObstacle(rnd()*40 - 20, 5 + rnd()*2000)
case 2 vObstacles[sizeof(vObstacles)] = BlueObstacle(rnd()*40 - 20, 5 + rnd()*2000)
endsel
next
qsort(vObstacles, function(a, b); return a.pos[2] - b.pos[2]; endfunc)
' Used for optimizing drawing and collision checks.
visible vMinVisObstacle = 0
visible vMaxVisObstacle = unset
' Add some targets for the player to shoot at.
visible vTargets = []
' All targets can share shadow image.
visible vTargetShadowImage = createimage(4.4*SHD_RES, 4.4*SHD_RES)
set image vTargetShadowImage
set color 0, 0, 0, 0
cls true
set image primary
for i = 1 to 200 vTargets[sizeof(vTargets)] = Target(rnd()*30 - 15, -1.5 - rnd()*15, 50 + rnd()*2000)
qsort(vTargets, function(a, b); return a.pos[2] - b.pos[2]; endfunc)
visible vMinVisTarget = 0
visible vMaxVisTarget = unset
' Forward vector.
fwdVec = [0, 0, 1, 0]
' For computations using s3d.
srcVec = [0, 0, 0, 0]
dstVec = [0, 0, 0, 0]
' Screen flash effect when ship hits an obstacle.
hitParam = 0
' For fps output.
lastClock = clock()
while not keydown(KEY_ESCAPE, true)
c = clock()
dt = (c - lastClock)/1000
lastClock = c
' Change direction.
dYaw = 0
dPitch = 0
if keydown(KEY_LEFT) dYaw = dYaw - 45
if keydown(KEY_RIGHT) dYaw = dYaw + 45
if keydown(KEY_UP) dPitch = dPitch + 30*ctrlYScale
if keydown(KEY_DOWN) dPitch = dPitch - 30*ctrlYScale
ship.rot.yaw = 0.95*ship.rot.yaw + 0.05*dYaw
ship.rot.pitch = 0.95*ship.rot.pitch + 0.05*dPitch
ship.rot.roll = 0.95*ship.rot.roll + 0.05*dYaw*0.5
' Get ships direction as a vector.
S3D_ClearTransformation()
S3D_RotateY(rad(ship.rot.yaw))
S3D_RotateX(rad(ship.rot.pitch))
S3D_RotateZ(rad(ship.rot.roll))
S3D_TransformVector(ship.dir, fwdVec)
VectorNormalize(ship.dir)
' Uhm, slow down when close to x and y limits.
dxMul = 1; dyMul =1
if ship.dir[0] < 0 dxMul = min(ship.pos[0] - xMin, 4)*0.25
elseif ship.dir[0] > 0 dxMul = min(xMax - ship.pos[0], 4)*0.25
if ship.dir[1] < 0 dyMul = min(ship.pos[1] - yMin, 4)*0.25
elseif ship.dir[1] > 0 dyMul = min(yMax - ship.pos[1], 4)*0.25
' Move.
ship.pos[0] = max(min(ship.pos[0] + ship.dir[0]*0.25*dxMul + ship.push[0], xMax), xMin)
ship.pos[1] = max(min(ship.pos[1] + ship.dir[1]*0.5*dyMul + ship.push[1], yMax), yMin)
ship.pos[2] = ship.pos[2] + 0.1 + ship.push[2]
' Update push, collision effect.
for i = 0 to 2
if ship.push[i] < 0 ship.push[i] = min(ship.push[i] + 0.01, 0)
elseif ship.push[i] > 0 ship.push[i] = max(ship.push[i] - 0.01, 0)
next
hitParam = max(hitParam - 0.025, 0)
' Update bounding box.
ship.box[0] = ship.pos[0] - 1.25 ' 2
ship.box[3] = ship.pos[0] + 1.25 ' 2
ship.box[1] = ship.pos[1] - 0.25
ship.box[4] = ship.pos[1] + 0.25
ship.box[2] = ship.pos[2] - 0.75 ' 1.25
ship.box[5] = ship.pos[2] + 1 '2
' Shoot.
ship.shootTimer = max(ship.shootTimer - 1, 0)
if keydown(KEY_SPACE) and ship.shootTimer <= 0
ship.shootTimer = 15
spd = 1
' Add two bullets with positions relative to the player ship.
S3D_ClearTransformation()
S3D_Translate(ship.pos[0], ship.pos[1], ship.pos[2])
S3D_RotateY(rad(ship.rot.yaw))
S3D_RotateX(rad(ship.rot.pitch))
S3D_RotateZ(rad(ship.rot.roll))
for x = -0.75 to 0.75 step 1.5
srcVec[0] = x; srcVec[1] = 0; srcVec[2] = 1; srcVec[3] = 1
bullet = [
mesh: bulletMesh,
pos: dim(3),
rot: [yaw: ship.rot.yaw, pitch: ship.rot.pitch, roll: ship.rot.roll],
mvec: [ship.dir[0]*spd, ship.dir[1]*spd, ship.dir[2]*spd],
box: dim(6),
shd: unset]
S3D_TransformVector(bullet.pos, srcVec)
bullet.box[0] = bullet.pos[0] - 0.5
bullet.box[1] = bullet.pos[1] - 0.5
bullet.box[2] = bullet.pos[2] - 1.5
bullet.box[3] = bullet.pos[0] + 0.5
bullet.box[4] = bullet.pos[1] + 0.5
bullet.box[5] = bullet.pos[2] + 0.5
bullets[sizeof(bullets)] = bullet
next
endif
' Check for collisions between ship and obstacles.
if typeof(vMaxVisObstacle)
i = vMinVisObstacle
xmin = ship.box[0]
xmax = ship.box[3]
ymin = ship.box[1]
ymax = ship.box[4]
zmin = ship.box[2]
zmax = ship.box[5]
px = 0; py = 0
while i < vMaxVisObstacle and i < sizeof(vObstacles)
o = vObstacles[i]
if zmax > o.box[2] and zmin < o.box[5] and
ymax > o.box[1] and ymin < o.box[4] and
xmax > o.box[0] and xmin < o.box[3]
dRight = xmax - o.box[0]
dLeft = o.box[3] - xmin
dDown = ymax - o.box[1]
if hitParam <= 0 hitParam = 1
' Find the smallest valid distance to the obstacle in the three directions and push
' the ship in the opposite direction.
if dLeft > 0 and dRight > 0
if dLeft < dRight
if dDown > 0 and dDown < dLeft py = py -1
else px = px + 1
else
if dDown > 0 and dDown < dRight py = py - 1
else px = px - 1
endif
elseif dLeft > 0
if dDown > 0 and dDown < dLeft py = py - 1
else px = px + 1
elseif dRight > 0
if dDown > 0 and dDown < dRight py = py - 1
else px = px - 1
elseif dDown > 0 py = py -1
endif
i = i + 1
wend
if px ship.push[0] = sgn(px)*0.2
if py ship.push[1] = sgn(py)*0.15
endif
' Position camera.
cam.pos[0] = cam.followX*ship.pos[0]
cam.pos[1] = 0.6*ship.pos[1] - 2
cam.pos[2] = ship.pos[2] - 7.5
' Update bullets.
i = 0
while i < sizeof(bullets)
b = bullets[i]
VectorAdd(b.pos, b.mvec)
if b.pos[1] >= 0 or b.pos[2] > cam.pos[2] + vRenderDepth
free key bullets, i
else
bb = b.box; bp = b.pos
bb[0] = bp[0] - 0.5
bb[1] = bp[1] - 0.5
bb[2] = bp[2] - 1.5
bb[3] = bp[0] + 0.5
bb[4] = bp[1] + 0.5
bb[5] = bp[2] + 0.5
hit = false
j = vMinVisTarget
while j < vMaxVisTarget and j < sizeof(vTargets)
t = vTargets[j]
if BoxesOverlap(bb, t.box)
hit = true
free key vTargets, j
else
j = j + 1
endif
wend
if hit
free key bullets, i
else
i = i + 1
endif
endif
wend
set color 48, 96, 128
cls
' Draw.
S3D_Clear()
S3D_RotateZ(rad(ship.rot.roll*0.5))
S3D_Translate(-cam.pos[0], -cam.pos[1], -cam.pos[2])
' Obstacles.
i = vMinVisObstacle
while i < sizeof(vObstacles)
o = vObstacles[i]
dz = o.pos[2] - cam.pos[2]
if dz < -10 vMinVisObstacle = i + 1
if dz > vRenderDepth + 10
vMaxVisObstacle = i
break
endif
S3D_Push()
S3D_Translate(o.pos[0], o.pos[1], o.pos[2])
S3D_Mesh(o.mesh, 0)
S3D_Pop()
i = i + 1
wend
' Targets.
i = vMinVisTarget
while i < sizeof(vTargets)
t = vTargets[i]
dz = t.pos[2] - cam.pos[2]
if dz < -10 vMinVisTarget = i + 1
if dz > vRenderDepth + 10
vMaxVisTarget = i
break
endif
t.rot.yaw = (t.rot.yaw + t.dyaw)%360
DrawObject(t)
i = i + 1
wend
DrawObject(ship)
foreach b in bullets DrawObject(b)
S3D_RenderFog(48, 96, 128, false)
if hitParam > 0
set color 192, 0, 0, hitParam*255
cls
endif
set color 255, 255, 255
set caret 4, 4
'wln "dx: " + str(ship.dir[0], 0, 2)
'wln "dy: " + str(ship.dir[1], 0, 2)
'wln "dz: " + str(ship.dir[2], 0, 2)
'wln
'wln "bullets: " + sizeof(bullets)
'wln "min obs: " + vMinVisObstacle
'wln "max obs: " + vMaxVisObstacle
'wln
wln "fps: " + floor(1/dt)
' Draw ship shadow.
'x = width(primary) - width(vTargetShadowImage) - 4
'set color 255, 0, 255
'draw rect x, 4, width(vTargetShadowImage), height(vTargetShadowImage), true
'set color 255, 255, 255
'draw image vTargetShadowImage, x, 4
redraw
fwait 60
wend
' DrawObject
' ----------
function DrawObject(o)
' Object.
S3D_Push()
S3D_Color3(255, 255, 255)
S3D_Translate(o.pos[0], o.pos[1], o.pos[2])
S3D_RotateY(rad(o.rot.yaw))
S3D_RotateX(rad(o.rot.pitch))
S3D_RotateZ(rad(o.rot.roll))
S3D_Mesh(o.mesh, 0)
S3D_Pop()
' Shadow?
if o.shd
' Render shadow, experimental stuff.
set image o.shd.img, false
set color 0, 0, 0, 0
cls true
S3D_Push()
S3D_SetView(o.shd.img, rad(10), 0.1, 50)
S3D_ClearTransformation()
S3D_SetDepthBuffer(S3D_NONE)
S3D_Color3(0, 0, 0)
S3D_Translate(0, 0, 25)
S3D_Scale(o.shd.scale, o.shd.scale, o.shd.scale)
S3D_RotateX(rad(90))
S3D_RotateY(rad(o.rot.yaw))
S3D_RotateX(rad(o.rot.pitch))
S3D_RotateZ(rad(o.rot.roll))
S3D_Mesh(o.mesh, 0)
S3D_SetDepthBuffer(S3D_Z_BUFFER)
S3D_SetView(primary, rad(60), 0.1, vRenderDepth)
set image primary
S3D_Pop()
so = SHD_OFFS
hs = o.shd.size*0.5
xmin = o.pos[0] - hs
xmax = o.pos[0] + hs
zmin = o.pos[2] - hs
zmax = o.pos[2] + hs
ymin = o.box[1]
S3D_Texture(o.shd.img)
S3D_Color4(255, 255, 255, SHD_ALPHA)
' Ground.
S3D_Begin(S3D_QUADS)
S3D_Vertex5(xmin, 0, zmax, 0, 0)
S3D_Vertex5(xmax, 0, zmax, 1, 0)
S3D_Vertex5(xmax, 0, zmin, 1, 1)
S3D_Vertex5(xmin, 0, zmin, 0, 1)
S3D_End()
' Obstacles
if typeof(vMaxVisObstacle)
i = vMinVisObstacle
S3D_SetDepthBuffer(S3D_Z_BUFFER_READ)
S3D_Begin(S3D_QUADS)
while i < vMaxVisObstacle and i < sizeof(vObstacles)
b = vObstacles[i].box
' Calculate intersection between shadow and obstacle.
x0 = max(xmin, b[0] - so)
x1 = min(xmax, b[3] + so)
z0 = max(zmin, b[2] - so)
z1 = min(zmax, b[5] + so)
if not (z1 < b[2] or z0 >= b[5] or x0 >= b[3] or x1 < b[0] or ymin > b[1])
umin = (x0 - xmin)/(xmax - xmin)
umax = (x1 - xmin)/(xmax - xmin)
vmin = 1 - (z0 - zmin)/(zmax - zmin)
vmax = 1 - (z1 - zmin)/(zmax - zmin)
y = b[1] - so
S3D_Color4(255, 255, 255, SHD_ALPHA)
S3D_Vertex5(x0, y, z1, umin, vmax)
S3D_Vertex5(x1, y, z1, umax, vmax)
S3D_Vertex5(x1, y, z0, umax, vmin)
S3D_Vertex5(x0, y, z0, umin, vmin)
if z0 < b[2]
'S3D_Color4(255, 255, 255, SHD_ALPHA*0.25)
S3D_Vertex5(x0, y, z0, umin, vmin)
S3D_Vertex5(x1, y, z0, umax, vmin)
S3D_Vertex5(x1, 0, z0, umax, vmin)
S3D_Vertex5(x0, 0, z0, umin, vmin)
endif
endif
i = i + 1
wend
S3D_End()
S3D_SetDepthBuffer(S3D_Z_BUFFER)
endif
S3D_Texture(unset)
endif
' Shadow.
'S3D_SetDepthBuffer(S3D_Z_BUFFER_READ)
'S3D_Push()
' S3D_Color(0, 0, 0)
' S3D_Translate(o.pos[0], 0, o.pos[2])
' S3D_Scale(1, 0, 1)
' S3D_RotateY(rad(o.rot.yaw))
' S3D_RotateX(rad(o.rot.pitch))
' S3D_RotateZ(rad(o.rot.roll))
' S3D_Mesh(o.mesh, 0)
'S3D_Pop()
'S3D_SetDepthBuffer(S3D_Z_BUFFER)
endfunc
' VectorNormalize
' ---------------
function VectorNormalize(v)
k = 1/sqr(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
v[0] = v[0]*k; v[1] = v[1]*k; v[2] = v[2]*k
endfunc
' VectorAdd
' ---------
function VectorAdd(dst, src)
dst[0] = dst[0] + src[0]
dst[1] = dst[1] + src[1]
dst[2] = dst[2] + src[2]
endfunc
' BoxMesh
' -------
function BoxMesh(xSize, ySize, zSize, r, g, b)
hx = xSize*0.5
hz = zSize*0.5
m = S3D_BeginMesh()
S3D_Begin(S3D_QUADS)
' Bottom face.
S3D_Color3(r*0.5, g*0.5, b*0.5)
S3D_Vertex5(hx, 0, -hz, 1, 0)
S3D_Vertex5(hx, 0, hz, 1, 1)
S3D_Vertex5(-hx, 0, hz, 0, 1)
S3D_Vertex5(-hx, 0, -hz, 0, 0)
' Top face.
S3D_Color3(r*1.25, g*1.25, b*1.25)
S3D_Vertex5(hx, -ySize, hz, 1, 1)
S3D_Vertex5(hx, -ySize, -hz, 1, 0)
S3D_Vertex5(-hx, -ySize, -hz, 0, 0)
S3D_Vertex5(-hx, -ySize, hz, 0, 1)
' Back face.
S3D_Color3(r*0.5, g*0.5, b*0.5)
S3D_Vertex5(hx, 0, hz, 1, 1)
S3D_Vertex5(hx, -ySize, hz, 1, 0)
S3D_Vertex5(-hx, -ySize, hz, 0, 0)
S3D_Vertex5(-hx, 0, hz, 0, 1)
' Front face.
S3D_Color3(r, g, b)
S3D_Vertex5(hx, -ySize, -hz, 1, 0)
S3D_Vertex5(hx, 0, -hz, 1, 1)
S3D_Vertex5(-hx, 0, -hz, 0, 1)
S3D_Vertex5(-hx, -ySize, -hz, 0, 0)
' Left face.
S3D_Color3(r*0.75, g*0.75, b*0.75)
S3D_Vertex5(-hx, 0, hz, 1, 1)
S3D_Vertex5(-hx, -ySize, hz, 0, 1)
S3D_Vertex5(-hx, -ySize, -hz, 0, 0)
S3D_Vertex5(-hx, 0, -hz, 1, 0)
' Right face.
S3D_Vertex5(hx, 0, -hz, 1, 0)
S3D_Vertex5(hx, -ySize, -hz, 0, 0)
S3D_Vertex5(hx, -ySize, hz, 0, 1)
S3D_Vertex5(hx, 0, hz, 1, 1)
S3D_End()
S3D_EndMesh()
return m
endfunc
' Obstacle
' --------
function Obstacle(mesh, x, y, z, w, h, d)
o = [
mesh: mesh,
pos: [x, y, z],
box: [x - w*0.5, y - h, z - d*0.5, x + w*0.5, y, z + d*0.5]]
return o
endfunc
' RedObstacle
' -----------
function RedObstacle(x, z)
return Obstacle(vRedObstacleMesh, x, 0, z, 5, 2.5, 5)
endfunc
' GreenObstacle
' -------------
function GreenObstacle(x, z)
return Obstacle(vGreenObstacleMesh, x, 0, z, 4, 5, 4)
endfunc
' BlueObstacle
' ------------
function BlueObstacle(x, z)
return Obstacle(vBlueObstacleMesh, x, 0, z, 2, 13, 2)
endfunc
' Target
' ------
function Target(x, y, z)
t = []
t.mesh = vTargetMesh
t.pos = [x, y, z]
t.box = [x - 2, y - 1.5, z - 2, x + 2, y + 1.5, z + 2]
t.rot = [yaw: rnd()*360, pitch: 0, roll: 0]
t.shd = [img: vTargetShadowImage, scale: 1, size: 4.4]
t.dyaw = rnd()*12 - 6
return t
endfunc
' BoxesOverlap
' ------------
function BoxesOverlap(a, b)
return not (a[2] > b[5] or b[2] > a[5] or a[0] > b[3] or b[0] > a[3] or a[1] > b[4] or b[1] > a[4])
endfunc
Posts: 784
Threads: 78
Joined: Nov 2023
Reputation:
8
Cool... Runs quite well. Avg about 62fps. No flickering... Very nicely done indeed!!
Logic is the beginning of wisdom.
Live long and prosper.
Posts: 784
Threads: 78
Joined: Nov 2023
Reputation:
8
Well... I dusted off my old Logitech Extreme 3D Pro joystick, made the appropriate changes and added the joystick to the keyboard commands and now I am flying 'key free'... The keyboard 'handles' better (movement wise) than the joystick. I find that the stick needs to be moved 'further' to make the turns... But that could actually add a level of difficulty. I do so miss the 'pew pew' when shooting... lol Oh, wait... I can fix that... Now where did I store my old 8 bit sound samples? Moo Ha Ha Ha...
Logic is the beginning of wisdom.
Live long and prosper.
Posts: 479
Threads: 63
Joined: Nov 2023
Reputation:
3
(09-15-2025, 03:34 AM) johnno56 Wrote: Well... I dusted off my old Logitech Extreme 3D Pro joystick, made the appropriate changes and added the joystick to the keyboard commands and now I am flying 'key free'... The keyboard 'handles' better (movement wise) than the joystick. I find that the stick needs to be moved 'further' to make the turns... But that could actually add a level of difficulty. I do so miss the 'pew pew' when shooting... lol Oh, wait... I can fix that... Now where did I store my old 8 bit sound samples? Moo Ha Ha Ha...
8 bit sound effect ? It would be perfect ... 'pew pew'....
Posts: 202
Threads: 16
Joined: Dec 2023
Reputation:
8
Thanks Marcus, very impressive. I look forward to checking out the amended library.
Posts: 784
Threads: 78
Joined: Nov 2023
Reputation:
8
Ok. It's not much of a change but I think it adds a little 'nostalgia' to the demo. Joystick (keyboard still works... lol) and 3 simple sounds.
flight.zip (Size: 56.57 KB / Downloads: 4)
Enjoy!
J
Logic is the beginning of wisdom.
Live long and prosper.
Posts: 479
Threads: 63
Joined: Nov 2023
Reputation:
3
(09-15-2025, 06:57 PM) johnno56 Wrote: Ok. It's not much of a change but I think it adds a little 'nostalgia' to the demo. Joystick (keyboard still works... lol) and 3 simple sounds.
Enjoy!
J
The joystick hums, my hands know every turn,
Each chipstune spark ignites the thrill I yearn
Gift boxes glimmer, treasures in the dark,
I chase them fast, like chasing childhood's spark,
Old Star Fox dreams still in my heart survive
Posts: 784
Threads: 78
Joined: Nov 2023
Reputation:
8
I was thinking about what to add to Star Fox... I know, it's a demo and not a full game... lol.. but still...
I was thinking about a 'health bar'... but then that would mean a damage routine would be needed as well as power ups to increase health and possible a 'game over' routine... and the list goes on...
Here is a simple 'health bar' that could be added to most 'retro' games. This example uses the left and right arrows to decrease and increase the health...
Code:
' 8-BIT HEALTH BAR EXAMPLE IN NAALAA 7
set window "8-Bit Health Bar", 300, 240, false, 2
set redraw off
' Health values
constant MAX_HEALTH = 20
health = MAX_HEALTH
' Function: Draw health bar
function draw_healthbar(x, y, health, max_health)
block_w = 8
block_h = 16
for i = 0 to max_health - 1
' Draw empty slot (darkish red)
set color 200, 40, 40 '60, 60, 60
draw rect x + i * (block_w + 2), y, block_w, block_h, true
' If this slot is still "filled", draw green
if i < health
set color 0, 160, 0
draw rect x + i * (block_w + 2), y, block_w, block_h, true
' Add border (black outline for 8-bit look)
set color 0, 0, 0
draw rect x + i * (block_w + 2), y, block_w, block_h, false
else
' Just border for empty
set color 0, 0, 0
draw rect x + i * (block_w + 2), y, block_w, block_h, false
endif
next
endfunc
' Main loop
while not keydown(KEY_ESCAPE)
set color 180, 200, 220
cls
' Draw health bar at (50,50)
draw_healthbar(50, 100, health, MAX_HEALTH)
' Reduce health with LEFT arrow, increase with RIGHT
if keydown(KEY_LEFT) and health > 0 then health = health - 1
if keydown(KEY_RIGHT) and health < MAX_HEALTH then health = health + 1
redraw
wait 30
wend
Hope you find it usefull...
J
Logic is the beginning of wisdom.
Live long and prosper.
Posts: 721
Threads: 95
Joined: Nov 2023
Reputation:
7
09-16-2025, 01:33 PM
(This post was last modified: 09-16-2025, 01:35 PM by Marcus .)
I'm glad you're adding stuff! But yes, I am planning to add enemies, powerups, levels and better looking models