Created
September 3, 2017 00:21
-
-
Save MegaLoler/7bb899fae99c2c225a2af75fc889c41e to your computer and use it in GitHub Desktop.
Ball physics with a tile map!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Marb Maze Yo</title> | |
<style> | |
#id | |
{ | |
padding: 0px; | |
margin: 0px; | |
border: 0px; | |
} | |
body | |
{ | |
padding: 0px; | |
margin: 0px; | |
border: 0px; | |
} | |
</style> | |
</head> | |
<script> | |
var freeMouseDebug = false; | |
var debugGraphics = true; | |
var simulation; | |
function arraySafeGet(array, index) | |
{ | |
if(array[index] == undefined) | |
{ | |
return 0; | |
} | |
else | |
{ | |
return array[index]; | |
} | |
} | |
function normalizeVector(vector) | |
{ | |
var length = getVectorLength(vector); | |
return vectorDivideConstant(vector, length); | |
} | |
function rotateVectorClockwise(vector) | |
{ | |
return [vector[1], -vector[0]]; | |
} | |
function rotateVectorCounterclockwise(vector) | |
{ | |
return [-vector[1], vector[0]]; | |
} | |
function dotProduct(a, b) | |
{ | |
var sum = 0; | |
for(var i = 0; i < a.length; i++) | |
{ | |
sum += a[i] * b[i]; | |
} | |
return sum; | |
} | |
function vectorAdd(a, b) | |
{ | |
var result = []; | |
var longest; | |
if(a.length > b.length) | |
{ | |
longest = a; | |
} | |
else | |
{ | |
longest = b; | |
} | |
for(var i in longest) | |
{ | |
var j = arraySafeGet(a, i) + arraySafeGet(b, i); | |
result.push(j); | |
} | |
return result; | |
} | |
function vectorSubtract(a, b) | |
{ | |
var result = []; | |
var longest; | |
if(a.length > b.length) | |
{ | |
longest = a; | |
} | |
else | |
{ | |
longest = b; | |
} | |
for(var i in longest) | |
{ | |
var j = arraySafeGet(a, i) - arraySafeGet(b, i); | |
result.push(j); | |
} | |
return result; | |
} | |
function vectorMultiply(a, b) | |
{ | |
var result = []; | |
var longest; | |
if(a.length > b.length) | |
{ | |
longest = a; | |
} | |
else | |
{ | |
longest = b; | |
} | |
for(var i in longest) | |
{ | |
var j = arraySafeGet(a, i) * arraySafeGet(b, i); | |
result.push(j); | |
} | |
return result; | |
} | |
function vectorDivide(a, b) | |
{ | |
var result = []; | |
var longest; | |
if(a.length > b.length) | |
{ | |
longest = a; | |
} | |
else | |
{ | |
longest = b; | |
} | |
for(var i in longest) | |
{ | |
var j = arraySafeGet(a, i) / arraySafeGet(b, i); | |
result.push(j); | |
} | |
return result; | |
} | |
function vectorMultiplyConstant(vector, coefficient) | |
{ | |
var result = []; | |
for(var value of vector) | |
{ | |
result.push(value * coefficient); | |
} | |
return result; | |
} | |
function vectorDivideConstant(vector, coefficient) | |
{ | |
var result = []; | |
for(var value of vector) | |
{ | |
result.push(value / coefficient); | |
} | |
return result; | |
} | |
function getDistance(a, b) | |
{ | |
var difference = vectorSubtract(a, b); | |
return getVectorLength(difference); | |
} | |
function getVectorLength(vector) | |
{ | |
var sum = 0; | |
for(var value of vector) | |
{ | |
sum += Math.pow(value, 2); | |
} | |
return Math.sqrt(sum); | |
} | |
function Tile_upLeftIncline() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
context.beginPath(); | |
context.moveTo((position[0]) * tileSize, (position[1] + 1) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1] + 1) * tileSize); | |
context.closePath(); | |
context.fill(); | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var left = 0; | |
var right = 1; | |
var top = 0; | |
var bottom = 1; | |
var topDirection = top - y; | |
var bottomDirection = bottom - y; | |
var leftDirection = left - x; | |
var rightDirection = right - x; | |
if(x > left && x < right && y > bottom) | |
{ | |
return [0, bottomDirection]; | |
} | |
else if(y > top && y < bottom && x > right) | |
{ | |
return [rightDirection, 0]; | |
} | |
else if(x >= right && y >= bottom) | |
{ | |
var cornerX = right; | |
var cornerY = bottom; | |
var dx = cornerX - x; | |
var dy = cornerY - y; | |
return [dx, dy]; | |
} | |
else | |
{ | |
var surfaceDirection = normalizeVector([1, -1]); | |
var normal = rotateVectorClockwise(surfaceDirection) | |
var surfaceTranslation = vectorMultiplyConstant(normal, Math.sqrt(2) / 2); | |
var dp = dotProduct(surfaceDirection, position); | |
var surfacePosition = vectorMultiplyConstant(surfaceDirection, dp); | |
surfacePosition[0] = Math.min(surfacePosition[0], 0.5); | |
surfacePosition[0] = Math.max(surfacePosition[0], -0.5); | |
surfacePosition[1] = Math.min(surfacePosition[1], 0.5); | |
surfacePosition[1] = Math.max(surfacePosition[1], -0.5); | |
var translatedPosition = vectorAdd(position, surfaceTranslation); | |
var surfaceVector = vectorSubtract(surfacePosition, translatedPosition); | |
return surfaceVector; | |
} | |
}; | |
this.detectCollision = function(position) | |
{ | |
return true; | |
}; | |
} | |
function Tile_upRightIncline() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
context.beginPath(); | |
context.moveTo((position[0]) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1] + 1) * tileSize); | |
context.lineTo((position[0]) * tileSize, (position[1] + 1) * tileSize); | |
context.closePath(); | |
context.fill(); | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var left = 0; | |
var right = 1; | |
var top = 0; | |
var bottom = 1; | |
var topDirection = top - y; | |
var bottomDirection = bottom - y; | |
var leftDirection = left - x; | |
var rightDirection = right - x; | |
if(x > left && x < right && y > bottom) | |
{ | |
return [0, bottomDirection]; | |
} | |
else if(y > top && y < bottom && x < left) | |
{ | |
return [leftDirection, 0]; | |
} | |
else if(x <= left && y >= bottom) | |
{ | |
var cornerX = left; | |
var cornerY = bottom; | |
var dx = cornerX - x; | |
var dy = cornerY - y; | |
return [dx, dy]; | |
} | |
else | |
{ | |
var surfaceDirection = normalizeVector([1, 1]); | |
var dp = dotProduct(surfaceDirection, position); | |
var surfacePosition = vectorMultiplyConstant(surfaceDirection, dp); | |
surfacePosition[0] = Math.min(surfacePosition[0], 1); | |
surfacePosition[0] = Math.max(surfacePosition[0], 0); | |
surfacePosition[1] = Math.min(surfacePosition[1], 1); | |
surfacePosition[1] = Math.max(surfacePosition[1], 0); | |
var surfaceVector = vectorSubtract(surfacePosition, position); | |
return surfaceVector; | |
} | |
}; | |
this.detectCollision = function(position) | |
{ | |
return true; | |
}; | |
} | |
function Tile_downLeftIncline() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
context.beginPath(); | |
context.moveTo((position[0]) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1] + 1) * tileSize); | |
context.closePath(); | |
context.fill(); | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var left = 0; | |
var right = 1; | |
var top = 0; | |
var bottom = 1; | |
var topDirection = top - y; | |
var bottomDirection = bottom - y; | |
var leftDirection = left - x; | |
var rightDirection = right - x; | |
if(x > left && x < right && y < top) | |
{ | |
return [0, topDirection]; | |
} | |
else if(y > top && y < bottom && x > right) | |
{ | |
return [rightDirection, 0]; | |
} | |
else if(x >= right && y <= top) | |
{ | |
var cornerX = right; | |
var cornerY = top; | |
var dx = cornerX - x; | |
var dy = cornerY - y; | |
return [dx, dy]; | |
} | |
else | |
{ | |
var surfaceDirection = normalizeVector([1, 1]); | |
var normal = rotateVectorClockwise(surfaceDirection) | |
var surfaceTranslation = vectorMultiplyConstant(normal, Math.sqrt(2) / 2); | |
var dp = dotProduct(surfaceDirection, position); | |
var surfacePosition = vectorMultiplyConstant(surfaceDirection, dp); | |
surfacePosition[0] = Math.min(surfacePosition[0], 1); | |
surfacePosition[0] = Math.max(surfacePosition[0], 0); | |
surfacePosition[1] = Math.min(surfacePosition[1], 1); | |
surfacePosition[1] = Math.max(surfacePosition[1], 0); | |
var translatedPosition = vectorAdd(position, surfaceTranslation); | |
var surfaceVector = vectorSubtract(surfacePosition, position); | |
return surfaceVector; | |
} | |
}; | |
this.detectCollision = function(position) | |
{ | |
return true; | |
}; | |
} | |
function Tile_downRightIncline() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
context.beginPath(); | |
context.moveTo((position[0]) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0] + 1) * tileSize, (position[1]) * tileSize); | |
context.lineTo((position[0]) * tileSize, (position[1] + 1) * tileSize); | |
context.closePath(); | |
context.fill(); | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var left = 0; | |
var right = 1; | |
var top = 0; | |
var bottom = 1; | |
var topDirection = top - y; | |
var bottomDirection = bottom - y; | |
var leftDirection = left - x; | |
var rightDirection = right - x; | |
if(x > left && x < right && y < top) | |
{ | |
return [0, topDirection]; | |
} | |
else if(y > top && y < bottom && x < left) | |
{ | |
return [leftDirection, 0]; | |
} | |
else if(x <= left && y <= top) | |
{ | |
var cornerX = left; | |
var cornerY = top; | |
var dx = cornerX - x; | |
var dy = cornerY - y; | |
return [dx, dy]; | |
} | |
else | |
{ | |
var surfaceDirection = normalizeVector([1, -1]); | |
var normal = rotateVectorClockwise(surfaceDirection) | |
var surfaceTranslation = vectorMultiplyConstant(normal, Math.sqrt(2) / 2); | |
var dp = dotProduct(surfaceDirection, position); | |
var surfacePosition = vectorMultiplyConstant(surfaceDirection, dp); | |
surfacePosition[0] = Math.min(surfacePosition[0], 0.5); | |
surfacePosition[0] = Math.max(surfacePosition[0], -0.5); | |
surfacePosition[1] = Math.min(surfacePosition[1], 0.5); | |
surfacePosition[1] = Math.max(surfacePosition[1], -0.5); | |
var translatedPosition = vectorAdd(position, surfaceTranslation); | |
var surfaceVector = vectorSubtract(surfacePosition, translatedPosition); | |
return surfaceVector; | |
} | |
}; | |
this.detectCollision = function(position) | |
{ | |
return true; | |
}; | |
} | |
function Tile_block() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
context.fillRect(position[0] * tileSize, position[1] * tileSize, tileSize, tileSize); | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var left = 0; | |
var right = 1; | |
var top = 0; | |
var bottom = 1; | |
var topDirection = top - y; | |
var bottomDirection = bottom - y; | |
var leftDirection = left - x; | |
var rightDirection = right - x; | |
var topDistance = Math.abs(topDirection); | |
var bottomDistance = Math.abs(bottomDirection); | |
var leftDistance = Math.abs(leftDirection); | |
var rightDistance = Math.abs(rightDirection); | |
if(x > left && x < right) | |
{ | |
var direction = topDistance < bottomDistance ? topDirection : bottomDirection; | |
return [0, direction]; | |
} | |
else if(y > top && y < bottom) | |
{ | |
var direction = leftDistance < rightDistance ? leftDirection : rightDirection; | |
return [direction, 0]; | |
} | |
else | |
{ | |
var cornerX, cornerY; | |
if(x <= left && y <= top) | |
{ | |
cornerX = left; | |
cornerY = top; | |
} | |
else if(x >= right && y <= top) | |
{ | |
cornerX = right; | |
cornerY = top; | |
} | |
else if(x <= left && y >= bottom) | |
{ | |
cornerX = left; | |
cornerY = bottom; | |
} | |
else if(x >= right && y >= bottom) | |
{ | |
cornerX = right; | |
cornerY = bottom; | |
} | |
var dx = cornerX - x; | |
var dy = cornerY - y; | |
return [dx, dy]; | |
} | |
}; | |
this.detectCollision = function(position) | |
{ | |
var x = position[0]; | |
var y = position[1]; | |
var xCollide = x >= 0 && x <= 1; | |
var yCollide = y >= 0 && y <= 1; | |
return xCollide && yCollide; | |
}; | |
} | |
function Tile_air() | |
{ | |
// global pixel space | |
this.draw = function(context, tileSize, position) | |
{ | |
}; | |
// within tile bounds, local tile space | |
// vector to surface | |
this.getSurfaceVector = function(position) | |
{ | |
return [0, 0]; | |
}; | |
this.detectCollision = function(position) | |
{ | |
return false; | |
}; | |
} | |
var tileSet = [new Tile_air(), new Tile_block(), new Tile_upLeftIncline(), new Tile_upRightIncline(), new Tile_downLeftIncline(), new Tile_downRightIncline()]; | |
function Marble(position) | |
{ | |
this.position = position; | |
this.previousPosition = position; | |
this.radius = 0.75; | |
this.draw = function(context, simulation) | |
{ | |
var x = (this.position[0] - simulation.cameraX) * simulation.tileSize; | |
var y = (this.position[1] - simulation.cameraY) * simulation.tileSize; | |
context.beginPath(); | |
context.arc(x, y, this.radius * simulation.tileSize, 0, Math.PI * 2); | |
context.fill(); | |
} | |
this.update = function(context, simulation) | |
{ | |
if(!freeMouseDebug) | |
{ | |
if(mouseDown) | |
{ | |
var mousePosition = [mouseX / simulation.tileSize + simulation.cameraX, mouseY / simulation.tileSize + simulation.cameraY]; | |
var delta = vectorSubtract(mousePosition, this.position); | |
var distance = getVectorLength(delta); | |
var direction = vectorDivideConstant(delta, distance); | |
var mouseForce = vectorMultiplyConstant(direction, simulation.acceleration); | |
this.position = vectorAdd(this.position, mouseForce); | |
} | |
this.position = vectorAdd(this.position, [0, simulation.gravity]); | |
} | |
this.collisions(context, simulation); | |
this.integrate(); | |
} | |
this.collisions = function(context, simulation) | |
{ | |
var left = this.position[0] - this.radius; | |
var right = this.position[0] + this.radius; | |
var top = this.position[1] - this.radius; | |
var bottom = this.position[1] + this.radius; | |
for(var tileX = Math.floor(left); tileX <= right; tileX++) | |
{ | |
for(var tileY = Math.floor(top); tileY <= bottom; tileY++) | |
{ | |
var tile = simulation.getTile(tileX, tileY); | |
var localX = this.position[0] - tileX; | |
var localY = this.position[1] - tileY; | |
var localPosition = [localX, localY]; | |
if(debugGraphics) | |
{ | |
context.strokeStyle = "red"; | |
var pixelX = (tileX - simulation.cameraX) * simulation.tileSize; | |
var pixelY = (tileY - simulation.cameraY) * simulation.tileSize; | |
context.strokeRect(pixelX, pixelY, simulation.tileSize, simulation.tileSize); | |
} | |
var surfaceVector = tile.getSurfaceVector(localPosition); | |
var length = getVectorLength(surfaceVector); | |
if(debugGraphics) | |
{ | |
context.strokeStyle = "blue"; | |
var pixelX = (this.position[0] - simulation.cameraX) * simulation.tileSize; | |
var pixelY = (this.position[1] - simulation.cameraY) * simulation.tileSize; | |
var pixelX2 = (this.position[0] + surfaceVector[0] - simulation.cameraX) * simulation.tileSize; | |
var pixelY2 = (this.position[1] + surfaceVector[1] - simulation.cameraY) * simulation.tileSize; | |
context.beginPath(); | |
context.moveTo(pixelX, pixelY); | |
context.lineTo(pixelX2, pixelY2); | |
context.stroke(); | |
} | |
if(length < this.radius) | |
{ | |
var penetrationAmount = this.radius - length; | |
var direction = vectorDivideConstant(surfaceVector, length); | |
var surfaceVector = vectorAdd(localPosition, vectorMultiplyConstant(direction, this.radius)); | |
if(debugGraphics) | |
{ | |
context.strokeStyle = "yellow"; | |
var pixelX = (tileX - simulation.cameraX) * simulation.tileSize; | |
var pixelY = (tileY - simulation.cameraY) * simulation.tileSize; | |
var pixelX2 = (tileX + surfaceVector[0] - simulation.cameraX) * simulation.tileSize; | |
var pixelY2 = (tileY + surfaceVector[1] - simulation.cameraY) * simulation.tileSize; | |
context.beginPath(); | |
context.moveTo(pixelX, pixelY); | |
context.lineTo(pixelX2, pixelY2); | |
context.stroke(); | |
} | |
if(tile.detectCollision(surfaceVector)) | |
{ | |
var penetrationVector = vectorMultiplyConstant(direction, -penetrationAmount); | |
if(debugGraphics) | |
{ | |
context.strokeStyle = "green"; | |
var pixelX = (this.position[0] - simulation.cameraX) * simulation.tileSize; | |
var pixelY = (this.position[1] - simulation.cameraY) * simulation.tileSize; | |
var pixelX2 = (this.position[0] + penetrationVector[0] - simulation.cameraX) * simulation.tileSize; | |
var pixelY2 = (this.position[1] + penetrationVector[1] - simulation.cameraY) * simulation.tileSize; | |
context.beginPath(); | |
context.moveTo(pixelX, pixelY); | |
context.lineTo(pixelX2, pixelY2); | |
context.stroke(); | |
} | |
penetrationVector = vectorDivideConstant(penetrationVector, simulation.impulseDivision); | |
if(!freeMouseDebug) this.position = vectorAdd(this.position, penetrationVector); | |
} | |
} | |
} | |
} | |
} | |
this.getVelocity = function() | |
{ | |
return vectorSubtract(this.position, this.previousPosition) | |
} | |
this.integrate = function() | |
{ | |
if(freeMouseDebug) | |
{ | |
this.position = [mouseX / simulation.tileSize + simulation.cameraX, mouseY / simulation.tileSize + simulation.cameraY]; | |
} | |
else | |
{ | |
var currentPosition = this.position; | |
this.position = vectorAdd(this.position, this.getVelocity()); | |
this.previousPosition = currentPosition; | |
} | |
} | |
} | |
function Simulation() | |
{ | |
this.map = []; | |
this.mapWrap = true; | |
this.mapWidth = 16; | |
this.mapHeight = 16; | |
this.ether = tileSet[1]; | |
this.cameraX = 0; | |
this.cameraY = 0; | |
// coordinate system is origin = top left, unit = tile size | |
this.tileSize = 32; | |
this.marbles = []; | |
this.gravity = 0.0001; | |
this.sweeps = 5; | |
this.impulseDivision = 5; | |
this.acceleration = 0.0005; | |
this.getTile = function(x, y) | |
{ | |
if(this.mapWrap) | |
{ | |
while(x < 0) x += this.mapWidth; | |
while(y < 0) y += this.mapHeight; | |
x %= this.mapWidth; | |
y %= this.mapHeight; | |
} | |
else | |
{ | |
if(x < 0 || x >= this.mapWidth) return this.ether; | |
if(y < 0 || y >= this.mapHeight) return this.ether; | |
} | |
var tile = this.map[x + y * this.mapWidth]; | |
if(tile == undefined) return this.ether; | |
return tile; | |
} | |
this.drawMap = function(context) | |
{ | |
var width = context.canvas.width / this.tileSize; | |
var height = context.canvas.height / this.tileSize; | |
for(var x = this.cameraX; x < this.cameraX + 1 + width; x += 1) | |
{ | |
for(var y = this.cameraY; y < this.cameraY + 1 + height; y += 1) | |
{ | |
var indexX = Math.floor(x); | |
var indexY = Math.floor(y); | |
var tile = this.getTile(indexX, indexY); | |
var position = [indexX - this.cameraX, indexY - this.cameraY]; | |
tile.draw(context, this.tileSize, position); | |
} | |
} | |
} | |
this.draw = function(context) | |
{ | |
context.fillStyle = "gray"; | |
this.drawMap(context); | |
for(var marble of this.marbles) | |
{ | |
marble.draw(context, this); | |
} | |
} | |
this.update = function(context) | |
{ | |
for(var i = 0; i < this.sweeps; i++) | |
{ | |
for(var marble of this.marbles) | |
{ | |
marble.update(context, this); | |
} | |
} | |
} | |
} | |
function draw() | |
{ | |
context.clearRect(0, 0, canvas.width, canvas.height); | |
simulation.draw(context); | |
} | |
function physics() | |
{ | |
simulation.update(context); | |
} | |
function loop() | |
{ | |
draw(); | |
physics(); | |
enterLoop(); | |
} | |
function enterLoop() | |
{ | |
window.requestAnimationFrame(loop); | |
} | |
function mapFromIndices(indices) | |
{ | |
var map = []; | |
for(var index of indices) | |
{ | |
map.push(tileSet[index]); | |
} | |
return map; | |
} | |
function setup() | |
{ | |
canvas = document.getElementById("canvas"); | |
context = canvas.getContext("2d"); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
simulation = new Simulation(); | |
simulation.map = mapFromIndices( | |
[0,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,0, | |
0,0,0,2,1,3,0,0,0,0,0,0,0,0,0,0, | |
0,0,2,1,1,1,3,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,4,1,3,0,0,2,1,3,0,0,0, | |
0,0,0,0,0,0,1,1,1,1,1,1,1,3,0,0, | |
0,0,0,0,0,0,4,1,1,5,0,0,0,4,3,0, | |
0,0,0,0,0,0,0,4,5,0,0,0,0,0,1,3, | |
3,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1, | |
1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1, | |
1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4, | |
4,1,0,0,0,0,0,0,0,0,2,1,3,0,0,0, | |
0,5,0,0,0,0,0,0,2,1,1,1,5,0,0,0, | |
0,0,0,2,1,1,1,1,1,1,1,5,0,0,0,0, | |
0,0,2,1,5,0,0,4,1,1,5,0,0,0,0,0,] | |
); | |
simulation.marbles.push(new Marble([6,0])); | |
} | |
function init() | |
{ | |
setup(); | |
enterLoop(); | |
} | |
function mouseDrag() | |
{ | |
var dx = mouseX - mouseClickX; | |
var dy = mouseY - mouseClickY; | |
simulation.cameraX = clickCameraX - dx / simulation.tileSize; | |
simulation.cameraY = clickCameraY - dy / simulation.tileSize; | |
} | |
window.onmousedown = function(event) | |
{ | |
mouseClickX = mouseX; | |
mouseClickY = mouseY; | |
clickCameraX = simulation.cameraX; | |
clickCameraY = simulation.cameraY; | |
mouseDown = true; | |
} | |
window.onmouseup = function(event) | |
{ | |
mouseDown = false; | |
} | |
window.onload = init; | |
var mouseX, mouseY; | |
var mouseClickX, mouseClickY; | |
var clickCameraX, clickCameraY; | |
var mouseDown = false; | |
// STOLEN MOUSE TRACKING CODE BC LAZY >< | |
document.onmousemove = function(event) | |
{ | |
var dot, eventDoc, doc, body, pageX, pageY; | |
event = event || window.event; // IE-ism | |
// If pageX/Y aren't available and clientX/Y are, | |
// calculate pageX/Y - logic taken from jQuery. | |
// (This is to support old IE) | |
if (event.pageX == null && event.clientX != null) { | |
eventDoc = (event.target && event.target.ownerDocument) || document; | |
doc = eventDoc.documentElement; | |
body = eventDoc.body; | |
event.pageX = event.clientX + | |
(doc && doc.scrollLeft || body && body.scrollLeft || 0) - | |
(doc && doc.clientLeft || body && body.clientLeft || 0); | |
event.pageY = event.clientY + | |
(doc && doc.scrollTop || body && body.scrollTop || 0) - | |
(doc && doc.clientTop || body && body.clientTop || 0 ); | |
} | |
// Use event.pageX / event.pageY here | |
mouseX = event.pageX; | |
mouseY = event.pageY; | |
if(mouseDown) mouseDrag(); | |
} | |
// OK THATS ALL TE STOLEN CODE | |
</script> | |
<body> | |
<canvas id="canvas"></canvas> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment