aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2015-11-16 16:58:18 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2015-11-16 16:58:18 +0200
commit13c5dc317abe0fb4458e703f2ab9397a7c24c859 (patch)
tree1410e5e6d250cbcadc29a1b66a851473e15da8b6 /src
Rengöring
Diffstat (limited to 'src')
-rw-r--r--src/button.js18
-rw-r--r--src/engine.js217
-rw-r--r--src/gameobject.js20
-rw-r--r--src/keyboard.js38
-rw-r--r--src/objecttypes.js107
-rw-r--r--src/platformer.js9
-rw-r--r--src/player.js67
-rw-r--r--src/settings.js15
-rw-r--r--src/sound.js20
9 files changed, 511 insertions, 0 deletions
diff --git a/src/button.js b/src/button.js
new file mode 100644
index 0000000..a214db3
--- /dev/null
+++ b/src/button.js
@@ -0,0 +1,18 @@
+function Button() {
+ this.graphics = new PIXI.Graphics();
+
+ this.graphics.beginFill(0xFFFF00);
+
+ // set the line style to have a width of 5 and set the color to red
+ this.graphics.lineStyle(5, 0xFF0000);
+
+ // draw a rectangle
+ this.graphics.drawRect(100, 150, 50, 50);
+
+ // make the button interactive..
+ this.graphics.setInteractive(true);
+
+ this.graphics.click = function(data) {
+ console.log('hit rect');
+ }
+} \ No newline at end of file
diff --git a/src/engine.js b/src/engine.js
new file mode 100644
index 0000000..30d7d7a
--- /dev/null
+++ b/src/engine.js
@@ -0,0 +1,217 @@
+var MENU = 1;
+var GAME = 2;
+var GAMEOVER = 3;
+
+var appRunning = true;
+var Engine = function() {
+
+ Engine.instance = this;
+
+ this.sound = new Sound();
+
+ this.state = MENU;
+
+ this.stage = new PIXI.Container();
+ this.renderer = PIXI.autoDetectRenderer(Settings.stage_WIDTH, Settings.stage_HEIGHT);
+
+ this.mapContainer = new PIXI.Container(),
+ this.unitsContainer = new PIXI.Container(),
+ this.menuContainer = new PIXI.Container();
+ this.clickableContainer = new PIXI.Container();
+
+ this.mapContainer.zIndex = 4;
+ this.unitsContainer.zIndex = 3;
+ this.menuContainer.zIndex = 2;
+ this.clickableContainer.zIndex = 1;
+
+ this.stage.addChild(this.mapContainer);
+ this.stage.addChild(this.menuContainer);
+ this.stage.addChild(this.unitsContainer);
+ this.stage.addChild(this.clickableContainer);
+
+ this.stage.updateLayersOrder = function () {
+ this.children.sort(function(a,b) {
+ a.zIndex = a.zIndex || 0;
+ b.zIndex = b.zIndex || 0;
+ return b.zIndex - a.zIndex
+ });
+ };
+ this.makeStageClickable();
+
+ this.setupGameObjects();
+ this.integralSpawnTimer = 0;
+ this.gameOverTimer = 0;
+
+ return this;
+}
+
+Engine.prototype.makeStageClickable = function() {
+ this.clickLayer = new PIXI.Graphics();
+ this.clickLayer.beginFill(0x000000, 0.0);
+ this.clickLayer.drawRect(0, 0, Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT);
+ this.clickLayer.interactive = true;
+
+ this.clickableContainer.addChild(this.clickLayer);
+
+ this.clickLayer.touchstart = this.clickLayer.mousedown = this.buttonPressed.bind(this);
+}
+
+Engine.prototype.activateMenu = function() {
+ this.state = MENU;
+ player.score = 0
+ console.log("changed to menu!");
+ logo1.sprite.visible = true;
+ logo2.sprite.visible = true;
+ this.resetPositions();
+ player.active = false;
+ scoreText.visible = false;
+ gameOverText.visible = false;
+ scoreBg.visible = false;
+
+ for (var i = 0; i < this.gameObjectList.length; i++) {
+ if (this.gameObjectList[i].objectType == "integral")
+ this.removeIntegral(this.gameObjectList[i])
+ }
+}
+
+Engine.prototype.activateGame = function() {
+ this.state = GAME;
+ console.log("game starting...")
+ player.active = true;
+ logo1.sprite.visible = false;
+ logo2.sprite.visible = false;
+ scoreText.moveToCorner();
+ scoreText.visible = true;
+ this.sound.play("start")
+}
+
+Engine.prototype.activateGameOver = function() {
+ this.state = GAMEOVER;
+ console.log("game over");
+ player.active = false;
+ logo1.sprite.active = true;
+ scoreText.moveToCenter();
+ this.gameOverTimer = 50;
+ gameOverText.visible = true;
+ scoreBg.visible = true;
+ this.sound.play("explosion")
+}
+
+Engine.prototype.removeIntegral = function(integral) {
+ var i = this.gameObjectList.indexOf(integral);
+ this.gameObjectList.splice(i, 1);
+ this.unitsContainer.removeChild(integral.sprite);
+ delete integral;
+}
+
+Engine.prototype.testForGameover = function() {
+ if (player.outOfScreen()) {
+ this.activateGameOver();
+ }
+
+ // collision detection
+ var g = this.gameObjectList;
+ var p = player.sprite
+ for (var i = 0; i < g.length; i++) {
+ if (g[i].objectType == "integral") {
+ var obj = g[i].sprite;
+
+ var xdist = obj.position.x - p.position.x;
+
+ if (xdist > -0.3 * obj.width && xdist < 0.2 * obj.width) {
+ var ydist = obj.position.y - p.position.y;
+
+ if (ydist > -obj.height / 2 && ydist < obj.height / 2) {
+ this.activateGameOver();
+ }
+ }
+ }
+ }
+}
+
+Engine.prototype.spawnIntegral = function() {
+ var i = new Integral(Math.random() * Settings.STAGE_HEIGHT);
+ this.gameObjectList.push(i);
+ this.unitsContainer.addChild(i.sprite);
+}
+
+Engine.prototype.updateSpawns = function() {
+ this.integralSpawnTimer -= 1;
+
+ if (this.integralSpawnTimer < 0) {
+ this.spawnIntegral();
+ this.integralSpawnTimer = 30 + Math.random() * 100;
+ }
+}
+
+Engine.prototype.update = function() {
+ updateDeltaTime();
+ if (this.state == GAME)
+ this.updateSpawns();
+
+ if (this.state == GAME || this.state == MENU) {
+ this.testForGameover();
+ for (var i = 0; i < this.gameObjectList.length; i++) {
+ var obj = this.gameObjectList[i];
+ obj.update();
+
+ // check if integral object has left the screen
+ if (obj.objectType == "integral") {
+ if (obj.sprite.x < -obj.sprite.width)
+ this.removeIntegral(obj);
+ }
+ }
+ }
+
+ if (this.state == GAMEOVER) {
+ this.gameOverTimer -= 1;
+ }
+
+ scoreText.update();
+
+ this.renderer.render(this.stage);
+}
+
+Engine.prototype.resetPositions = function() {
+ for (var i = 0; i < this.gameObjectList.length; i++) {
+ this.gameObjectList[i].initPosition();
+ }
+}
+
+Engine.prototype.buttonPressed = function() {
+ player.boost();
+
+ if (this.state == MENU) {
+ this.activateGame();
+ player.boost();
+ }
+ else if (this.state == GAME) {
+ player.boost();
+ }
+ else if (this.state == GAMEOVER) {
+ if (this.gameOverTimer < 0)
+ this.activateMenu();
+ }
+}
+
+Engine.prototype.setupGameObjects = function() {
+ // add player to gameobjectlist
+ this.gameObjectList = [];
+
+ this.unitsContainer.addChild(player.sprite);
+ this.menuContainer.addChild(logo1.sprite);
+ this.menuContainer.addChild(logo2.sprite);
+ this.mapContainer.addChild(bg1.sprite);
+ this.mapContainer.addChild(bg2.sprite);
+ this.menuContainer.addChild(scoreBg);
+ this.menuContainer.addChild(scoreText);
+ this.menuContainer.addChild(gameOverText);
+
+ this.gameObjectList = this.gameObjectList.concat([player, logo1, logo2, bg1, bg2]);
+
+ k_space.press = this.buttonPressed.bind(this);
+
+ this.stage.updateLayersOrder();
+}
+
+var engine = new Engine(); \ No newline at end of file
diff --git a/src/gameobject.js b/src/gameobject.js
new file mode 100644
index 0000000..0b50553
--- /dev/null
+++ b/src/gameobject.js
@@ -0,0 +1,20 @@
+function GameObject(texture) {
+ this.texture = PIXI.Texture.fromImage("res/" + texture + ".png");
+ this.sprite = new PIXI.Sprite(this.texture);
+
+ this.initPosition();
+ this.active = true;
+ this.objectType = "gameobject";
+}
+
+GameObject.prototype.initPosition = function() {
+ this.sprite.anchor.x = 0.5;
+ this.sprite.anchor.y = 0.5;
+
+ this.sprite.position.x = Settings.STAGE_WIDTH * 0.5;
+ this.sprite.position.y = Settings.STAGE_HEIGHT * 0.5;
+}
+
+GameObject.prototype.update = function() {
+
+} \ No newline at end of file
diff --git a/src/keyboard.js b/src/keyboard.js
new file mode 100644
index 0000000..8f9b12d
--- /dev/null
+++ b/src/keyboard.js
@@ -0,0 +1,38 @@
+function keyboard(keyCode) {
+ var key = {};
+ key.code = keyCode;
+ key.isDown = false;
+ key.isUp = true;
+ key.press = undefined;
+ key.release = undefined;
+ //The `downHandler`
+ key.downHandler = function(event) {
+ if (event.keyCode === key.code) {
+ if (key.isUp && key.press) key.press();
+ key.isDown = true;
+ key.isUp = false;
+ }
+ event.preventDefault();
+ };
+
+ //The `upHandler`
+ key.upHandler = function(event) {
+ if (event.keyCode === key.code) {
+ if (key.isDown && key.release) key.release();
+ key.isDown = false;
+ key.isUp = true;
+ }
+ event.preventDefault();
+ };
+
+ //Attach event listeners
+ window.addEventListener(
+ "keydown", key.downHandler.bind(key), false
+ );
+ window.addEventListener(
+ "keyup", key.upHandler.bind(key), false
+ );
+ return key;
+}
+
+var k_space = keyboard(32) // space bar
diff --git a/src/objecttypes.js b/src/objecttypes.js
new file mode 100644
index 0000000..d7b0df4
--- /dev/null
+++ b/src/objecttypes.js
@@ -0,0 +1,107 @@
+// bg
+function Background(x_offset) {
+ GameObject.call(this, "bg");
+ this.x_offset = x_offset;
+ this.initPosition();
+
+ this.x_speed = 10
+ this.objectType = "background";
+}
+
+Background.prototype = Object.create(GameObject.prototype);
+Background.prototype.constructor = Background;
+
+Background.prototype.update = function() {
+ this.sprite.position.x -= this.x_speed
+
+ if (this.sprite.position.x < -Settings.STAGE_WIDTH) {
+ this.sprite.position.x = Settings.STAGE_WIDTH - this.x_speed;
+ }
+}
+
+Background.prototype.initPosition = function() {
+ this.sprite.position.x = this.x_offset;
+ this.sprite.position.y = 0;
+ this.sprite.anchor.x = 0;
+ this.sprite.anchor.y = 0;
+}
+
+var bg1 = new Background(0);
+var bg2 = new Background(Settings.STAGE_WIDTH);
+
+// logo
+var logo1 = new GameObject("logo1");
+logo1.update = function() {
+ this.sprite.rotation = 0.1 * Math.sin(0.001 * Date.now());
+}
+
+logo1.initPosition = function() {
+ logo1.sprite.position.y = Settings.STAGE_WIDTH * 0.2
+}
+logo1.initPosition();
+
+// press space to play text
+var logo2 = new GameObject("logo2");
+logo2.initPosition = function() {
+ this.sprite.position.y = Settings.STAGE_HEIGHT * 0.6;
+}
+logo2.initPosition();
+
+// background box for score display at gameover
+var scoreBg = new PIXI.Graphics();
+scoreBg.beginFill(0xAAAAAA, 1.0);
+scoreBg.visible = false;
+
+// score display
+var scoreText = new PIXI.Text("W", { font: '35px Arial', fill: 'black', align: 'left' });
+scoreText.visible = false;
+scoreText.update = function() {
+ this.text = "W = " + player.score + " J";
+}
+
+scoreText.moveToCorner = function() {
+ this.position.x = Settings.STAGE_WIDTH * 0.7;
+ this.position.y = Settings.STAGE_HEIGHT * 0.1;
+}
+
+scoreText.moveToCenter = function() {
+ this.position.x = Settings.STAGE_WIDTH * 0.5 - this.width / 2;
+ this.position.y = Settings.STAGE_HEIGHT * 0.5 - this.height / 2;
+}
+scoreText.moveToCorner();
+
+// gameover screen title text
+var gameOverText = new PIXI.Text("Nettovoiman tekemä työ:", { font: '35px Arial', fill: 'black', align: 'center' });
+gameOverText.visible = false;
+gameOverText.position.x = Settings.STAGE_WIDTH * 0.5 - gameOverText.width / 2;;
+gameOverText.position.y = Settings.STAGE_HEIGHT * 0.4 - gameOverText.height / 2;;
+
+// move the gameover bg box now that we now the width of the text
+var yDiff = scoreText.position.y - gameOverText.position.y + gameOverText.height;
+scoreBg.drawRect(gameOverText.position.x - 10, gameOverText.position.y - 10, gameOverText.width + 20, -yDiff);
+
+// integral sign
+function Integral(y) {
+ GameObject.call(this, "int");
+
+ this.initPosition()
+ this.sprite.position.y = y;
+
+ this.speed = -10;
+ this.objectType = "integral";
+
+}
+
+Integral.prototype = Object.create(GameObject.prototype);
+Integral.prototype.constructor = Integral;
+
+Integral.prototype.initPosition = function() {
+ this.sprite.position.x = Settings.STAGE_WIDTH + this.sprite.width;
+ this.sprite.position.y = Settings.STAGE_HEIGHT + this.sprite.height;
+ this.sprite.anchor.x = 0;
+ this.sprite.anchor.y = 0.5;
+}
+
+Integral.prototype.update = function() {
+ this.sprite.position.x += this.speed;
+} \ No newline at end of file
diff --git a/src/platformer.js b/src/platformer.js
new file mode 100644
index 0000000..3d19130
--- /dev/null
+++ b/src/platformer.js
@@ -0,0 +1,9 @@
+document.body.appendChild(Engine.instance.renderer.view);
+
+requestAnimationFrame(animate);
+
+function animate() {
+ requestAnimationFrame(animate);
+
+ Engine.instance.update();
+} \ No newline at end of file
diff --git a/src/player.js b/src/player.js
new file mode 100644
index 0000000..64f00f8
--- /dev/null
+++ b/src/player.js
@@ -0,0 +1,67 @@
+function Player(texture) {
+ GameObject.call(this, texture);
+ this.active = false;
+ this.acceleration = 18;
+ this.boost_velocity = -70;
+ this.velocity = 0.0;
+ this.terminal_velocity = 60;
+
+ this.score = 0;
+
+ this.initPosition();
+
+ // bind space bar to boost up
+ //k_space.press = this.boost.bind(this);
+}
+
+Player.prototype = Object.create(GameObject.prototype);
+Player.prototype.constructor = Player;
+
+Player.prototype.initPosition = function() {
+ GameObject.prototype.initPosition.call(this);
+
+ this.sprite.position.x = Settings.STAGE_WIDTH * 0.1;
+ this.sprite.position.y = Settings.STAGE_HEIGHT * 0.6;
+ this.sprite.rotation = 0;
+}
+
+Player.prototype.updatePhysics = function() {
+ // update velocity
+ this.velocity += 0.01 * this.acceleration * dt;
+ if (this.velocity >= this.terminal_velocity) {
+ this.velocity = this.terminal_velocity;
+ }
+
+ // update position
+ this.sprite.position.y += 0.01 * this.velocity * dt;
+
+ // limit going upwards
+ this.sprite.position.y = Math.max(0, this.sprite.position.y);
+}
+
+Player.prototype.updateControls = function() {
+ // TODO
+}
+
+Player.prototype.boost = function() {
+ this.velocity = this.boost_velocity;
+ engine.sound.play("jump");
+}
+
+Player.prototype.outOfScreen = function() {
+ return this.sprite.position.y > Settings.STAGE_HEIGHT;
+}
+
+Player.prototype.update = function() {
+ GameObject.prototype.update.call(this);
+
+ this.sprite.rotation += 0.1;
+
+ if (this.active) {
+ this.score += 1;
+ this.updatePhysics();
+ this.updateControls();
+ }
+}
+
+var player = new Player("player"); \ No newline at end of file
diff --git a/src/settings.js b/src/settings.js
new file mode 100644
index 0000000..b515171
--- /dev/null
+++ b/src/settings.js
@@ -0,0 +1,15 @@
+var Settings = function() {}
+Settings.STAGE_WIDTH = 800;
+Settings.STAGE_HEIGHT = 600;
+Settings.STAGE_BGCOLOR = 0xA0A0A0;
+
+var lastTime = Date.now();
+var dt = 0.0;
+
+function updateDeltaTime() {
+ var last = lastTime;
+ var current = Date.now();
+
+ lastTime = current;
+ dt = current - last;
+} \ No newline at end of file
diff --git a/src/sound.js b/src/sound.js
new file mode 100644
index 0000000..51f4330
--- /dev/null
+++ b/src/sound.js
@@ -0,0 +1,20 @@
+var Sound = function() {
+ // start music
+ this.bgMusic = new Howl({
+ urls: ['res/bg.mp3'],
+ autoplay: true,
+ loop: true,
+ volume: 1,
+ buffer: true
+ });
+
+ this.sounds = {jump: new Howl({ urls: ['res/jump.wav'], buffer: true }),
+ start: new Howl({ urls: ['res/start.wav'], buffer: true }),
+ explosion: new Howl({ urls: ['res/explosion.wav'], buffer: true })};
+
+ this.play = function(effect) {
+ this.sounds[effect].play()
+ }
+
+ return this;
+} \ No newline at end of file