Large diffs are not rendered by default.

@@ -1,17 +1,15 @@
$(document).ready(function ()
{

var canvasHA = document.querySelector("#hedgehog-apocalypse canvas");
var ctxHA = canvasHA.getContext("2d");

var assetsToLoadHA = [];
var assetsLoadedHA = 0;

var spritesHA = [];

var imageHA = new Image();
imageHA.addEventListener("load", loadHandler);
imageHA.src = "hedgehogApocalypse.png";
imageHA.src = "HedgehogApocalypse/Resources/hedgehogApocalypse.png";
assetsToLoadHA.push(imageHA);

//Game States
@@ -31,14 +29,88 @@ $(document).ready(function ()
var moveLeft = false;
var jumping = false;

var HedgehogObject = function ()
{
this.sprite = new SpriteObject();
this.NORMAL = [1, 0];
this.SQUASHED = [2, 0];
this.state = this.NORMAL;

this.update = function ()
{
this.sprite.srcX = this.state[0] * this.sprite.srcW;
this.sprite.srcY = this.state[1] * this.sprite.srcW;
};

this.speed = 1;
};
{
var map =
[
[7, 7, 8, 9, 7, 7, 7, 8, 9, 7, 7, 7, 8, 9, 7, 7],
[8, 9, 7, 7, 4, 9, 7, 7, 7, 8, 9, 7, 7, 7, 8, 5],
[4, 7, 7, 7, 7, 7, 8, 9, 7, 7, 7, 8, 9, 7, 4, 4],
[7, 7, 4, 7, 7, 4, 4, 4, 4, 7, 7, 7, 7, 7, 7, 7],
[8, 9, 4, 7, 7, 7, 7, 8, 9, 7, 7, 4, 8, 9, 7, 7],
[7, 4, 4, 4, 7, 8, 9, 7, 7, 7, 4, 4, 7, 7, 4, 8],
[9, 7, 8, 9, 7, 7, 7, 8, 9, 4, 7, 4, 9, 7, 7, 7],
[7, 7, 7, 7, 7, 4, 4, 7, 7, 7, 7, 4, 4, 4, 4, 7],
[8, 9, 7, 7, 7, 7, 7, 7, 7, 8, 9, 7, 7, 8, 9, 7],
[7, 7, 4, 4, 4, 4, 7, 7, 4, 7, 7, 7, 7, 7, 7, 7],
[7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, 7, 7],
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
];

var gameObjects =
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
];
}

var EMPTY = 0;
var CAT = 1;
var HEDGEHOG = 2;
var BOX = 4;
var DOOR = 5;

var SIZE = 64;

var cat = null;
var door = null;
var gameOverDisplay = null;
var gameOverMessage = null;

var spritesHA = [];
var hedgehogs = [];
var boxes = [];
var messages = [];

var hedgehogsSquashed = 0;

var ROWS = map.length;
var COLS = map[0].length;

var tileSheetColumns = 3;

function loadHandler()
{
assetsLoadedHA += 1;

if ( assetsLoadedHA == assetsToLoadHA.length )
if (assetsLoadedHA == assetsToLoadHA.length)
{
imageHA.removeEventListener("load", loadHandler);
gameState = PLAYING;
gameState = BUILD_MAP;

window.addEventListener("keydown", function (e)
{
@@ -83,7 +155,9 @@ $(document).ready(function ()
console.log("Loading...");
break;
case BUILD_MAP:
// TODO BUILD_MAP state
buildMap(map);
buildMap(gameObjects);
gameState = PLAYING;
break;
case PLAYING:
playGame();
@@ -95,22 +169,249 @@ $(document).ready(function ()
render();
}



function render()
{
ctxHA.clearRect(0,0,canvasHA.width,canvasHA.height);
for (var i = 0;i<spritesHA.length; i++)
ctxHA.clearRect(0, 0, canvasHA.width, canvasHA.height);

for (var i = 0; i < spritesHA.length; i ++)
{
var sprite = spritesHA[i];

if (sprite.visible)
{
ctxHA.drawImage(imageHA,
sprite.srcX,sprite.srcY,
sprite.srcW,sprite.srcH,
Math.floor(sprite.x),Math.floor(sprite.y),
sprite.w,sprite.h);
sprite.srcX, sprite.srcY,
sprite.srcW, sprite.srcH,
Math.floor(sprite.x), Math.floor(sprite.y),
sprite.w, sprite.h);
}
}
}

function buildMap(levelMap)
{
for (var row = 0; row < ROWS; row ++)
{
for (var col = 0; col < COLS; col ++)
{
var currentTile = levelMap[row][col];

if (currentTile != EMPTY)
{
var tileSheetX = Math.floor((currentTile - 1) % tileSheetColumns) * SIZE;
var tileSheetY = Math.floor((currentTile - 1) / tileSheetColumns) * SIZE;

switch (currentTile)
{
case CAT:
cat = new SpriteObject();
cat.srcX = tileSheetX;
cat.srcY = tileSheetY;
cat.srcH = 64;
cat.srcW = 64;
cat.x = col * SIZE;
cat.y = row * SIZE;
cat.w = 64;
cat.h = 64;
spritesHA.push(cat);
break;
case HEDGEHOG:
var hedgehog = new HedgehogObject();
hedgehog.sprite.srcX = tileSheetX;
hedgehog.sprite.srcY = tileSheetY;
hedgehog.sprite.srcW = 64;
hedgehog.sprite.srcH = 64;
hedgehog.sprite.x = col * SIZE;
hedgehog.sprite.y = row * SIZE;
hedgehog.sprite.w = 64;
hedgehog.sprite.h = 64;
spritesHA.push(hedgehog.sprite);
hedgehogs.push(hedgehog);
break;
case BOX:
var box = new SpriteObject();
box.srcX = tileSheetX;
box.srcY = tileSheetY;
box.srcW = 64;
box.srcH = 64;
box.x = col * SIZE;
box.y = row * SIZE;
box.w = 64;
box.h = 64;
spritesHA.push(box);
boxes.push(box);
break;
case DOOR:
door = new SpriteObject();
door.srcX = tileSheetX;
door.srcY = tileSheetY;
door.srcW = 64;
door.srcH = 64;
door.x = col * SIZE;
door.y = row * SIZE;
door.w = 64;
door.h = 64;
spritesHA.push(door);
break;
default:
var sprite = new SpriteObject();
sprite.srcX = tileSheetX;
sprite.srcY = tileSheetY;
sprite.srcW = 64;
sprite.srcH = 64;
sprite.x = col * SIZE;
sprite.y = row * SIZE;
sprite.w = 64;
sprite.h = 64;
spritesHA.push(sprite);
break;


}
}
}
}
}

function createOtherObjects()
{
gameOverDisplay = new SpriteObject();
gameOverDisplay.srcX = 0;
gameOverDisplay.srcY = 192;
gameOverDisplay.srcW = 192;
gameOverDisplay.srcH = 128;
gameOverDisplay.w = 192;
gameOverDisplay.h = 128;
gameOverDisplay.x = canvasHA.width / 2 - gameOverDisplay.w / 2;
gameOverDisplay.y = canvasHA.height / 2 - gameOverDisplay.h / 2;
gameOverDisplay.visible = false;
spritesHA.push(gameOverDisplay);

gameOverMessage = new MessageObject();
gameOverMessage.x = gameOverDisplay.x + 20;
gameOverMessage.y = gameOverDisplay.y + 34;
gameOverMessage.font = "bold 30px Helvetica";
gameOverMessage.fillStyle = "black";
gameOverMessage.text = "";
gameOverMessage.visible = false;
messages.push(gameOverMessage);
}

function playGame()
{
if (jumping && cat.isOnGround)
{
cat.vy += cat.jumpForce;
cat.ax = - 0.2;
cat.isOnGround = false;
cat.friction = 1;

}
if (moveLeft && ! moveRight)
{
cat.ax = - 0.2;
cat.friction = 1;
}
else if (! moveLeft && moveRight)
{
cat.ax = 0.2;
cat.friction = 1;
}

if (! moveLeft && ! moveRight)
{
cat.ax = 0;
cat.friction = 0.96;
}

for (var i = 0; i < boxes.length; i ++)
{
var collisionSide = blockRectangle(cat, boxes[i]);

if (collisionSide === "bottom" && cat.vy >= 0)
{
cat.isOnGround = true;
cat.vy = - cat.gravity;
}
else if (collisionSide === "top" & cat.vy <= 0)
cat.vy = 0;
else if (collisionSide === "right" & cat.vx <= 0)
cat.vx = 0;
else if (collisionSide === "left" & cat.vx <= 0)
cat.vx = 0;

if (collisionSide !== "bottom" & cat.vy > 0)
cat.isOnGround = false;
}

if (cat.x < 0)
{
cat.vx = 0;
cat.x = 0;
}
else if (cat.x + cat.w > canvasHA.width)
{
cat.vx = 0;
cat.x = canvasHA.width - cat.w;
}

if (cat.y + cat.h > canvasHA.height)
{
cat.y = canvasHA.height - cat.h;
cat.isOnGround = true;
cat.vy = - cat.gravity;
}
console.log(cat.vy);


for (var i = 0; i < hedgehogs.length; i ++)
{
var hedgehog = hedgehogs[i];

if (hedgehog.state === hedgehog.NORMAL)
{
hedgehog.x += hedgehog.vx;
hedgehog.y += hedgehog.vy;
}

if (Math.floor(hedgehog.x) % SIZE === 0 && Math.floor(hedgehog.y) % SIZE === 0)
{
var hedgehogColumn = Math.floor(hedgehog.x / SIZE);
var hedgehogRow = Math.floor(hedgehog.y / SIZE);

if (hedgehogRow < ROWS - 1)
{
var thingBelowLeft = map[hedgehogRow + 1][hedgehogColumn - 1];
var thingBelowRight = map[hedgehogRow + 1][hedgehogColumn + 1];

if (thingBelowLeft !== BOX || thingBelowRight !== BOX)
hedgehog.vx *= - 1;
}

if (hedgehogColumn > 0)
{
var thingToTheLeft = map[hedgehogRow][hedgehogColumn - 1];
if (thingToTheLeft === BOX)
hedgehog.vx *= - 1;
}

if (hedgehogColumn < COLS - 1)
{
var thingToTheRight = map[hedgehogRow][hedgehogColumn + 1];
if (thingToTheRight === BOX)
hedgehog.vx *= - 1;
}
}
}

cat.vx += cat.ax;
cat.vy += cat.gravity;
if (cat.isOnGround)
cat.vx *= cat.friction;
cat.x += cat.vx;
cat.y += cat.vy;
}

update();
});
@@ -1,26 +1,37 @@
/**
* gets a random int between bottom number and top provided
* @param {int} bot lowest number you can get
* @param {int} top highest number you can get
* @returns {int} random result
*/
function getRandom(bot,top)
{
return Math.floor(Math.random()*(top + 1 - bot)) + bot;
}

/**
* removes the given object from the given array
*
* @param {type} objectToRemove the object that is to be removed
* @param {type} array the array the object will be removed from
*/
function removeObject(objectToRemove,array)
{
var index = array.indexOf(objectToRemove);

if(index != -1)
{
array.splice(index,1);
}
/**
* gets a random int between bottom number and top provided
* @param {int} bot lowest number you can get
* @param {int} top highest number you can get
* @returns {int} random result
*/
function getRandom(bot,top)
{
return Math.floor(Math.random()*(top + 1 - bot)) + bot;
}

/**
* removes the given object from the given array
*
* @param {type} objectToRemove the object that is to be removed
* @param {type} array the array the object will be removed from
*/
function removeObject(objectToRemove,array)
{
var index = array.indexOf(objectToRemove);

if(index != -1)
{
array.splice(index,1);
}
}

/**
* returns string of percentage of the 2 numbers given 0-100
* @param {int} a first number
* @param {int} b total number
* @returns {String} percentage of 2 numbers given
*/
function getPercentage(a,b)
{
return Math.floor((a / b)*100).toString();
}
@@ -9,7 +9,7 @@ function hitTestPoint(px, py, r)
{
var hit = false;

if ( px > r.left() && px < r.right() && py > r.top() && py < r.bottom() )
if (px > r.left() && px < r.right() && py > r.top() && py < r.bottom())
hit = true;

return hit;
@@ -28,12 +28,153 @@ function hitTestRectangle(r1, r2)
var dy = r1.center().y - r2.center().y;

var sumHalfWidths = r1.halfWidth() + r2.halfWidth();
if ( Math.abs(dx) < sumHalfWidths )
if (Math.abs(dx) < sumHalfWidths)
{
var sumHalfHeights = r1.halfHeight() + r2.halfHeight();

if ( Math.abs(dy) < sumHalfHeights )
if (Math.abs(dy) < sumHalfHeights)
hit = true;
}
return hit;
}
}

function hitTestCircle(c1, c2)
{
var vx = c1.center().x - c2.center().x;
var vy = c1.center().y - c2.center().y;

var magnitude = Mathsqrt(vx * vx + vy * vy);
var totalRadii = c1.halfWidth() + c2.halfWidth();
var hit = magnitude < totalRadii;

return hit;
}

function blockCircle(c1, c2, bounce)
{
if (typeof bounce === "undefined")
bounce = false;

var vx = c1.center().x - c2.center().x;
var vy = c1.center().y - c2.center().y;

var magnitude = Mathsqrt(vx * vx + vy * vy);
var totalRadii = c1.halfWidth() + c2.halfWidth();

if (magnitude < totalRadii)
{
var overlap = totalRadii - magnitude;
dx = vx / magnitude;
dy = vy / magnitude;

c1.x += overlap * dx;
c1.y += overlap * dy;

if (bounce)
{
var s = {};

s.vx = vy;
s.vy = - vx;

bounceOffSurface(c1, s);
}
}
}

function bounceOffSurface(o, s)
{
s.lx = s.vy;
s.ly = s.vx;

s.magnitude = Math.sqrt(s.vx * s.vx + s.vy * s.vy);

s.dx = s.vx / s.magnitude;
s.dy = s.vy / s.magnitude;

var dp1 = o.vx * s.dx + o.vy * s.dy;

var p1Vx = dp1 * s.dx;
var p1Vy = dp1 * s.dy;

var dp2 = o.vx * (s.lx / s.magnitude) + o.vy * (s.ly / s.magnitude);

var p2Vx = dp2 * (s.lx / s.magnitude);
var p2Vy = dp2 * (s.ly / s.magnitude);

p2Vx *= - 1;
p2Vy *= - 1;

var bounceVx = p1Vx + p2Vx;
var bounceVy = p1Vy + p2Vy;

o.vx = bounceVx;
o.vy = bounceVy;
}

function blockRectangle(r1, r2, bounce)
{
if (typeof bounce === "undefined")
bounce = false;

var collisionSide = "";

var dx = r1.center().x - r2.center().x;
var dy = r1.center().y - r2.center().y;

var sumHalfWidths = r1.halfWidth() + r2.halfWidth();
if (Math.abs(dx) < sumHalfWidths)
{
var sumHalfHeights = r1.halfHeight() + r2.halfHeight();

if (Math.abs(dy) < sumHalfHeights)
{
var overlapX = sumHalfWidths - Math.abs(dx);
var overlapY = sumHalfHeights - Math.abs(dy);

if (overlapX >= overlapY)
{
if (dy > 0)
{
collisionSide = "top";
r1.y = r1.y + overlapY;
}
else
{
collisionSide = "bottom";
r1.y = r1.y - overlapY;
}

if (bounce)
r1.vy *= - 1;
}
else
{
if (dx > 0)
{
collisionSide = "left";

r1.x = r1.x + overlapX;
}
else
{
collisionSide = "right";

r1.x = r1.x - overlapX;
}

if (bounce)
r1.vx *= - 1;
}
}
else
{
collisionSide = "none";
}
}
else
{
collisionSide = "none";
}
return collisionSide;
}
@@ -12,9 +12,18 @@ var SpriteObject = function ()
this.srcW = 32;
this.srcH = 32;

this.ay = 0;
this.ax = 0;
this.vx = 0;
this.vy = 0;


this.friction = 0.96;
this.bounce = -0.7;
this.gravity = 0.3;

this.jumpForce = -10;
this.isOnGround = undefined;

this.visible = true;

this.left = function ()
@@ -36,27 +45,27 @@ var SpriteObject = function ()
{
return this.y + this.h;
};

this.center = function ()
{
return {
x: this.x + (this.w / 2),
y: this.y + (this.h / 2)
};
};

this.halfWidth = function ()
{
return this.w / 2;
};

this.halfHeight = function ()
{
return this.h / 2;
};
};

var MessageObject = function ()
var MessageObject = function ()
{
this.x = 0;
this.y = 0;
@@ -65,4 +74,4 @@ var MessageObject = function ()
this.fontStyle = "black";
this.textBaseline = "top";
this.text = "message";
};
};