Drag the Wall
From OxeyeWiki
(Difference between revisions)
Jeb (Talk | contribs)
(Created page with '== Description == In Drag the Wall your objective is to pull the white wall piece with your mouse so that it touches all of the small white boxes. In the small room there are fo...')
(Created page with '== Description == In Drag the Wall your objective is to pull the white wall piece with your mouse so that it touches all of the small white boxes. In the small room there are fo...')
Latest revision as of 11:38, 7 February 2010
Contents |
Description
In Drag the Wall your objective is to pull the white wall piece with your mouse so that it touches all of the small white boxes. In the small room there are four defense towers that charge up a blast that will kill you, so you need to find safe spots not to get caught.
This example was rewritten for DaisyMoon 1.1.0. Download all files here: dragthewall.zip
Disclaimer: DaisyMoon is pretty bad at doing 3D since it's mainly a 2D engine. Doing 3D stuff is dodgy, to say the least.
Assets
Files
- main.lua
- vectorMath.lua
- itt.dat
- speckle.jpg
- 120poly.obj
- font.fnt
- warning1.wav
- warning2.wav
- warning3.wav
- warning4.wav
- collide1.wav
- collide2.wav
- collide3.wav
- death.wav
- explosion1.wav
main.lua
math.randomseed( os.time() )
dofile("vectorMath.lua")
-- copy from global namespace
local vectorMath, video, math = _vectorMath, video, math
local d45 = math.cos(math.pi * .25)
local circleSprite, blockSprite, tankNode, light, myPhysics
local cameraPosition = { x = 0, y = 0, z = -9.5 }
local cameraTarget = { x = 0, y = 0, z = 0 }
local testMaterial = {
texture = "daisyMoon/speckle.jpg",
lighting = true,
zbuffer = true,
zwrite = true,
clockwiseCull = false,
materialType = 0,
}
local transparentMaterial = {
texture = "daisyMoon/speckle.jpg",
lighting = true,
zbuffer = true,
zwrite = false,
clockwiseCull = false,
materialType = 11,
}
local chain = {}
local obstacles = {}
local items = {}
local transparent = {}
local gameData = {
selectedLink = nil,
lastSelectedLink = nil,
gameOver = 0,
}
local function positionOnZedPlane(x, y)
local sx, sy, sz, ex, ey, ez = video.getCameraRay(x, y)
-- calculate collision with Z plane
local x = sx - ((ex - sx) * sz) / (ez - sz)
local y = sy - ((ey - sy) * sz) / (ez - sz)
return x, y
end
local function createBevel(width, height, depth)
-- front
local fx1, fx2, fy1, fy2, fz = -width + depth, width - depth, -height + depth, height - depth, -depth
local bevel = {
-- front -- left -- right -- bottom -- top
x = { fx1, fx1, fx2, fx2, -width, -width, fx1, fx1, fx2, fx2, width, width, -width, fx1, fx2, width, fx1, -width, width, fx2 },
y = { fy1, fy2, fy2, fy1, -height, height, fy2, fy1, fy1, fy2, height, -height, -height, fy1, fy1, -height, fy2, height, height, fy2 },
z = { fz, fz, fz, fz, 0, 0, fz, fz, fz, fz, 0, 0, 0, fz, fz, 0, fz, 0, 0, fz },
nx = { 0, 0, 0, 0, -d45, -d45, -d45, -d45, d45, d45, d45, d45, 0, 0, 0, 0, 0, 0, 0, 0 },
ny = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d45, d45, d45, d45, -d45, -d45, -d45, -d45 },
nz = { -1, -1, -1, -1, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45 },
u = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
v = {0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 },
i = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19 },
tris = 10,
verts = 20,
physX = { -width, -width, width, width },
physY = { height, -height, -height, height },
}
return bevel
end
local function transformBevel(bevel, formX, formY, formCX1, formCY1, formCX2, formCY2)
local copy = {
-- copy references to tables that aren't modified
z = bevel.z,
nz = bevel.nz,
u = bevel.u,
v = bevel.v,
i = bevel.i,
tris = bevel.tris,
verts = bevel.verts
}
-- transform x and y
copy.x, copy.y = {}, {}
copy.nx, copy.ny = {}, {}
for i=1,bevel.verts do
copy.x[i], copy.y[i] = vectorMath.xFormMultiply(formX, formY, formCX1, formCY1, formCX2, formCY2, bevel.x[i], bevel.y[i])
copy.nx[i], copy.ny[i] = vectorMath.xFormMultiply(0, 0, -formCX1, -formCY1, -formCX2, -formCY2, -bevel.nx[i], bevel.ny[i])
end
--copy.nx, copy.ny = bevel.nx, bevel.ny
return copy
end
local function createTransparent(x, y, w, h, d)
local o = {}
o.bevel = createBevel(w * .5, h * .5, d)
o.body = myPhysics:createEntity({}, x, y)
myPhysics:addBoxShape(o.body, { x = 0, y = 0, width = w, height = h, density = 10, isSensor = true })
myPhysics:activateEntity(o.body)
table.insert(transparent, o)
return o
end
local chargeCounter = 1
local function createObstacle(x, y, w, h, d, isCharger)
local o = {}
o.bevel = createBevel(w * .5, h * .5, d)
o.body = myPhysics:createEntity({}, x, y)
myPhysics:addBoxShape(o.body, { x = 0, y = 0, width = w, height = h, density = 10 })
if isCharger then
o.isCharger = true
o.chargeTimer = -10 + math.random() * -15
if chargeCounter == 1 then
o.chargeTimer = 0
end
o.chargeOverlay = createTransparent(x, y, w + 3.5, h + 3.5, d + .1)
o.chargeSound = "warning" .. chargeCounter .. ".wav"
chargeCounter = chargeCounter + 1
if chargeCounter > 4 then
chargeCounter = 1
end
end
table.insert(obstacles, o)
return o
end
local function createItem(x, y)
local i = {}
i.bevel = createBevel(.25, .25, .1)
i.body = myPhysics:createEntity({linearDamping = 1, angularDamping = 1}, x, y)
myPhysics:addBoxShape(i.body, { x = 0, y = 0, width = .5, height = .5, density = .5, userData = "item_" .. #items })
myPhysics:setEntityAngle(i.body, math.random() * 2.0 * math.pi)
myPhysics:activateEntity(i.body)
table.insert(items, i)
return i
end
local function gameInit()
--video.setScreenSize(1280, 960)
circleSprite = video.createSpriteState("Circle", "itt.dat")
blockSprite = video.createSpriteState("Square", "itt.dat")
--tankNode = video.createSceneNode("tank.obj", "tex.tga", 0, 0, 0, 0, 0, 0, 1, 1, 1)
video.setCameraPosition(cameraPosition.x, cameraPosition.y, cameraPosition.z)
video.setCameraViewPosition(cameraTarget.x, cameraTarget.y, cameraTarget.z)
--video.setCameraUpVector(0, 0, -1)
light = video.createLightSceneNode(0, 0, -3, 6)
tankNode = video.createSceneNode("120poly.obj", "speckle.jpg", 4, 1, 37.5, 0, 0, 0, .5, .5, .5)
myPhysics = Physics(-1000, -1000, 1000, 1000, 0, 0)
local bodyDef = { linearDamping = 20, angularDamping = 20, fixedRotation = false, isBullet = false }
local startY = -5.5
chain.links = {}
for i=1,1 do
chain.links[i] = {}
chain.links[i].bevel = createBevel(.25, 1.5, .1)
chain.links[i].body = myPhysics:createEntity(bodyDef, 0, startY + (i-1) * -1)
myPhysics:addBoxShape(chain.links[i].body, { x = 0, y = 0, width = .5, height = 3, density = 5, friction = .1, restitution = 1 })
myPhysics:activateEntity(chain.links[i].body)
if i > 1 then
-- link with previous piece
-- 1: Create a body between the pieces
local shapeA = myPhysics:createEntity(bodyDef, 0, startY + (i-2) * -1 - .5)
myPhysics:addBoxShape(shapeA, {x = 0, y = 0, width = .2, height = .6, density = 1, userData = "player"})
myPhysics:activateEntity(shapeA)
-- 2: Attach the shape to the previous piece
myPhysics:createRevoluteJoint(shapeA, chain.links[i-1].body, 0, startY + (i-2) * -1 - .5 + .3, {enableLimit = true, lowerAngle = math.pi * -.1, upperAngle = math.pi * .1})
myPhysics:createRevoluteJoint(shapeA, chain.links[i].body, 0, startY + (i-2) * -1 - .5 - .3, {enableLimit = true, lowerAngle = math.pi * -.1, upperAngle = math.pi * .1})
end
end
local o = createObstacle(-4, 2.5, 2, 3, .3)
myPhysics:setEntityAngle(o.body, math.pi * .3)
createObstacle(-4, -2, 2, 3, .29)
createObstacle(4, -5, 2, 6, .29)
createObstacle(4, 2.5, 2, 3, .3)
createObstacle(0, 0, 3, 2, .3)
createObstacle(4, 2.5, 1.5, 1.5, .4, true)
createObstacle(4, -3, 1.5, 1.5, .4, true)
o = createObstacle(-4, 2.5, 1.5, 1.5, .4, true)
myPhysics:setEntityAngle(o.body, math.pi * .3)
createObstacle(-4, -2, 1.5, 1.5, .4, true)
createObstacle(-8.5, 0, 2, 11, .3)
createObstacle(0, 6.5, 19, 2, .3)
createObstacle(8.5, 0, 2, 11, .3)
createObstacle(-4.5, -18, 8.5, 25, .3)
createObstacle(4.5, -18, 8.5, 25, .3)
--createTransparent(4, -3, 5.5, 5.5, .45)
--createTransparent(-4, 2.5, 5.5, 5.5, .45)
--createTransparent(-4, -2, 5.5, 5.5, .45)
--createTransparent(4, 2.5, 5.5, 5.5, .45)
for i=1,30 do
createItem(math.random() * 12 - 6, math.random() * 8 - 4)
end
--[[
local grid = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 },
{ 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 },
}
local gridSize = 2
for y=1,#grid do
for x=1,#grid[y] do
if grid[y][x] > 0 then
createObstacle(-(gridSize * 5.5) + x * gridSize, -2 + (gridSize * #grid) - y * gridSize, gridSize, gridSize, .2)
end
end
end
]]
end
hook.add("gameInit", gameInit)
local cameraTime = 0
local function gameUpdate(time)
--local w,h = video.getScreenSize()
if time > .06 then
time = .06
end
cameraTime = cameraTime + time
video.setSceneNodeRotation(tankNode, cameraTime * math.pi * .038, cameraTime * math.pi * .338, cameraTime * math.pi)
--cameraPosition.x = math.cos(cameraTime) * 3
--video.setCameraPosition(cameraPosition.x, cameraPosition.y, cameraPosition.z)
--video.setSceneNodePosition(light, cameraPosition.x, cameraPosition.y, cameraPosition.z)
myPhysics:update(time, 10)
if daisy.isMouseButtonPressed(0) and gameData.gameOver == 0 then
local mx, my = daisy.getMousePosition()
local wx, wy = positionOnZedPlane(mx, my)
if gameData.selectedLink then
-- pull link based on delta distance
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(gameData.selectedLink.body)
--gameData.startWX, gameData.startWY = wx, wy
local localX, localY = vectorMath.xFormMultiply(cx, cy, x1, y1, x2, y2, gameData.startX, gameData.startY)
local dx, dy = (wx - localX), (wy - localY)
local diff = math.sqrt(dx * dx + dy * dy)
if diff > 0 then
dx = dx / diff
dy = dy / diff
myPhysics:applyEntityForce(gameData.selectedLink.body, localX, localY, dx * 700, dy * 700)
end
else
for i=1,#chain.links do
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(chain.links[i].body)
local xCoords, yCoords = {}, {}
for v=1,#chain.links[i].bevel.physX do
xCoords[v], yCoords[v] = vectorMath.xFormMultiply(cx, cy, x1, y1, x2, y2, chain.links[i].bevel.physX[v], chain.links[i].bevel.physY[v])
end
chain.links[i].isPointInside = true
for v=1,4 do
local u = v + 1
if u > 4 then
u = 1
end
-- vector from v to u
local dx, dy = xCoords[u] - xCoords[v], yCoords[u] - yCoords[v]
-- vector from v to position
local tx, ty = wx - xCoords[v], wy - yCoords[v]
if vectorMath.cross22(dx, dy, tx, ty) < 0 then
chain.links[i].isPointInside = false
end
end
if chain.links[i].isPointInside then
gameData.selectedLink = chain.links[i]
gameData.startX, gameData.startY = vectorMath.xFormInvert(cx, cy, x1, y1, x2, y2, wx, wy)
gameData.startWX, gameData.startWY = wx, wy
end
end
end
else
if gameData.selectedLink then
gameData.selectedLink.isPointInside = false
end
gameData.selectedLink = nil
end
do
if gameData.selectedLink then
--gameData.lastSelectedLink = gameData.selectedLink
end
if not gameData.lastSelectedLink then
gameData.lastSelectedLink = chain.links[1]
end
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(gameData.lastSelectedLink.body)
video.setSceneNodePosition(light, cx, cy, -2)
local px, py = cx, cy
for index, item in ipairs(items) do
cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(item.body)
-- attempt to avoid the player!
local dx, dy = px - cx, py - cy
local diff = math.sqrt(dx * dx + dy * dy)
item.runAwayTimer = item.runAwayTimer or 0
item.runAwayTimer = item.runAwayTimer + time
if item.runAwayTimer > 3 then
item.runLeft = not item.runLeft
item.runAwayTimer = math.random()
end
if diff < 3 then
dx = dx / diff
dy = dy / diff
-- rotate 90 degrees
local temp = dx
dx = -dy
dy = temp
local run = 2
if item.runLeft then
run = -2
end
myPhysics:applyEntityForce(item.body, cx, cy, dx * run, dy * run)
else
dx = 2 * dx / diff
dy = 2 * dy / diff
myPhysics:applyEntityForce(item.body, cx, cy, -dx, -dy)
end
end
local impacts = myPhysics:getEntityCollisions(gameData.lastSelectedLink.body)
if impacts then
for i=1,#impacts do
if impacts[i].impulse > 1 then
--print("impact " .. impacts[i].impulse)
local found = false
-- locate if it was an item we hit
for index, item in ipairs(items) do
if item.body == impacts[i].id then
--print("killed item")
audio.playSound("death.wav")
myPhysics:deleteEntity(item.body)
table.remove(items, index)
found = true
break
end
end
if not found then
if impacts[i].impulse > 30 then
audio.playSound("collide" .. math.random(1,3) .. ".wav")
end
end
end
end
end
local playerSensors = myPhysics:getEntitySensorPoints(gameData.lastSelectedLink.body)
if playerSensors then
for s=1,#playerSensors do
for index, obstacle in ipairs(transparent) do
if obstacle.body == playerSensors[s].id and obstacle.activeTimer and obstacle.activeTimer > 0 then
--print("hit by sensor")
gameData.gameOver = 2
end
end
end
end
end
if gameData.gameOver == 0 then
for index, obstacle in ipairs(obstacles) do
if obstacle.isCharger then
obstacle.chargeTimer = obstacle.chargeTimer + time * 2
local prevFlash = obstacle.doFlash
obstacle.doFlash = obstacle.chargeTimer > 0 and math.sin(obstacle.chargeTimer * obstacle.chargeTimer) > .8
if not prevFlash and obstacle.doFlash then
audio.playSound(obstacle.chargeSound, .2 + obstacle.chargeTimer / 20, 0, .5 + obstacle.chargeTimer / 15)
end
if obstacle.chargeTimer > 15 then
obstacle.chargeTimer = -math.random() * 20
obstacle.chargeOverlay.activeTimer = 1
audio.playSound("explosion1.wav", .6)
end
end
end
end
for index, obstacle in ipairs(transparent) do
obstacle.rotationTimer = obstacle.rotationTimer or 0
obstacle.rotationTimer = obstacle.rotationTimer + time * 10
myPhysics:setEntityAngle(obstacle.body, obstacle.rotationTimer)
if obstacle.activeTimer and obstacle.activeTimer > 0 then
obstacle.activeTimer = obstacle.activeTimer - time
end
end
if #items == 0 and gameData.gameOver == 0 then
gameData.gameOver = 1
end
end
hook.add("frameUpdate", gameUpdate)
local bgGrid = {
x = { -.1, -.1, 0, 0, .1, .1, 0, 0 },
y = { -1, 1, 1, -1, 1, -1, -1, 1 },
z = { .1, .1, 0, 0, .1, .1, 0, 0 },
nx = { -d45, -d45, -d45, -d45, d45, d45, d45, d45 },
ny = { 0, 0, 0, 0, 0, 0, 0, 0 },
nz = { -d45, -d45, -d45, -d45, -d45, -d45, -d45, -d45 },
u = { 0, 0, 1, 1, 0, 0, 1, 1 },
v = { 0, 1, 1, 0, 0, 1, 1, 0 },
i = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 },
tris = 4,
verts = 8,
}
do
-- generate bg grid
local v = 1
local i = 1
local zOff = 0
for yCount=1,5 do
local y = 6 - yCount * 2
for xCount=1,7 do
local x = -8 + xCount * 2
-- create back and front
bgGrid.x[v + 0] = x - .1
bgGrid.x[v + 1] = x - .1
bgGrid.x[v + 2] = x
bgGrid.x[v + 3] = x
bgGrid.x[v + 4] = x + .1
bgGrid.x[v + 5] = x + .1
bgGrid.x[v + 6] = x
bgGrid.x[v + 7] = x
bgGrid.y[v + 0] = y - 1
bgGrid.y[v + 1] = y + 1
bgGrid.y[v + 2] = y + 1
bgGrid.y[v + 3] = y - 1
bgGrid.y[v + 4] = y + 1
bgGrid.y[v + 5] = y - 1
bgGrid.y[v + 6] = y - 1
bgGrid.y[v + 7] = y + 1
bgGrid.z[v + 0] = .1 + zOff
bgGrid.z[v + 1] = .1 + zOff
bgGrid.z[v + 2] = 0 + zOff
bgGrid.z[v + 3] = 0 + zOff
bgGrid.z[v + 4] = .1 + zOff
bgGrid.z[v + 5] = .1 + zOff
bgGrid.z[v + 6] = 0 + zOff
bgGrid.z[v + 7] = 0 + zOff
bgGrid.nx[v + 0] = -d45
bgGrid.nx[v + 1] = -d45
bgGrid.nx[v + 2] = -d45
bgGrid.nx[v + 3] = -d45
bgGrid.nx[v + 4] = d45
bgGrid.nx[v + 5] = d45
bgGrid.nx[v + 6] = d45
bgGrid.nx[v + 7] = d45
bgGrid.ny[v + 0] = 0
bgGrid.ny[v + 1] = 0
bgGrid.ny[v + 2] = 0
bgGrid.ny[v + 3] = 0
bgGrid.ny[v + 4] = 0
bgGrid.ny[v + 5] = 0
bgGrid.ny[v + 6] = 0
bgGrid.ny[v + 7] = 0
bgGrid.nz[v + 0] = -d45
bgGrid.nz[v + 1] = -d45
bgGrid.nz[v + 2] = -d45
bgGrid.nz[v + 3] = -d45
bgGrid.nz[v + 4] = -d45
bgGrid.nz[v + 5] = -d45
bgGrid.nz[v + 6] = -d45
bgGrid.nz[v + 7] = -d45
bgGrid.u[v + 0] = 0
bgGrid.u[v + 1] = 0
bgGrid.u[v + 2] = 1
bgGrid.u[v + 3] = 1
bgGrid.u[v + 4] = 0
bgGrid.u[v + 5] = 0
bgGrid.u[v + 6] = 1
bgGrid.u[v + 7] = 1
bgGrid.v[v + 0] = 0
bgGrid.v[v + 1] = 1
bgGrid.v[v + 2] = 1
bgGrid.v[v + 3] = 0
bgGrid.v[v + 4] = 0
bgGrid.v[v + 5] = 1
bgGrid.v[v + 6] = 1
bgGrid.v[v + 7] = 0
bgGrid.i[i + 0] = v + 0 - 1
bgGrid.i[i + 1] = v + 1 - 1
bgGrid.i[i + 2] = v + 2 - 1
bgGrid.i[i + 3] = v + 0 - 1
bgGrid.i[i + 4] = v + 2 - 1
bgGrid.i[i + 5] = v + 3 - 1
bgGrid.i[i + 6] = v + 4 - 1
bgGrid.i[i + 7] = v + 5 - 1
bgGrid.i[i + 8] = v + 6 - 1
bgGrid.i[i + 9] = v + 4 - 1
bgGrid.i[i + 10] = v + 6 - 1
bgGrid.i[i + 11] = v + 7 - 1
v = v + 8
i = i + 12
-- create top and bottom
bgGrid.x[v + 0] = x - 1
bgGrid.x[v + 1] = x + 1
bgGrid.x[v + 2] = x + 1
bgGrid.x[v + 3] = x - 1
bgGrid.x[v + 4] = x - 1
bgGrid.x[v + 5] = x + 1
bgGrid.x[v + 6] = x + 1
bgGrid.x[v + 7] = x - 1
bgGrid.y[v + 0] = y + .1
bgGrid.y[v + 1] = y + .1
bgGrid.y[v + 2] = y
bgGrid.y[v + 3] = y
bgGrid.y[v + 4] = y
bgGrid.y[v + 5] = y
bgGrid.y[v + 6] = y - .1
bgGrid.y[v + 7] = y - .1
bgGrid.z[v + 0] = .1 + zOff
bgGrid.z[v + 1] = .1 + zOff
bgGrid.z[v + 2] = 0 + zOff
bgGrid.z[v + 3] = 0 + zOff
bgGrid.z[v + 4] = 0 + zOff
bgGrid.z[v + 5] = 0 + zOff
bgGrid.z[v + 6] = .1 + zOff
bgGrid.z[v + 7] = .1 + zOff
bgGrid.nx[v + 0] = 0
bgGrid.nx[v + 1] = 0
bgGrid.nx[v + 2] = 0
bgGrid.nx[v + 3] = 0
bgGrid.nx[v + 4] = 0
bgGrid.nx[v + 5] = 0
bgGrid.nx[v + 6] = 0
bgGrid.nx[v + 7] = 0
bgGrid.ny[v + 0] = d45
bgGrid.ny[v + 1] = d45
bgGrid.ny[v + 2] = d45
bgGrid.ny[v + 3] = d45
bgGrid.ny[v + 4] = -d45
bgGrid.ny[v + 5] = -d45
bgGrid.ny[v + 6] = -d45
bgGrid.ny[v + 7] = -d45
bgGrid.nz[v + 0] = -d45
bgGrid.nz[v + 1] = -d45
bgGrid.nz[v + 2] = -d45
bgGrid.nz[v + 3] = -d45
bgGrid.nz[v + 4] = -d45
bgGrid.nz[v + 5] = -d45
bgGrid.nz[v + 6] = -d45
bgGrid.nz[v + 7] = -d45
bgGrid.u[v + 0] = 0
bgGrid.u[v + 1] = 0
bgGrid.u[v + 2] = 1
bgGrid.u[v + 3] = 1
bgGrid.u[v + 4] = 0
bgGrid.u[v + 5] = 0
bgGrid.u[v + 6] = 1
bgGrid.u[v + 7] = 1
bgGrid.v[v + 0] = 0
bgGrid.v[v + 1] = 1
bgGrid.v[v + 2] = 1
bgGrid.v[v + 3] = 0
bgGrid.v[v + 4] = 0
bgGrid.v[v + 5] = 1
bgGrid.v[v + 6] = 1
bgGrid.v[v + 7] = 0
bgGrid.i[i + 0] = v + 0 - 1
bgGrid.i[i + 1] = v + 1 - 1
bgGrid.i[i + 2] = v + 2 - 1
bgGrid.i[i + 3] = v + 0 - 1
bgGrid.i[i + 4] = v + 2 - 1
bgGrid.i[i + 5] = v + 3 - 1
bgGrid.i[i + 6] = v + 4 - 1
bgGrid.i[i + 7] = v + 5 - 1
bgGrid.i[i + 8] = v + 6 - 1
bgGrid.i[i + 9] = v + 4 - 1
bgGrid.i[i + 10] = v + 6 - 1
bgGrid.i[i + 11] = v + 7 - 1
v = v + 8
i = i + 12
end
end
bgGrid.verts = v - 1
bgGrid.tris = bgGrid.verts / 2
end
local function render()
local w,h = video.getScreenSize()
video.setMaterial(testMaterial)
do
local a, r, g, b = {}, {}, {}, {}
local intensity = 200 + math.floor(55 * math.random())
for v=1,bgGrid.verts do
a[v] = 255
r[v] = intensity
g[v] = 128
b[v] = 128
end
video.renderTriangleListWithNormals(
bgGrid.verts, bgGrid.tris, bgGrid.i,
bgGrid.x, bgGrid.y, bgGrid.z,
bgGrid.nx, bgGrid.ny, bgGrid.nz,
bgGrid.u, bgGrid.v,
a, r, g, b
)
end
for i=1,#chain.links do
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(chain.links[i].body)
local bevel = transformBevel(chain.links[i].bevel, cx, cy, x1, y1, x2, y2)
local a, r, g, b = {}, {}, {}, {}
local intensity = 200 + math.floor(55 * math.random())
for v=1,bevel.verts do
a[v] = 255
--if chain.links[i].isPointInside then
-- r[v] = 0
-- g[v] = intensity
-- b[v] = 0
--else
r[v] = intensity
g[v] = intensity
b[v] = intensity
--end
end
video.renderTriangleListWithNormals(
bevel.verts, bevel.tris, bevel.i,
bevel.x, bevel.y, bevel.z,
bevel.nx, bevel.ny, bevel.nz,
bevel.u, bevel.v,
a, r, g, b
)
end
for index, obstacle in ipairs(obstacles) do
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(obstacle.body)
local bevel = transformBevel(obstacle.bevel, cx, cy, x1, y1, x2, y2)
local a, r, g, b = {}, {}, {}, {}
local intensity = 200 + math.floor(55 * math.random())
for v=1,bevel.verts do
if obstacle.doFlash then
a[v] = 255
r[v] = 255
g[v] = 255
b[v] = 255
else
a[v] = 255
r[v] = intensity
g[v] = 0
b[v] = 0
end
end
video.renderTriangleListWithNormals(
bevel.verts, bevel.tris, bevel.i,
bevel.x, bevel.y, bevel.z,
bevel.nx, bevel.ny, bevel.nz,
bevel.u, bevel.v,
a, r, g, b
)
end
for index, item in ipairs(items) do
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(item.body)
local bevel = transformBevel(item.bevel, cx, cy, x1, y1, x2, y2)
local a, r, g, b = {}, {}, {}, {}
local intensity = 200 + math.floor(55 * math.random())
for v=1,bevel.verts do
a[v] = 255
r[v] = intensity
g[v] = intensity
b[v] = intensity
end
video.renderTriangleListWithNormals(
bevel.verts, bevel.tris, bevel.i,
bevel.x, bevel.y, bevel.z,
bevel.nx, bevel.ny, bevel.nz,
bevel.u, bevel.v,
a, r, g, b
)
end
video.render3dScene()
--video.renderSpriteState3d(circleSprite, 0, 0, -0.01, 0, 1.0 / 96.0, false, 255, 255, 0, 0)
video.setMaterial(transparentMaterial)
for index, obstacle in ipairs(transparent) do
if obstacle.activeTimer and obstacle.activeTimer > 0 then
local cx, cy, x1, y1, x2, y2 = myPhysics:getEntityXForm(obstacle.body)
local bevel = transformBevel(obstacle.bevel, cx, cy, x1, y1, x2, y2)
local a, r, g, b = {}, {}, {}, {}
local intensity = 200 + math.floor(55 * math.random())
for v=1,bevel.verts do
a[v] = 128
r[v] = intensity
g[v] = intensity
b[v] = intensity
end
video.renderTriangleListWithNormals(
bevel.verts, bevel.tris, bevel.i,
bevel.x, bevel.y, bevel.z,
bevel.nx, bevel.ny, bevel.nz,
bevel.u, bevel.v,
a, r, g, b
)
end
end
if gameData.gameOver > 0 then
if gameData.gameOver == 1 then
video.renderText("You won", 400, 300 - 20, 1)
elseif gameData.gameOver == 2 then
video.renderText("You lost", 400, 300, 1)
end
video.renderText("Press Ctrl+R to Play Again", 400, 300 + 20, 1)
video.renderText("Press Q to Quit", 400, 300 + 30, 1)
video.renderText("A Game by Jens Bergensten for Ludum Dare 14", 400, 550, 1)
video.renderText("http://www.oxeyegames.com", 400, 565, 1)
end
end
hook.add("frameRender", render)
local function keyPressed(key)
if key == 81 then -- Q
daisy.exitGame()
end
end
hook.add("keyPress", keyPressed)
vectorMath.lua
This is a vector math lua file that we use in many projects.
-- GLOBALS
_vectorMath = {}
-- LOCALS
local vectorMath = _vectorMath
vectorMath.cross2 = function(x, y, z)
return y * z, -x * z
end
vectorMath.cross22 = function(x1, y1, x2, y2)
return x1 * y2 - y1 * x2
end
vectorMath.dot2 = function(x1, y1, x2, y2)
return x1 * x2 + y1 * y2
end
vectorMath.normalize2 = function(x, y)
local length = math.sqrt(vectorMath.dot2(x, y, x, y))
return x / length, y / length
end
vectorMath.xFormMultiply = function(formX, formY, formCX1, formCY1, formCX2, formCY2, x, y)
local newX = formCX1 * x + formCX2 * y
local newY = formCY1 * x + formCY2 * y
return newX + formX, newY + formY
end
vectorMath.xFormInvert = function(formX, formY, formCX1, formCY1, formCX2, formCY2, x, y)
x = x - formX
y = y - formY
local d = formCX1 * formCY2 - formCY1 * formCX2
local oldX = (formCY2 * x - formCX2 * y) / d
local oldY = (formCX1 * y - formCY1 * x) / d
return oldX, oldY
end
vectorMath.pointToLineSquareDistance = function(x, y, x1, y1, x2, y2)
-- get vector from start to test point and to end
local px, py = x - x1, y - y1
local vx, vy = x2 - x1, y2 - y1
-- also get vectors from the other end, to see if the test point is between
local px2, py2 = x - x2, y - y2
local vx2, vy2 = x1 - x2, y1 - y2
-- the dots between these vectors must have equal signs
local dot1 = vectorMath.dot2(px, py, vx, vy)
local dot2 = vectorMath.dot2(px2, py2, vx2, vy2)
if (dot1 < 0 and dot2 > 0) or (dot1 > 0 and dot2 < 0) then
-- return the distance to the closest end point
local dist1 = px * px + py * py
local dist2 = px2 * px2 + py2 * py2
if dist1 < dist2 then
return dist1
end
return dist2
end
-- project the test vector on the line vector, and calculate rejection
local scale = dot1 / (vx*vx + vy*vy)
local nx, ny = vx * scale - px, vy * scale - py
return nx * nx + ny * ny
end