Drag the Wall
From OxeyeWiki
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