Files
memory-manager-concurrent/games/mario/frog/main.js
2026-01-21 18:11:33 +08:00

237 lines
7.1 KiB
JavaScript

$(window).on("load", 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 canvas = document.getElementById("foreground"),
context = canvas.getContext("2d");
adjustViewport(canvas);
var spriteNames = [
"land1", "land2", "land3", "land4", "land5", "land6",
"mush1", "mush2", "mush3", "mush4", "mush5", "mush6",
"water1", "cloud1", "cloud2", "cloud3", "cloud-happy1", "cloud-happy2", "cloud-happy3",
"cloud-small", "ground", "land8", "ground2", "block", "land7", "block2",
"cloud-platform1", "cloud-platform2", "cloud-platform3", "cloud-platform4", "cloud-platform5", "cloud-platform6",
"water2", "cloud4", "cloud5", "cloud6", "cloud-happy4", "cloud-happy5", "cloud-happy6",
"frog", "platform"
];
Backbone.Controller = Backbone.Model.extend({
initialize: function(attributes, options) {
options || (options = {});
var controller = this;
_.bindAll(this, "onChangeState", "toggleState", "saveWorld", "loadWorld");
// Create our sprite sheets and attach them to existing sprite classes
this.spriteSheets = new Backbone.SpriteSheetCollection([{
id: "frog",
img: "#frog",
tileWidth: 50,
tileHeight: 65,
tileColumns: 3,
tileRows: 1
}, {
id: "tiles",
img: "#tiles",
tileWidth: 32,
tileHeight: 32,
tileColumns: 29,
tileRows: 28
}]).attachToSpriteClasses();
// Create the debug panel
this.debugPanel = new Backbone.DebugPanel();
// User input (turn off touchpad to start)
this.input = new Backbone.Input({
drawTouchpad: true
});
// Camera
this.camera = new Backbone.Camera();
// Our world
this.world = new Backbone.World(
_.extend({viewportBottom: 156}, window._world), {
input: this.input,
camera: this.camera
});
// Message
this.message = new Backbone.Message({
x: 480, y: 20
});
// Buttons
this.toggleButton = new Backbone.Button({
x: 4, y: 4, width: 52, height: 52, borderRadius: 5,
img: "#icons", imgX: 0, imgY: 0, imgWidth: 32, imgHeight: 32, imgMargin: 10
});
this.toggleButton.on("tap", this.toggleState, this);
this.saveButton = new Backbone.Button({
x: 904, y: 548, width: 52, height: 52, borderRadius: 5,
img: "#icons", imgX: 96, imgY: 0, imgWidth: 32, imgHeight: 32, imgMargin: 10
});
this.saveButton.on("tap", this.saveWorld, this);
this.restartButton = new Backbone.Button({
x: 904, y: 608, width: 52, height: 52, borderRadius: 5,
img: "#icons", imgX: 128, imgY: 0, imgWidth: 32, imgHeight: 32, imgMargin: 10
});
this.restartButton.on("tap", this.restartWorld, this);
this.downloadButton = new Backbone.Button({
x: 888, y: 10, width: 52, height: 52, borderRadius: 5,
img: "#icons", imgX: 64, imgY: 0, imgWidth: 32, imgHeight: 32, imgMargin: 10
});
this.downloadButton.on("tap", this.downloadNewVersion, this);
// The game engine
this.engine = new Backbone.Engine({}, {
canvas: canvas,
debugPanel: this.debugPanel
});
this.engine.add(_.compact([
this.world,
this.camera,
this.toggleButton,
this.message,
this.debugPanel
]));
// The sprite picker and editor
this.editor = new Backbone.WorldEditor({
spriteNames: spriteNames,
width: 34*20+4
}, {
world: this.world
});
// Controls
$(document).on("keypress.Controller", function(e) {
if (e.keyCode == 66 || e.keyCode == 98)
controller.engine.toggle(); // b to break the animation
else if (e.keyCode == 80 || e.keyCode == 112)
controller.toggleState(); // p to pause and pause
});
this.listenTo(this.world, "change:state", this.onChangeState);
this.onChangeState();
// If we have Application Cache active, load the latest world
this.loadWorld();
},
toggleState: function(e) {
var state = this.world.get("state");
this.world.set("state", state == "edit" ? "play" : "edit");
if (!this.engine.isRunning()) this.engine.start();
},
onChangeState: function() {
var state = this.world.get("state");
if (state == "edit") {
// Edit
context.clearRect(0, 0, canvas.width, canvas.height);
this.engine.remove(this.input);
this.engine.add(this.editor);
this.engine.add([this.saveButton, this.restartButton]);
this.toggleButton.set({imgX: 32});
} else {
// Play
context.clearRect(0, 0, canvas.width, canvas.height);
this.engine.remove(this.editor);
this.engine.remove([this.saveButton, this.restartButton]);
this.engine.add(this.input);
this.toggleButton.set({imgX: 0});
}
},
// Save our world to the server when changed. Debounce by 5 seconds
// and push back saving upon activity
saveWorld: function() {
var controller = this,
world = this.world
message = this.message;
message.show("Saving...");
world.save(null, {
success: function() {
setTimeout(function() {
message.hide();
}, 1000);
},
error: function(xhr, textStatus, errorThrown ) {
message.show("Error: " + errorThrown);
}
});
return this;
},
// Load our world from the server.
loadWorld: function() {
var controller = this,
world = this.world,
message = this.message;
message.show("Loading...");
world.fetch({
success: function() {
world.spawnSprites();
message.hide();
},
error: function(xhr, textStatus, errorThrown ) {
message.show('Error: ' + errorThrown);
setTimeout(function() {
message.hide();
}, 2000);
}
});
return this;
},
restartWorld: function() {
var controller = this,
world = this.world,
message = this.message;
message.show("Restarting...");
localStorage.removeItem(world.id);
world.set(window._world).spawnSprites();
setTimeout(function() {
message.hide();
}, 2000);
return this;
},
downloadNewVersion: function() {
window.applicationCache.swapCache();
this.message.show("Please wait...");
window.location.reload();
}
});
var controller = new Backbone.Controller();
// When a newer version is available, load it and inform
// the user it can be downloaded.
if (window.applicationCache !== undefined)
window.applicationCache.addEventListener('updateready', function() {
controller.engine.add(controller.downloadButton);
});
// Expose things as globals - easier to debug
_.extend(window, {
canvas: canvas,
context: context,
controller: controller
});
});