Files
2026-01-21 18:11:33 +08:00

313 lines
11 KiB
JavaScript

(function() {
/**
*
* Backbone Game Engine - An elementary HTML5 canvas game engine using Backbone.
*
* Copyright (c) 2014 Martin Drapeau
* https://github.com/martindrapeau/backbone-game-engine
*
*/
var sequenceDelay = 300,
animations;
// Mushroom is the base enemie class.
Backbone.Mushroom = Backbone.Character.extend({
defaults: _.extend(_.deepClone(Backbone.Character.prototype.defaults), {
name: "mushroom",
type: "character",
width: 32,
height: 64,
paddingTop: 32,
spriteSheet: "enemies",
state: "idle-left",
velocity: 0,
yVelocity: 0,
collision: true,
aiDelay: 0
}),
animations: _.extend(_.deepClone(Backbone.Character.prototype.animations), {
"squished-left": {
sequences: [2],
velocity: 0,
scaleX: 1,
scaleY: 1
},
"squished-right": {
sequences: [2],
velocity: 0,
scaleX: -1,
scaleY: 1
}
}),
ai: function(dt) {
var cur = this.getStateInfo();
if (cur.mov == "squished" && !this.get("collision")) this.cancelUpdate = true;
return this;
},
isAttacking: function(sprite, dir, dir2) {
if (this.cancelUpdate) return false;
var cur = this.getStateInfo();
return (cur.mov == "walk" || cur.mov == "idle");
},
squish: function(sprite) {
var self = this,
cur = this.getStateInfo();
this.set({
state: this.buildState("squished", cur.dir),
collision: false
});
this.world.setTimeout(function() {
if (self && self.world) self.world.remove(self);
}, 2000);
this.cancelUpdate = true;
return this;
},
hit: function(sprite, dir, dir2) {
if (this._handlingSpriteHit) return this;
this._handlingSpriteHit = sprite;
var cur = this.getStateInfo(),
opo = dir == "left" ? "right" : (dir == "right" ? "left" : (dir == "top" ? "bottom" : "top"));
if (sprite.get("hero")) {
if (dir == "top")
this.squish.apply(this, arguments);
} else if (sprite.get("state").indexOf("slide") != -1 ||
sprite.get("type") == "tile" && dir == "bottom" && sprite.get("state") == "bounce") {
this.knockout.apply(this, arguments);
}
sprite.trigger("hit", this, opo);
this._handlingSpriteHit = undefined;
return this;
}
});
Backbone.Turtle = Backbone.Mushroom.extend({
defaults: _.extend(_.deepClone(Backbone.Mushroom.prototype.defaults), {
name: "turtle"
}),
animations: _.deepClone(Backbone.Mushroom.prototype.animations),
isAttacking: function() {
var cur = this.getStateInfo();
return (cur.mov == "walk" || cur.mov == "idle");
},
slide: function(sprite, dir, dir2) {
if (this.wakeTimerId) {
this.world.clearTimeout(this.wakeTimerId);
this.wakeTimerId = null;
}
var dir = sprite.getCenterX(true) > this.getCenterX(true) ? "left" : "right";
this.set("state", this.buildState("walk", "slide", dir));
this.cancelUpdate = true;
return this;
},
squish: function(sprite, dir, dir2) {
var cur = this.getStateInfo();
if (cur.mov == "squished" || cur.mov == "wake")
return this.slide.apply(this, arguments);
if (this.wakeTimerId) {
this.world.clearTimeout(this.wakeTimerId);
this.wakeTimerId = null;
}
this.set("state", this.buildState("squished", cur.dir));
this.wakeTimerId = this.world.setTimeout(this.wake.bind(this), 5000);
this.cancelUpdate = true;
return this;
},
hit: function(sprite, dir, dir2) {
if (this._handlingSpriteHit) return this;
this._handlingSpriteHit = sprite;
var cur = this.getStateInfo(),
opo = dir == "left" ? "right" : (dir == "right" ? "left" : (dir == "top" ? "bottom" : "top"));
if (cur.mov2 == "slide") this.cancelUpdate = true;
if (dir == "top") {
this.squish.apply(this, arguments);
} else if (sprite.get("hero") && (cur.mov == "squished" || cur.mov == "wake")) {
this.slide.apply(this, arguments);
opo = "bottom";
} else if (sprite.get("state").indexOf("slide") != -1 ||
sprite.get("type") == "tile" && dir == "bottom" && sprite.get("state") == "bounce") {
this.knockout.apply(this, arguments);
}
sprite.trigger("hit", this, opo);
this._handlingSpriteHit = undefined;
return this;
},
wake: function() {
var cur = this.getStateInfo();
if (this.wakeTimerId) {
this.world.clearTimeout(this.wakeTimerId);
this.wakeTimerId = null;
}
if (cur.mov == "squished") {
this.set("state", this.buildState("wake", cur.dir));
this.wakeTimerId = this.world.setTimeout(this.wake.bind(this), 5000);
} else if (cur.mov == "wake") {
this.set("state", this.buildState("walk", cur.dir));
}
return this;
}
});
animations = Backbone.Turtle.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [6];
animations["walk-left"].sequences = animations["walk-right"].sequences = [6, 7];
animations["squished-left"].sequences = animations["squished-right"].sequences = [10];
_.extend(animations, {
"wake-left": {
sequences: [10, 11],
velocity: 0,
scaleX: 1,
scaleY: 1,
delay: sequenceDelay
},
"wake-right": {
sequences: [10, 11],
velocity: 0,
scaleX: -1,
scaleY: 1,
delay: sequenceDelay
},
"walk-slide-left": {
sequences: [10],
velocity: -300,
scaleX: 1,
scaleY: 1
},
"walk-slide-right": {
sequences: [10],
velocity: 300,
scaleX: -1,
scaleY: 1
},
"fall-slide-left": {
sequences: [10],
velocity: -300,
yVelocity: animations["fall-left"].yVelocity,
yAcceleration: animations["fall-left"].yAcceleration,
scaleX: 1,
scaleY: 1
},
"fall-slide-right": {
sequences: [10],
velocity: 300,
yVelocity: animations["fall-right"].yVelocity,
yAcceleration: animations["fall-right"].yAcceleration,
scaleX: -1,
scaleY: 1
}
});
Backbone.FlyingTurtle = Backbone.Turtle.extend({
defaults: _.extend(_.deepClone(Backbone.Turtle.prototype.defaults), {
name: "flying-turtle"
}),
animations: _.deepClone(Backbone.Turtle.prototype.animations),
fallbackSprite: Backbone.Turtle,
onUpdate: function(dt) {
var cur = this.getStateInfo(),
animation = this.getAnimation(),
attrs = {};
if (cur.mov2 == null && cur.mov == "walk" && this.world.get("state") == "play") {
attrs.state = this.buildState("fall", cur.dir);
attrs.yVelocity = -this.animations["fall-right"].yVelocity;
}
if (!_.isEmpty(attrs)) this.set(attrs);
return true;
},
squish: function(sprite) {
var cur = this.getStateInfo();
var newSprite = new this.fallbackSprite({
x: this.get("x"),
y: this.get("y"),
state: "walk-" + cur.dir
});
newSprite.set("id", this.world.buildIdFromName(newSprite.get("name")));
this.world.add(newSprite);
this.world.remove(this);
this.cancelUpdate = true;
}
});
animations = Backbone.FlyingTurtle.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [8];
animations["walk-left"].sequences = animations["walk-right"].sequences = [8, 9];
Backbone.RedTurtle = Backbone.Turtle.extend({
defaults: _.extend(_.deepClone(Backbone.Turtle.prototype.defaults), {
name: "red-turtle"
}),
animations: _.deepClone(Backbone.Turtle.prototype.animations)
});
animations = Backbone.RedTurtle.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [108];
animations["walk-left"].sequences = animations["walk-right"].sequences = [108, 109];
animations["squished-left"].sequences = animations["squished-right"].sequences =
animations["walk-slide-left"].sequences = animations["walk-slide-right"].sequences =
animations["fall-slide-left"].sequences = animations["fall-slide-right"].sequences = [112];
animations["wake-left"].sequences = animations["wake-right"].sequences = [112, 113];
Backbone.RedFlyingTurtle = Backbone.FlyingTurtle.extend({
defaults: _.extend(_.deepClone(Backbone.FlyingTurtle.prototype.defaults), {
name: "red-flying-turtle"
}),
animations: _.deepClone(Backbone.FlyingTurtle.prototype.animations),
fallbackSprite: Backbone.RedTurtle
});
animations = Backbone.RedFlyingTurtle.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [110];
animations["walk-left"].sequences = animations["walk-right"].sequences = [110, 111];
animations["squished-left"].sequences = animations["squished-right"].sequences =
animations["walk-slide-left"].sequences = animations["walk-slide-right"].sequences =
animations["fall-slide-left"].sequences = animations["fall-slide-right"].sequences = [112];
animations["wake-left"].sequences = animations["wake-right"].sequences = [112, 113];
Backbone.Beetle = Backbone.Turtle.extend({
defaults: _.extend(_.deepClone(Backbone.Turtle.prototype.defaults), {
name: "beetle"
}),
animations: _.deepClone(Backbone.Turtle.prototype.animations)
});
animations = Backbone.Beetle.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [33];
animations["walk-left"].sequences = animations["walk-right"].sequences = [33, 32];
animations["squished-left"].sequences = animations["squished-right"].sequences =
animations["walk-slide-left"].sequences = animations["walk-slide-right"].sequences =
animations["fall-slide-left"].sequences = animations["fall-slide-right"].sequences =
animations["wake-left"].sequences = animations["wake-right"].sequences = [34];
Backbone.Spike = Backbone.Mushroom.extend({
defaults: _.extend(_.deepClone(Backbone.Mushroom.prototype.defaults), {
name: "spike"
}),
animations: _.deepClone(Backbone.Mushroom.prototype.animations),
squish: function() {}
});
animations = Backbone.Spike.prototype.animations;
animations["idle-left"].sequences = animations["idle-right"].sequences =
animations["fall-left"].sequences = animations["fall-right"].sequences =
animations["ko-left"].sequences = animations["ko-right"].sequences = [133];
animations["walk-left"].sequences = animations["walk-right"].sequences = [133, 132];
}).call(this);