Commit b7820884 authored by Pablo R. Mier's avatar Pablo R. Mier

Initial commit, basic functionality implemented

parents
# Created by https://www.gitignore.io/api/intellij,linux
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
\ No newline at end of file
var invadersApp = {};
invadersApp.Boot = function (game) {
};
invadersApp.Boot.prototype = {
init: function () {
// Unless you specifically know your game needs to support multi-touch I would recommend setting this to 1
this.input.maxPointers = 1;
// Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here:
this.stage.disableVisibilityChange = true;
if (this.game.device.desktop)
{
// If you have any desktop specific settings, they can go in here
this.scale.pageAlignHorizontally = true;
}
else
{
// Same goes for mobile settings.
// In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768"
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.setMinMax(480, 260, 1024, 768);
this.scale.forceLandscape = true;
this.scale.pageAlignHorizontally = true;
}
// Pixelized!
this.game.antialias = false;
this.game.stage.smoothed = false;
},
preload: function () {
this.load.image('preloaderBackground', 'assets/background.png');
this.load.image('retroFont', 'assets/fonts/font3.png');
this.load.image('preloaderBar', 'assets/preload.png');
this.load.bitmapFont('minecraftia', 'assets/fonts/minecraftia.png', 'assets/fonts/minecraftia.xml');
},
create: function () {
// By this point the preloader assets have loaded to the cache, we've set the game settings
// So now let's start the real preloader going
this.state.start('Preloader');
}
};
// Game global config vars
var WALL_MARGIN = 80;
var DIR_CHANGE_MIN_TIME = 10;
var SHOOT_DELAY = 100;
var MIN_INVADERS = 4;
var INITIAL_INVADERS = 6;
var MIN_GENERATION_TIME = Phaser.Time.SECOND * 2;
// Extended sprite object for Invaders
Invader = function (ctx, genes, x, y) {
var game = ctx.game;
x = x || game.world.randomX;
y = y || game.world.randomY % (game.world.height - WALL_MARGIN * 1.5) ;
Phaser.Sprite.call(this, game, x, y, 'invader');
game.physics.enable(this, Phaser.Physics.ARCADE);
// Initialize genes by getting the default values from settings.json
this.genes = genes || function () {
var settings = ctx.settings;
var genes = {};
for(var gene in settings.genes){
genes[gene] = game.rnd.realInRange(settings.genes[gene].min, settings.genes[gene].max);
}
return genes;
}();
this.anchor.setTo(0.5, 0.5);
var alpha = Math.round(this.genes['alpha']);
this.tint = Phaser.Color.getColor(alpha, alpha, alpha);
this.body.velocity.x = this.genes['xvelocity'];
this.body.velocity.y = this.genes['yvelocity'];
this.scale.setTo(this.genes['scale'], this.genes['scale']);
this.body.collideWorldBounds = true;
this.body.bounce.set(1);
// Used to control the probability of x-y change in direction
this.lastTimeChanged = 0;
// Create a shield
var shield = this.game.make.graphics(0,0);
shield.lineStyle(1, 0x15AFF0, 1);
shield.drawCircle(-0.5, -0.5, 22);
//shield.anchor.setTo(0.5, 0.5);
this.addChild(shield);
shield.visible = false;
// Add the invader to the game (move this outside this class?)
game.add.existing(this);
};
Invader.prototype = Object.create(Phaser.Sprite.prototype);
Invader.prototype.constructor = Invader;
Invader.prototype.update = function() {
// Decide if it is time to change direction.
if (this.game.time.now > this.lastTimeChanged + DIR_CHANGE_MIN_TIME) {
this.lastTimeChanged = this.game.time.now;
if (this.game.rnd.frac() < this.genes['x_prob_change_dir']) {
this.body.velocity.x = -this.body.velocity.x;
}
if (this.game.rnd.frac() < this.genes['y_prob_change_dir']) {
this.body.velocity.y = -this.body.velocity.y;
}
}
};
Invader.prototype.showField = function (show, color) {
if (show == undefined) show = true;
if (color == undefined) color = 0x15AFF0;
this.getChildAt(0).tilt = color;
this.getChildAt(0).visible = show;
};
Invader.prototype.freeze = function (freeze) {
if (freeze == undefined) freeze = true;
if (freeze){
this.body.velocity.setTo(0, 0);
} else {
this.body.velocity.x = this.genes['xvelocity'];
this.body.velocity.y = this.genes['yvelocity'];
}
};
invadersApp.Game = function (game) {
// Auto-injected properties
this.game; // a reference to the currently running game (Phaser.Game)
this.add; // used to add sprites, text, groups, etc (Phaser.GameObjectFactory)
this.camera; // a reference to the game camera (Phaser.Camera)
this.cache; // the game cache (Phaser.Cache)
this.input; // the global input manager. You can access this.input.keyboard, this.input.mouse, as well from it. (Phaser.Input)
this.load; // for preloading assets (Phaser.Loader)
this.math; // lots of useful common math operations (Phaser.Math)
this.sound; // the sound manager - add a sound, play one, set-up markers, etc (Phaser.SoundManager)
this.stage; // the game stage (Phaser.Stage)
this.time; // the clock (Phaser.Time)
this.tweens; // the tween manager (Phaser.TweenManager)
this.state; // the state manager (Phaser.StateManager)
this.world; // the game world (Phaser.World)
this.particles; // the particle manager (Phaser.Particles)
this.physics; // the physics manager (Phaser.Physics)
this.rnd; // the repeatable random number generator (Phaser.RandomDataGenerator)
// Stores the reference to game elements
this.objects = {};
this.settings;
this.player;
this.bullets;
this.cursors;
this.fireButton;
this.lastShootAt = 0;
this.readyToFire = true;
this.currentGenerationTime = Phaser.Time.SECOND * 5;
};
invadersApp.Game.prototype = {
create: function () {
var that = this;
// Load game config
this.settings = this.game.cache.getJSON('settings');
// Initialize basic physics
this.game.physics.startSystem(Phaser.Physics.ARCADE);
// Group of invaders
this.objects.invaders = this.add.group();
this.objects.invaders.enableBody = true;
this.objects.invaders.physicsBodyType = Phaser.Physics.ARCADE;
// Initialize
this.objects.invaders = [];
for (var i = 0; i < INITIAL_INVADERS; i++) this.objects.invaders.push(new Invader(this));
this.player = this.add.sprite(this.game.width / 2, this.game.height - 30, 'nao');
this.player.anchor.setTo(0.5, 0.5);
this.game.physics.enable(this.player, Phaser.Physics.ARCADE);
this.player.body.collideWorldBounds = true;
//var player = new Player(this);
//this.game.add.existing(player);
// create a new bitmap data object
var wallBmp = this.game.add.bitmapData(this.game.width, 3);
// draw the wall
wallBmp.ctx.beginPath();
wallBmp.ctx.rect(0,0,this.game.width,3);
wallBmp.ctx.fillStyle = '#ffffff';
wallBmp.ctx.fill();
// use the bitmap data as the texture for the sprite
this.wall = this.add.sprite(0, this.game.height - WALL_MARGIN, wallBmp);
this.game.physics.enable(this.wall, Phaser.Physics.ARCADE);
this.wall.body.immovable = true;
this.cursors = this.game.input.keyboard.createCursorKeys();
this.fireButton = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
this.bullets = this.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
this.bullets.createMultiple(6, 'bullet');
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 1);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
var readyText = invadersApp.utils.addText(this, this.game.width / 2, this.game.height / 2, 'READY!', 5);
this.game.input.keyboard.onDownCallback = function () {
that.game.paused = false;
if (readyText.visible){
readyText.kill();
}
};
this.game.paused = true;
//this.pausePhysics();
},
update: function () {
// If physics are paused, skip all
if (this.game.physics.arcade.isPaused) return;
var that = this;
this.game.physics.arcade.overlap(this.bullets, this.objects.invaders, function (invader, bullet) {
bullet.kill();
var alive = that.objects.invaders.filter(function (invader) {
return invader.alive;
}).length;
if (alive > MIN_INVADERS){
invader.kill();
} else {
// Draw circle?
that.objects.invaders.forEach(function (invader) {
invader.showField(true);
});
}
}, null, this);
this.game.physics.arcade.collide(this.wall, this.objects.invaders);
this.player.body.velocity.setTo(0, 0);
if (this.cursors.left.isDown) {
if (this.player.scale.x > 0){
this.player.scale.x *= -1;
}
this.player.body.velocity.x = -250;
}
else if (this.cursors.right.isDown) {
if (this.player.scale.x < 0){
this.player.scale.x *= -1;
}
this.player.body.velocity.x = 250;
}
if (this.fireButton.isDown && this.readyToFire) {
this.readyToFire = false;
// Grab the first bullet we can from the pool
if (this.game.time.now > this.lastShootAt + SHOOT_DELAY) {
this.lastShootAt = this.game.time.now;
var bullet = this.bullets.getFirstExists(false);
if (bullet) {
// And fire it
var xpos;
if (this.player.scale.x < 0){
xpos = this.player.x - 21;
} else {
xpos = this.player.x + 21;
}
bullet.reset(xpos, this.player.y - 20);
bullet.body.velocity.y = -1200;
}
}
}
if (this.fireButton.isUp){
this.readyToFire = true;
}
},
quitGame: function (pointer) {
// TODO: Stop music, delete sprites, purge caches, free resources...
// Then let's go back to the main menu.
this.state.start('MainMenu');
},
pausePhysics: function (pause) {
if (pause == undefined) pause = true;
this.game.physics.arcade.isPaused = pause;
}
};
invadersApp.MainMenu = function (game) {
this.music = null;
this.playButton = null;
};
invadersApp.MainMenu.prototype = {
create: function () {
this.music = this.add.audio('titleMusic');
//this.music.play('', 0, 1, true, true);
var textTop = invadersApp.utils.addText(this, this.game.width / 2, 50, 'CITIUS PROUDLY PRESENTS:' , 2);
textTop.alpha = 0;
//var companyText = this.add.bitmapText(this.game.width / 2, 50, 'minecraftia', 'CiTIUS PROUDLY PRESENTS:', 16);
//companyText.anchor.x = 0.5;
/*
var presentsText = this.add.bitmapText(this.game.width / 2, companyText.y + 30, 'minecraftia', 'PROUDLY PRESENTS:', 16);
presentsText.anchor.x = 0.5;
*/
var titleYPos = this.game.height / 3;
var title = this.add.sprite(this.game.width / 2, -100, 'title');
title.anchor.setTo(0.5, 0.5);
/*
var copyright = this.add.sprite(this.game.width / 2, this.game.height - 30, 'copyright');
copyright.anchor.setTo(0.5, 0.5);*/
var logo = this.add.sprite(this.game.width / 2, this.game.height - 60, 'logo');
logo.anchor.setTo(0.5, 0.5);
logo.scale.setTo(0.6, 0.6);
logo.visible = false;
//var titleText = this.add.bitmapText(this.game.width / 2, 50, 'minecraftia', 'CiTIUS INVADERS', 50);
//titleText.anchor.x = 0.5;
var textPressStart = invadersApp.utils.addText(this, this.game.width / 2, titleYPos + 200, 'PRESS START', 2);
textPressStart.visible = false;
//var startEntry = this.addMenuEntry('START GAME', titleYPos + 160, this.startGame);
//this.addMenuEntry('CONFIGURE', startEntry.y + 40);
var textCopyright = invadersApp.utils.addText(this, this.game.width / 2, logo.y + 40, 'CENTRO SINGULAR DE INVESTIGACION EN TECNOLOXIAS DA INFORMACION', 1);
textCopyright.visible = false;
var tweenPresents = this.game.add.tween(textTop).to( { alpha: 1 }, 800, Phaser.Easing.Linear.None, false, 200);
var tweenTitle = this.game.add.tween(title).to( { y: this.game.height / 3 }, 1200, Phaser.Easing.Bounce.Out, false);
tweenPresents.chain(tweenTitle);
tweenPresents.onComplete.add(function () {
// Play music
this.music.play('', 0, 1, true, true);
}, this);
tweenTitle.onComplete.add(function () {
// Show bottom info
logo.visible = true;
textCopyright.visible = true;
textPressStart.visible = true;
// Start blinking event for 'PRESS START'
this.game.time.events.loop(Phaser.Timer.HALF, function () {
textPressStart.visible = !textPressStart.visible;
}, this);
//this.music.play('', 0, 1, true, true);
}, this);
// Start animated chain
tweenPresents.start();
this.game.input.keyboard.addKey(Phaser.Keyboard.ENTER).onDown.add(function () {
this.startGame();
}, this);
},
update: function () {
},
startGame: function (pointer) {
this.music.stop();
this.state.start('Game');
},
addMenuEntry: function(text, y, clickEvent) {
var entryText = invadersApp.utils.addText(this, this.game.width / 2, y, text, 3);
//var entryText = this.add.bitmapText(0, y, 'minecraftia', text, 27);
//entryText.anchor.x = 0.5;
//entryText.x = this.game.width / 2 - entryText.textWidth / 2;
//entryText.x = this.game.width / 2;
entryText.inputEnabled = true;
clickEvent = clickEvent || function () {};
entryText.events.onInputDown.add(clickEvent, this);
entryText.events.onInputOver.add(function (){
entryText.tint = 0xf345ff
}, this);
entryText.events.onInputOut.add(function () {
entryText.tint = 0xffffff
}, this);
return entryText;
}
};
invadersApp.Preloader = function (game) {
this.background = null;
this.preloadBar = null;
this.ready = false;
};
invadersApp.Preloader.prototype = {
preload: function () {
// These are the assets we loaded in Boot.js
// this.background = this.game.add.tileSprite(0, 0, this.game.width, this.game.height, 'preloaderBackground');
//var loadingText = this.add.bitmapText(this.game.width / 2, this.game.height / 2 - 60, 'minecraftia', 'Loading...');
var loadingText = invadersApp.utils.addText(this, this.game.width / 2, this.game.height / 2 - 60, 'Loading...', 3);
//loadingText.anchor.x = 0.5;
//loadingText.anchor.setTo(0.5, 0.5);
this.preloadBar = this.add.sprite(this.game.width / 2, loadingText.y + 40, 'preloaderBar');
this.preloadBar.anchor.setTo(0.5, 0.5);
//this.preloadBar.tint =
// This sets the preloadBar sprite as a loader sprite.
// What that does is automatically crop the sprite from 0 to full-width
// as the files below are loaded in.
this.load.setPreloadSprite(this.preloadBar);
// Here we load the rest of the assets our game needs.
// As this is just a Project Template I've not provided these assets, swap them for your own.
this.load.image('titlepage', 'assets/title.png');
//this.load.atlas('playButton', 'images/play_button.png', 'images/play_button.json');
this.load.audio('titleMusic', ['assets/audio/bodenstaendig_2000_in_rock_4bit.ogg']);
// + lots of other required assets here
this.load.image('nao', 'assets/nao.png');
this.load.image('invader', 'assets/invader.png');
this.load.image('bullet', 'assets/player_bullet.png');
this.load.image('title', 'assets/title-3.png');
this.load.image('logo', 'assets/citius-logo-8bit.png');
// Read game settings
this.load.json('settings', 'settings.json');
},
create: function () {
// Once the load has finished we disable the crop because we're going to sit in the update loop for a short while as the music decodes
this.preloadBar.cropEnabled = false;
},
update: function () {
if (this.cache.isSoundDecoded('titleMusic') && this.ready == false)
{
this.ready = true;
this.state.start('MainMenu');
}
}
};
This diff is collapsed.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8" />
<title>CiTIUS Invaders</title>
<script src="http://zeptojs.com/zepto.min.js"></script>
<script src="phaser.min.js"></script>
<script src="Boot.js"></script>
<script src="Preloader.js"></script>
<script src="js/Utils.js"></script>
<!--<script src="js/Player.js"></script>-->
<script src="MainMenu.js"></script>
<script src="Game.js"></script>
</head>
<body>
<div id="gameContainer"></div>
<script type="text/javascript">
window.onload = function() {
// Create your Phaser game and inject it into the gameContainer div.
// We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, - whatever floats your boat)
var game = new Phaser.Game(960, 540, Phaser.AUTO, 'gameContainer');
// Add the States your game has.
// You don't have to do this in the html, it could be done in your Boot state too, but for simplicity I'll keep it here.
game.state.add('Boot', invadersApp.Boot);
game.state.add('Preloader', invadersApp.Preloader);
game.state.add('MainMenu', invadersApp.MainMenu);
game.state.add('Game', invadersApp.Game);
// Now start the Boot state.
game.state.start('Boot');
};
</script>
</body>
</html>
\ No newline at end of file
/**
* Created by Pablo Rodríguez Mier
*/
var invadersApp = invadersApp || {};
invadersApp.evolution = {
evolve: function(individuals){
var recombinate = function(){
};
}
};
\ No newline at end of file
invadersApp = invadersApp || {};
invadersApp.Player = function (ctx) {
this.ctx = ctx;
this.game = ctx.game;
Phaser.Sprite.call(this, this.game, this.game.width / 2, this.game.height - 30, 'nao');
this.game.physics.enable(this, Phaser.Physics.ARCADE);
this.anchor.setTo(0.5, 0.5);
this.game.physics.enable(this, Phaser.Physics.ARCADE);
this.body.collideWorldBounds = true;
// Create a pool of bullets
this.bullets = this.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
this.bullets.createMultiple(6, 'bullet');
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 1);
this.bullets.setAll('outOfBoundsKill', true);