Created
September 21, 2015 04:19
-
-
Save markdev/f993947206d1c3404675 to your computer and use it in GitHub Desktop.
Source code to video game at www.spacefishgame.com
This file contains hidden or 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
| <!DOCTYPE html> | |
| <head> | |
| <style> | |
| canvas#canvas { background-color: #000; } | |
| h1 {color: white;} | |
| </style> | |
| </head> | |
| <body> | |
| <canvas id="canvas" height="700" width="1200"> | |
| </canvas> | |
| <ul id="results"></ul> | |
| <script> | |
| function extend(destination, source) { | |
| for (var k in source) { | |
| if (source.hasOwnProperty(k)) { | |
| destination[k] = source[k]; | |
| } | |
| } | |
| return destination; | |
| } | |
| window.requestAnimFrame = function(){ | |
| return ( | |
| window.requestAnimationFrame || | |
| window.webkitRequestAnimationFrame || | |
| window.mozRequestAnimationFrame || | |
| window.oRequestAnimationFrame || | |
| window.msRequestAnimationFrame || | |
| function(/* function */ callback) { window.setTimeout(callback, 1000 / 60);} | |
| ); | |
| }(); | |
| var Game = function () { | |
| this.canvas = document.getElementById("canvas"); | |
| this.ctx = canvas.getContext("2d"); | |
| // Loading screen | |
| this.ctx.font = "20pt Arial"; | |
| this.ctx.fillStyle = "white"; | |
| this.ctx.fillText("Now loading images...just a few seconds...I do hope you enjoy my fish", 10, 30); | |
| this.bufferCanvas = document.createElement("canvas"); | |
| this.bufferCanvasCtx = this.bufferCanvas.getContext("2d"); | |
| this.bufferCanvasCtx.canvas.width = this.ctx.canvas.width; | |
| this.bufferCanvasCtx.canvas.height = this.ctx.canvas.height; | |
| this.intervals = []; | |
| this.gameLoop = {cancelAnimationFrame : true}; | |
| this.time = 0; | |
| this.startTime = 0; | |
| this.currentLevel = ""; | |
| this.events = []; | |
| this.score = 0; | |
| this.lives = 3; | |
| this.img = {}; | |
| this.imgArray = [ | |
| "spaceShip", | |
| "spaceShipA", | |
| "spaceShipB", | |
| "spaceShipMegaA", | |
| "spaceShipMegaB", | |
| "spaceShipShield", | |
| "spaceShipShieldA", | |
| "spaceShipShieldB", | |
| "blackhole", | |
| "alienaudience", | |
| "AGHeads", | |
| "planets", | |
| "planetview", | |
| "seasky", | |
| "theSea", | |
| "trippyeyeballs", | |
| "youLose", | |
| "youWin", | |
| "startScreenWInstructions", | |
| "bigBloater", | |
| "bigBloaterA", | |
| "bigBloaterB", | |
| "crabCakesA", | |
| "crabCakesB", | |
| "homingFishA", | |
| "homingFishB", | |
| "sinusoidSwimmerA", | |
| "sinusoidSwimmerB", | |
| "speedyBlueA", | |
| "speedyBlueB", | |
| "explosionSprite", | |
| "orbbouncy", | |
| "orbdrill", | |
| "orbhellfire", | |
| "orbhoming", | |
| "orblaser", | |
| "orbmega", | |
| "orbshock", | |
| "spitFireBulletA", | |
| "spitFireBulletB", | |
| "spitFireFishA", | |
| "spitFireFishB", | |
| "splitFishBigA", | |
| "splitFishBigB", | |
| "splitFishSmallA", | |
| "splitFishSmallB" | |
| ]; | |
| }; | |
| Game.prototype = { | |
| loadImage : function loadImage(i) { // naming this function makes it accessible only for self-reference; it is not globally accessible | |
| i = (typeof i !== 'undefined') ? i : 0; | |
| var img = new Image(); | |
| img.src = 'images/' + game.imgArray[i] + '.png'; | |
| img.onload = function(e) { | |
| window['game']['img'][game.imgArray[i]] = img; | |
| i++; | |
| if (i < game.imgArray.length) { | |
| loadImage(i); // see, that was painless | |
| } else { | |
| // <!-- Move this into a script later | |
| window.spaceFishData = { | |
| startScreen : { | |
| "type" : "startScreen", | |
| "background" : "startScreenWInstructions", | |
| "flashText" : { | |
| x: 500, | |
| y: 625, | |
| content: "Click to continue", | |
| font: "20pt Arial", | |
| color: "white" | |
| }, | |
| "events" : [ | |
| { | |
| "event" : "mousedown", | |
| "action" : function() {game.loadGameLoop("One");} | |
| } | |
| ] | |
| }, | |
| One : { | |
| "type" : "sideScrollLevel", | |
| "background" : "seasky", | |
| "timer" : 20, | |
| //"timer" : 5, | |
| "opponents": ["Bill", "Sam"], | |
| "win" : "Two" | |
| }, | |
| Two : { | |
| "type" : "sideScrollLevel", | |
| "background" : "planetview", | |
| "timer" : 25, | |
| //"timer" : 5, | |
| "opponents": ["Bill", "Sam", "Luciano"], | |
| "win" : "Three" | |
| }, | |
| Three : { | |
| "type" : "sideScrollLevel", | |
| "background" : "planets", | |
| "timer" : 30, | |
| //"timer" : 5, | |
| "opponents": ["Sam", "Luciano", "Darren"], | |
| "win" : "Four" | |
| }, | |
| Four : { | |
| "type" : "sideScrollLevel", | |
| "background" : "blackhole", | |
| "timer" : 35, | |
| //"timer" : 5, | |
| "opponents": ["Darren", "Homer"], | |
| "win" : "Five" | |
| }, | |
| Five : { | |
| "type" : "sideScrollLevel", | |
| "background" : "alienaudience", | |
| "timer" : 40, | |
| //"timer" : 5, | |
| "opponents": ["Homer", "Frank"], | |
| "win" : "Six" | |
| }, | |
| Six : { | |
| "type" : "sideScrollLevel", | |
| "background" : "trippyeyeballs", | |
| "timer" : 45, | |
| //"timer" : 5, | |
| "opponents": ["Frank", "Crabcakes"], | |
| "win" : "Seven" | |
| }, | |
| Seven : { | |
| "type" : "sideScrollLevel", | |
| "background" : "AGHeads", | |
| "timer" : 50, | |
| //"timer" : 5, | |
| "opponents": ["Sam", "Luciano", "Darren", "Homer", "Frank", "Crabcakes"], | |
| "win" : "winScreen" | |
| }, | |
| winScreen : { | |
| "type" : "basicSplashScreen", | |
| "background" : "youWin", | |
| "flashText" : { x: 500, y: 600, content: "Click to start over", font: "20pt Arial", color: "white"}, | |
| "events" : [ | |
| {"event" : "mousedown", | |
| "action" : function() {game.loadGameLoop("startScreen");}} | |
| ] | |
| }, | |
| loseScreen : { | |
| "type" : "basicSplashScreen", | |
| "background" : "youLose", | |
| "flashText" : { x: 500, y: 600, content: "Click to start over", font: "20pt Arial", color: "white"}, | |
| "events" : [ | |
| {"event" : "mousedown", | |
| "action" : function() {game.initialize();}} | |
| ] | |
| } | |
| } | |
| // --> move this into a script later | |
| game.initialize(); | |
| } | |
| }; | |
| }, | |
| initialize : function() { | |
| game.lives = 5; | |
| game.score = 0; | |
| game.loadGameLoop("startScreen"); | |
| }, | |
| loadGameLoop : function(gameLoopType) { | |
| // stop the current gameLoop, otherwise the previous loop will keep rendering | |
| game.gameLoop.cancelAnimationFrame = true; | |
| // initialize gameLoop variables | |
| var gameLoopType = (typeof gameLoopType === "undefined")? "startScreen" : gameLoopType; | |
| game.currentLevel = gameLoopType; | |
| game.startTime = String(new Date().getTime()).substring(10); | |
| game.gameLoop = new GameLoop(); | |
| // remove all the event handlers and empty this.events | |
| if (game.events.length > 0) { | |
| for (var i=0, len=game.events.length-1; i<=len; i++) { | |
| game.canvas.removeEventListener(game.events[0].event, game.events[0].action); | |
| game.events.shift(); | |
| } | |
| } | |
| // load game.events and add handlers | |
| if (game.events.length == 0) { | |
| // load from game data | |
| if (spaceFishData[gameLoopType].hasOwnProperty('events')) { | |
| for (var i=0; i<=spaceFishData[gameLoopType]['events'].length-1; i++) { | |
| game.events[game.events.length] = spaceFishData[gameLoopType]['events'][i]; | |
| game.canvas.addEventListener(game.events[game.events.length-1].event, game.events[game.events.length-1].action); | |
| } | |
| } | |
| // load from level function | |
| if (window[spaceFishData[gameLoopType].type].hasOwnProperty('events')) { | |
| for (var i=0; i<=window[spaceFishData[gameLoopType].type].events.length-1; i++) { | |
| game.events[game.events.length] = window[spaceFishData[gameLoopType].type]['events'][i]; | |
| game.canvas.addEventListener(game.events[game.events.length-1].event, game.events[game.events.length-1].action); | |
| } | |
| } | |
| } | |
| // assign members to game.gameLoop from levelData | |
| for (var key in spaceFishData[gameLoopType]) { | |
| game.gameLoop[key] = spaceFishData[gameLoopType][key]; | |
| } | |
| // extend an invoked function with an object | |
| extend(game.gameLoop, window[spaceFishData[gameLoopType].type]); // TODO: fix the extend function, remember to search | |
| // clear all the existing intervals | |
| if (typeof game.intervals[0] !== 'undefined') { | |
| for (var i=0; i<=game.intervals.length-1; i++) { | |
| clearInterval(game.intervals[i]); | |
| } | |
| } | |
| // start this shit | |
| game.gameLoop.initialize(); | |
| // run the animation loop | |
| game.gameLoop.animate(); | |
| } | |
| } | |
| var GameLoop = function() { | |
| var self = this; | |
| this.cancelAnimationFrame = false; | |
| this.initialize = function() {}; | |
| this.clearScreen = function() {}; | |
| this.update = function() {}; | |
| this.render = function() {}; | |
| this.drawbuffer = function() { | |
| game.ctx.drawImage(game.bufferCanvas, 0, 0, game.bufferCanvas.width, game.bufferCanvas.height); | |
| }; | |
| this.animate = function(time) { | |
| game.time = time; | |
| self.clearScreen(); | |
| self.update(); | |
| self.render(); | |
| self.drawbuffer(); | |
| if (self.cancelAnimationFrame == false) { | |
| window.requestAnimFrame(self.animate); | |
| } | |
| }; | |
| } | |
| /* | |
| * GameLoop Types | |
| * | |
| */ | |
| var basicSplashScreen = { | |
| "clearScreen" : function() { | |
| game.bufferCanvasCtx.drawImage(window['game']['img'][this.background], 0, 0); | |
| }, | |
| "update" : function() { | |
| var d = new Date(); | |
| var n = String(d.getTime()); | |
| if (n.substring(10) > 500) { | |
| game.bufferCanvasCtx.font = this.flashText.font; | |
| game.bufferCanvasCtx.fillStyle = this.flashText.color; | |
| game.bufferCanvasCtx.fillText(this.flashText.content, this.flashText.x, this.flashText.y); | |
| } | |
| } | |
| } | |
| var startScreen = { | |
| "initialize" : function () { | |
| game.lives = 3; | |
| game.score = 0; | |
| } | |
| } | |
| extend(startScreen, basicSplashScreen); // TODO: fix this gay ass function | |
| var sideScrollLevel = { | |
| "initialize" : function() { | |
| //splash screen | |
| game.bufferCanvasCtx.fillStyle = "red"; | |
| game.bufferCanvasCtx.fillRect(0, 0, game.bufferCanvas.width, game.bufferCanvas.height); | |
| game.startTime = +new Date(); | |
| game.elapsedTime = undefined; | |
| game.levelTime = window.spaceFishData[game.currentLevel].timer * 1000; | |
| game.backgroundShift = 0; // TODO: fix this gayness | |
| game.playerArray = []; | |
| game.playerProjectileArray = []; | |
| game.opponentProjectileArray = []; | |
| game.opponentArray = []; | |
| game.itemArray = []; | |
| game.effectArray = []; | |
| game.displayArray = []; | |
| game.objectArrays = [ | |
| { | |
| "name" : "playerArray", | |
| "collidesWith" : "opponentArray", | |
| "action" : function(a, b, i, j) {if (a.x + a.w > b.x && a.x < b.x + b.w && a.y + a.h > b.y && a.y < b.y + b.h) { a.getHit(i); game.opponentArray.splice(j,1);}} | |
| }, | |
| { | |
| "name" : "playerProjectileArray", | |
| "collidesWith" : "opponentArray", | |
| "action" : function (a, b, i, j) {if (a.x + a.radius > b.x && a.x < b.x + b.w && a.y + a.radius > b.y && a.y < b.y + b.h) {b.getHit(j); game.playerProjectileArray.splice(i,1);}} | |
| }, | |
| { | |
| "name" : "opponentProjectileArray", | |
| "collidesWith" : "playerArray", | |
| "action" : function (a, b, i, j) {if (a.x + a.radius > b.x && a.x < b.x + b.w && a.y + a.radius > b.y && a.y < b.y + b.h) {b.getHit(j); game.opponentProjectileArray.splice(i,1);}} | |
| }, | |
| { | |
| "name" : "opponentArray" | |
| }, | |
| { | |
| "name" : "itemArray", | |
| "collidesWith" : "playerArray", | |
| "action" : function(a, b, i, j) {if (a.x + a.w > b.x && a.x < b.x + b.w && a.y + a.h > b.y && a.y < b.y + b.h) { /*game.itemArray[i].action();*/ game.playerArray[0].loadItem(game.itemArray[i]); game.itemArray.splice(i,1);}} | |
| }, | |
| { | |
| "name" : "effectArray" | |
| }, | |
| { | |
| "name" : "displayArray" | |
| } | |
| ]; | |
| // Create the player | |
| game.playerArray[game.playerArray.length] = new sideScrollLevel.Player({ x : 0, y : canvas.height/2, w : 120, h : 60 }); | |
| // Create the main display | |
| game.displayArray[game.displayArray.length] = new sideScrollLevel.Display({"level" : game.currentLevel, "score" : game.score, "time" : 30, "lives" : game.lives, | |
| "update" : function() {}, | |
| "render" : function() { | |
| game.bufferCanvasCtx.font = "20pt Arial"; | |
| game.bufferCanvasCtx.fillStyle = "white"; | |
| var ymargin = 30; | |
| game.bufferCanvasCtx.fillText("Level: " + game.currentLevel, 20, ymargin); | |
| game.bufferCanvasCtx.fillText("Score: " + game.score, 300, ymargin); | |
| game.bufferCanvasCtx.fillText("Time: " + game.currentTime.substr(0,2), 500, ymargin); | |
| game.bufferCanvasCtx.fillText("Lives: " + game.lives, 800, ymargin); | |
| } | |
| }); | |
| // Generate Opponents | |
| game.intervals[game.intervals.length] = setInterval(function() { // Generate opponents at random | |
| game.opponentArray[game.opponentArray.length] = new sideScrollLevel.Opponent(sideScrollLevel['OpponentData'][spaceFishData[game.currentLevel]['opponents'][Math.floor(Math.random() * spaceFishData[game.currentLevel]['opponents'].length)]]); | |
| }, 1000); | |
| }, | |
| "clearScreen" : function() { | |
| game.bufferCanvasCtx.fillStyle = "black"; | |
| game.bufferCanvasCtx.fillRect(0, 0, game.bufferCanvasCtx.canvas.width, game.bufferCanvasCtx.canvas.height); | |
| game.bufferCanvasCtx.drawImage(game['img'][window.spaceFishData[game.currentLevel].background], game.backgroundShift, 0); | |
| }, | |
| "update" : function() { | |
| // shift background | |
| game.backgroundShift -= .2; | |
| // update game time | |
| game.currentTime = String(game.levelTime - (+new Date() - game.startTime)); | |
| while (game.currentTime.length !== 5) { | |
| var zero = "0"; | |
| game.currentTime = zero.concat(game.currentTime); | |
| } | |
| if (isNaN(Number(game.currentTime))) game.loadGameLoop(window.spaceFishData[game.currentLevel].win); | |
| // update object arrays | |
| for (var k=0; k<=game.objectArrays.length-1; k++) { | |
| if (typeof game[game.objectArrays[k].name][0] !== "undefined") { | |
| for (var i=0; i<=game[game.objectArrays[k].name].length-1; i++) { | |
| game[game.objectArrays[k].name][i].update(); | |
| // DetectRemoval will switch the terminate value to true, which wipes it out below. | |
| game[game.objectArrays[k].name][i].detectRemoval(); | |
| // Collision detection | |
| var a = game[game.objectArrays[k].name][i]; | |
| if (typeof game.objectArrays[k].collidesWith !== "undefined") { | |
| for (var j=0; j<=game[game.objectArrays[k].collidesWith].length-1; j++) { | |
| var b = game[game.objectArrays[k].collidesWith][j]; | |
| game.objectArrays[k].action(a, b, i, j); | |
| } | |
| } | |
| } | |
| // Remove blasts from projectileArray when they fly off the screen | |
| for (var i=0; i<=game[game.objectArrays[k].name].length-1; i++) { | |
| if (game[game.objectArrays[k].name][i].terminate == true) { | |
| game[game.objectArrays[k].name].splice(i,1); | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "render" : function() { | |
| for (var k=0; k<=game.objectArrays.length-1; k++) { | |
| if (typeof game[game.objectArrays[k].name] !== "undefined") { | |
| for (var i=0; i<=game[game.objectArrays[k].name].length-1; i++) { | |
| game[game.objectArrays[k].name][i].render(game[game.objectArrays[k].name][i]); | |
| } | |
| } | |
| } | |
| var modeHeight = 0; | |
| if (game.playerArray[0].weapon.name !== "peaShooter") { | |
| game.bufferCanvasCtx.fillStyle = game.playerArray[0].weapon.color; | |
| var startX = (game.bufferCanvas.width/2) - ((game.playerArray[0].weapon.endTime - game.playerArray[0].weapon.currentTime) / (game.playerArray[0].weapon.endTime - game.playerArray[0].weapon.startTime)) * (game.bufferCanvas.width/2); | |
| var endX = ((game.playerArray[0].weapon.endTime - game.playerArray[0].weapon.currentTime) / (game.playerArray[0].weapon.endTime - game.playerArray[0].weapon.startTime)) * (game.bufferCanvas.width/2) * 2; | |
| game.bufferCanvasCtx.fillRect(startX, game.bufferCanvas.height-50, endX, 50); | |
| game.bufferCanvasCtx.font = "20pt Arial"; | |
| game.bufferCanvasCtx.fillStyle = "white"; | |
| game.bufferCanvasCtx.fillText(game.playerArray[0].weapon.title, game.bufferCanvas.width/2 - 50, game.bufferCanvas.height - 15); | |
| modeHeight += 50; | |
| } | |
| if (game.playerArray[0].mode.name !== "normal") { | |
| game.bufferCanvasCtx.fillStyle = game.playerArray[0].mode.color; | |
| var startX = (game.bufferCanvas.width/2) - ((game.playerArray[0].mode.endTime - game.playerArray[0].mode.currentTime) / (game.playerArray[0].mode.endTime - game.playerArray[0].mode.startTime)) * (game.bufferCanvas.width/2); | |
| var endX = ((game.playerArray[0].mode.endTime - game.playerArray[0].mode.currentTime) / (game.playerArray[0].mode.endTime - game.playerArray[0].mode.startTime)) * (game.bufferCanvas.width/2) * 2; | |
| game.bufferCanvasCtx.fillRect(startX, game.bufferCanvas.height-(50+modeHeight), endX, 50); | |
| game.bufferCanvasCtx.font = "20pt Arial"; | |
| game.bufferCanvasCtx.fillStyle = "white"; | |
| game.bufferCanvasCtx.fillText(game.playerArray[0].mode.title, game.bufferCanvas.width/2 - 50, game.bufferCanvas.height - (15+modeHeight)); | |
| } | |
| }, | |
| "events" : [ | |
| {"event" : "mousedown", "action" : function() { | |
| sideScrollLevel['WeaponData'][game.playerArray[0].weapon.name]["fire"](); | |
| }}, | |
| {"event" : "mousemove", "action" : function(e) { | |
| if (typeof game.playerArray[0] !== "undefined") { | |
| game.playerArray[0].y = e.pageY; | |
| } | |
| }} | |
| ], | |
| /* | |
| * Game Object Prototypes | |
| * | |
| */ | |
| "GameObject" : { | |
| "terminate" : false, | |
| "name" : "", | |
| "x" : 0, | |
| "y" : 0, | |
| "velx" : 0, | |
| "vely" : 0, | |
| "w" : 30, | |
| "h" : 15, | |
| "update" : function () {this.x += this.velx; this.y += this.vely;}, | |
| "detectRemoval" : function () {if (this.x < -(this.w) || this.x > canvas.width) {this.terminate = true;}}, | |
| "render" : function (updateObject) { | |
| img = updateObject.img; | |
| // toggles the opponent image | |
| if (updateObject.hasOwnProperty('imgb')) { | |
| img = (Number(String(Date.now()).charAt(10)) > 5)? updateObject.img : updateObject.imgb; | |
| } | |
| game.bufferCanvasCtx.drawImage(game['img'][img], updateObject.x, updateObject.y, updateObject.w, updateObject.h); | |
| } | |
| }, | |
| "GameObjectInit" : function (self, argData) { | |
| for (var key in sideScrollLevel.GameObject) {if (!self.hasOwnProperty(key)) self[key] = sideScrollLevel.GameObject[key];} | |
| for (var key in argData) {self[key] = argData[key];} | |
| }, | |
| "Player" : function (argData) { | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.name = "player"; | |
| this.health = 1; | |
| this.img = "spaceShipA"; | |
| this.imgb = "spaceShipB"; | |
| this.weapon = {"name" : "peaShooter", "color" : "white", "title" : "Pea Shooter", "startTime" : 0, "endTime" : 0, "currentTime" : 0 }; | |
| this.mode = {"name" : "normal", "color" : "white", "title" : "Normal", "startTime" : 0, "endTime" : 0, "currentTime" : 0 }; | |
| this.update = function () { | |
| if (this.weapon.name !== "peaShooter") { | |
| this.weapon.currentTime = +new Date(); | |
| if (this.weapon.currentTime > this.weapon.endTime) this.changeWeapon({"weapon" : "peaShooter"}); | |
| } | |
| if (this.mode.name !== "normal") { | |
| this.mode.currentTime = +new Date(); | |
| if (this.mode.currentTime > this.mode.endTime) this.changeMode({"mode" : "normal"}); | |
| } | |
| }; | |
| this.getHit = function () { //TODO: create a more robust, dynamic way of involving items | |
| if (self.mode.name == "mega") { | |
| self.changeMode({"mode" : "normal"}); | |
| } else if (self.mode.name == "drill") { | |
| // nothing happens! | |
| } else if (self.mode.name == "normal") { | |
| self.health -= 1; | |
| self.die(); | |
| } | |
| }; | |
| this.die = function () { | |
| game.effectArray[game.effectArray.length] = new sideScrollLevel.Effect({ | |
| "x" : self.x, | |
| "y" : self.y, | |
| "img" : "explosionSprite", | |
| "update" : function() { | |
| this.sx += 100; | |
| if (this.sx >= 600) { | |
| this.sx = 0; | |
| this.sy += 100; | |
| } if (this.sy > 600) { | |
| this.terminate = true; | |
| game.lives -= 1; | |
| var levelToLoad = game.lives > 0 ? game.currentLevel : "loseScreen"; | |
| game.loadGameLoop(levelToLoad); | |
| } | |
| }, | |
| "render" : function() { | |
| game.bufferCanvasCtx.drawImage(game['img'][this.img], this.sx, this.sy, 100, 100, this.x, this.y, 200, 200) | |
| } | |
| }); | |
| }; | |
| this.loadItem = function(itemData) { | |
| if (itemData.hasOwnProperty("weapon")) { | |
| self.changeWeapon(itemData); | |
| } else if (itemData.hasOwnProperty("mode")) { | |
| self.changeMode(itemData); | |
| } | |
| }; | |
| this.changeWeapon = function (itemData) { | |
| this.weapon.name = itemData.weapon; | |
| this.weapon.startTime = +new Date(); | |
| this.weapon.endTime = this.weapon.startTime + (itemData.duration * 1000); | |
| this.weapon.color = itemData.color; | |
| this.weapon.title = itemData.title; | |
| }; | |
| this.changeMode = function(itemData) { | |
| var modes = sideScrollLevel.PlayerModes; | |
| for (var key in modes[itemData.mode]) { | |
| if (modes[itemData.mode].hasOwnProperty(key)) { | |
| if (key === "mode") { | |
| self.mode.name = modes[itemData.mode][key]; // TODO: make polymorphic? Maybe? | |
| } else { | |
| self[key] = modes[itemData.mode][key]; | |
| } | |
| } | |
| } | |
| if (itemData.mode !== "normal") { | |
| self.mode.startTime = +new Date(); | |
| self.mode.endTime = self.mode.startTime + (modes[itemData.mode].duration * 1000); | |
| self.mode.color = modes[itemData.mode].color; | |
| self.mode.title = itemData.mode; | |
| } | |
| }; | |
| }, | |
| "Blast" : function (argData) { | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.source = typeof argData.source !== "undefined" ? argData.source : "player"; | |
| this.x = typeof argData.x !== "undefined" ? argData.x : game.playerArray[0].w; | |
| this.y = typeof argData.y !== "undefined" ? argData.y : game.playerArray[0].y + game.playerArray[0].h/2; | |
| this.radius = typeof argData.radius !== "undefined" ? argData.radius : 10; | |
| this.color = typeof argData.color !== "undefined" ? argData.color : "white"; | |
| this.detectRemoval = typeof argData.detectRemoval !== "undefined" ? argData.detectRemoval : function() { | |
| if (this.x > canvas.width || this.x < this.radius) this.terminate = true; | |
| }; | |
| this.render = typeof argData.render !== "undefined" ? argData.render : function (updateObject) { | |
| game.bufferCanvasCtx.fillStyle = updateObject.color; | |
| game.bufferCanvasCtx.beginPath(); | |
| game.bufferCanvasCtx.arc(updateObject.x, updateObject.y, updateObject.radius, 0, 2 * Math.PI); | |
| game.bufferCanvasCtx.fill(); | |
| }; | |
| }, | |
| "Effect" : function(argData) { | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.sx = typeof argData.sx !== "undefined" ? argData.sx: 0; | |
| this.sy = typeof argData.sy !== "undefined" ? argData.sy: 0; | |
| this.opacity = typeof argData.opacity !== "undefined" ? argData.opacity: 0; | |
| this.text = typeof argData.text !== "undefined" ? argData.text : ""; | |
| }, | |
| "Display" : function(argData) { | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.text = typeof argData.text !== "undefined" ? argData.text : ""; | |
| }, | |
| "Opponent" : function (argData) { | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.score = typeof argData.score !== 'undefined' ? argData.score : 0; | |
| this.x = typeof argData.x !== 'undefined' ? argData.x : canvas.width; | |
| this.y = typeof argData.y !== 'undefined' ? argData.y : Math.random() * (canvas.height - this.h); | |
| this.detectRemoval = typeof argData.detectRemoval !== "undefined" ? argData.detectRemoval : function() { | |
| if (this.x < -(this.w)) { | |
| this.terminate = true; | |
| } | |
| }; | |
| this.getHit = typeof argData.getHit !== 'undefined' ? argData.getHit : function(i) { | |
| // Generate item by default | |
| var argData = sideScrollLevel['ItemData'][sideScrollLevel['OpponentData'][self.name]["item"]]; | |
| argData.x = self.x; | |
| argData.y = self.y + self.h/2; | |
| // Draw the score | |
| game.score += self.score; | |
| game.effectArray[game.effectArray.length] = new sideScrollLevel.Effect({"x" : self.x + self.w/2, "y" : self.y, "opacity" : 1, "text" : self.score, "update" : function() {this.y -= 2; this.opacity -= .02; if (this.opacity <= 0) {this.terminate = true;}}, "render" : function() {game.bufferCanvasCtx.font = "20pt Arial"; game.bufferCanvasCtx.fillStyle = "rgba(255,255,255," + this.opacity + ")"; game.bufferCanvasCtx.fillText(this.text, this.x, this.y);}}); | |
| self.explode(); | |
| game.itemArray[game.itemArray.length] = new sideScrollLevel.Item(argData); | |
| game.opponentArray.splice(i,1); | |
| }; | |
| this.explode = function () { | |
| game.effectArray[game.effectArray.length] = new sideScrollLevel.Effect({"x" : self.x, "y" : self.y, "img" : "explosionSprite", "update" : function() {this.sx += 100; if (this.sx >= 600) {this.sx = 0; this.sy += 100;} if (this.sy > 600) {this.terminate = true;}}, "render" : function() {game.bufferCanvasCtx.drawImage(game['img'][this.img], this.sx, this.sy, 100, 100, this.x, this.y, 200, 200)}}); | |
| }; | |
| }, | |
| "Item" : function(argData) { // TODO: make this dynamic so that it is called by the opponent | |
| var self = this; | |
| this.init = sideScrollLevel.GameObjectInit(self, argData); | |
| this.w = 40; // TODO: change this to a radius maybe | |
| this.h = 40; | |
| this.velx = -4; | |
| }, | |
| /* | |
| * Game Object Data | |
| * | |
| */ | |
| "PlayerModes" : { | |
| "normal" : { | |
| "mode" : "normal", | |
| "h" : 60, | |
| "w" : 120, | |
| "color" : "white", | |
| "health" : 1, | |
| "img" : "spaceShipA", | |
| "imgb" : "spaceShipB" | |
| }, | |
| "mega" : { | |
| "mode" : "mega", | |
| "h" : 80, | |
| "w" : 120, | |
| "color" : "green", | |
| "duration" : 10, | |
| "health" : 2, | |
| "img" : "spaceShipMegaA", | |
| "imgb" : "spaceShipMegaB" | |
| }, | |
| "drill" : { | |
| "mode" : "drill", | |
| "h" : 60, | |
| "w" : 145, | |
| "color" : "orange", | |
| "duration" : 2, | |
| "health" : 1, | |
| "img" : "spaceShipShieldA", | |
| "imgb" : "spaceShipShieldB" | |
| } | |
| }, | |
| "OpponentData" : { | |
| "Bill" : { | |
| "name" : "Bill", | |
| "score" : 100, | |
| "w" : 300, | |
| "h" : 150, | |
| "velx" : 15, | |
| "img" : "bigBloaterA", | |
| "imgb" : "bigBloaterB", | |
| "item" : "mega", | |
| "update" : function() {this.x -= this.velx;} | |
| }, | |
| "Sam" : { | |
| "name" : "Sam", | |
| "score" : 200, | |
| "w" : 150, | |
| "h" : 75, | |
| "velx" : 20, | |
| "img" : "speedyBlueA", | |
| "imgb" : "speedyBlueB", | |
| "item" : "dualLaser", | |
| "update" : function() {this.x -= this.velx;} | |
| }, | |
| "Luciano" : { | |
| "name" : "Luciano", | |
| "score" : 300, | |
| "w" : 200, | |
| "h" : 300, | |
| "velx" : 25, | |
| "img" : "sinusoidSwimmerA", | |
| "imgb" : "sinusoidSwimmerB", | |
| "item" : "shockWave", | |
| "update" : function() {this.x -= this.velx; var sin = Math.sin(this.x * 2.5) * 80; this.y += sin;} | |
| }, | |
| "Homer" : { | |
| "name" : "Homer", | |
| "score" : 400, | |
| "w" : 230, | |
| "h" : 115, | |
| "velx" : 35, | |
| "img" : "homingFishA", | |
| "imgb" : "homingFishB", | |
| "item" : "homingMissile", | |
| "update" : function() {this.x -= this.velx; this.y += ((this.y + this.h/2) > game.playerArray[0].y)? -10 : 10;} | |
| }, | |
| "Darren" : { | |
| "name" : "Darren", | |
| "score" : 500, | |
| "w" : 250, | |
| "h" : 250, | |
| "velx" : 15, | |
| "img" : "splitFishBigA", | |
| "imgb" : "splitFishBigB", | |
| "item" : "dualLaser", | |
| "update" : function() {this.x -= this.velx;}, "getHit" : function(i) { | |
| game.opponentArray[i].explode(); | |
| for (var k=-5; k<=5; k+=5) { | |
| var dylanData = sideScrollLevel['OpponentData']['Dylan']; | |
| dylanData.x = game.opponentArray[i].x; dylanData.y = game.opponentArray[i].y; dylanData.vely = k; | |
| game.opponentArray[game.opponentArray.length] = new sideScrollLevel.Opponent(dylanData); | |
| } | |
| game.opponentArray.splice(i,1); | |
| } | |
| }, | |
| "Dylan" : { | |
| "name" : "Dylan", | |
| "score" : 500, | |
| "w" : 125, | |
| "h" : 75, | |
| "velx" : 25, | |
| "img" : "splitFishSmallA", | |
| "imgb" : "splitFishSmallB", | |
| "item" : "bouncyBalls", | |
| "update" : function() {this.x -= this.velx; this.y -= this.vely;} | |
| }, | |
| "Frank" : { | |
| "name" : "Frank", | |
| "score" : 600, | |
| "w" : 300, | |
| "h" : 150, | |
| "velx" : 15, | |
| "img" : "spitFireFishA", | |
| "imgb" : "spitFireFishB", | |
| "item" : "drill", | |
| "update" : function() { | |
| this.x -= this.velx; | |
| if (this.x >700 && this.x < 720) { | |
| game.opponentProjectileArray[game.opponentProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "name" : "Heroin", | |
| "source" : "opponent", | |
| "x" : this.x, | |
| "y" : this.y + this.h/2, | |
| "velx" : -20, | |
| "vely" : 0, | |
| "update" : function () {this.x += this.velx}, | |
| "radius" : 10, | |
| "color" : "orange" | |
| } | |
| )} | |
| } | |
| }, | |
| "CrabCakes" : { | |
| "name" : "CrabCakes", | |
| "score" : 700, | |
| "w" : 200, | |
| "h" : 200, | |
| "velx" : 20, | |
| "vely" : 4, | |
| "img" : "crabCakesA", | |
| "imgb" : "crabCakesB", | |
| "item" : "hellFire", | |
| "update" : function() { | |
| this.x -= this.velx; | |
| if (this.x < 0) this.velx = -this.velx; | |
| if (this.x + this.w > canvas.width && this.velx < 0) this.velx = -this.velx; | |
| this.y -= this.vely; | |
| if (this.y < 0) this.vely = -this.vely; | |
| if (this.y + this.h > canvas.height && this.vely < 0) this.vely = -this.vely; | |
| } | |
| } | |
| }, | |
| "ItemData" : { | |
| "mega" : { | |
| "title" : "Mega", | |
| "mode" : "mega", | |
| "img" : "orbmega", | |
| "color" : "green", | |
| "duration" : 20 | |
| }, | |
| "dualLaser" : { | |
| "title" : "Dual Laser", | |
| "weapon" : "dualLaser", | |
| "img" : "orblaser", | |
| "color" : "purple", | |
| "duration" : 2 | |
| }, | |
| "shockWave" : { | |
| "title" : "Shock Wave", | |
| "weapon" : "shockWave", | |
| "img" : "orbshock", | |
| "color" : "yellow", | |
| "duration" : 3 | |
| }, | |
| "homingMissile" : { | |
| "title" : "Homing Missile", | |
| "weapon" : "homingMissile", | |
| "img" : "orbhoming", | |
| "color" : "red", | |
| "duration" : 4 | |
| }, | |
| "bouncyBalls" : { | |
| "title" : "Bouncy Balls", | |
| "weapon" : "bouncyBalls", | |
| "img" : "orbbouncy", | |
| "color" : "blue", | |
| "duration" : 5 | |
| }, | |
| "drill" : { | |
| "title" : "Drill", | |
| "mode" : "drill", | |
| "img" : "orbdrill", | |
| "color" : "orange", | |
| "duration" : 6 | |
| }, | |
| "hellFire" : { | |
| "title" : "Hell Fire", | |
| "weapon" : "hellFire", | |
| "img" : "orbhellfire", | |
| "color" : "black", | |
| "duration" : 7 | |
| } | |
| }, | |
| "WeaponData" : { // TODO: figure out whether to put this with itemData, not sure yet | |
| "peaShooter" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Placebo", | |
| "velx" : 10, | |
| "vely" : 0, | |
| "color" : "white" | |
| }); | |
| } | |
| }, | |
| "dualLaser" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Speed", | |
| "y" : (game.playerArray[0].y + game.playerArray[0].h/2)-15, | |
| "velx" : 10, | |
| "vely" : 0, | |
| "radius" : 7, | |
| "color" : "red" | |
| }); | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Speed", | |
| "y" : (game.playerArray[0].y + game.playerArray[0].h/2)+15, | |
| "velx" : 10, | |
| "vely" : 0, | |
| "radius" : 7, | |
| "color" : "red" | |
| }); | |
| } | |
| }, | |
| "shockWave" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Molly", | |
| "velx" : 10, | |
| "vely" : 0, | |
| "update" : function () {this.x += this.velx; var sin = Math.sin(this.x * 2.5) * 8; this.y += sin;}, | |
| "color" : "yellow" | |
| }); | |
| } | |
| }, | |
| "homingMissile" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Coke", | |
| "velx" : 5, | |
| "vely" : 0, | |
| "update" : function () { | |
| if (game.opponentArray.length > 0) { | |
| this.y += (game.opponentArray[game.opponentArray.length-1].y - this.y) * .05; | |
| } | |
| this.x += this.velx; | |
| }, | |
| "radius" : 20, | |
| "color" : "red" | |
| }); | |
| } | |
| }, | |
| "bouncyBalls" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "LSD", | |
| "velx" : 10, | |
| "vely" : Math.round(Math.random()*2 - 1) * 10, | |
| "update" : function () { | |
| this.x += this.velx; | |
| this.y += this.vely; | |
| if (this.y < 0) this.vely = -this.vely; | |
| if (this.y + this.radius > canvas.height) this.vely = -this.vely; | |
| }, | |
| "color" : "purple" | |
| }); | |
| } | |
| }, | |
| "hellFire" : { | |
| "fire" : function() { | |
| game.playerProjectileArray[game.playerProjectileArray.length] = new sideScrollLevel.Blast({ | |
| "title" : "Party", | |
| "velx" : Math.round(Math.random()*20 - 10), | |
| "vely" : Math.round(Math.random()*20 - 10), | |
| "update" : function () { | |
| this.x += this.velx; | |
| if (this.x < 0) this.velx = -this.velx; | |
| if (this.x + this.radius > canvas.width && this.velx > 0) this.velx = -this.velx; | |
| this.y -= this.vely; | |
| if (this.y < 0) this.vely = -this.vely; | |
| if (this.y + this.radius > canvas.height && this.vely < 0) this.vely = -this.vely; | |
| }, | |
| "color" : "red" | |
| }); | |
| } | |
| } | |
| } | |
| } | |
| if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { | |
| alert("Sorry, this game is not optimized for mobile devices"); | |
| } | |
| var game = new Game(); | |
| game.loadImage(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment