Commit c54ae757 authored by Matthew Odle's avatar Matthew Odle

Merge branch 'develop' into 'master'

Develop

See merge request !20
parents 5b8a45f8 814079c2
/*jslint white: true */
var collisions = {
check : function() {
this.checkLaser(this.getLaserTargets());
this.checkPlayerVsEnemies(this.getPlayerEnemies());
this.removeDestroyedTargets();
// TODO abstract non-centipede functionality and move to canvas-libs
init : function() {
Object.assign(this, collisionsBase);
supporting.applyOverrides(this);
console.log('collisions initialized');
},
getLaserTargets : function() {
targets = [];
targets.push(...mushrooms.mushrooms);
targets.push(...centipedes.centipedes);
targets.push(...intervalCreatures.worms);
targets.push(...intervalCreatures.flies);
targets.push(...spiders.spiders);
return targets;
},
checkLaser : function(targets) {
lasers.lasers.map(laser =>
targets.map(target => {
if (!laser.remove && laser.crashWith(target)) {
this.processImpact(target);
laser.remove = true;
};
})
);
this.removeUsedLasers();
},
processImpact : function(target) {
this.damageTarget(target);
sounds.playImpactSound(target.type);
this.updateTargetAppearance(target);
},
damageTarget : function(target) {
target.hitPoints--;
if (target.hitPoints <= 0) {
this.processKill(target);
};
},
updateTargetAppearance(target) {
if (target.type == 'mushroom') {
target.height -= knobsAndLevers.mushrooms.side * 0.25;
};
},
processKill : function(target) {
metrics.addNewFloatingPoint(target.getMiddleX(), target.getMiddleY(), target.pointValue, "gain");
metrics.changeScore(target.pointValue);
this.handleCentipedeKill(target);
},
handleCentipedeKill(target) {
if (target.type === 'centipede') {
mushrooms.make({x : target.x, y : target.y}, 'green')
centipedes.numberKilled += 1;
};
},
removeUsedLasers : function() {
lasers.lasers = lasers.lasers.filter(laser => !laser.remove);
},
getPlayerEnemies : function() {
targets = [];
targets.push(...centipedes.centipedes);
targets.push(...spiders.spiders);
targets.push(...intervalCreatures.flies);
return targets;
},
checkPlayerVsEnemies : function(targets) {
if (!knobsAndLevers.game.playerCollisionsEnabled) {
return;
};
targets.forEach(target => {
if (player.gamePiece.crashWith(target)) {
this.killPlayer();
functionOverrides : {
handleSpecialKills(target) {
if (target.type === 'centipede') {
mushrooms.make({x : target.x, y : target.y})
centipedes.numberKilled += 1;
};
},
getPlayerEnemies : function() {
let enemies = [];
enemies.push(...centipedes.centipedes);
enemies.push(...gameObjects.fleas);
enemies.push(...gameObjects.spiders);
return enemies;
},
getLaserTargets : function() {
let targets = [];
targets.push(...mushrooms.mushrooms);
targets.push(...centipedes.centipedes);
targets.push(...gameObjects.worms);
targets.push(...gameObjects.fleas);
targets.push(...gameObjects.spiders);
return targets;
},
check : function() {
let targets = this.getLaserTargets();
Object.keys(lasers.lasers).forEach(key => {
this.checkLaser(key, targets, lasers.lasers);
});
Object.keys(players.players).forEach(player =>
this.checkPlayerVsEnemies(players.players[player], this.getPlayerEnemies())
);
this.removeDestroyedTargets(targets);
},
checkPlayerVsEnemies : function(player, targets) {
if (!knobsAndLevers.game.playerCollisionsEnabled) {
return;
};
});
},
killPlayer : function() {
player.died = true;
metrics.lives -= 1;
if (metrics.lives <= 0) {
game.gameOver = true;
return;
};
targets.forEach(target => {
if (player.crashWith(target)) {
this.killPlayer();
return;
};
});
},
removeDestroyedTargets : function(targets) {
mushrooms.mushrooms = mushrooms.mushrooms.filter(mushroom => mushroom.hitPoints > 0);
centipedes.centipedes = centipedes.centipedes.filter(centipede => centipede.hitPoints > 0);
gameObjects.worms = gameObjects.worms.filter(worm => worm.hitPoints > 0);
gameObjects.fleas = gameObjects.fleas.filter(flea => flea.hitPoints > 0);
gameObjects.spiders = gameObjects.spiders.filter(spider => spider.hitPoints > 0);
},
},
withMushrooms : function(obj) {
for (i = 0; i < mushrooms.mushrooms.length; i += 1) {
if (obj.crashWith(mushrooms.mushrooms[i])) {
return true;
};
};
return false;
},
removeDestroyedTargets : function(targets) {
mushrooms.mushrooms = mushrooms.mushrooms.filter(mushroom => mushroom.hitPoints > 0);
centipedes.centipedes = centipedes.centipedes.filter(centipede => centipede.hitPoints > 0);
intervalCreatures.worms = intervalCreatures.worms.filter(worm => worm.hitPoints > 0);
intervalCreatures.flies = intervalCreatures.flies.filter(fly => fly.hitPoints > 0);
spiders.spiders = spiders.spiders.filter(spider => spider.hitPoints > 0);
return mushrooms.mushrooms.find(mushroom => obj.crashWith(mushroom));
},
}
};
/*jslint white: true */
function Component(args) {
this.remove = false;
this.speedX = 0;
this.speedY = 0;
this.x = args.x;
this.y = args.y;
this.width = args.width;
this.height = args.height;
if (args.background) {
this.background = args.background;
};
this.color = args.color;
if (args.fontSize) {
this.fontSize = args.fontSize;
};
if (args.extraArgs) {
this.type = args.extraArgs.type;
if (args.extraArgs.speed) {
this.speedX = args.extraArgs.speed.x;
this.speedY = args.extraArgs.speed.y;
};
};
this.update = function() {
if (this.background) {
this.background.update();
};
let ctx = game.gameArea.context;
ctx.fillStyle = this.color;
if (this.type == "text") {
this.makeText(ctx);
} else if (this.type == "centipede") {
customComponents.makeACentipede(ctx, this.moveVertically, this);
// to draw the ship instead of a square
// } else if (this.type == "player") {
// let playerImage = new Image();
// playerImage.src = knobsAndLevers.mediaPath + "ship.png";
// ctx.drawImage(playerImage, this.x, this.y);
} else {
this.makeARectangle(ctx);
};
};
this.stop = function() {
this.speedX = 0;
this.speedY = 0;
},
this.makeText = function(ctx) {
ctx.font = this.fontSize + " " + knobsAndLevers.text.font;
ctx.fillText(this.text, this.x, this.y);
};
this.makeARectangle = function(ctx) {
ctx.fillRect(this.x, this.y, this.width, this.height);
};
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
};
this.crashWith = function(otherObject) {
let crash = true;
if (this.getBottom() < otherObject.getTop() || this.getTop() > otherObject.getBottom() || this.getRight() < otherObject.getLeft() || this.getLeft() > otherObject.getRight()) {
crash = false;
};
return crash;
};
this.crashWithSidesOnly = function(otherObject) {
let crash = true;
// delay collision slightly by allowing objects to overlap by 1 pixel
if (this.getRight() < otherObject.getLeft() + 1 || this.getLeft() > otherObject.getRight() - 1) {
crash = false;
};
return crash;
};
this.getMiddleX = function() {
return this.x + this.width / 2;
};
this.getMiddleY = function() {
return this.y + this.height / 2;
};
this.getTop = function() {
return this.y;
};
this.getBottom = function() {
return this.y + this.height;
};
this.getLeft = function() {
return this.x;
};
this.getRight = function() {
return this.x + this.width;
};
};
var customComponents = {
makeACentipede : function(ctx, isVertical, baseObject) {
ctx.beginPath();
let vertices = this.getCentipedeVertices(isVertical, baseObject);
ctx.moveTo(vertices.x1, vertices.y1);
ctx.lineTo(vertices.x2, vertices.y2);
ctx.lineTo(vertices.x3, vertices.y3);
ctx.fill();
},
getCentipedeVertices : function(isVertical, baseObject) {
let direction = '';
if (isVertical) {
direction = baseObject.directionY > 0 ? 'down' : 'up';
} else {
direction = baseObject.directionX > 0 ? 'right' : 'left';
};
return new TriangleVertices(direction, baseObject);
},
};
function TriangleVertices(direction, dimensions) {
with (dimensions) {
this.x1 = x;
this.y1 = y;
this.x2 = x;
this.y2 = y;
this.x3 = x;
this.y3 = y;
if (direction == 'up') {
this.y1 = y + height;
this.x2 = x + width / 2;
this.x3 = x + width;
this.y3 = y + height;
};
if (direction == 'down') {
this.x2 = x + width / 2;
this.y2 = y + height;
this.x3 = x + width;
};
if (direction == 'right') {
this.x2 = x + width;
this.y2 = y + height / 2;
this.y3 = y + height;
};
if (direction == 'left') {
this.x1 = x + width;
this.y2 = y + height / 2;
this.x3 = x + width;
this.y3 = y + height;
};
};
};
......@@ -2,65 +2,88 @@
var centipedes = {
// TODO rename this to segments?
centipedes : [],
positions : [],
numberSpawned : 0,
numberKilled : 0,
manage : function() {
if (this.eligibleToSpawn()) {
spawnPoints : 1,
init : function() {
Object.assign(this, gameObjectsBase);
supporting.applyOverrides(this);
console.log('centipedes initialized');
},
functionOverrides : {
manage : function() {
this.spawn();
}
this.update();
},
eligibleToSpawn : function() {
let eligible =
game.gameArea.frameNo == 1
|| this.numberSpawned < knobsAndLevers.centipede.maxNumber + metrics.currentLevel;
return eligible;
},
spawn : function() {
let centipede = this.make();
for (i = 0; i < this.centipedes.length; i += 1) {
if (this.centipedes[i].crashWith(centipede)) {
this.update();
},
spawn : function() {
this.determineSpawnPositions();
if (!this.eligibleToSpawn()) {
return;
};
this.setXPosition();
let centipede = this.make();
if (this.cannotAdd(centipede)) {
return;
};
this.add(centipede);
},
make : function() {
let centipede = Object.assign(new Component(knobsAndLevers.centipede.args), knobsAndLevers.centipede.defaults);
let pointValue = knobsAndLevers.centipede.pointValue;
centipede.pointValue = supporting.getRandom(pointValue, pointValue + 20);
centipede.sound = sounds.getSound('centipede');
return centipede;
},
add : function(centipede) {
this.centipedes.push(centipede);
this.numberSpawned++;
},
update : function() {
this.resetCentipedeUpdateFlag();
this.determineDirections();
this.updateDirections();
this.updateCoordinates();
for (i = 0; i < this.centipedes.length; i += 1) {
this.centipedes[i].update();
};
},
clear : function() {
this.centipedes = [];
this.numberSpawned = 0;
this.numberKilled = 0;
},
},
determineSpawnPositions : function() {
if (!game.levelIsOver()) {
return;
};
this.add(centipede);
},
make : function() {
centipede = new Component(knobsAndLevers.centipede.args);
centipede.directionX = 1;
centipede.directionY = 1;
centipede.distanceMovedX = 0;
centipede.distanceMovedY = 0;
centipede.distanceMovedFromBottom = 0;
centipede.reverseDirectionX = false;
centipede.reverseDirectionY = false;
centipede.moveVertically = true;
let pointValue = knobsAndLevers.centipede.pointValue;
centipede.pointValue = supporting.getRandom(pointValue, pointValue + 20);
centipede.hitPoints = 1;
centipede.updated = false;
return centipede;
},
add : function(centipede) {
this.centipedes.push(centipede);
this.numberSpawned++;
},
update : function() {
this.resetCentipedeUpdateFlag();
this.determineDirections();
this.updateDirections();
this.updateCoordinates();
for (i = 0; i < this.centipedes.length; i += 1) {
this.centipedes[i].update();
this.buildCentipedeStructure();
},
buildCentipedeStructure : function() {
let tier = knobsAndLevers.game.tier;
this.segments = tier.current * 2 + knobsAndLevers.centipede.maxNumber;
this.positions = [];
let upperLimit = tier.isMaxed ? tier.max : tier.current;
while (this.positions.length < supporting.getRandom(1, upperLimit)) {
this.positions.push(this.determineHorizontalPosition());
};
},
clear : function() {
this.centipedes = [];
this.numberSpawned = 0;
this.numberKilled = 0;
determineHorizontalPosition : function() {
let baseRange = game.gameArea.canvas.width;
return supporting.getRandom(baseRange * 0.2, baseRange * 0.8);
},
eligibleToSpawn : function() {
return this.numberSpawned < this.segments;
},
setXPosition : function() {
knobsAndLevers.centipede.args.x = this.positions[this.centipedes.length % this.positions.length];
},
cannotAdd : function(centipede) {
return this.centipedes.find(checkCentipede => checkCentipede.crashWith(centipede));
},
determineDirections : function() {
this.centipedes.filter(centipede => !centipede.updated).map(centipede => {
this.centipedes.filter(centipede => !centipede.updated).forEach(centipede => {
this.moveDownwardInitially(centipede);
this.checkYDirectionInPlayerArea(centipede);
this.checkHorizonalCollisions(centipede);
......@@ -71,7 +94,7 @@ var centipedes = {
this.centipedes.map(centipede => centipede.updated = false);
},
moveDownwardInitially : function(centipede) {
if (centipede.y < game.gameArea.firstMushroomLayer - 1) {
if (centipede.y < game.gameArea.gridStart - 1) {
centipede.moveVertically = true;
centipede.updated = true;
};
......@@ -79,7 +102,8 @@ var centipedes = {
checkYDirectionInPlayerArea : function(centipede) {
if (centipede.getBottom() > game.gameArea.canvas.height) {
centipede.reverseDirectionY = true;
} else if (centipede.getTop() < player.topLimit && centipede.distanceMovedFromBottom > 0) {
centipede.poisoned = false;
} else if (centipede.getTop() < knobsAndLevers.player.topLimit && centipede.distanceMovedFromBottom > 0) {
centipede.reverseDirectionY = true;
centipede.distanceMovedFromBottom = 0;
};
......@@ -103,23 +127,18 @@ var centipedes = {
return hasCollided;
},
hasCollidedWithMushroom : function(centipede) {
for (j = 0; j < mushrooms.mushrooms.length; j += 1) {
if (
centipede.crashWithSidesOnly(mushrooms.mushrooms[j])
&& Math.abs(centipede.y - mushrooms.mushrooms[j].y) < 5
&& centipede.distanceMovedX > game.gameArea.gridSquareSideLength
) {
this.centipedes.filter(centipede => !centipede.updated).map(centipede => {
if (centipede.y < game.gameArea.firstMushroomLayer - 1) {
centipede.moveVertically = true;
centipede.updated = true;
};
this.reverseHorizontalAtNextLayer(centipede);
});
return true;
};
let theMushroom = this.getTheMushroom(centipede);
if (theMushroom && theMushroom.poisoned) {
centipede.poisoned = true;
};
return false;
return theMushroom;
},
getTheMushroom : function(centipede) {
return mushrooms.mushrooms.find(mushroom =>
centipede.crashWith(mushroom)
&&
centipede.distanceMovedX > game.gameArea.gridSquareSideLength
);
},
reverseHorizontalAtNextLayer : function(centipede) {
if (centipede.distanceMovedY >= game.gameArea.gridSquareSideLength) {
......@@ -128,6 +147,7 @@ var centipedes = {
centipede.distanceMovedY = 0;
centipede.updated = true;
};
centipede.moveVertically = centipede.poisoned ? true : centipede.moveVertically;
},
updateDirections : function() {
for (i = 0; i < this.centipedes.length; i += 1) {
......
/*jslint white: true */
var displayObjectPrototype = {
manage : function() {
this.spawn();
this.update();
this.clearOutsideCanvas();
},
spawn : function() {
// look we're spawning things
},
update : function() {
// look we're updating things
},
clearOutsideCanvas : function() {
// define me in inheriting object
},
};
/*jslint white: true */
var gameObjects = {
worms : [],
fleas : [],
spiders : [],
init : function() {
Object.assign(this, gameObjectsBase);
supporting.applyOverrides(this);
this.intervals = {
fleas : knobsAndLevers.fleas.initialInterval,
worms : knobsAndLevers.worms.initialInterval,
spiders : knobsAndLevers.spiders.initialInterval,
};
console.log('gameObjects initialized');
},
functionOverrides : {
manage : function() {
Object.keys(this.intervals).forEach(type => {
this.spawnCreatureAtIntervals(type);
if (this[type] == false) {
return;
};
this[type] = this.clearOutsideCanvas(type);
this.update(type);
});
},
spawn : function(type) {
this.setMax(type);
if (this[type].length >= knobsAndLevers[type].maxNumber) {
return;
};
this.make(type);
},
make : function(type) {
let spawnedCreature = new Component(knobsAndLevers[type].args);
let pointValue = knobsAndLevers[type].pointValue;
spawnedCreature.pointValue = supporting.getRandom(pointValue, pointValue + 400);
spawnedCreature.sound = sounds.getSound(type);
this[type].push(spawnedCreature);
},
clearOutsideCanvas : function(type) {
if (this[type] == false) { return; };
return this[type].filter(target => {
return target.x < game.gameArea.canvas.width + 10
&& target.x > 0 - target.width
&& target.y < game.gameArea.canvas.height
});
},
update : function(type) {
this[type].forEach(creature => {
if (type == 'spiders') {
this.setSpeed(creature, type);
this.setDirection(creature);
this.removeMushrooms(creature);
};
if (type == 'fleas') {
this.dropMushrooms(creature);
};
if (type == 'worms') {
this.changeMushrooms(creature);
};
creature.newPos();
creature.update();
});
},
clear : function() {
this.worms = [];
this.fleas = [];
this.spiders = [];
},
},
spawnCreatureAtIntervals(type) {
if (supporting.everyinterval(game.gameArea.frameNo, this.intervals[type])) {
this.intervals[type] = supporting.getRandom(knobsAndLevers[type].interval.min, knobsAndLevers[type].interval.max);
this.spawn(type);
if (type == 'fleas') {
knobsAndLevers.fleas.mushroomCreateInterval = supporting.getRandom(75, 150);
};
};
},
setMax : function(type) {
let tier = knobsAndLevers.game.tier;
knobsAndLevers[type].maxNumber = tier.isMaxed ? tier.max : tier.current;
},
setSpeed : function(creature, type) {
let speedLimits = knobsAndLevers[type].speedLimits;
creature.speedX = Math.sign(creature.speedX) * (supporting.roll(10).crit ? speedLimits.max : speedLimits.min);
creature.speedY = creature.directionY * (supporting.roll(10).crit ? speedLimits.max : speedLimits.min);
},
setDirection : function(creature) {
if (creature.getBottom() > game.gameArea.canvas.height) {
creature.directionY = -1;
} else if (creature.getTop() < game.gameArea.canvas.height - (knobsAndLevers.player.areaHeight * 2)) {
creature.directionY = 1;
};
},
dropMushrooms : function(creature) {
if (this.eligibleToDrop() && creature.y <= game.gameArea.canvas.height * 0.90 && creature.y >= game.gameArea.gridStart) {
mushrooms.make({x : creature.x, y : creature.y});
};
},
eligibleToDrop : function() {
return supporting.everyinterval(
game.gameArea.frameNo,
knobsAndLevers.fleas.mushroomCreateInterval
);
},
removeMushrooms : function(creature) {
let theMushroom = mushrooms.mushrooms.find(mushroom => creature.crashWith(mushroom));
if (theMushroom) {
theMushroom.hitPoints = (supporting.roll(sides = 4).crit || theMushroom.creatureTouched) ? 0 : theMushroom.hitPoints;
theMushroom.creatureTouched = true;
};
},
changeMushrooms : function(creature) {
mushrooms.mushrooms.forEach(mushroom => {
if (creature.crashWithMiddle(mushroom)) {
mushroom.color = 'black';
mushroom.poisoned = true;
};
});
},
};
/*jslint white: true */
var intervalCreatures = {
worms : [],
flies : [],
init : function() {