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
    x=speed*math.cos(math.rad(angV))*math.sin(math.rad(angH))
    y=speed*math.sin(math.rad(angV))
    z=speed*math.cos(math.rad(angV))*math.cos(math.rad(angH)) 
    
    -- 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
            x=math.cos(math.rad(angV))*math.sin(math.rad(angH))
            y=math.sin(math.rad(angV))
            z=math.cos(math.rad(angV))*math.cos(math.rad(angH)) 
            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.