mirror of
https://github.com/ysoftdevs/pf2016.git
synced 2026-01-11 14:30:51 +01:00
persist game state
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 18 KiB |
371
index.html
371
index.html
@@ -9,388 +9,29 @@
|
||||
<link rel="stylesheet" href="css/pf2016.css" type="text/css" />
|
||||
|
||||
<script src="js/kiwi-js-v1.4.0/kiwi.js"></script>
|
||||
<script src="js/save-manager-1.0.2/save-manager.js"></script>
|
||||
<script src="js/app/level-tools.js"></script>
|
||||
<script src="js/app/level-selector.js"></script>
|
||||
<script src="js/app/game-state.js"></script>
|
||||
<script src="js/app/levels-01-12.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var state = new Kiwi.State('state');
|
||||
|
||||
var levels = [
|
||||
level1, level2, level3, level4, level5, level6, level7, level8, level9,
|
||||
level10, level11, level12];
|
||||
|
||||
state.preload = function() {
|
||||
this.addJSON('level1', 'data/levels/level-01.json');
|
||||
this.addJSON('level2', 'data/levels/level-02.json');
|
||||
this.addJSON('level3', 'data/levels/level-03.json');
|
||||
this.addJSON('level4', 'data/levels/level-04.json');
|
||||
this.addJSON('level5', 'data/levels/level-05.json');
|
||||
this.addJSON('level6', 'data/levels/level-06.json');
|
||||
this.addJSON('level7', 'data/levels/level-07.json');
|
||||
this.addJSON('level8', 'data/levels/level-08.json');
|
||||
this.addJSON('level9', 'data/levels/level-09.json');
|
||||
this.addJSON('level10', 'data/levels/level-10.json');
|
||||
this.addJSON('level11', 'data/levels/level-11.json');
|
||||
this.addJSON('level12', 'data/levels/level-12.json');
|
||||
this.addSpriteSheet('base', './data/images/gfx64/tiles.png', 64, 64);
|
||||
this.addSpriteSheet('character', './data/images/gfx64/marble_black.png', 80, 80 );
|
||||
this.addSpriteSheet('oneWay', './data/images/gfx64/st_oneway.png', 64, 64 );
|
||||
this.addSpriteSheet('finishMarker', './data/images/gfx64/finish_marker.png', 64, 64 );
|
||||
this.addSpriteSheet('button', './data/images/gfx64/button.png', 128, 64 );
|
||||
this.addSpriteSheet('teleport', './data/images/gfx64/st_spitter_idle.png', 64, 64);
|
||||
this.addSpriteSheet('box', './data/images/gfx64/st_box_wood.png', 64, 64);
|
||||
this.addSpriteSheet('switch', './data/images/gfx64/st_switch.png', 64, 64);
|
||||
this.addSpriteSheet('laserBeam', './data/images/gfx64/it_laser.png', 64, 64);
|
||||
this.addSpriteSheet('laser', './data/images/gfx64/st_laser.png', 64, 64);
|
||||
}
|
||||
|
||||
state.velocityX = 64;
|
||||
state.velocityY = 64;
|
||||
|
||||
state.create = function() {
|
||||
var level = levels[this.game.levelIndex - 1];
|
||||
this.tilemap = new Kiwi.GameObjects.Tilemap.TileMap(this, 'level' + this.game.levelIndex.toString(), this.textures.base);
|
||||
|
||||
this.character = new Kiwi.GameObjects.Sprite(this, this.textures.character, 0, 0);
|
||||
this.character.initialX = 2*64;
|
||||
this.character.initialY = 64;
|
||||
this.character.initialVelocityX = 0;
|
||||
this.character.initialVelocityY = this.velocityY;
|
||||
// Hitbox is detecting collision in future step.
|
||||
// This is little bit counter intuitive.
|
||||
// You have to make collision box smaller at least one step.
|
||||
this.character.box.hitbox = new Kiwi.Geom.Rectangle( 12, 12, 58, 58 );
|
||||
this.character.physics = this.character.components.add( new Kiwi.Components.ArcadePhysics( this.character, this.character.box ) );
|
||||
|
||||
this.character.animation.add('walking', [ 0, 1 ], 0.2, true);
|
||||
this.character.animation.add('idle', [ 2, 3, 4, 5, 6, 5, 4, 3 ], 0.2, true);
|
||||
this.character.animation.add('failed', [ 11, 10, 9, 8, 7, 8, 9, 10], 0.2, true);
|
||||
|
||||
this.redirectorGroup = new Kiwi.Group( this );
|
||||
|
||||
this.finishMarker = new Kiwi.GameObjects.Sprite(this, this.textures.finishMarker, 6*64, 4*64);
|
||||
this.finishMarker.animation.add('idle', [ 0, 1, 2, 3, 2, 1 ], 0.3, true);
|
||||
this.finishMarker.animation.play('idle', true);
|
||||
|
||||
// Ground layer
|
||||
this.addChild(this.tilemap.layers[0]);
|
||||
|
||||
// Load level specific data
|
||||
level.create(this);
|
||||
|
||||
// Fix character coordinates and speed
|
||||
this.resetCharacter();
|
||||
|
||||
this.addChild(this.finishMarker);
|
||||
|
||||
// Walls layer
|
||||
this.addChild(this.tilemap.layers[1]);
|
||||
|
||||
// Add action objects
|
||||
this.addChild(this.redirectorGroup);
|
||||
|
||||
this.addChild(this.character);
|
||||
|
||||
// Sky layer
|
||||
this.addChild(this.tilemap.layers[2]);
|
||||
|
||||
// Create collision layer
|
||||
for(var i = 21; i < this.tilemap.tileTypes.length; i++) {
|
||||
this.tilemap.tileTypes[i].allowCollisions = Kiwi.Components.ArcadePhysics.ANY;
|
||||
}
|
||||
|
||||
this.keyboard = this.game.input.keyboard;
|
||||
|
||||
this.leftKey = this.keyboard.addKey(Kiwi.Input.Keycodes.LEFT, true);
|
||||
this.rightKey = this.keyboard.addKey(Kiwi.Input.Keycodes.RIGHT, true);
|
||||
//Prevent the down key from scrolling the page
|
||||
this.keyboard.addKey(Kiwi.Input.Keycodes.DOWN, true);
|
||||
|
||||
this.stageState = 'init';
|
||||
|
||||
this.myButton = new Kiwi.GameObjects.Textfield( this, "Start", 6*64+16, 60, "#000", 32, 'normal', 'Impact' );
|
||||
this.myButtonSprite = new Kiwi.GameObjects.Sprite(this, this.textures.button, 6*64, 50);
|
||||
this.myButtonSprite.input.onUp.add( this.buttonReleased, this );
|
||||
|
||||
this.character.input.onUp.add( this.buttonReleased, this );
|
||||
}
|
||||
|
||||
state.buttonReleased = function(sprite) {
|
||||
if (this.stageState == 'init') {
|
||||
this.myButton.text = '...';
|
||||
this.activateScene();
|
||||
} else if (this.stageState == 'stop') {
|
||||
this.resetStage();
|
||||
this.myButton.text = 'Start'
|
||||
this.stageState = 'init';
|
||||
} else if (this.stageState == 'complete') {
|
||||
game.states.switchState('levelSelector');
|
||||
}
|
||||
}
|
||||
|
||||
state.resetCharacter = function () {
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
this.character.x = this.character.initialX - 8;
|
||||
this.character.y = this.character.initialY - 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all objects that should be back in the original position.
|
||||
* Dragable redirectors are left on original place.
|
||||
*/
|
||||
state.resetStage = function() {
|
||||
this.resetCharacter();
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
var redirector = redirectors[i];
|
||||
if (redirector.type == 'box') {
|
||||
redirector.x = redirector.initialX;
|
||||
redirector.y = redirector.initialY;
|
||||
} else if (redirector.type == 'switch') {
|
||||
redirector.cellIndex = redirector.initialCellIndex;
|
||||
} else if (redirector.type == 'laserBeam') {
|
||||
redirector.visible = redirector.initialVisible;
|
||||
} else if (redirector.type == 'laser') {
|
||||
redirector.animation.play(redirector.initialAnimation, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.startedDrag = function(sprite) {
|
||||
sprite.formerX = sprite.x;
|
||||
sprite.formerY = sprite.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse effect of drag operaion. Set original coordinates.
|
||||
*/
|
||||
state.resetDrag = function(sprite) {
|
||||
sprite.x = sprite.formerX;
|
||||
sprite.y = sprite.formerY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tile index from specified coordinates.
|
||||
*/
|
||||
state.getTileIndex = function(x, y) {
|
||||
var tile = this.tilemap.layers[0].getTileFromXY(x / 64 , y / 64);
|
||||
if (tile == null) {
|
||||
return 0;
|
||||
}
|
||||
return tile.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform adjustments of coordinates for drop operation.
|
||||
* Make sure that object is dropped on valid place and check
|
||||
* collision with other objects. In case of failure revert
|
||||
* to former coordinates.
|
||||
*/
|
||||
state.stoppedDrag = function(sprite) {
|
||||
if (sprite.x % 64 > 32) {
|
||||
sprite.x += 64;
|
||||
}
|
||||
if (sprite.y % 64 > 32) {
|
||||
sprite.y += 64;
|
||||
}
|
||||
sprite.x = sprite.x - sprite.x % 64;
|
||||
sprite.y = sprite.y - sprite.y % 64;
|
||||
|
||||
// Make sure that we drop tile only on valid ground
|
||||
if (this.getTileIndex(sprite.x, sprite.y) == 0) {
|
||||
this.resetDrag(sprite);
|
||||
} else {
|
||||
// Make sure that we are not dropping on another redirector object
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
var redirector = redirectors[i];
|
||||
|
||||
// Skip comparision of self
|
||||
if (sprite === redirector) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((sprite.x == redirector.x) && (sprite.y == redirector.y)) {
|
||||
this.resetDrag(sprite);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.activateScene = function () {
|
||||
this.character.physics.velocity.x = this.character.initialVelocityX;
|
||||
this.character.physics.velocity.y = this.character.initialVelocityY;
|
||||
this.stageState = 'running';
|
||||
}
|
||||
|
||||
state.update = function () {
|
||||
//Update all the gameobjects
|
||||
Kiwi.State.prototype.update.call(this);
|
||||
|
||||
//Update physics
|
||||
this.checkCollision();
|
||||
|
||||
this.updateCharacterAnimation();
|
||||
}
|
||||
|
||||
state.updateCharacterAnimation = function () {
|
||||
|
||||
if(( this.character.physics.velocity.y != 0 ) || (this.character.physics.velocity.x != 0)) {
|
||||
this.character.animation.play('walking', false);
|
||||
} else {
|
||||
if (this.stageState == 'stop') {
|
||||
this.character.animation.play('failed', false);
|
||||
} else {
|
||||
this.character.animation.play('idle', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.turnOff = function(items) {
|
||||
for (var i=0; i!=items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.type == 'laserBeam') {
|
||||
item.visible = false;
|
||||
} else if (item.type == 'switch') {
|
||||
item.cellIndex = 2;
|
||||
} else {
|
||||
item.animation.play('idle');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.turnOn = function(items) {
|
||||
for (var i=0; i!=items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.type == 'laserBeam') {
|
||||
item.visible = true;
|
||||
} else if (item.type == 'switch') {
|
||||
item.cellIndex = 0;
|
||||
} else {
|
||||
item.animation.play('burning');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create effect based on type of redirector.
|
||||
*/
|
||||
state.applyRedirectorMechanics = function(tileX, tileY, redirector) {
|
||||
var isRecalculationRequired = false;
|
||||
var redirectorTileX = Math.round(redirector.x/64);
|
||||
var redirectorTileY = Math.round(redirector.y/64);
|
||||
|
||||
// Box has hit regions around. Compute based on vector of player
|
||||
if (redirector.type == 'box') {
|
||||
tileX+=this.character.physics.velocity.x/64;
|
||||
tileY+=this.character.physics.velocity.y/64;
|
||||
}
|
||||
|
||||
// Check for hit
|
||||
if ((tileX != redirectorTileX ) || (tileY != redirectorTileY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (redirector.type == 'vector') {
|
||||
this.character.physics.velocity.x = redirector.affectVelocityX;
|
||||
this.character.physics.velocity.y = redirector.affectVelocityY;
|
||||
} else if (redirector.type == 'teleport') {
|
||||
this.character.x = redirector.affectedX - 8;
|
||||
this.character.y = redirector.affectedY - 8;
|
||||
} else if (redirector.type == 'box') {
|
||||
// Move tile when it is possible
|
||||
if (this.getTileIndex(redirector.x + this.character.physics.velocity.x, redirector.y + this.character.physics.velocity.y) != 0) {
|
||||
redirector.x += this.character.physics.velocity.x;
|
||||
redirector.y += this.character.physics.velocity.y;
|
||||
}
|
||||
// Bounce
|
||||
this.character.physics.velocity.x = -this.character.physics.velocity.x;
|
||||
this.character.physics.velocity.y = -this.character.physics.velocity.y;
|
||||
|
||||
// Bounce from box should relaunch direction calculation
|
||||
// This is for the case when box lies close to redirector
|
||||
isRecalculationRequired = true;
|
||||
} else if (redirector.type == 'switch') {
|
||||
// Flip the switch
|
||||
if (redirector.cellIndex == 0) {
|
||||
redirector.cellIndex = 2;
|
||||
this.turnOff(redirector.linkedItems);
|
||||
} else {
|
||||
redirector.cellIndex = 0;
|
||||
this.turnOn(redirector.linkedItems);
|
||||
}
|
||||
} else if (redirector.type == 'laserBeam') {
|
||||
if (redirector.visible) {
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Correction of coordinates
|
||||
this.character.y = Math.round(this.character.y);
|
||||
this.character.x = Math.round(this.character.x);
|
||||
return isRecalculationRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve collisions between the character and the first layer.
|
||||
*/
|
||||
state.checkCollision = function () {
|
||||
this.tilemap.layers[1].physics.overlapsTiles( this.character, true );
|
||||
|
||||
if ((this.character.physics.velocity.x == 0) && (this.character.physics.velocity.y == 0)) {
|
||||
if (this.stageState == 'running') {
|
||||
this.stageState = 'stop';
|
||||
this.myButton.text = 'Restart'
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Make collision detection only when ball is fully on the same tile
|
||||
var positionX = Math.round(this.character.x) + 8;
|
||||
var positionY = Math.round(this.character.y) + 8;
|
||||
if ((Math.round(positionX) % 64 != 0) || (Math.round(positionY)% 64 != 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isRecalculationRequired = false;
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
if (this.applyRedirectorMechanics(Math.round(positionX/64), Math.round(positionY/64), redirectors[i])) {
|
||||
isRecalculationRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the second round of calculation in case of hit of box
|
||||
if (isRecalculationRequired) {
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
this.applyRedirectorMechanics(Math.round(positionX/64), Math.round(positionY/64), redirectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (((Math.round(positionX/64) == Math.round(this.finishMarker.x/64) )) && (Math.round(positionY/64) == Math.round(this.finishMarker.y/64))) {
|
||||
this.stageState = 'complete';
|
||||
this.myButton.text = 'Next->'
|
||||
this.addChild( this.myButtonSprite );
|
||||
this.addChild( this.myButton );
|
||||
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var gameOptions = {
|
||||
width: 840,
|
||||
height: 600
|
||||
height: 600,
|
||||
plugins: ["SaveGame"]
|
||||
};
|
||||
var game = new Kiwi.Game(null, 'PF 2016', levelSelectorState, gameOptions);
|
||||
game.stage.color = "121d35";
|
||||
game.levelIndex = 0;
|
||||
game.levelStatus = 'none';
|
||||
game.states.addState(state);
|
||||
|
||||
</script>
|
||||
|
||||
366
js/app/game-state.js
Normal file
366
js/app/game-state.js
Normal file
@@ -0,0 +1,366 @@
|
||||
var state = new Kiwi.State('state');
|
||||
|
||||
|
||||
state.preload = function() {
|
||||
this.addJSON('level1', 'data/levels/level-01.json');
|
||||
this.addJSON('level2', 'data/levels/level-02.json');
|
||||
this.addJSON('level3', 'data/levels/level-03.json');
|
||||
this.addJSON('level4', 'data/levels/level-04.json');
|
||||
this.addJSON('level5', 'data/levels/level-05.json');
|
||||
this.addJSON('level6', 'data/levels/level-06.json');
|
||||
this.addJSON('level7', 'data/levels/level-07.json');
|
||||
this.addJSON('level8', 'data/levels/level-08.json');
|
||||
this.addJSON('level9', 'data/levels/level-09.json');
|
||||
this.addJSON('level10', 'data/levels/level-10.json');
|
||||
this.addJSON('level11', 'data/levels/level-11.json');
|
||||
this.addJSON('level12', 'data/levels/level-12.json');
|
||||
this.addSpriteSheet('base', './data/images/gfx64/tiles.png', 64, 64);
|
||||
this.addSpriteSheet('character', './data/images/gfx64/marble_black.png', 80, 80 );
|
||||
this.addSpriteSheet('oneWay', './data/images/gfx64/st_oneway.png', 64, 64 );
|
||||
this.addSpriteSheet('finishMarker', './data/images/gfx64/finish_marker.png', 64, 64 );
|
||||
this.addSpriteSheet('button', './data/images/gfx64/button.png', 128, 64 );
|
||||
this.addSpriteSheet('teleport', './data/images/gfx64/st_spitter_idle.png', 64, 64);
|
||||
this.addSpriteSheet('box', './data/images/gfx64/st_box_wood.png', 64, 64);
|
||||
this.addSpriteSheet('switch', './data/images/gfx64/st_switch.png', 64, 64);
|
||||
this.addSpriteSheet('laserBeam', './data/images/gfx64/it_laser.png', 64, 64);
|
||||
this.addSpriteSheet('laser', './data/images/gfx64/st_laser.png', 64, 64);
|
||||
}
|
||||
|
||||
state.velocityX = 64;
|
||||
state.velocityY = 64;
|
||||
|
||||
state.create = function() {
|
||||
var level = levels[this.game.levelIndex - 1];
|
||||
this.tilemap = new Kiwi.GameObjects.Tilemap.TileMap(this, 'level' + this.game.levelIndex.toString(), this.textures.base);
|
||||
|
||||
this.character = new Kiwi.GameObjects.Sprite(this, this.textures.character, 0, 0);
|
||||
this.character.initialX = 2*64;
|
||||
this.character.initialY = 64;
|
||||
this.character.initialVelocityX = 0;
|
||||
this.character.initialVelocityY = this.velocityY;
|
||||
// Hitbox is detecting collision in future step.
|
||||
// This is little bit counter intuitive.
|
||||
// You have to make collision box smaller at least one step.
|
||||
this.character.box.hitbox = new Kiwi.Geom.Rectangle( 12, 12, 58, 58 );
|
||||
this.character.physics = this.character.components.add( new Kiwi.Components.ArcadePhysics( this.character, this.character.box ) );
|
||||
|
||||
this.character.animation.add('walking', [ 0, 1 ], 0.2, true);
|
||||
this.character.animation.add('idle', [ 2, 3, 4, 5, 6, 5, 4, 3 ], 0.2, true);
|
||||
this.character.animation.add('failed', [ 11, 10, 9, 8, 7, 8, 9, 10], 0.2, true);
|
||||
|
||||
this.redirectorGroup = new Kiwi.Group( this );
|
||||
|
||||
this.finishMarker = new Kiwi.GameObjects.Sprite(this, this.textures.finishMarker, 6*64, 4*64);
|
||||
this.finishMarker.animation.add('idle', [ 0, 1, 2, 3, 2, 1 ], 0.3, true);
|
||||
this.finishMarker.animation.play('idle', true);
|
||||
|
||||
// Ground layer
|
||||
this.addChild(this.tilemap.layers[0]);
|
||||
|
||||
// Load level specific data
|
||||
level.create(this);
|
||||
|
||||
// Fix character coordinates and speed
|
||||
this.resetCharacter();
|
||||
|
||||
this.addChild(this.finishMarker);
|
||||
|
||||
// Walls layer
|
||||
this.addChild(this.tilemap.layers[1]);
|
||||
|
||||
// Add action objects
|
||||
this.addChild(this.redirectorGroup);
|
||||
|
||||
this.addChild(this.character);
|
||||
|
||||
// Sky layer
|
||||
this.addChild(this.tilemap.layers[2]);
|
||||
|
||||
// Create collision layer
|
||||
for(var i = 21; i < this.tilemap.tileTypes.length; i++) {
|
||||
this.tilemap.tileTypes[i].allowCollisions = Kiwi.Components.ArcadePhysics.ANY;
|
||||
}
|
||||
|
||||
this.keyboard = this.game.input.keyboard;
|
||||
|
||||
this.leftKey = this.keyboard.addKey(Kiwi.Input.Keycodes.LEFT, true);
|
||||
this.rightKey = this.keyboard.addKey(Kiwi.Input.Keycodes.RIGHT, true);
|
||||
//Prevent the down key from scrolling the page
|
||||
this.keyboard.addKey(Kiwi.Input.Keycodes.DOWN, true);
|
||||
|
||||
this.stageState = 'init';
|
||||
|
||||
this.myButton = new Kiwi.GameObjects.Textfield( this, "Start", 6*64+16, 60, "#000", 32, 'normal', 'Impact' );
|
||||
this.myButtonSprite = new Kiwi.GameObjects.Sprite(this, this.textures.button, 6*64, 50);
|
||||
this.myButtonSprite.input.onUp.add( this.buttonReleased, this );
|
||||
|
||||
this.character.input.onUp.add( this.buttonReleased, this );
|
||||
}
|
||||
|
||||
state.buttonReleased = function(sprite) {
|
||||
if (this.stageState == 'init') {
|
||||
this.myButton.text = '...';
|
||||
this.activateScene();
|
||||
} else if (this.stageState == 'stop') {
|
||||
this.resetStage();
|
||||
this.myButton.text = 'Start'
|
||||
this.stageState = 'init';
|
||||
} else if (this.stageState == 'complete') {
|
||||
game.levelStatus = 'complete';
|
||||
game.states.switchState('levelSelector');
|
||||
}
|
||||
}
|
||||
|
||||
state.resetCharacter = function () {
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
this.character.x = this.character.initialX - 8;
|
||||
this.character.y = this.character.initialY - 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all objects that should be back in the original position.
|
||||
* Dragable redirectors are left on original place.
|
||||
*/
|
||||
state.resetStage = function() {
|
||||
this.resetCharacter();
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
var redirector = redirectors[i];
|
||||
if (redirector.type == 'box') {
|
||||
redirector.x = redirector.initialX;
|
||||
redirector.y = redirector.initialY;
|
||||
} else if (redirector.type == 'switch') {
|
||||
redirector.cellIndex = redirector.initialCellIndex;
|
||||
} else if (redirector.type == 'laserBeam') {
|
||||
redirector.visible = redirector.initialVisible;
|
||||
} else if (redirector.type == 'laser') {
|
||||
redirector.animation.play(redirector.initialAnimation, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.startedDrag = function(sprite) {
|
||||
sprite.formerX = sprite.x;
|
||||
sprite.formerY = sprite.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse effect of drag operaion. Set original coordinates.
|
||||
*/
|
||||
state.resetDrag = function(sprite) {
|
||||
sprite.x = sprite.formerX;
|
||||
sprite.y = sprite.formerY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tile index from specified coordinates.
|
||||
*/
|
||||
state.getTileIndex = function(x, y) {
|
||||
var tile = this.tilemap.layers[0].getTileFromXY(x / 64 , y / 64);
|
||||
if (tile == null) {
|
||||
return 0;
|
||||
}
|
||||
return tile.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform adjustments of coordinates for drop operation.
|
||||
* Make sure that object is dropped on valid place and check
|
||||
* collision with other objects. In case of failure revert
|
||||
* to former coordinates.
|
||||
*/
|
||||
state.stoppedDrag = function(sprite) {
|
||||
if (sprite.x % 64 > 32) {
|
||||
sprite.x += 64;
|
||||
}
|
||||
if (sprite.y % 64 > 32) {
|
||||
sprite.y += 64;
|
||||
}
|
||||
sprite.x = sprite.x - sprite.x % 64;
|
||||
sprite.y = sprite.y - sprite.y % 64;
|
||||
|
||||
// Make sure that we drop tile only on valid ground
|
||||
if (this.getTileIndex(sprite.x, sprite.y) == 0) {
|
||||
this.resetDrag(sprite);
|
||||
} else {
|
||||
// Make sure that we are not dropping on another redirector object
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
var redirector = redirectors[i];
|
||||
|
||||
// Skip comparision of self
|
||||
if (sprite === redirector) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((sprite.x == redirector.x) && (sprite.y == redirector.y)) {
|
||||
this.resetDrag(sprite);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.activateScene = function () {
|
||||
this.character.physics.velocity.x = this.character.initialVelocityX;
|
||||
this.character.physics.velocity.y = this.character.initialVelocityY;
|
||||
this.stageState = 'running';
|
||||
}
|
||||
|
||||
state.update = function () {
|
||||
//Update all the gameobjects
|
||||
Kiwi.State.prototype.update.call(this);
|
||||
|
||||
//Update physics
|
||||
this.checkCollision();
|
||||
|
||||
this.updateCharacterAnimation();
|
||||
}
|
||||
|
||||
state.updateCharacterAnimation = function () {
|
||||
|
||||
if(( this.character.physics.velocity.y != 0 ) || (this.character.physics.velocity.x != 0)) {
|
||||
this.character.animation.play('walking', false);
|
||||
} else {
|
||||
if (this.stageState == 'stop') {
|
||||
this.character.animation.play('failed', false);
|
||||
} else {
|
||||
this.character.animation.play('idle', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.turnOff = function(items) {
|
||||
for (var i=0; i!=items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.type == 'laserBeam') {
|
||||
item.visible = false;
|
||||
} else if (item.type == 'switch') {
|
||||
item.cellIndex = 2;
|
||||
} else {
|
||||
item.animation.play('idle');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.turnOn = function(items) {
|
||||
for (var i=0; i!=items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.type == 'laserBeam') {
|
||||
item.visible = true;
|
||||
} else if (item.type == 'switch') {
|
||||
item.cellIndex = 0;
|
||||
} else {
|
||||
item.animation.play('burning');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create effect based on type of redirector.
|
||||
*/
|
||||
state.applyRedirectorMechanics = function(tileX, tileY, redirector) {
|
||||
var isRecalculationRequired = false;
|
||||
var redirectorTileX = Math.round(redirector.x/64);
|
||||
var redirectorTileY = Math.round(redirector.y/64);
|
||||
|
||||
// Box has hit regions around. Compute based on vector of player
|
||||
if (redirector.type == 'box') {
|
||||
tileX+=this.character.physics.velocity.x/64;
|
||||
tileY+=this.character.physics.velocity.y/64;
|
||||
}
|
||||
|
||||
// Check for hit
|
||||
if ((tileX != redirectorTileX ) || (tileY != redirectorTileY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (redirector.type == 'vector') {
|
||||
this.character.physics.velocity.x = redirector.affectVelocityX;
|
||||
this.character.physics.velocity.y = redirector.affectVelocityY;
|
||||
} else if (redirector.type == 'teleport') {
|
||||
this.character.x = redirector.affectedX - 8;
|
||||
this.character.y = redirector.affectedY - 8;
|
||||
} else if (redirector.type == 'box') {
|
||||
// Move tile when it is possible
|
||||
if (this.getTileIndex(redirector.x + this.character.physics.velocity.x, redirector.y + this.character.physics.velocity.y) != 0) {
|
||||
redirector.x += this.character.physics.velocity.x;
|
||||
redirector.y += this.character.physics.velocity.y;
|
||||
}
|
||||
// Bounce
|
||||
this.character.physics.velocity.x = -this.character.physics.velocity.x;
|
||||
this.character.physics.velocity.y = -this.character.physics.velocity.y;
|
||||
|
||||
// Bounce from box should relaunch direction calculation
|
||||
// This is for the case when box lies close to redirector
|
||||
isRecalculationRequired = true;
|
||||
} else if (redirector.type == 'switch') {
|
||||
// Flip the switch
|
||||
if (redirector.cellIndex == 0) {
|
||||
redirector.cellIndex = 2;
|
||||
this.turnOff(redirector.linkedItems);
|
||||
} else {
|
||||
redirector.cellIndex = 0;
|
||||
this.turnOn(redirector.linkedItems);
|
||||
}
|
||||
} else if (redirector.type == 'laserBeam') {
|
||||
if (redirector.visible) {
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Correction of coordinates
|
||||
this.character.y = Math.round(this.character.y);
|
||||
this.character.x = Math.round(this.character.x);
|
||||
return isRecalculationRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve collisions between the character and the first layer.
|
||||
*/
|
||||
state.checkCollision = function () {
|
||||
this.tilemap.layers[1].physics.overlapsTiles( this.character, true );
|
||||
|
||||
if ((this.character.physics.velocity.x == 0) && (this.character.physics.velocity.y == 0)) {
|
||||
if (this.stageState == 'running') {
|
||||
this.stageState = 'stop';
|
||||
this.myButton.text = 'Restart'
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Make collision detection only when ball is fully on the same tile
|
||||
var positionX = Math.round(this.character.x) + 8;
|
||||
var positionY = Math.round(this.character.y) + 8;
|
||||
if ((Math.round(positionX) % 64 != 0) || (Math.round(positionY)% 64 != 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isRecalculationRequired = false;
|
||||
var redirectors = this.redirectorGroup.members;
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
if (this.applyRedirectorMechanics(Math.round(positionX/64), Math.round(positionY/64), redirectors[i])) {
|
||||
isRecalculationRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the second round of calculation in case of hit of box
|
||||
if (isRecalculationRequired) {
|
||||
for ( var i = 0; i < redirectors.length; i++ ) {
|
||||
this.applyRedirectorMechanics(Math.round(positionX/64), Math.round(positionY/64), redirectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (((Math.round(positionX/64) == Math.round(this.finishMarker.x/64) )) && (Math.round(positionY/64) == Math.round(this.finishMarker.y/64))) {
|
||||
this.stageState = 'complete';
|
||||
this.myButton.text = 'Next->'
|
||||
this.addChild( this.myButtonSprite );
|
||||
this.addChild( this.myButton );
|
||||
|
||||
this.character.physics.velocity.x = 0;
|
||||
this.character.physics.velocity.y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +1,55 @@
|
||||
var levelSelectorState = new Kiwi.State('levelSelector');
|
||||
|
||||
/**
|
||||
* Save status of locks.
|
||||
*/
|
||||
levelSelectorState.save = function() {
|
||||
this.game.saveManager.add('levelStatus', this.levelStatus);
|
||||
this.game.saveManager.save();
|
||||
}
|
||||
|
||||
levelSelectorState.preload = function() {
|
||||
this.addSpriteSheet('button', './data/images/gfx64/button.png', 128, 64 );
|
||||
|
||||
if (this.game.saveManager.exists('levelStatus')) {
|
||||
this.levelStatus = this.game.saveManager.getData('levelStatus');
|
||||
} else {
|
||||
this.levelStatus = ['unlocked', 'locked', 'locked', 'locked', 'locked', 'locked', 'locked', 'locked', 'locked',
|
||||
'locked', 'locked', 'locked'
|
||||
];
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
levelSelectorState.create = function() {
|
||||
var counterX = 0;
|
||||
var counterY = 0;
|
||||
|
||||
// Unlock next level when previous was completed
|
||||
if (game.levelStatus == 'complete') {
|
||||
if (game.levelIndex < 12) {
|
||||
this.levelStatus[game.levelIndex] = 'unlocked';
|
||||
game.levelStatus = 'none';
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
for (var i=1; i<levels.length+1; i++) {
|
||||
|
||||
var text = new Kiwi.GameObjects.Textfield( this, "Level " + i.toString(), 16+counterX*140, 60+counterY*80, "#000", 32, 'normal', 'Impact' );
|
||||
var sprite = new Kiwi.GameObjects.Sprite(this, this.textures.button, counterX*140, 50+counterY*80);
|
||||
var sprite = new Kiwi.GameObjects.Sprite(this, this.textures.button, 40+counterX*140, 50+counterY*80);
|
||||
sprite.levelIndex = i;
|
||||
sprite.input.onUp.add( this.buttonReleased, this );
|
||||
this.addChild( sprite );
|
||||
this.addChild( text );
|
||||
|
||||
if (this.levelStatus[i-1] == 'locked') {
|
||||
sprite.cellIndex = 1;
|
||||
} else {
|
||||
var text = new Kiwi.GameObjects.Textfield( this, i.toString(), 100+counterX*140, 60+counterY*80, "#1d5f0e", 32, 'normal', 'Impact' );
|
||||
this.addChild(text);
|
||||
sprite.input.onUp.add( this.buttonReleased, this );
|
||||
}
|
||||
|
||||
counterX++;
|
||||
if (counterX > 4) {
|
||||
if (counterX > 3) {
|
||||
counterX = 0;
|
||||
counterY++;
|
||||
}
|
||||
|
||||
1
js/save-manager-1.0.2/save-manager.js
Normal file
1
js/save-manager-1.0.2/save-manager.js
Normal file
@@ -0,0 +1 @@
|
||||
Kiwi.Plugins.SaveGame={name:"SaveGame",version:"1.0.2",minimumKiwiVersion:"1.0.0"};Kiwi.PluginManager.register(Kiwi.Plugins.SaveGame);Kiwi.Plugins.SaveGame.create=function(e){var t=new Kiwi.Plugins.SaveGame.SaveManager(e);e.saveManager=t;return e.saveManager};Kiwi.Plugins.SaveGame.SaveManager=function(e){this.game=e};Kiwi.Plugins.SaveGame.SaveManager.prototype.objType=function(){return"SaveManager"};Kiwi.Plugins.SaveGame.SaveManager.prototype.boot=function(){this.localStorage=new Kiwi.Plugins.SaveGame.LocalStorage(this.game);this.current=this.localStorage};Kiwi.Plugins.SaveGame.SaveManager.prototype.switchCurrent=function(e){if(typeof e==="undefined")return;switch(e){case Kiwi.Plugins.SaveGame.SaveManager.LOCAL_STORAGE:this.current=this.localStorage;break}};Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"add",{get:function(){return this.current.add.bind(this.current)},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"edit",{get:function(){return this.current.edit.bind(this.current)},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"remove",{get:function(){return this.current.remove.bind(this.current)},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"getData",{get:function(){return this.current.getData.bind(this.current)},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"save",{get:function(){return this.current.save.bind(this.current)},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.SaveManager.prototype,"exists",{get:function(){return this.current.exists.bind(this.current)},enumerable:true,configurable:true});Kiwi.Plugins.SaveGame.SaveManager.LOCAL_STORAGE=1;Kiwi.Plugins.SaveGame.LocalStorage=function(e){this.game=e;this._data={};this._supported=Kiwi.DEVICE.localStorage;if(this.supported)this._retrieveData()};Object.defineProperty(Kiwi.Plugins.SaveGame.LocalStorage.prototype,"data",{get:function(){return this._data},enumerable:true,configurable:true});Object.defineProperty(Kiwi.Plugins.SaveGame.LocalStorage.prototype,"supported",{get:function(){return this._supported},enumerable:true,configurable:true});Kiwi.Plugins.SaveGame.LocalStorage.prototype.objType=function(){return"LocalStorage"};Kiwi.Plugins.SaveGame.LocalStorage.prototype._retrieveData=function(){if(localStorage.getItem(this.game.stage.name)!==null){var e=localStorage.getItem(this.game.stage.name);this._data=JSON.parse(e)}else{this._create()}};Kiwi.Plugins.SaveGame.LocalStorage.prototype._create=function(){try{this._data={name:this.game.stage.name};localStorage.setItem(this.game.stage.name,JSON.stringify(this._data))}catch(e){console.log("Can not use localstorage due to memory limitations.");this._supported=false}};Kiwi.Plugins.SaveGame.LocalStorage.prototype.add=function(e,t,n){if(typeof n=="undefined")n=false;if(this.supported===true){this._data[e]=t;if(n===true){return this.save()}else{return true}}return false};Kiwi.Plugins.SaveGame.LocalStorage.prototype.edit=function(e,t,n){if(typeof n=="undefined")n=false;if(this.supported===true){if(this._data[e]!==null){this._data[e]=t;if(n===true){this.save()}else{return true}}}return false};Kiwi.Plugins.SaveGame.LocalStorage.prototype.getData=function(e){if(this.supported===true){if(typeof this._data[e]!=="undefined"){return this._data[e]}}return null};Kiwi.Plugins.SaveGame.LocalStorage.prototype.exists=function(e){return this._data[e]!==undefined};Kiwi.Plugins.SaveGame.LocalStorage.prototype.remove=function(e,t){if(typeof t=="undefined")t=false;if(this.supported===true){if(this._data[e]!==null){delete this._data[e];if(t===true){this.save()}else{return true}}}};Kiwi.Plugins.SaveGame.LocalStorage.prototype.clear=function(e){if(typeof e=="undefined")e=false;if(this.supported===true){this._data={};if(e===true)this.save()}};Kiwi.Plugins.SaveGame.LocalStorage.prototype.save=function(){try{localStorage.setItem([this.game.stage.name],JSON.stringify(this._data));return true}catch(e){console.log("Localstorage is full. Could not update.");return false}};Kiwi.Plugins.SaveGame.LocalStorage.prototype.load=function(){if(this.supported===true){this._data=JSON.parse(localStorage.getItem(this.game.stage.name));return true}return false}
|
||||
Reference in New Issue
Block a user