This is my first 3D project, it uses the 2D physics engine to create the physics needed for the table top effect.
Here’s the code, its a two player game with a basic score system, the score doesn’t have a limit although air hockey is 7.
--# Main
-- 3Dairhockey
-- Use this function to perform your initial setup
function setup()
displayMode(FULLSCREEN)
cube = {}
cube[1] = Cube(vec3(0,0,145)*5,vec3(440,4,20)*5)
cube[2] = Cube(vec3(210,0,100)*5,vec3(20,4,80)*5)
cube[3] = Cube(vec3(210,0,-100)*5,vec3(20,4,80)*5)
cube[4] = Cube(vec3(-210,0,100)*5,vec3(20,4,80)*5)
cube[5] = Cube(vec3(-210,0,-100)*5,vec3(20,4,80)*5)
cube[6] = Cube(vec3(0,0,-145)*5,vec3(440,4,20)*5)
cube[7] = Cube(vec3(0,-10,0)*5,vec3(5,1,300)*5)
cube[7]:setColors(50,50,255,100)
puck = Cylinder(vec3(0,0,0),60,15)
puckp = physics.body(CIRCLE,60)
puckp.position = vec2(0,0)
puckp.gravityScale = 0
puckp.restitution = 1
puckp.friction = 0
puckp.sleepingAllowed = false
puckp.interpolate = true
puckp.mask = {1}
puckp.categories = {1}
floorv = {vec2(200,-60)*5,vec2(200,-135)*5,vec2(-200,-135)*5,vec2(-200,-60)*5}
floor = physics.body(CHAIN,false,unpack(floorv))
floor.categories = {0,1}
floor.restitution = 1
floorv = {vec2(200,60)*5,vec2(200,135)*5,vec2(-200,135)*5,vec2(-200,60)*5}
floor2 = physics.body(CHAIN,false,unpack(floorv))
floor2.categories = {0,1}
floor2.restitution = 1
t1 = Touch()
t2 = Touch()
ply1 = Cylinder(vec3(0,0,WIDTH-200),100,15)
plyp1 = physics.body(CIRCLE,100)
plyp1.position = vec2(WIDTH-200,0)
plyp1.gravityScale = 0
plyp1.friction = 0.2
plyp1.restitution = 0.2
plyp1.sleepingAllowed = false
plyp1.interpolate = true
plyp1.categories = {0,1}
ply2 = Cylinder(vec3(0,0,0),100,15)
plyp2 = physics.body(CIRCLE,100)
plyp2.position = vec2(-800,0)
plyp2.gravityScale = 0
plyp2.friction = 0.2
plyp2.restitution = 0.2
plyp2.sleepingAllowed = false
plyp2.interpolate = true
plyp2.categories = {0,1}
splitter = physics.body(EDGE,vec2(0,-135*5),vec2(1,135*5))
splitter.type = STATIC
back1 = physics.body(EDGE,vec2(1000,-60*5),vec2(1001,60*5))
back1.categories = {0}
back1.type = STATIC
back2 = physics.body(EDGE,vec2(-1000,-60*5),vec2(-1001,60*5))
back2.categories = {0}
back2.type = STATIC
score1 = 0
score2 = 0
end
function touched(t)
if t.state == BEGAN then
if t.x > WIDTH/2 then
t1:touched(t)
elseif t.x < WIDTH/2 then
t2:touched(t)
end
end
if t1.mov and t.id == t1.id then
t1:touched(t)
end
if t2.mov and t.id == t2.id then
t2:touched(t)
end
end
-- This function gets called once every frame
function draw()
if t1.state == MOVING then
if t1.x > WIDTH/2 then
t1.state = ENDED
end
plyp1:applyForce(vec2(t1.deltaX,-t1.deltaY)*1000)
end
if t2.state == MOVING then
if t2.x < WIDTH/2 then
t2.state = ENDED
end
plyp2:applyForce(vec2(t2.deltaX,-t2.deltaY)*1000)
end
if puckp.x > 1200 or puckp.x < -1200 then
if puckp.x > 1200 then
score1 = score1 + 1
end
if puckp.x < -1200 then
score2 = score2 + 1
end
puckp.position = vec2(0,0)
puckp.linearVelocity = vec2(0,0)
plyp1.position = vec2(600,0)
plyp2.position = vec2(-600,0)
end
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
pushStyle()
fill(255)
text("Player 1 Score:"..score1,120,75)
text("Player 2 Score:"..score2,WIDTH-120,75)
popStyle()
-- Do your drawing here
perspective(90, WIDTH/HEIGHT)
-- Position the camera up and back, look at origin
camera(0,900,1, 0, 0, 0, 0,1,0)
for k,v in pairs(cube) do
v.shader = shadr
v:draw()
end
puckp.linearVelocity = puckp.linearVelocity*0.992
plyp1.linearVelocity = plyp1.linearVelocity*0.9
plyp2.linearVelocity = plyp2.linearVelocity*0.9
pushMatrix()
local puckpos = puckp.position
translate(puckpos.x,0,puckpos.y)
puck.shader = shadr
puck:draw()
popMatrix()
pushMatrix()
local plypos = plyp1.position
translate(plypos.x,0,plypos.y)
ply1.shader = shadr
ply1:draw()
popMatrix()
pushMatrix()
local plypos = plyp2.position
translate(plypos.x,0,plypos.y)
ply2.shader = shadr
ply2:draw()
popMatrix()
ortho()
-- Restore the view matrix to the identity
viewMatrix(matrix())
end
--# Cube
Cube = class()
function Cube:init(pos,size)
-- you can accept and set parameters here
self.pos = pos
self.size = size
self.verts = {
pos+vec3(-0.5*size.x, -0.5*size.y, 0.5*size.z), -- Left bottom front
pos+vec3( 0.5*size.x, -0.5*size.y, 0.5*size.z), -- Right bottom front
pos+vec3( 0.5*size.x, 0.5*size.y, 0.5*size.z), -- Right top front
pos+vec3(-0.5*size.x, 0.5*size.y, 0.5*size.z), -- Left top front
pos+vec3(-0.5*size.x, -0.5*size.y, -0.5*size.z), -- Left bottom back
pos+vec3( 0.5*size.x, -0.5*size.y, -0.5*size.z), -- Right bottom back
pos+vec3( 0.5*size.x, 0.5*size.y, -0.5*size.z), -- Right top back
pos+vec3(-0.5*size.x, 0.5*size.y, -0.5*size.z), -- Left top back
}
-- now construct a cube out of the vertices above
self.cverts = {
-- Front
self.verts[1], self.verts[2], self.verts[3],
self.verts[1], self.verts[3], self.verts[4],
-- Right
self.verts[2], self.verts[6], self.verts[7],
self.verts[2], self.verts[7], self.verts[3],
-- Back
self.verts[6], self.verts[5], self.verts[8],
self.verts[6], self.verts[8], self.verts[7],
-- Left
self.verts[5], self.verts[1], self.verts[4],
self.verts[5], self.verts[4], self.verts[8],
-- Top
self.verts[4], self.verts[3], self.verts[7],
self.verts[4], self.verts[7], self.verts[8],
-- Bottom
self.verts[5], self.verts[6], self.verts[2],
self.verts[5], self.verts[2], self.verts[1],
}
self.texverts = { vec2(0.03,0.24),
vec2(0.97,0.24),
vec2(0.03,0.69),
vec2(0.97,0.69) }
-- apply the texture coordinates to each triangle
self.texCoords = {
-- Front
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
-- Right
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
-- Back
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
-- Left
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
-- Top
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
-- Bottom
self.texverts[1], self.texverts[2], self.texverts[4],
self.texverts[1], self.texverts[4], self.texverts[3],
}
self.m = mesh()
self.m.vertices = self.cverts
self.m.texCoords = self.texCoords
--self.m.texture = readImage("Documents:checker")
self.m:setColors(255,255,255,255)
-- all the unique texture positions needed
end
function Cube:setColors(colr,colg,colb,alpha)
local a = alpha or 255
self.m:setColors(colr,colg,colb,a)
end
function Cube:draw()
self.m:draw()
end
function Cube:touched(touch)
-- Codea does not automatically call this method
end