<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://www.oxeyegames.com/wiki/skins/common/feed.css?270"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.oxeyegames.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Drag_the_Wall</id>
		<title>Drag the Wall - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.oxeyegames.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Drag_the_Wall"/>
		<link rel="alternate" type="text/html" href="http://www.oxeyegames.com/wiki/index.php?title=Drag_the_Wall&amp;action=history"/>
		<updated>2026-05-06T12:57:38Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.16.0</generator>

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

	</feed>