UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

393 lines (321 loc) 12.7 kB
/************************************************************************************/ /* */ /* a player entity */ /* */ /************************************************************************************/ game.PlayerEntity = me.Entity.extend({ init: function(x, y, settings) { // call the constructor this._super(me.Entity, 'init', [x, y , settings]); // player can exit the viewport (jumping, falling into a hole, etc.) this.alwaysUpdate = true; // walking & jumping speed this.body.setVelocity(3, 15); this.body.setFriction(0.4,0); this.dying = false; this.mutipleJump = 1; // set the display around our position me.game.viewport.follow(this, me.game.viewport.AXIS.HORIZONTAL); // enable keyboard me.input.bindKey(me.input.KEY.LEFT, "left"); me.input.bindKey(me.input.KEY.RIGHT, "right"); me.input.bindKey(me.input.KEY.X, "jump", true); me.input.bindKey(me.input.KEY.UP, "jump", true); me.input.bindKey(me.input.KEY.DOWN, "down"); me.input.bindKey(me.input.KEY.A, "left"); me.input.bindKey(me.input.KEY.D, "right"); me.input.bindKey(me.input.KEY.W, "jump", true); me.input.bindKey(me.input.KEY.S, "down"); // set a renderable this.renderable = game.texture.createAnimationFromName([ "walk0001.png", "walk0002.png", "walk0003.png", "walk0004.png", "walk0005.png", "walk0006.png", "walk0007.png", "walk0008.png", "walk0009.png", "walk0010.png", "walk0011.png" ]); // define a basic walking animatin this.renderable.addAnimation ("walk", ["walk0001.png", "walk0002.png", "walk0003.png"]); // set as default this.renderable.setCurrentAnimation("walk"); // set the renderable position to bottom center this.anchorPoint.set(0.5, 1.0); }, /* ----- update the player pos ------ */ update : function (dt) { if (me.input.isKeyPressed('left')) { this.body.vel.x -= this.body.accel.x * me.timer.tick; this.renderable.flipX(true); } else if (me.input.isKeyPressed('right')) { this.body.vel.x += this.body.accel.x * me.timer.tick; this.renderable.flipX(false); } if (me.input.isKeyPressed('jump')) { this.body.jumping = true; if (this.multipleJump <= 2) { // easy 'math' for double jump this.body.vel.y -= (this.body.maxVel.y * this.multipleJump++) * me.timer.tick; me.audio.play("jump", false); } } else if (!this.body.falling && !this.body.jumping) { // reset the multipleJump flag if on the ground this.multipleJump = 1; } else if (this.body.falling && this.multipleJump < 2) { // reset the multipleJump flag if falling this.multipleJump = 2; } // apply physics to the body (this moves the entity) this.body.update(dt); // check if we fell into a hole if (!this.inViewport && (this.pos.y > me.video.renderer.getHeight())) { // if yes reset the game me.game.world.removeChild(this); me.game.viewport.fadeIn('#fff', 150, function(){ me.audio.play("die", false); me.levelDirector.reloadLevel(); me.game.viewport.fadeOut('#fff', 150); }); return true; } // handle collisions against other shapes me.collision.check(this); // check if we moved (an "idle" animation would definitely be cleaner) if (this.body.vel.x!=0 || this.body.vel.y!=0 || (this.renderable&&this.renderable.isFlickering())) { this._super(me.Entity, 'update', [dt]); return true; } return false; }, /** * colision handler */ onCollision : function (response, other) { switch (other.body.collisionType) { case me.collision.types.WORLD_SHAPE: // Simulate a platform object if (other.type === "platform") { if (this.body.falling && !me.input.isKeyPressed('down') && // Shortest overlap would move the player upward (response.overlapV.y > 0) && // The velocity is reasonably fast enough to have penetrated to the overlap depth (~~this.body.vel.y >= ~~response.overlapV.y) ) { // Disable collision on the x axis response.overlapV.x = 0; // Repond to the platform (it is solid) return true; } // Do not respond to the platform (pass through) return false; } break; case me.collision.types.ENEMY_OBJECT: if (!other.isMovingEnemy) { // spike or any other fixed danger this.body.vel.y -= this.body.maxVel.y * me.timer.tick; this.hurt(); } else { // a regular moving enemy entity if ((response.overlapV.y > 0) && this.body.falling) { // jump this.body.vel.y -= this.body.maxVel.y * 1.5 * me.timer.tick; } else { this.hurt(); } // Not solid return false; } break; default: // Do not respond to other objects (e.g. coins) return false; } // Make the object solid return true; }, /** * ouch */ hurt : function () { if (!this.renderable.flickering) { this.renderable.flicker(750); // flash the screen me.game.viewport.fadeIn("#FFFFFF", 75); me.audio.play("die", false); } } }); /** * a coin (collectable) entiry */ game.CoinEntity = me.CollectableEntity.extend({ /** * constructor */ init: function (x, y, settings) { // call the super constructor this._super(me.CollectableEntity, 'init', [x, y , settings]); // add the coin sprite as renderable this.renderable = game.texture.createSpriteFromName("coin.png"); // set the renderable position to center this.anchorPoint.set(0.5, 0.5); }, /** * collision handling */ onCollision : function (response) { // do something when collide me.audio.play("cling", false); // give some score game.data.score += 250; //avoid further collision and delete it this.body.setCollisionMask(me.collision.types.NO_OBJECT); me.game.world.removeChild(this); return false; } }); /** * An enemy entity * follow a horizontal path defined by the box size in Tiled */ game.PathEnemyEntity = me.Entity.extend({ /** * constructor */ init: function (x, y, settings) { // save the area size defined in Tiled var width = settings.width || settings.framewidth; var height = settings.height || settings.frameheight; // adjust the setting size to the sprite one settings.width = settings.framewidth; settings.height = settings.frameheight; // call the super constructor this._super(me.Entity, 'init', [x, y , settings]); // set start/end position based on the initial area size x = this.pos.x; this.startX = x; this.endX = x + width - settings.framewidth this.pos.x = x + width - settings.framewidth; // update the entity bounds since we manually change the entity position this.updateBounds(); // apply gravity setting if specified this.body.gravity = settings.gravity || me.sys.gravity; this.walkLeft = false; // walking & jumping speed this.body.setVelocity(settings.velX || 1, settings.velY || 6); // set a "enemyObject" type this.collisionType = me.collision.types.ENEMY_OBJECT; // don't update the entities when out of the viewport this.alwaysUpdate = false; // a specific flag to recognize these enemies this.isMovingEnemy = true; }, /** * manage the enemy movement */ update : function (dt) { if (this.alive) { if (this.walkLeft && this.pos.x <= this.startX) { this.body.vel.x = this.body.accel.x * me.timer.tick; this.walkLeft = false; this.renderable.flipX(true); } else if (!this.walkLeft && this.pos.x >= this.endX) { this.body.vel.x = -this.body.accel.x * me.timer.tick; this.walkLeft = true; this.renderable.flipX(false); } // check & update movement this.body.update(dt); } // return true if we moved of if flickering return (this._super(me.Entity, 'update', [dt]) || this.body.vel.x != 0 || this.body.vel.y != 0); }, /** * collision handle */ onCollision : function (response) { // res.y >0 means touched by something on the bottom // which mean at top position for this one if (this.alive && (response.overlapV.y > 0) && response.a.body.falling) { // make it dead this.alive = false; //avoid further collision and delete it this.body.setCollisionMask(me.collision.types.NO_OBJECT); // set dead animation this.renderable.setCurrentAnimation("dead"); // make it flicker and call destroy once timer finished var self = this; this.renderable.flicker(750, function(){me.game.world.removeChild(self)}); // dead sfx me.audio.play("enemykill", false); // give some score game.data.score += 150; } return false; } }); /** * An Slime enemy entity * follow a horizontal path defined by the box size in Tiled */ game.SlimeEnemyEntity = game.PathEnemyEntity.extend({ /** * constructor */ init: function (x, y, settings) { // super constructor this._super(game.PathEnemyEntity, 'init', [x, y, settings]); // set a renderable this.renderable = game.texture.createAnimationFromName([ "slime_normal.png", "slime_walk.png", "slime_dead.png" ]); // custom animation speed ? if (settings.animationspeed) { this.renderable.animationspeed = settings.animationspeed; } // walking animatin this.renderable.addAnimation ("walk", ["slime_normal.png", "slime_walk.png"]); // dead animatin this.renderable.addAnimation ("dead", ["slime_dead.png"]); // set default one this.renderable.setCurrentAnimation("walk"); // set the renderable position to bottom center this.anchorPoint.set(0.5, 1.0); } }); /** * An Fly enemy entity * follow a horizontal path defined by the box size in Tiled */ game.FlyEnemyEntity = game.PathEnemyEntity.extend({ /** * constructor */ init: function (x, y, settings) { // super constructor this._super(game.PathEnemyEntity, 'init', [x, y, settings]); // set a renderable this.renderable = game.texture.createAnimationFromName([ "fly_normal.png", "fly_fly.png", "fly_dead.png" ]); // custom animation speed ? if (settings.animationspeed) { this.renderable.animationspeed = settings.animationspeed; } // walking animatin this.renderable.addAnimation ("walk", ["fly_normal.png", "fly_fly.png"]); // dead animatin this.renderable.addAnimation ("dead", ["fly_dead.png"]); // set default one this.renderable.setCurrentAnimation("walk"); // set the renderable position to bottom center this.anchorPoint.set(0.5, 1.0); } });