# starter game 16

Here’s another starter game for whoever wants it. It’s my attempt at a 3D game. The object is to fly around 3D space shooting at 3D cubes. To move thru space, just drag your finger around the screen to change your direction. You are always moving in the direction you are looking. You can change your horizontal direction by 360 degrees and your verticle direction by +/- 60 degrees. At the top I show your horizontal angle (H) and your verticle angle (V). I also show your X,Y, and Z coordinates. Try to stay within values of + or - 500 because all the cubes are within + or - 200. To shoot at a cube, just press SHOOT, but you have to wait 2 seconds before you can shoot again if you miss. If you are hit by a cube, the screen turns RED for 2 seconds. Also at the top is how many cubes you hit or the ship was hit. I didn’t get too involved in this, so I’m shooting a cube at the other cubes instead of creating a missile. I created crossed lines with X and Y text marking the center of space to make it easy to know where the center is. These can be removed once you get used to moving around in 3D. I create 100 cubes, but if this amount slows your device down, you can reduce the number. The for loop is at the bottom of a Cube:init() .

displayMode(FULLSCREEN)

function setup()
eyeX,eyeY,eyeZ=0,0,400      -- camera position
lookX,lookY,lookZ=0,0,-800  -- looking at position
angH,angV=180,0 -- horizontal and verticle angle
speed=.5    -- ship speed
x,y,z=0,0,0     -- amount of ship movement in x,y,z
mx,my,mz=0,0,0  -- amount of missile movement in x,y,z
shipHit=0
cubesHit=0
c=color(0)
resetCubemissile()
Cubes=Cube()
end

function draw()
background(c)

--
fill(255,0,0)
rect(WIDTH/2-50,50,100,50)

-- draw position and angle info and number of cubes
fill(255)
text("SHOOT",WIDTH/2,75)
text(string.format("H %4.0f    V %4.0f",angH,angV),WIDTH/2,HEIGHT-25)
text(string.format("X %4.1f    Y %4.1f    Z %4.1f",eyeX,eyeY,eyeZ),WIDTH/2,HEIGHT-50)
text("Cubes hit  "..cubesHit.."      Ship hit  "..shipHit,WIDTH/2,HEIGHT-80)

-- calculate speed and direction to move

-- camera position
eyeX=eyeX+x
eyeY=eyeY+y
eyeZ=eyeZ+z

-- camera look direction
lookX=eyeX+2000*x
lookY=eyeY+2000*y
lookZ=eyeZ+2000*z

perspective()
camera(eyeX,eyeY,eyeZ,lookX,lookY,lookZ, 0,1,0)

-- draw x,y center coordinate for reference point
stroke(255)
strokeWidth(1)
line(0,-2000,0,2000)
line(-2000,0,2000,0)
text("X+",20,0)
text("-X",-20,0)
text("+Y",0,20)
text("-Y",0,-20)

-- draw missile cube
bx=bx+mx+x
by=by+my+y
bz=bz+mz+z
Cubes.cubesTab[1]=vec3(bx,by,bz)    -- use first cube as missile

Cubes:draw()
end

function touched(t)
if t.state==BEGAN then
-- shoot cube using rect or all of the bottom of the screen
if t.y<100 and not shoot then
shoot=true
tween.delay(2,function() resetCubemissile() end)
bx,by,bz=eyeX,eyeY,eyeZ
mx,my,mz=x,y,z
sound(SOUND_SHOOT, 41974)
return
end
end
if t.state==MOVING then
-- change horizontal and verticle direction
angH=angH+t.deltaX/5
if angH>360 then
angH=angH-360
end
if angH<0 then
angH=angH+360
end
angV=angV-t.deltaY/5
if angV>60 then
angV=60
end
if angV<-60 then
angV=-60
end
end
end

function resetCubemissile()
shoot=false
bx,by,bz=99999,99999,99999
end

Cube = class()

function Cube:init()
local vertices = {
vec3(-0.5, -0.5,  0.5),
vec3( 0.5, -0.5,  0.5),
vec3( 0.5,  0.5,  0.5),
vec3(-0.5,  0.5,  0.5),
vec3(-0.5, -0.5, -0.5),
vec3( 0.5, -0.5, -0.5),
vec3( 0.5,  0.5, -0.5),
vec3(-0.5,  0.5, -0.5),
}
local cubeverts = {
vertices[1], vertices[2], vertices[3],
vertices[1], vertices[3], vertices[4],
vertices[2], vertices[6], vertices[7],
vertices[2], vertices[7], vertices[3],
vertices[6], vertices[5], vertices[8],
vertices[6], vertices[8], vertices[7],
vertices[5], vertices[1], vertices[4],
vertices[5], vertices[4], vertices[8],
vertices[4], vertices[3], vertices[7],
vertices[4], vertices[7], vertices[8],
vertices[5], vertices[6], vertices[2],
vertices[5], vertices[2], vertices[1],
}
local texverts = { vec2(0.03,0.24),vec2(0.97,0.24),
vec2(0.03,0.69),vec2(0.97,0.69) }
local cubetexCoords = {
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
texverts[1], texverts[2], texverts[4],
texverts[1], texverts[4], texverts[3],
}
self.m=mesh()
self.m.vertices = cubeverts
self.m.texture = "Planet Cute:Stone Block"
self.m.texCoords = cubetexCoords
self.cubesTab={}    -- table for cubes
dist=200    -- cube distance for random position
for z=1,100 do  -- create random position cubes
table.insert(self.cubesTab,vec3(math.random(-dist,dist),
math.random(-dist,dist),math.random(-dist,dist)))
end
end

function Cube:draw()
for a,b in pairs(self.cubesTab) do
resetMatrix()
translate(b.x,b.y,b.z)
-- check if missile cube hit another cube
if a>1 then -- skip cube 1, the missile cube
-- calculate how close missile cube is to another cube
local x=math.abs(bx-b.x)
local y=math.abs(by-b.y)
local z=math.abs(bz-b.z)
if x<.5 and y<.5 and z<.5 then
-- remove cube
table.remove(self.cubesTab,a)
cubesHit=cubesHit+1
-- reset missile info
resetCubemissile()
sound(SOUND_EXPLODE, 18893)
end
local x=math.abs(eyeX-b.x)
local y=math.abs(eyeY-b.y)
local z=math.abs(eyeZ-b.z)
if x<1.5 and y<1.5 and z<1.5 then
-- cube ran into ship
table.remove(self.cubesTab,a)
shipHit=shipHit+1
sound(SOUND_EXPLODE, 18902)
c=color(255,0,0)
tween.delay(2,function() c=color(0) end)
end
end
-- draw cubes
self.m:draw()
end
end

That’s hard! I only hit 1 cube, and I got hit 10 times. Maybe if you had a crosshair to aim with…

Are you going to enter something into the game jam?

@yojimbo2000 If it had a crosshair, it would be too easy. The uncertainty makes it interesting. I don’t like to play games, so I won’t be entering anything in the game jam. The game starters I create are usually spinoffs from something else I’m working on. I just write enough code to get it going and the rest is for whoever wants to add to it.

I love your starter game series and learned much from your code, im going to study this 3D game.