制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】

制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】

我的网站已经上线了 http://javapub.net.cn/

博主介绍: 自媒体 JavaPub 独立维护人,全网粉丝15w+,csdn博客专家、java领域优质创作者,51ctoTOP10博主,知乎/掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和副业。


公众号:JavaPub ⭐ ⭐简历模板、学习资料、面试题库等都给你


文末获取源码 无套路,免费领取

点赞再看,养成习惯

适合人群:初级学习者和爱好者,下面有展示图。计算机毕业设计

文章目录

    • 1 前言
    • 2 正文
      • 2.1 展示预览
      • 2.2 项目结构
      • 2.2 主要代码展示
      • 源码下载
    • 系列推荐:
    • [查看更多博主首页更多实战项目 >>>](https://blog.csdn.net/qq_40374604/category_11788364.html)
      • 源码获取:

1 前言

获取源码,文末公众号回复【制作温馨浪漫爱心表白动画特效】,即可。
⭐欢迎点赞留言

2 正文

公众号:JavaPub

2.1 展示预览

1MB GIF可以欣赏:
https://tvax1.sinaimg.cn/large/007F3CC8ly1h3dn7ib17ig30ug0lxe5x.gif

制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】_第1张图片

制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】_第2张图片

2.2 项目结构

制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】_第3张图片

2.2 主要代码展示


<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Backbone Game Engine</title>
    <meta name="description" content="Elementary HTML5 Canvas Game Engine based on Backbone. Specialized for 2D platformers, and optimized for mobile.">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <link href="apple_touch_icon.png" rel="apple-touch-icon" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    
    <script src="docs/jquery.min.js" type="text/javascript"></script>
    <script src="docs/bootstrap.min.js" type="text/javascript"></script>
    <link href="docs/bootstrap.min.css" rel="stylesheet" type="text/css" charset="utf-8">

    <link href="docs/docs.css" rel="stylesheet" type="text/css" charset="utf-8">
  </head>

  <body data-spy="scroll" data-target="#sidebar" data-offset="100">
    <header class="navbar navbar-inverse" role="banner">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle pull-left" data-toggle="collapse" data-target="#navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="index.html" title="Elementary HTML5 Canvas Game Engine based on Backbone."><img src="apple_touch_icon.png" /> Backbone Game Engine</a>
      </div>
      <div id="navbar-collapse" class="collapse navbar-collapse" role="navigation">
        <ul class="nav navbar-nav">
          <li><a href="index.html">Documentation</a></li>
          <li><a href="examples.html">Examples</a></li>
        </ul>
        <ul class="nav navbar-nav navbar-right">
          <li class="github-icon"><a href="https://github.com/martindrapeau/backbone-game-engine" title="Fork me on Github"><img src="docs/github.png" />Github</a></li>
        </ul>
      </div>
    </header>

    <div class="container">
    <div class="row">

    <div class="col-md-9">
      <div id="introduction" class="row">
        <div class="col-md-12">
          <h1>HTML5 Canvas &amp; Backbone</h1>
        </div>
      </div>
      <div class="row">
        <div class="col-md-6 col-xs-6">
          <p>
            An elementary HTML5 Canvas game engine built on Backbone. Specialized for 2D platformers, and optimized for mobile.
          </p>
          <h4>Examples</h4>
          <ul>
            <li>Real game: <a href="http://www.ludosquest.com" target="_blank">Ludo's Quest - launched on iOS using Cocoon.io
            
  • Test game: Mariocraft
  • Advanced: Super Mario Bros, level 1-1
  • Elementary: Bouncing ball
  • Basic: Mario in an empty world
  • Basic: GUI
  • Basic: Hoppy frog
  • These examples are on Github.

    CocoonJS Example

    Backbone Game Engine was written to run inside of CocoonJS Canvas+, so you can turn your HTML5 game into a native application on iOS or Android. If you have the CocoonJS launcher loaded on your iOS or Android device, you can load Super Mario Bros level 1-1 via this URL:

    http://martindrapeau.github.io/cocoon-mario/cocoon-mario.zip
    

    Features:

    • Built on Backbone. Events, models, collections, inheritance and RESTful persistence. Why reinvent the wheel?
    • HTML5 canvas only. No jQuery, as little DOM manipulations as possible.
    • Mobile optimized. Build to run on mobile devices with transparent touch and viewport support. Everything is optimized for maxium frames per seconds (FPS).
    • Go Native with CocoonJS.. Built to run in Ludei's <a href="http://support.ludei.com/hc/en-us/articles/200767118-Canvas-development-Guide" target="_blank">CocoonJS canvas+</a>. Deploy native on iOS and Android.</li> <li><strong>2D platformer</strong>. Built with side-scrollers in mind. Built-in classes for sprites, sprite sheets, characters, hero, quad-tree collision detection, world and editor.</li> <li><strong>No compilation</strong>. You don't need to install node, grunt or whatever else. Just code and press F5 to run.
    • No server required. Fork this repo and your Github site is up and going. Create your own game and point your friends to it. Rebase to pull in latest engine updates.
    • Built for mobile. Conceived to run on tablets. Share your URL with Mom so she can add it to the home screen of her iPad.
    • Take if offline. With HTML5 Application Cache, your game runs offline. Perfect for taking it on the road or on a fishing trip.
    • Save state. With HTML5 Local Storage, save where you are.
    • World editor. Conceived for tile-based games, comes with a world editor. Place your tiles and characters, then hit play to try it out. Hit save to save your world.

    Dependencies

    All included in the 3rd folder. That and nothing else.

    Why Backbone?

    Backbone implements events, models, collections, inheritance and persistence. Models implement getters and setters for object attributes. Models and Collections have an extend function to easily do inheritance. They implement methods for persistence (RESTful JSON by default). They can also trigger events and bind to them. Everything you need to build a great extensible game engine. Plus, Backbone is now widely used and provides these features in a standard fashion with a huge community to support them. I hope this project can make game programming accessible to developers already familiar with Backbone.

    Using and Contributing

    Backbone Game Engine was built to get you going fast. Fork this repository, and your own Github page will be ready in minutes. You can then create your own games by simply creating a new directory, and putting files in it.

    The default branch is gh-pages so that any changes get published automatically to the Github page. Changes typically take only a few seconds to get published. This allows you to develop, test, document and deploy rapidly. It is a double-edge sword though. Any untested code you push to your fork on that branch will be felt by your users. It is therefore a good practice to create and work on another branch, and fast-forward merge to the gh-pages branch when done.

    To report a bug, use Github issues. To contribute improvements, bug fixes or new examples, make changes to your fork and do a pull request. For anyone looking to help, here is a short to-do list:

    • Implement vertical panning in Backbone.Camera.
    • Revamp collision detection: optimize lookup and better functions.
    • Implement sound.
    • Add missing behaviors in Super Mario: character death, break brick, etc.

    Getting Started

    Backbone

    The engine is based on Backbone so it is essential to understand its core structure: a Backbone.Model. A model has hash of attributes that are changed via getter and setter methods get and set. These attributes should only contain state information as it is those attributes which get saved and restored. A model is a Javascript object. Hence behaviour can be stored as properties and methods directly on the object. For example a sprite sheet points to an image. Attribute img contains the Image object or DOM selector (by id) for retrieving the Image object. Property img contains reference to the Image object. It is automatically set when the sprite sheet model is initialized.

    var spriteSheet = new Backbone.SpriteSheet({
      id: "mario",
      img: "#mario",
      tileWidth: 32,
      tileHeight: 64,
      tileColumns: 21,
      tileRows: 6
    });
    spriteSheet.get("img"); // attribute
    // #mario
    
    spriteSheet.img; // property
    // <img id=​"mario" src=​"../​super-mario-bros/​super-mario-2x.png" style=​"display:​none;​">
    
    spriteSheet.img.width
    //672
    
    spriteSheet.img.height
    //384
    

    In fact, a model stores its attributes in the object property attributes. Methods get, set and toJSON operate on that property. Just remember that state date like sprite coordinates, velocity, etc go in there. However references to other objects do not.

    Note on nomenclature: The word attribute is used to define state data (get and set stored in obejct property attributes) while the word property is used to define behavioural data stored directly on the object.

    Living without jQuery

    Backbone Game Engine does not use jQuery. Instead, it depends on backbone.native which re-creates the ubiquitous $ function/object with only essentials required by Backbone. As such, you are limited to simple DOM selectors enabled by querySelectorAll and events. Since the framework is for canvas-based games, avoid HTML manipulations. Canvas-based only allows for easier wrapping with CocoonJS. Consult the documentation of backbone.native to understand limitations.

    Directory structure

    To create a new example (or game), create an empty directory at the same level as super-mario-bros. Then, add some files. Here is the recommended file structure:

    3rd/
    src/
    ...
    super-mario-bros/
    my-game/
            index.html
            main.js
    

    index.html is the HTML document which loads your assets, and defines your canvas. File main.js is where you instantiate the game engine and sprites. It must get loaded last.

    index.html

    The HTML document (usually named index.html in its own folder) declares the assets to be loaded and the canvas element. Javascript assets are declared in the HEAD element. Images are loaded via IMG elements. They must be hidden with inline CSS. Everything is bootstrap-loaded as declared in the HTML file. There is no asynchronous loading.

    Here is an example HTML file taken from the example Mario.

    <!doctype html>
    <html style="touch-action: none;">
        <head>
            <title>Mario - Backbone Game Engine</title>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon" />
            <link href="../apple_touch_icon.png" rel="apple-touch-icon" />
    
            <meta name="viewport" content="width=960, user-scalable=no"/>
            <meta name="apple-mobile-web-app-capable" content="yes" />
            <meta name="mobile-web-app-capable" content="yes" />
            <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
    
            <script src="../3rd/underscore.js" type="text/javascript"></script>
            <script src="../3rd/backbone.native.js" type="text/javascript"></script>
            <script src="../3rd/backbone.js" type="text/javascript"></script>
    
            <script src="../src/shapes.js" type="text/javascript"></script>
            <script src="../src/core.js" type="text/javascript"></script>
            <script src="../src/input.js" type="text/javascript"></script>
            <script src="../src/hero.js" type="text/javascript"></script>
            <script src="../src/world.js" type="text/javascript"></script>
    
            <script src="main.js" type="text/javascript"></script>
    
            <style>
                body {
                    margin: 0;
                    background-color: #000;
                }
                canvas {
                    position: fixed;
                    top: 0;
                    left: 0;
                }
            </style>
    
        </head>
    
        <body>
            <img id="mario" src="../super-mario-bros/super-mario-2x.png" style="display:none;" />
            <canvas id="foreground" width="960" height="700">
                Your browser does not support canvas element.
            </canvas>
        </body>
    
    </html>
    

    Some important notes:

    • HTML meta tags viewport, apple-mobile-web-app-capable, mobile-web-app-capable and apple-mobile-web-app-status-bar-style ensure the canvas is properly sized and styled on iPads and other mobile devices. The width specified there should be the same as the canvas elements. On mobile devices, an orientation change will recalculate and change the width to fit the canvas in the viewport.
    • Style touch-action: none; on the HTML tag disables touch behaviors, like pan and zoom for IE10.
    • Elements must all have ids since we use the native getElementById Javascript function to retrieve the Canvas and Image objects from their respective DOM elements.

    main.js

    File main.js is where you declare and initialize your objects. It is recommended that you wrap that code in a function which gets executed once the document and all assets are loaded (i.e. window.onload event). You can use for example $(window).on("load", function() {});.

    Other files use a simple anonymous function instead since they contain class declarations mainly. However in main.js is where Canvas and Image objects are retrieved from the DOM elements. So they must first be loaded. This keeps things simple. Assets are as a consequence always loaded synchronously.

    Here is a sample main.js file, taken from the Mario example.

    $(window).on("load", function() {
    
      // Mario alone in an empty world. Control him with the touchpad.
    
      Backbone.Mario = Backbone.Hero.extend({
        defaults: _.extend({}, Backbone.Hero.prototype.defaults, {
          name: "mario",
          spriteSheet: "mario"
        })
      });
    
      var canvas = document.getElementById("foreground");
    
      var spriteSheets = new Backbone.SpriteSheetCollection([{
        id: "mario",
        img: "#mario",
        tileWidth: 32,
        tileHeight: 64,
        tileColumns: 21,
        tileRows: 6
      }]).attachToSpriteClasses();
    
      var debugPanel = new Backbone.DebugPanel();
    
      var input = new Backbone.Input({
        drawTouchpad: true,
        drawPause: true
      });
    
      var mario = new Backbone.Mario({
        x: 400, y: 400, floor: 500
      }, {
        input: input
      });
    
      var world = new Backbone.World({
        width: 30, height: 18,
        tileWidth: 32, tileHeight: 32,
        backgroundColor: "rgba(66, 66, 255, 1)",
        viewportBottom: 156
      });
      world.add(mario);
    
      var engine = new Backbone.Engine({}, {
        canvas: canvas,
        debugPanel: this.debugPanel,
        input: input
      });
      engine.add([
        world,
        input,
        debugPanel
      ]);
    
      // Expose things as globals - easier to debug
      _.extend(window, {
        canvas: canvas,
        engine: engine
      });
    
      // Ensure the canvas is always visible and centered
      adjustViewport(canvas, canvas.width, canvas.height);
    
    });
    

    Reference

    Backbone Game Engine defines classes in the Backbone namespace. Most are sub-classed from Backbone.Model or Backbone.Collection.

    Backbone.Engine

    new Backbone.Engine([attributes], [options])

    Backbone.Engine is a Backbone model that holds a Backbone collection of sprite models. It uses HTML5's <a href="https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame" target="_blank">requestAnimationFrame</a> to provide a 60 frames per second game loop. </p> <p> The sprite collection is stored in property <code>sprites</code>. You may directly access it however for convenience, methods <code>add</code>, <code>remove</code> and <code>reset</code> exist as proxy the engine. </p> <h4>Attributes</h4> <ul> <li><code>clearOnDraw</code>: Optional. Boolean to ask for a clear of the canvas before redraw. Defaults to false. Note that this is an expensive call. Better to only clear the area that changed.</li> <li><code>tapDetectionDelay</code>: Optional. The delay in ms before a tap gestured is detected. Defaults to 50ms</li> <li><code>tapMoveTolerance</code>: Optional. The amount of pixel move tolerated to detect a tap gesture. Defaults to +/-5 pixels. Beyond that, a drag gesture will be trigerred.</li> </ul> <h4>Options</h4> <p> Upon instantiation, these options can be passed. They will be stored as properties on the <code>Backbone.Engine</code> model instance. </p> <ul> <li><code>canvas</code>: The canvas to draw upon. Drawing is on its 2d context.</li> <li><code>input</code>: Optional. The user control input instance. If passed and the pause button is enabled, will stop/start then engine when pressed.</li> <li><code>debugPanel</code>: Optional. A <a href="#documentation-DebugPanel">Backbone.DebugPanel</a> instance. If passed <code>fps</code> and <code>cycleTime</code> are output.</li> </ul> <h4>Methods</h4> <ul> <li><code>add()</code>: Adds one or multiple models delegating to the sprite collection's add method.

  • remove(): Removes one or multiple models delegating to the sprite collection's <code>remove</code> method.</li> <li><code>reset()</code>: Clears or sets the sprites collection delegating to the <code>reset</code> method.</li> <li><code>isRunning()</code>: Returns true if the engine is running, or false if not.</li> <li><code>start(), stop()</code>: Starts or stops the engine.</li> <li><code>toggle()</code>: Toggle start/stop the engine.</li> </ul> <h4>Events</h4> <ul> <li><code>tap</code>: Trigerred when the user clicks or taps on the canvas. A tap is defined when the user presses/clicks on a position without moving for more than <code>tapDetectionDelay</code> ms. The event callback function is passed the DOM event object, with these extra properties attached: <code>canvas</code>, <code>canvasX</code> and <code>canvasY</code>. In addition, property <code>canvasHandled</code> is provided as a mechanism to stop propagation (see below). </li> <li><code>key</code>: Trigerred when the user types in a key. The event callback function is passed the DOM event object, with additional property <code>canvas</code>.</li> <li><code>dragstart</code>, <code>dragmove</code> and <code>dragend</code>: Trigerred when a drag gesture occurs. This happens when the user presses/clicks and holds and moves. When these events are trigerred, the <code>tap</code> event does not get trigerred.</li> </ul> <div class="alert alert-info"> Note: The <code>tap</code> and <code>drag*</code> events are broadcasted to whomever is listening. Event property <code>canvasHandled</code> is used to to prevent propagation to many overlapping objects. At first it is set to <code>false</code>. The first object to intercept and handle the event should set it to <code>true</code>. Subsequent objects intercepting the event should look at this property and return without action when <code>true</code>. <code>Backbone.Button</code> and <code>Backbone.WorldEditor</code> implement this behavior. </div> <h4>How it works</h4> <p>During every animation frame, the engine performs these things:</p> <ul> <li>Loop through models (in order), and calls their <code>update</code> method. Passing <code>dt</code>, the time in milliseconds since the last call to update. The update method must return <code>true</code> to ask for a redraw, or <code>false</code> not to.</li> <li>Loop through all models that requested a redraw, and call their <code>draw</code> method passing <code>context</code>, the canvas 2d context. Perform whatever magic you like in the draw method.</li> <li>Call itself again upon the next animation frame.</li> </ul> <div class="alert alert-info">Note: By default the engine does not clear the canvas before redraw. You can set the <code>clearOnDraw</code> option to do so however it is an expensive call. Better to do it only when required. See class <a href="#documentation-World">Backbone.World</a> for an example.</div> <p> The <code>update</code> method is used to update the model position, animation, detect collisions, or whatever you like. If it requests a redraw, the engine will then call its <code>draw</code> method. The engine ensures that models are updated and drawn in the order they are sorted in the collection. You can define the sort order by defining a <a href="http://backbonejs.org/#Collection-comparator" target="_blank">comparator</a>. </p> <p> Models added to the collection receive an <code>attach</code> event and have property <code>engine</code> set as backreference. When removed, they receive a <code>detach</code> event. </p> <p> To measure performance, two properties are set: <code>fps</code> and <code>cycleTime</code>. If you passed option <code>debugPanel</code>, they will be drawn on screen. </p> <p> The engine can be started and stopped. When running, will perform an update/draw sequence 60 times per second. Use methods <code>start</code>, <code>stop</code> or <code>toggle</code>. Use method <code>isRunning</code> to determine if the engine is running. If you passed option <code>input</code>, the engine will bind to the <em>pause</em> button (or the <em>p</em> key) to toggle start/stop. </p> <h4>Usage</h4> <pre> var canvas = document.getElementById("foreground"); var debugPanel = new Backbone.DebugPanel(); var ball = new Backbone.Ball({ x: 100, y: 100, color: "blue" }); var engine = new Backbone.Engine({ clearOnDraw: true }, { canvas: canvas, debugPanel: debugPanel }); engine.add([ ball, debugPanel ]); </pre> <p> Taken from the <a href="ball/index.html" target="_blank">Bouncing Ball</a> example. Draws two models: the debug panel and a bouncing ball. </p> </div> </div> <div id="documentation-SpriteSheet" class="row"> <div class="col-md-12"> <h3>Backbone.SpriteSheet</h3> <pre>new Backbone.SpriteSheet([attributes], [options]);</pre> <p> <code>Backbone.SpriteSheet</code> is a Backbone model which breaks an image into frames used for animation. </p> <h4>Attributes</h4> <ul> <li><code>img</code>: The <code>Image</code> object or element id selector of the image to find in the DOM (i.e. <code>#icons). A pointer to the Image object is then stored in property img.
  • <li><code>imgUrl</code>: Optional. The url to the image to load dynamically. If specified, and the image element does not exist, will try to load the image.</li> <li><code>tileWidth, tileHeight</code>: Size of tiles in pixels.</li> <li><code>tileColumns, tileRows</code>: Number of tiles in the image.</li> </ul> <h4>Properties</h4> <ul> <li><code>frames</code>: Array of animation frames. Automatically set when model is instantiated.</li> <li><code>img</code>: Pointer to <code>Image</code> object. Automatically set when model is instantiated.</li> </ul> <h4>Events</h4> <ul> <li><code>spawnImg</code>: Trigerred when the image is fully loaded.</li> <li><code>destroyImg</code>: Trigerred when the image is unloaded.</li> </ul> <p> When a sprite sheet is instantiated, an array of frames is built and stored in property <code>frames</code>. A frame object contains the coordinates of the frame. It consists of <code>{x, y, width, height}</code> representing the pixel position and size of the frame. These will be passed to the <a href="https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D#drawImage()" target="_blank">HTML5 canvas drawImage</a> function as arguments <code>sx, sy, sw, sh</code> by the <code>draw</code> method. </p> <p> Sprite sheets are not generally created on their own, but rather in a <code>Backbone.SpriteSheetCollection</code>. See below for usage. </p> </div> </div> <div id="documentation-SpriteSheetCollection" class="row"> <div class="col-md-12"> <h3>Backbone.SpriteSheetCollection</h3> <pre>new Backbone.SpriteSheetCollection([models], [options]);</pre> <p> <code>Backbone.SpriteSheetCollection</code> is a Backbone collection of <code>Backbone.SpriteSheet</code> models. </p> <h4>Methods</h4> <ul> <li><code>attachToSpriteClasses()</code>: Attaches sprite sheets to sprite class prototypes. Does so by finding all defined sprite classes (<code>Backbone.*</code>) with default attribute <code>spriteSheet</code> matching a sprite sheet id in the collection. Then sets their <code>spriteSheet</code> property to point to the correct sprite sheet in the collection.</li> </ul> <h4>Events</h4> <ul> <li><code>allSpawnImg</code>: Trigerred when all images are fully loaded.</li> </ul> <h4>Usage</h4> <p> Define your sprite sheets by creating a collection as such: </p> <pre> this.spriteSheets = new Backbone.SpriteSheetCollection([{ id: "mario", img: "#mario", tileWidth: 32, tileHeight: 64, tileColumns: 21, tileRows: 2 }, { id: "tiles", img: "#tiles", tileWidth: 32, tileHeight: 32, tileColumns: 29, tileRows: 28 }]).attachToSpriteClasses(); </pre> <p> <img src="docs/super-mario-sprite.png" class="img-responsive" alt="Backbone.Input" /> </p> <p> Here two sprite sheets are created <code>mario</code> and <code>tiles</code>. Their graphics are in <code>Image</code> objects found in the DOM. The attribute <code>img</code> is the selector to retrieve them. </p> <p> Calling method <code>attachToSpriteClasses</code> will attach the sprite sheets to each sprite class found in the <code>Backbone</code> namespace. </p> </div> </div> <div id="documentation-Sprite" class="row"> <div class="col-md-12"> <h3>Backbone.Sprite</h3> <pre>new Backbone.Sprite([attributes], [options]);</pre> <p> <code>Backbone.Sprite</code> is a <a href="http://backbonejs.org/#Model" target="_blank">Backbone Model</a> which implements the required <code>update</code> and <code>draw</code> methods to animate a sprite, frame by frame. </p> <h4>Attributes</h4> <ul> <li><code>x, y</code>: The coordinates in pixels.</li> <li><code>width, height</code>: Size of the sprite in pixels.</li> <li><code>paddingLeft, paddingRight, paddingTop, paddingBottom</code>: Optional. Internal padding to account for empty space inside the tile of a sprite. Useful to specify empty zones for collision detection.</li> <li><code>sequenceIndex</code>: The current animation sequence frame. Automatically set.</li> <li><code>state</code>: The current animation.</li> <li><code>spriteSheet</code>: Sprite sheet id. </li> <li><code>collision</code>: Optional. For use with <a href="#documentation-World">Backbone.World</a>.</li> <li><code>static</code>: Optional. For use with <a href="#documentation-World">Backbone.World</a>.</li> <li><code>visible</code>: Optional boolean. If true, the sprite is not drawn. Default is false.</li> <li><code>zIndex</code>: Optional. Specifies the drawing order. Higher value is drawn above sprites with lower values. Default is 0.</li> </ul> <div class="alert alert-info"> Note: <code>zIndex</code> is only used in <code>Backbone.World</code>. Currently, it is partially implemented - only 0 and 1 values are recognized. </div> <h4>Properties</h4> <ul> <li><code>animations</code>: Hash of animations of the sprite. Described further below.</li> <li><code>spriteSheet</code>: Instance of the <code>Backbone.SpriteSheet</code> holding the images to animate. This is automatically set when you define your sprite sheet collection. See <a href="#documentation-SpriteSheetCollection">Backbone.SpriteSheetCollection</a> for details.</li> <li><code>saveAttributes</code>: Attributes serialized for persistence. Defaults to <code>["name", "state", "sequenceIndex", "x", "y"]</code>.</li> </ul> <h4>Methods</h4> <ul> <li><code>toSave()</code>: Serializes attributes for persistence. Attributes to be serialized are specified in the <code>saveAttributes</code> property.</li> <li><code>update(dt)</code>: Called by then engine 60 times a second. Updates sprite attribues and implements behavior. Returns true to ask for a redraw, or false for none.</li> <li><code>onUpdate(dt)</code>: Not defined by default. If you define it, it is called at the end of <code>update</code>. Useful for extending the behavior of a sprite without having to overload metod <code>update</code>. Note that <code>draw</code> is called based on the Boolean return value of this method to decide whether to draw or not. It must therefore return <code>true</code> to perform a draw, or <code>false</code> not to.</li> <li><code>draw(context, options)</code>: Called by the engine after <code>update</code>, if a redraw was asked. Takes care of rendering the sprite, and its proper animation at the correct position. Argument <code>options</code> can be used by a model serving as proxy. For example it is passed when drawn by a <code>Backbone.World</code>instance. It will contain <code>offsetX</code> and <code>offsetY</code> to transform <code>x</code> and <code>y</code> from world coordinates to canvas coordinates.</li> <li><code>onDraw(context, options)</code>: Not defined by default. If defined, it is called at the end of <code>draw</code>. Useful for extending the rendering of a sprite without having to overload metod <code>draw</code>.</li> <li><code>getAnimation([state])</code>: Returns the current animation based on argument <code>state</code>. If argument <code>state</code> is omitted, the attribute is used instead.</li> <li><code>overlaps(x, y):</code>: Checks to see if the sprite overlaps with the passed coordinates. Returns a Boolean.</li> <li><code>getLeft(withPadding), getRight(withPadding), getTop(withPadding), getBotttom(withPadding)</code>: Returns the left, right, top or bottom-most position of a sprite. Argument withPadding is a boolean specifying whether to include the padding or not. Defaults to false.</li> <li><code>bbox(withPadding)</code>: Returns the bounding box of the sprite as an object <code>{x1, y1, x2, y2}</code>. Argument <code>withPadding</code> is a boolean specifying whether to include the padding or not. Defaults to false.</li> <li><code>getCenterX(withPadding)</code>: Returns the center <code>x</code> of the sprite. Argument <code>withPadding</code> is a boolean specifying whether to include the padding or not. Defaults to false.</li> <li><code>getCenterX(withPadding)</code>: Returns the center <code>y</code> of the sprite. Argument <code>withPadding</code> is a boolean specifying whether to include the padding or not. Defaults to false.</li> </ul> <h4>Events</h4> <ul> <li><code>attach</code>: Triggered when the sprite is attached to the engine.</li> <li><code>detach</code>: Triggered when the sprite is detached to the engine.</li> </ul> <p> The <code>attach</code> and <code>detach</code> events can be used to start/stop listening to events. For example, the <code>Backbone.Hero</code> sprite starts listening to user input when attached, and stops when detached. </p> <h4>Sprite and sprite sheets</h4> <p> Graphics are obtained from a <a href="#documentation-SpriteSheet">Backbone.SpriteSheet</a> model. In attribute <code>spriteSheet</code>, specify the sprite sheet id you previously defined in a <code>Backbone.SpriteSheetCollection</code> instance. The collection will automatically attach it to the sprite by setting property <code>spriteSheet</code> as back reference. Building on the example above: </p> <pre> var spriteSheets = new Backbone.SpriteSheetCollection([{ id: "mario", img: "#mario", tileWidth: 32, tileHeight: 64, tileColumns: 21, tileRows: 2 }]).attachToSpriteClasses(); var mario = new Backbone.Mario({ spriteSheet: "mario" }); mario.get("spriteSheet"); // mario spriteSheets.get("mario"); // child {cid: "c2", attributes: Object, collection: child, _changing: false, _previousAttributes: Object…} mario.spriteSheet; // child {cid: "c2", attributes: Object, collection: child, _changing: false, _previousAttributes: Object…} </pre> <h4>Inheritance</h4> <p> Instantiating a <code>Backbone.Sprite</code> model is not very useful by itself. You must first extend the <code>Backbone.Sprite</code> class to provide your own animations and a pointer to the sprite sheet. For example this defines a sprite with 3 animations <code>idle</code>, <code>walk-left</code> and <code>walk-right</code>. It points to the sprite sheet id <code>mario</code>. </p> <pre> Backbone.MySprite = Backbone.Sprite.extend({ defaults: _.extend(_.deepClone(Backbone.Sprite.prototype.defaults), { x: 400, y: 400, spriteSheet: "mario", state: "idle", sequenceIndex: 0, static: false, collision: true }), animations: { idle: { sequences: [0] }, "walk-right": { sequences: [1, 2, 3, 2], delay: 200 }, "walk-left": { sequences: [1, 2, 3, 2], scaleX: -1, delay: 200 } } }); </pre> <p> Above, the <code>Backbone.Sprite</code> was sub-classed using <code>extend</code> method. <code>defaults</code> are the default attributes to give any new <code>Backbone.MySprite</code> instance. They extend the Sprite class' defaults.

    If you want to reuse parts of defaults or animations from a parent class, make sure to make a copy. You can use the helper function _.deepClone for that purpose (_.clone only goes one level deep). Otherwise you may change the parent class behavior. For example the Backbone.PennieUg class reuses the Backbone.Pennie class' properties <code>defaults</code> and <code>animations</code> by first creating copies. </p> <pre> Backbone.PennieUg = Backbone.Pennie.extend({ defaults: _.extend(_.deepClone(Backbone.Pennie.prototype.defaults), { name: "pennie-ug" }), animations: _.deepClone(Backbone.Pennie.prototype.animations) }); Backbone.PennieUg.prototype.animations.idle.sequences = [168, 168, 169, 170, 169, 168]; </pre> <div class="alert alert-info"> Helper function <code>deepClone</code> was created as a mixin of <code>underscore</code>. When it makes sense, make general functions available that way. Look at the end of <code>src/core.js</code> for all mixins. </div> <h4>Animations</h4> <p> Sprite property <code>animations</code> contains a hash of animations. Each animation contains a sequence of frames and a delay between frames for animation. For example: </p> <pre> animations: { idle: { sequences: [0, 1], delay: 200 } } </pre> <p> This defines an animation of two frames, alternating at an interval of 200ms. Values 0 and 1 in array <code>sequences</code> are frame indices defined in the sprite sheet. Sprite attributes <code>state</code> and <code>sequenceIndex</code> control which animation and sequence are currently used. The <code>sequenceIndex</code> is automatically incremented (and reset to 0) by the sprite's draw function. Attribute state determines the current animation. It must be set to idle in the above example (as there is only one).

    Extra animation options are available. Here is a complete list:

    • sequences: Array of frame indices, or squence objects. A sequence object looks like this: {frame: 52, x: 0, y: -32, scaleX: 1.00, scaleY: 1}. It allows you to specify an offset to apply when the sprite is drawn, and a scaling factor.
    • scaleX, scaleY: Optional. Scaling factors. Set scaleX to -1 to flip horizontally. Defaults to 1 if omitted.
    • delay: Optional. The time to change to the next sequence. No need to specify if there is only one frame (as there is no animation). You can also define a sprite method sequenceDelay to programmatically return the delay. It will be passed the current animation.

    For detailed examples of animations, look at file artifacts.js in the super-mario-bros folder. Class Backbone.Pennie implements a basic animation sequence using frame indices, while Backbone.FlyingPennie implements a more complex animation with sequence objects.

    Backbone.Pennie = Backbone.AnimatedTile.extend({
      ...
      animations: {
        idle: {
          sequences: [52, 52, 53, 54, 53, 52],
          delay: 50
        }
      },
      ...
    
    Backbone.FlyingPennie = Backbone.Sprite.extend({
      ...
      animations: {
        anim: {
          sequences: [
            {frame: 52, x: 0, y: -32, scaleX: 1.00, scaleY: 1},
            {frame: 52, x: 0, y: -64, scaleX: 0.50, scaleY: 1},
            {frame: 53, x: 0, y: -90, scaleX: 0.50, scaleY: 1},
            {frame: 53, x: 0, y: -128, scaleX: 1.00, scaleY: 1},
            {frame: 53, x: 0, y: -128, scaleX: 0.50, scaleY: 1},
            {frame: 52, x: 0, y: -112, scaleX: 0.50, scaleY: 1},
            {frame: 52, x: 0, y: -90, scaleX: 1.00, scaleY: 1},
            {frame: 52, x: 0, y: -80, scaleX: 0.50, scaleY: 1},
            {frame: 53, x: 0, y: -80, scaleX: 0.50, scaleY: 1}
          ],
          delay: 50
        }
      },
      ...
    
    

    Backbone.Input

    new Backbone.Input([attributes], [options]);

    Backbone.Input class is a model which captures user input events and stores them as model attributes. For example pressing the left arrow, sets the left attribute to true. Depressing sets it to false. Bind to on the attribute change event to be notified.

    Backbone.Input supports keyboard, mouse and touch events. It can draw a touchpad on screen with left and right arrow keys, an A (red) button and a B (blue) button.

    Backbone.Input

    Note: The Backbone.Input model only captures input when attached to a Backbone.Engine.

    Attributes

    This attribute can be passed when creating the model, to configure the input.

    • drawTouchpad: Optional. Boolean or string "auto" to indicate whether to draw the touchpad. When "auto", the touchpad will be drawn only on touch devies. Defaults to "auto".

    The following model attributes are set by the model. They should not be set externally.

    • touchEnabled: Boolean set to true if the device is touch enabled.
    • left: Boolean set to true when the left touchpad arrow or left keyboard arrow key is pressed.
    • right: Boolean set to true when the right touchpad arrow or right keyboard arrow key is pressed.
    • buttonA: Boolean set to true when the A touchpad button is pressed, or when the z keyboard key is pressed.
    • buttonB: Boolean set to true when the B touchpad button is pressed, or when the x keyboard key is pressed.

    Methods

    • hasTouchpad(): Returns true if the touchpad is drawn.
    • leftPressed(): Returns true if the left button is pressed.
    • rightPressed(): Returns true if the right button is pressed.
    • buttonAPressed(): Returns true if button A is pressed.
    • buttonBPressed(): Returns true if button B is pressed.

    Events

    • attach: Triggered when the input is attached to the engine. Will start listening to user input.
    • detach: Triggered when the input is detached to the engine. Will stop listening to user input.

    You can add or remove a Backbone.Input model from the engine on the fly. In the Super Mario Bros example, the Backbone.Input and the Backbone.WorldEditor are swapped when moving from play to edit modes.

    Usage

    var input = new Backbone.Input();
    var engine = new Backbone.Engine();
    engine.add(input);
    input.bind("change:left", function(input) {
      if (input.leftPressed())
        console.log("left pressed:)");
      else
        console.log("left depressed:(");
    });
    

    Backbone.World

    new Backbone.World([attributes], [options])

    Backbone.World is model which contains a collection of sprites that interact with each other. A world is an environment composed of tiles and characters. The world extends beyond the canvas however the viewport, the visible portion, is constrained within its prescribed limits. Backbone.World is similar to a sprite; it implements the update and draw methods required by the Backbone.Engine collection.

    Attributes

    • x, y: Origin of top-left corner in pixels.
    • width, height: Size of world in tiles.
    • tileWidth, tileHeight: Size of a tile in pixels.
    • viewportLeft, viewportRight, viewportTop, viewportBottom: Defines an area in the canvas the world is constrained to. Each value provides gutter regions in pixels. Anything drawn by the world will be clipped in the area. Useful for drawing a menu bar or buttons on the same canvas. In provided demos for example, viewportBottom is set to 156 pixels to make room the the touchpad.
    • sprites: Array of sprite models for persistence.
    • backgroundColor: Background color of the world.
    • backgroundImage: Id attribute of an image element in the DOM to show as background.
    • state: Persisted state either play or pause.
    Note: Setting a viewport different than the canvas size uses canvas clipping. Avoid using if you can as clipping the is expensive and can introduce performance issues.

    Options

    • backgroundImage: Optional. Pass to use a background image instead of a background color. Anchored to the origin.
    • input: Input instance to control the hero.
    • camera: Camera instance to keep the hero in the viewport.
    • debugPanel: Optional.

    Methods

    A Backbone.World is a model that wraps a collection stored in property sprites. To prevent outside direct access to this collection, it provides these two methods:

    • add(models, [options]): Add one or many models. Adds world to options and delegates to the sprites collection's <code>add</code> method. Then sets the <code>world</code> property as back-reference on the new model(s). Returns the new model(s).</li> <li><code>remove(models, [options])</code>: Removes one or many models. Delegates to the <code>sprites</code> collection's remove method. Deletes the world back-reference and returns the model(s).

    In addition to standard Backbone.Model methods, it also exposes these:

    • spawnSprites(): Resets the sprites collection by retrieving the sprites attribute from the model. This is called after the world is loaded.
    • update(dt): Update function called by the engine. Will in turn call the update method of all sprites.
    • draw(context): Draw function called by the engine. Will in turn call the draw method of all sprites.
    • cloneAtPosition(sprite, x, y): Clones the sprite model and places the new instance at the specified coordinates. Will pass world to the options payload when created. Will also set property world as back-reference. If the sprite name matches that of the world attribute hero it will also pass option input, and if a Backbone.Camera exists, it will be tied to it. This function also acts as a toggle when placing a sprite over a tile where another exists. The existing one is removed. This ensures only one tile (static sprite) exists at one location.
    • width(), height(): Return the size of the world in pixels.
    • getWorldIndex(object): Calculates the index position of a tile based on coordinates. Argument object must contain x and y, or be a model with those attributes. The index is calculated with formula height * x/tileWidth + y/tileHeight. This method is used to set the id of tile sprites.
    • getWorldCol(x), getWorldRow(y): Returns the tile position in columns or rows of a coordinate.
    • findAt(x, y, [type], [exclude], [collision]): Finds the first sprite at the specified coordinate. Use for collision detection. Optional arguments allow you to filter what to look for. Set type to character to find moving sprites, or tile to find tiles. Set exclude to the id of the sprite you want to exclude from the search. In a collision detection scheme, this is usually the id of the sprite you are checking against. Set collision to true to find only tiles that have their collision flag set.
    • filterAt(x, y, [type], [exclude], [collision]): Same as findAt but returns the list of all matching sprites instead of the first.
    • findCollidingAt(x, y): Finds a colliding tile. Just like calling findAt(x, y, "tile", null, true).
    • findCollisions(): Finds collisions for a given set of collision map.

    Events

    • attach: Triggered when the sprite is attached to the engine. Will trigger the attach method of all sprites in the world.
    • detach: Triggered when the sprite is detached to the engine. Will trigger the detach event of all sprites in the world.
    • tap: Trigerred when the user taps or clicks on the canvas. The callback will be passed the DOM event extended with these properties: canvas, canvasX, canvasY, world, worldX and worldY.
    • key: Trigerred on a keyup event. The event callback will be passed the DOM event as argument.

    How it works

    Sprites can be added and removed via methods add and remove. Sprites are automatically attached to the Backbone.Engine the world is attached to. Sprites then have properties engine and world set as back-reference. In each request frame, the same mechanics apply as for sprites attached directly to an engine; methods update and draw are called for each sprite. The exception is for static sprites which are only updated/redrawn when required (see below).

    Internally, the world keeps sprites into a collection stored in property sprites. It further splits sprites into 2 collections for faster lookup:

    • staticSprites: Background sprites that have no animation. These are usually same-sized tiles. Sprites that have their static attribute set to true will be put in this collection. Sprites are given an id determined by their position (column and row). The collection is ordered and indexed on id allowing for fast lookup on a pair of x/y coordinates. In addition, these sprites are drawn on a background canvas only drawn when required (i.e. world is panned).
    • dynamicSprites: Animated tiles and characters. Their static attribute must be set to false to fall in this collection. These sprites are given unique id attributes based on their name (i.e. mario.1). They are not indexed therefore lookup has an order of N. Keep the number of sprites here to a minimum.

    A world is measured in tiles via attributes width, height, tileWidth and tileHeight. Call methods width and height to get the size in pixels. Attributes x and y determine the origin in pixels (top-left corner) and allow the world to be panned consequently changing the viewport.

    Note: If you define an animated tile, make sure its static attribute is set to false to prevent redraws every animation frame. Also ensure the width of tile sprites match that of world attributes tileWidth and tileHeight.

    Sprites

    When the world is created, sprites are instantiated in method spawnSprites. Each sprite instance is attached to the engine. Sprites then have properties engine and world set pointing to those respective objects.

    Sprites can be categorized with attribute type as to identify one another when they interact with each other. Sprites of type tile are usually static and obstacles. Sprites of type character are usually dynamic and moving sprites.

    You can add sprites with method add which delegates to the sprites collection's <code>add</code> method. It takes care of passing the <code>world</code> as option. </p> <p> You can also use method <code>cloneAtPosition(sprite, x, y)</code>. It takes as argument an existing sprite, and coordinates. It will clone the sprite and place it at the specified coordinates passing <code>world</code> and <code>input</code> as options. If the sprite has its <code>hero</code> attribute set to <code>ture</code>, and if a <code>Backbone.Camera</code> exists, it will be tied to it. Backbone.WorldEditor</code> uses this function for instance. </p> <p> Methods <code>getWorldIndex</code>, <code>getWorldCol</code> and <code>getWorldRow</code> can be used to find the position of a sprite. A sprite's x and y attributes determine their position relative to the world origin.

    Background and Tiles

    The background of a world is composed of same-size tiles defined by attributes tileWidth and tileHeight. A tile is usually a non-animated sprite with its static attribute set to true. The model id is the position of the sprite on screen (column and row). As such, there can only be one tile per location.

    Character Sprites

    Characters are sprites that interact with their environment. Backbone.Character and Backbone.Hero are character sprites. Character sprite models usually have teir type attribute set to character. You are free to use attribute type to classify your sprites.

    Collision detection

    Internally sprite positions are stored in a QuadTree. As a sprite moves, its position in the QuadTree is updated.

    Three methods exist to detect collisions.

    • findAt(x, y, [type], [exclude], [collision]): Find the first sprite touching the given point or null if none are found. Optional arguments can be passed for limiting the lookup:
      • type: Optional. If set, will only lookup sprites matching that type. Typical values are character or tile.
      • exlcude: Optional. The sprite model's <code>id</code> to exclude in lookup.</li> <li><code>collision</code>: Optional. Boolean indicating whether to only include sprites that have the <code>collision</code> attribute explicitly set to <code>true</code>. </ul> </li> <li><code>filterAt(x, y, [type], [exclude], [collision])</code>: Same as a above but finds all sprites touching the given point. Returns an array of sprites.</li> <li><code>findCollisions(map, [type], [exclude], [collision])</code>: Detects collisions on sprites for a set of named coordinates. Optional arguments are the same as above. Argument <code>map</code> is an array of objects that is passed in, and passed out. A map object must contain: <ul> <li><code>x</code> and <code>y</code>: Coordinates to detect the collision.</li> <li><code>dir</code>: The lookout direction: <code>top</code>, <code>right</code>, <code>bottom</code> or <code>left</code>.</li> <li><code>sprites</code>: Array of detected colliding sprites. Reset/initialized to [] every call.</li> <li><code>sprite</code>: The closest sprite based on the lookout direction.</li> </ul> </li> </ul> <p> Look at the code in <code>Backbone.Character</code> and <code>Backbone.Hero</code> classes for examples on how to perform collision detection. </p> <h4>Persistence</h4> <p> The world model attributes contain all that is necessary to persist the state of the world to disk, or in the cloud. Calling the <code>save</code> method first serializes the sprite collection from the <code>sprites</code> property into the <code>sprites</code> attribute. It calls the <code>toSave</code> method on each sprite to save their position and state. It then delegates to the backbone model's save method to save to a server or local storage in JSON format. See the Backbone documentation for details.

        The world can be restored by calling spawnSprites passing as argument a saved world in JSON format. For example, file super-mario-world/level-1-1.js contains the level in JSON format. It is set in global variable _world. The world can be restarted anytime with this line of code:

        world.set(window._world).spawnSprites();

        Usage

          var mario = new Backbone.Mario({
            x: 400, y: 400, floor: 500
          });
        
          var world = new Backbone.World({
            width: 30, height: 18,
            tileWidth: 32, tileHeight: 32,
            backgroundColor: "rgba(66, 66, 255, 1)"
          });
          world.add(mario);
        
          var engine = new Backbone.Engine();
          engine.add(world);
        

        A sprite (mario) is first created and added it the world. The world is then added to the engine. This is taken from file mario/main.js for the Mario example.

    Backbone.WorldEditor

    new Backbone.WorldEditor([attributes], [options])

    Backbone.WorldEditor is a model which displays a palette of sprites and allows the user to edit a Backbone.World instance by placing and removing sprites. Also allows the user to pan the world. In the Super Mario Bros demo, an editor is drawn at the bottom of the world replacing the Backbone.Input. Like sprites and world, it must be added to the Backbone.Engine to render. The palette will page automatically if there are too many sprites.

    Backbone.Input

    Attributes

    • x, y: Top-left placement position in pixels of the editor on the canvas.
    • width, height: Size of editor in pixels.
    • tileWidth, tileHeight: Size of sprites drawn in the palette.
    • padding: Padding in pixels around sprites.
    • backgroundColor: Background color of the editor.
    • selectColor: Background and outline color of a selected sprite.
    • selected: The name of the cuurrently selected sprite.
    • spriteNames: Ordered array of sprite names in the palette.

    Options

    • world: The Backbone.World to edit.
    • debugPanel: Optional. If passed will output mouse coordinates.

    Events

    • attach: Triggered when the sprite is attached to the engine. Will start listening to user input.
    • detach: Triggered when the sprite is detached to the engine. Will stop listening to user input.

    How it works

    The palette is drawn as a series of tiles left to right, top to bottom. Each tile is a sprite. The sprite may be bigger than the specified tile size, in which case it will be resized to fit the tileWidth and tileHeight attributes.

    Backbone.Character

    new Backbone.Character([attributes], [options])

    The Backbone.Character is a sub-classed Backbone.Sprite which implements an animated character with elementary AI (artificial intelligence) and physics. AI is limited to moving left, right, jumping/gravity and dying. Direction changes occur with collisions against an obstacle; either a tile or another character. You are free to extend the AI by subclassing it.

    A Backbone.Character must live inside a Backbone.World.

    Attributes

    • x, y: Position of the sprite.
    • floor: Set this value to prevent the character to fall outisde of the world due to gravity. By default it is null meaning the character will be removed from the world if it falls below the bottom of the world.
    • ceiling: Analogous to floor but for exiting the world from above.
    • width, height: Size of the sprite in pixels. Defaults to 32 x 32.
    • paddingLeft, paddingRight, paddingTop, paddingBottom: Optional. Internal padding to account for empty space inside the tile of a sprite. Useful to specify empty zones for collision detection.
    • sequenceIndex: The current animation sequence frame. Automatically set.
    • name: Name of the sprite.
    • type: Type of sprite. Defaults to character.
    • spriteSheet: Id of sprite sheet.
    • state: Current animation. Starts with idle-right.
    • collision: Boolean indicating whether it can be detected by other sprites. Defaults to true.
    • static: Set to false for the World to draw every animation frame.
    • visible: Set to true for the sprite to be drawn.
    • zIndex: Optional. Specifies the drawing order. Higher value is drawn above sprites with lower values. Default is 0.
    • velocity, acceleration: Current horizontal movement. Controlled by the AI in update.
    • yVelocity, yAcceleration: Current vertical movement. Controlled by the AI in update.
    • health: Amount of health the character has. When health is 0, the is "knocked-out" and dies. Defaults to 1.
    • attackDamage: This is the amount of damage the character does to an opponent. Will reduce their health by this value. Defaults to 1.
    • aiDelay: Time in ms between AI calls.

    Methods

    Backbone.Character inherits all methods from Backbone.Sprite. Here are additional methods, and ones with a different signature.

    • getStateInfo([state]): Decomposes state into move and direction components. For example walk-left would be decomposed into {mov:"walk", mov2: null, dir:"left", opo:"right"}. If argument state is omitted, the state attribute is used instead. See Backbone.Hero for a more detailed description.
    • buildState(mov, [mov2], [dir]): Helper to construct and return a dash-separated state string. Ignores falsy values. For instance buildState("walk", "left") and buildState("walk", null, "left") both return walk-left.
    • update(dt): Handles the character movements and collision detection. Also calls the ai function.
    • ai(dt): Implements the AI. Is called at an interval defined by attribute aiDelay.
    • updateSequenceIndex(dt): Returns the new sequenceIndex (animation frame). Called by update.
    • toggleDirection(dirIntent): Invokes a left or right direction change.
    • startNewAnimation(state, attrs, done): Changes the state of the character starting a new animation. Pass hash attrs to set attributes at the same time. Callback done is called once the animation is complete. Useful for performing only one animation sequence.
    • hit(sprite, [dir], [dir2]): Function invoked usually by a hit event. Implement this to determine what happens when another sprite hits the character. Argument dir is the primary direction of the hit (left, right, top or bottom). Argument dir2 is the secondary direction. In top-left for example, it would be left. dir2 can also be attack in which case health is reduced by attackDamage amount.
    • hurt(sprite, [dir], [dir2]): Function invoked when the character gets attacked and has remaining health. The character bounces back.
    • knockout(sprite, [dir], [dir2]): Function invoked when the sprite gets knocked out of the world. The sprite is litterally knocked out updside down. This function is called when health is 0.

    Events

    • attach: Triggered when the sprite is attached to the world. Turns on the AI.
    • detach: Triggered when the sprite is detached to the world. Turns off the AI meaning the character will not move.
    • hit: Trigger this event on the Backbone.Character to indicate a hit with another character. Delegates to the hit method above. For example, Backbone.Hero executes this when he lands on a character: sprite.trigger("hit", this, "top", "left");.
    • change:health: Whenever the character health decreases method hurt gets called. If health reaches 0, method knockout gets called instead.

    How it works

    During an animation frame, it is important to understand the method and event sequence. First, the update method is called. It may then call the ai method if the aiDelay internal is reached. Afterwhich collision detection is performed. At that point, the character may trigger hit events on other characters. Those may in turn trigger a hit event on the character. The character position and velocities are updated, and finally, the character model is set. The update method then returns true to tell the engine to draw the sprite, or false to prevent a redraw.

    These events are synchroneous, and will occur before the update method is completely executed. Therefore methods ai, hit, hurt and knockout may set the character model and abort the update. To abort the update, those methods set property cancelUpdate to true.

    Example

    In the Super Mario Bros example, look at file enemies.js. There are implementations for basic characters in that game. The hit method implements collision detection outcome, notably when Mario lands on a character. In the case of a Mushroom, it gets squished. When a turtle shell is sliding, it would cause a knockout.

    ...
    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;
    }
    ...
    

    The hit method will in turn trigger a hit event on the sprite which caused the collision. That sprite may in turn trigger a hit event. To avoid the possibility of inifite callback loops, private property _handleSpriteHit is used.

    Backbone.Hero

    new Backbone.Hero([attributes], [options])

    The Backbone.Hero is a sub-classed Backbone.Character which implements a controlable character with input and physics. Its playability is based on that of Mario in the Nintendo classic Super Mario Bros. Currently, only the small Mario is implemented.

    A Backbone.Hero must live inside a Backbone.World.

    Attributes

    • x, y: Position of the sprite.
    • floor: Set this value to prevent the character to fall outisde of the world due to gravity. By default it is null meaning the character will be removed from the world if it falls below the bottom of the world.
    • ceiling: Analogous to floor but for exiting the world from above.
    • width, height: Size of the sprite in pixels. Defaults to 32 x 64.
    • paddingLeft, paddingRight, paddingTop, paddingBottom: Optional. Internal padding to account for empty space inside the tile of a sprite. Useful to specify empty zones for collision detection. paddingTop is set to 32 to start as Mario is small.
    • sequenceIndex: The current animation sequence frame. Automatically set.
    • name: Name of the sprite. Defaults to hero.
    • hero: Boolean set to true indicating this character sprite is the hero. Backbone.World will detect this and pass the Backbone.Input instance for taking user input.
    • type: Type of sprite. Defaults to character.
    • spriteSheet: Id of sprite sheet.
    • state: Current animation. Starts with idle-right.
    • collision: Boolean indicating whether it can be detected by other sprites. Defaults to true.
    • static: Set to false for the World to draw every animation frame.
    • visible: Set to true for the sprite to be drawn.
    • zIndex: Optional. Specifies the drawing order. Higher value is drawn above sprites with lower values. Default is 0.
    • velocity, acceleration: Current horizontal movement. Do not set.
    • yVelocity, yAcceleration: Current vertical movement. Do not set.
    • health: Amount of health as an integer. When set to 0, the character is knocked out and dies. Defaults to 1.
    • healthMax: The maximum allowed health. Defaults to 2.
    • dead: Boolean flag indicating if the sprite is dead.
    • attackDamage: This is the amount of damage the hero does to an opponent. Will reduce their health by this value. Defaults to 1.
    • ignoreInput: Flag to prevent the hero from accepting user input. Defaults to false.
    • canAttack: Flag indicating whether the B button will result in an attack. Defaults to false.
    • canTurnInJump: By default the hero cannot turn in air (jumping or falling). Set this to tru to enable it.

    Options

    • input: Optional. A Backbone.Input instance to allow control of the character with the keyboard (left and right arrows, z and x) or via touch events on the on-screen drawn gamepad.

    Methods

    Backbone.Hero inherits all methods from Backbone.Sprite and Backbone.Character. In addition, it provides these methods you can override:

    • dirToggled(dirIntent): Called when the user presses the left or right buttons. Argument dirIntent maye be left or right. The default implementation handles left/right movements.
    • buttonAToggled: Called when the user presses the A button (rigt-most blue on pad, or x on keyboard). The default implementation handles jumping.
    • buttonBToggled: Called when the user presses the B button (left-most red on pad, or z on keyboard). The default implementation handles running and attacking (if canAttack is set to true).

    Events

    Backbone.Hero has the same events as Backbone.Character.

    How it works

    Attribute state determines the current animation. A state is a pair of move and direction. For example idle-right, walk-left and jump-right. Method getStateInfo will decompose the state for you into those components.

    With attribute nextState, we are able to implement tweens, or in-between animations. For example, holding the right arrow button puts the hero in a walk-right state (and slide-right next state). Releasing the right arrow button transitions to the slide-right state (and idle-right next state) for quick decelration until velocity reaches 0 to fall to the idle-right state. If instead the left arrow button is pressed, we transition to the skid-left state (and walk-left next state) for quicker decelartion until velocity reaches 0 to then accelerate in the opposite direction to fall in the walk-left state (and slide-left next state).

    Holding an arrow button and the A button (z on keyboard) allows the character to run. Its state becomes run-right (or run-left). Pressing the B button allows the character to jump (jump-left or jump-right). Hold the B button to jump higher. You can control the direction and distance jumped with the arrow buttons. And like in the real game, a jump while running will go higher to cover more distance.

    Physics are implemented with attributes velocity, acceleration, yVelocity and yAcceleration measured in pixels per seconds. The two first control horizontal translations over time where a positive velocity indicates a move to the right, and negative to the left. The latter two control vertical translations where a positive yVelocity indicates a move downwards, and negative upwards.

    Each animation have targets of these properties when required. They are omitted otherwise (i.e. walk-right has no yVelocity or yAcceleration). The update method updates the model attributes according to the targets configured on the current animation. When state changes to another animation, so do the targets, and so follow the actual velocities over time to reach their targets. This gives the character momentum.

    Gravity is implemented with a positive yAcceleration. Unless atop a tile, our character will fall. However it is constrained by the extent of the Backbone.World it is contained in. And will therefore stop falling when the bottom is reached.

    Collisions

    Our character detects collisions either from tiles or other characters to constrain its movements. It does so using collision detection method findCollidings from Backbone.World. Every update, collisions with other sprites are detected on the outline of the sprite:

    Hero Collisions

    Collisions are only handled when necessary. For instance, when jumping collisions are handled top and right only. The decision is based on looking at velocity and yVelocity. For gravity, a check is performed every time at the bottom of the sprite to land or to fall.

    var bottomWorld = this.world.height() + tileHeight,
        floor = this.get("floor") || bottomWorld,
        bottomY = Math.min(floor, bottomWorld);
    
    for (i = 0; i < this.collisionMap.bottom.sprites.length; i++) {
      sprite = this.collisionMap.bottom.sprites[i];
      bottomY = Math.min(bottomY, sprite.getTop(true));
      if (sprite.get("type") == "platform") bottomPlatform = sprite;
    }
    
    ...
    
    if (yVelocity > 0 && heroBottomY >= bottomY) {
      // Stop falling
      land(bottomY);
      for (i = 0; i < this.collisionMap.bottom.sprites.length; i++)
        this.collisionMap.bottom.sprites[i].trigger("hit", this, "top", cur.dir);
      if (this.cancelUpdate) return true;
    } else if (cur.mov != "jump" && yVelocity == 0 && heroBottomY < bottomY) {
      // Start falling if no obstacle below
      attrs.nextState = state;
      attrs.state = this.buildState("jump", cur.mov2, cur.dir);
    } else if (yVelocity == 0 && heroBottomY == bottomY) {
      // On a floating platform - same vertical velocity
      if (bottomPlatform)
        relativeVelocity = bottomPlatform.get("velocity");
    }
    

    When an obstacle is hit, the character stops moving. Its x is anchored, and velocity set to 0.

    if (velocity >= 0) {
      // Stop if obstacle to the right
      var rightX = this.world.width();
      for (i = 0; i < this.collisionMap.right.sprites.length; i++)
        if (heroTopY > 0 )
          rightX = Math.min(rightX, this.collisionMap.right.sprites[i].getLeft(true));
    
      if (heroRightX >= rightX) {
        attrs.velocity = velocity = 0;
        attrs.x = x = rightX - heroWidth - paddingLeft;
        for (i = 0; i < this.collisionMap.right.sprites.length; i++)
          this.collisionMap.right.sprites[i].trigger("hit", this, "left", cur.mov2);
        if (this.cancelUpdate) return true;
      }
    }
    

    A collision with other sprites triggers an hit event on that sprite. The event hanlder will receive the colliding sprite (hero), and its relative position where the hit occured (left of the enemie sprite in this case).

    Usage

    This excerpt is taken from the Mario example.

      Backbone.Mario = Backbone.Hero.extend({
        defaults: _.extend({}, Backbone.Hero.prototype.defaults, {
          name: "mario",
          spriteSheet: "mario"
        })
      });
    
      var canvas = document.getElementById("foreground");
    
      var spriteSheets = new Backbone.SpriteSheetCollection([{
        id: "mario",
        img: "#mario",
        tileWidth: 32,
        tileHeight: 64,
        tileColumns: 21,
        tileRows: 6
      }]).attachToSpriteClasses();
    
      var input = new Backbone.Input({
        drawTouchpad: true,
        drawPause: true
      });
    
      var mario = new Backbone.Mario({
        x: 400, y: 400
      }, {
        input: input
      });
    
      var world = new Backbone.World({
        width: 30, height: 18,
        tileWidth: 32, tileHeight: 32,
        backgroundColor: "rgba(66, 66, 255, 1)"
      });
      world.add(mario);
    
      var engine = new Backbone.Engine({}, {
        canvas: canvas,
        input: input
      });
      engine.add([
        world,
        input
      ]);
    

    Backbone.Camera

    new Backbone.Camera([attributes], [options])

    Backbone.Camera is a model which ensures a sprite, the subject, is always in the viewport (the canvas). It pans the Backbone.World when the character steps out of a window in the viewport. Backbone.Camera must be added to the engine (not the world).

    Attributes

    • left, right, top, bottom: Coordinates of the window with respect to the drawn canvas.

    Options

    • subject: The sprite to keep in the viewport.
    • world: The Backbone.World.

    Methods

    • update(dt): No-op. Simply returns false for no redraw.
    • draw(context): No-op.
    • maybePan(): Called when the x or y position of the subject changes. Ensures the subject is within the specified window, otherwise pans the world.

    Events

    • attach: Triggered when the sprite is attached to the engine. Starts monitoring the subject and pans the Backbone.World when necessary.
    • detach: Triggered when the sprite is detached to the engine. Stops monitoring the subject.

    Usage

    var spriteSheets = new Backbone.SpriteSheetCollection({
      id: "mario",
      img: "#mario",
      tileWidth: 32,
      tileHeight: 64,
      tileColumns: 21,
      tileRows: 6
    });
    var mario = new Backbone.Mario();
    var world = new Backbone.World();
    var camera = new Backbone.Camera(
      {left: 200, right: 600, top: 100, bottom: 50},
      {subject: mario, world: world}
    );
    world.add(mario);
    var engine = new Backbone.Engine();
    engine.add([world, camera]);
    

    Backbone.Clock

    Backbone.Clock is a model which ticks at a set time interval. Attribute ticks stores an integer tick value that gets incremented every interval. Useful for synchronizing sprite animations.

    Attributes

    • ticks: Initial tick value. An integer that gets incremented every interval.
    • delay: Interval between ticks.

    Methods

    • update(dt): Updates the ticks.
    • draw(context): No-op. Simply returns the model.

    Events

    • attach: Triggered when the sprite is attached to the engine. Starts ticking.
    • detach: Triggered when the sprite is detached to the engine. Stops ticking.

    Usage

    var clock = new Backbone.Clock({delay: 2000});
    clock.on("change:ticks", function() {
      console.log("tick", clock.get("ticks");
    });
    

    As an example, look at the Super Mario Bros example, question blocks and pennies are all synced on the same clock. These sprites are sub-classes of Backbone.AnimatedTile. Instances create a Backbone.Clock if one does not exist. Otherwise, they find the existing one by that name and reuse it.

    Backbone.AnimatedTile = Backbone.Tile.extend({
      initialize: function(attributes, options) {
        Backbone.Tile.prototype.initialize.apply(this, arguments);
        this.on("attach", this.onAttach, this);
        this.on("detach", this.onDetach, this);
      },
      onAttach: function() {
        if (!this.engine) return;
        this.onDetach();
    
        this.clock = this.engine.findWhere({name: "animatedTileClock"});
    
        if (!this.clock)
          this.clock = this.engine.add(new Backbone.Clock({name: "animatedTileClock", delay: 200}));
    
        this.listenTo(this.clock, "change:ticks", this.updateAnimationIndex);
      },
      onDetach: function() {
        if (this.clock) this.stopListening(this.clock);
        this.clock = undefined;
      },
      update: function(dt) {
        return true;
      },
      updateAnimationIndex: function() {
        var animation = this.getAnimation(),
            sequenceIndex = this.get("sequenceIndex") || 0;
        if (!animation) return;
        this.set("sequenceIndex", sequenceIndex < animation.sequences.length-1 ? sequenceIndex + 1 : 0);
      }
    });
    

    Backbone.Element

    Backbone.Element is a model that mimics a rudimentary DOM element. Currently, it supports these features:

    • Fixed position specified by top-left x and y.
    • Optional background color and rounded corners.
    • Optional image.
    • Optional text.
    • Can be animated with easing functions. Supported animations are: translation, fade in and fade out.

    Attributes

    • x, y: Top left corner of button.
    • width, height: Size of button.
    • backgroundColor: Fill style of the button. Set to transparent to see thru.
    • borderRadius: Border radius in pixels for rounded corners.
    • img: The Image object or element id selector of the image to find in the DOM (i.e. #icons). A pointer to the Image object is then stored in property img
    • imgX, imgY, imgWidth, imgHeight: Bounding box of image location in source image.
    • imgMargin: Offset in pixels to apply when drawing the image inside the button.
    • text: Text to draw. If empty, not text is drawn.
    • textPadding, textLineHeight: Padding around the text and line height in pixels.
    • textContextAttributes: Canvas text styling properties. Will be set on the canvas context before calling fillText. Consult HTML5 fillText documentation for details.
    • easing: Easing function to use as defined in Backbone.EasingFunctions (see below).
    • easingTime: Duration of the animation in ms. Defaults to 1000ms.
    • opacity: Opacity of the element. 1 for fully visible, 0 for invisible and in-between for translucent. This value is changed by fadeIn and fadeOut animations.
    • scale: Zoom-in, zoom-out scale to apply to the element. Default is 1. Can be used to defined your own animation (see Backbone.Button's <code>pressed</code> animation below).</li> </ul> <h4>Methods</h4> <ul> <li><code>update(dt)</code>: Draws the element and handles animations.</li> <li><code>onUpdate(dt)</code>: Not defined by default. If deinfed, called at the end of <code>update</code>. It must return <code>true</code> or <code>false</code> to determine whether to draw the element or not.</li> <li><code>draw(context, options)</code>: Draws the element.</li> <li><code>onDraw(context, options)</code>: Not defined by default. If deinfed, called at the end of <code>draw</code>.</li> <li><code>drawText(b, context, options)</code>: Called by <code>draw</code> to draw text. Argument <code>b</code> is the JSONized model (<code>this.toJSON()</code>) defining the context. You can call this to draw extra text if you implemented method <code>onDraw</code>.</li> <li><code>overlaps(x, y):</code>: Checks to see if the sprite overlaps with the passed coordinates. Returns a Boolean.</li> <li><code>moveTo(x, y, callback)</code>: Translation animation. Will move the element from the current position to the specified <code>x</code> and <code>y</code> position using the <code>easing</code> function and <code>easingTime</code> duration.</li> <li><code>fadeIn(callback)</code>: Animates a fade in. Starts with an opacity of 0 going up to 1.</li> <li><code>fadeOut(callback)</code>: Animates a fade out. Starts with an opacity of 1 going down to 0.</li> </ul> <h4>Events</h4> <ul> <li><code>attach</code>: Triggered when the sprite is attached to the engine. Starts listening to user input.</li> <li><code>detach</code>: Triggered when the sprite is detached to the engine. Stops listening to user input.</li> </ul> <h4>Animations</h4> <p> Animations are driven by attributes <code>easing</code> and <code>easingTime</code>. The first defines the easing function to use and the second the duration in ms. These functions are found in <code>Backbone.EasingFunctions</code> and are: <ul> <li><code>linear</code></li> <li><code>easeInQuad</code></li> <li><code>easeOutQuad</code></li> <li><code>easeInOutQuad</code></li> <li><code>easeInCubic</code></li> <li><code>easeOutCubic</code></li> <li><code>easeInOutCubic</code></li> <li><code>easeInQuart</code></li> <li><code>easeOutQuart</code></li> <li><code>easeInOutQuart</code></li> <li><code>easeInQuint</code></li> <li><code>easeOutQuint</code></li> <li><code>easeInOutQuint</code></li> </ul> Easing functions return a value between 0 and 1. </p> <p> You can create your own animations pretty easily. Look at the code for examples. </p> <h4>Usage</h4> <pre> TO DO... </pre> </div> </div> <div id="documentation-Button" class="row"> <div class="col-md-12"> <h3>Backbone.Button</h3> <p> <code>Backbone.Button</code> is a <code>Backbone.Element</code> which listens to tap/click events and triggers a <code>tap</code> event when pressed. When pressed there is a grow-shrink animation to give the user feedback. </p> <h4>Usage</h4> <pre> var button = 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 }); button.on("tap", function() { console.log("button tapped!"); }); </pre> </div> </div> <div id="documentation-DebugPanel" class="row"> <div class="col-md-12"> <h3>Backbone.DebugPanel</h3> <p> <code>Backbone.DebugPanel</code> is a Backbone model on which you set attributes to be dumped on screen. Upon draw, it will <code>JSON.stringify</code> attributes. </p> <h4>Events</h4> <ul> <li><code>update(dt)</code>: No-op. Simply returns true.</li> <li><code>draw(context)</code>: Draws the debug information on screen.</li> <li><code>attach</code>: Triggered when the sprite is attached to the engine.</li> <li><code>detach</code>: Triggered when the sprite is detached to the engine.</li> </ul> <h4>Usage</h4> <pre> var debugPanel = new Backbone.DebugPanel(); var engine = new Backbone.Engine({}, { debugPanel: debugPanel }); engine.add(debugPanel); debugPanel.set({hello: "Word"}); // Draws this on screen // {"fps": 58, "ct": 7, "hello": "World"} debugPanel.set({hello: "Dolly"}); // {"fps": 58, "ct": 7, "hello": "Dolly"} debugPanel.unset("hello"); // {"fps": 58, "ct": 7} </pre> <p> In the above example, the debug panel is created. It is added to the engine as a model to draw. It is also passed as an option to the engine so it can output <code>fps</code> and <code>ct</code> (cycle time). </p> <p> We manually add attribute <code>hello</code> to be tracked. Whenever it changes, so does the print out on screen. Use <code>unset</code> to remove a tracked attribute. </p> <h4>Conditional Usage</h4> <p> It is recommended that you support the non-existence of the debug panel with an <code>if (this.debugPanel)</code> statement before setting. For example, when you extend a class, pass in the debug panel as an option. Then, in your code, check to see if it exists. For example, this is done in the <code>Backbone.Engine.draw</code> method: </p> <pre>if (this.debugPanel) this.debugPanel.set({fps: this.fps, ct: this.cycleTime});</pre> <p> This supports the case where the debug panel is never created (<code>debugPanel</code> = <code>undefined</code>), such as in production. </p> </div> </div> <div id="documentation-Shapes" class="row"> <div class="col-md-12"> <h3>Shape functions</h3> <p> File <code>shapes.js</code> contains helper functions to draw elementary shapes in the 2d drawing context of a canvas. You are free to use direct methods on the context to draw. These are provided as convenience. The functions are added to the global scope, under <code>window</code>. Supported functions are: </p> <pre> drawRect(ctx, x, y, width, height, fill, stroke) drawCircle(ctx, x, y, radius, fill, stroke) drawRoundRect(ctx, x, y, width, height, radius, fill, stroke) </pre> <p> I encourage you to add your own. If you do, respect these recommendations: </p> <ul> <li>Functions take as first argument <code>ctx</code> the drawing context.</li> <li>Second and third arguments should be <code>x</code> and <code>y</code> coordinates.</li> <li>Last arguments should be <code>fill</code> the fill style, and <code>stroke</code> the stroke style. They should be optional if possible.</li> </ul> </div> </div> <div id="mobile-devices" class="row"> <div class="col-md-12"> <h1>Mobile Devices</h1> <p> Backbone Game Engine was built for mobile first. </p> <h3>Touch Events</h3> <p> <a href="#documentation-Engine">Backbone.Engine</a>, <a href="#documentation-Input">Backbone.Input</a>, <a href="#documentation-Button">Backbone.Button</a> and <a href="#documentation-WorldEditor">Backbone.WorldEditor</a> support touch and mouse events transparently. Works on Android, iOS and Windows. </p> <h3>Viewport resizing and canvas centering</h3> <p> On mobile devices, the <code>meta</code> tag <code>viewport</code> is set to 960 pixels wide. On iOS, Android and Windows mobile devices, this will ensure the canvas is full width. The HTML file contains the necessary header tags to ensure everything works. You can change the viewport width value to whatever you want. </p> <pre> &lt;meta name="viewport" content="width=960, user-scalable=no"/&gt; &lt;meta name="mobileoptimized" content="0" /&gt; </pre> <p> Not all screens have the same aspec ratio. To take care of the height, you can change the height of the canvas upon start by calling the global function <code>adjustViewport()</code> (see file <code>adjust-viewport.js</code> for details). </p> <pre> var canvas = document.getElementById("foreground"); adjustViewport(canvas); </pre> <p> If you want to maintain the aspect ratio, pass true. The canvas will be centered on screen. </p> <pre> var canvas = document.getElementById("foreground"); adjustViewport(canvas, true); </pre> <p> On desktop the <code>viewport</code> meta tag is ignored. <code>adjustViewport</code> will center the canvas, even handling resizes. It will try to reduce the height of the canvas if too tall unless you omit the <code>keepRatio</code> argument. </p> <h3>Web App</h3> <p> These meta tags are set to enable Web App support: </p> <pre> &lt;meta name="apple-mobile-web-app-capable" content="yes" /&gt; &lt;meta name="mobile-web-app-capable" content="yes" /&gt; &lt;meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/&gt; </pre> <p> To suggest users to put add the home page to the home screen, checkout this great plugin: <a href="https://github.com/cubiq/add-to-homescreen" target="_blank">Cubiq's Add To Homescreen.

    Going Offline

    With HTML Application Cache, you can go offline with your game. Super Mario Bros level 1-1 uses the application cache. The first time your browser loads that page, it will save the web page, along with all assets in its application cache. Subsequent visits will load these from the application cache instead of the server.

    Note: Application Cache only works when loaded from a server. It will not if you have forked the repo, and are loading the file from your disk (file:///). That's good because under development, we want to load the new code every refresh. </div> <p> If you have Google Chrome, open the console and you will see this: </p> <pre> Creating Application Cache with manifest http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/offline.appcache Application Cache Checking event martindrapeau.github.io/:1 Application Cache Downloading event martindrapeau.github.io/:1 Application Cache Progress event (0 of 23) http://martindrapeau.github.io/backbone-game-engine/3rd/qtree.js Application Cache Progress event (1 of 23) http://martindrapeau.github.io/backbone-game-engine/src/input.js ... Application Cache Progress event (22 of 23) http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/super-mario-enemies-2x.png Application Cache Progress event (23 of 23) Application Cache Cached event </pre> <p> Subsequent times, you will see this: </p> <pre> Document was loaded from Application Cache with manifest http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/offline.appcache Application Cache Checking event Application Cache NoUpdate event </pre> <h3>Manifest File</h3> <p> Using an Application Cache is dead simple. First you must add the <code>manifest</code> attribute to your HTML tag. It points to the manifest file: </p> <pre> &lt;!doctype html&gt; &lt;html manifest="offline.appcache"&gt; &lt;head&gt; </pre> Second, create the <code>manifest</code> file. It contains files that must be cached. For example here is the <code>offline.appcache</code>: </p> <pre> CACHE MANIFEST # Version 0.11 (c) 2014-2015 Martin Drapeau ../3rd/qtree.js ../3rd/underscore.js ../3rd/backbone.native.js ../3rd/backbone.js ../src/input.js ../src/shapes.js ../src/core.js ../src/world.js ../src/local-storage.js ../src/camera.js ../src/editor.js ../src/hero.js mario.js tiles.js artifacts.js enemies.js display.js level_1-1.js main.js super-mario-2x.png super-mario-tiles-2x.png super-mario-enemies-2x.png icons.png </pre> <p> If you have server requests, you can add a <code>NETWORK</code> section. Consult the docs for details. </p> <p> Fianally, the comment with <code>Version 0.11</code> is important. When a new version of Super Mario Bros level 1-1 is released, the version number is increased to force the browser to reload the files. It will also trigger an <code>updateready</code> event which gets captured to show a download button. That informs the user a new version is ready to be downloaded. Clicking on that button simply refreshes the browser to reload the new version. </p> </div> </div> <div id="persistence" class="row"> <div class="col-md-12"> <h1>Persistence</h1> <p> Backbone offers RESTful persistence via <a href="http://backbonejs.org/#Sync" target="_blank">Backbone.sync</a>. Models have methods <code>fetch</code> and <code>save</code> to retrieve/send the model/collection JSONified data to/from the server. As such, you can easily implement server-side persistence using well established RESTful standards. </p> <p> In our Super Mario Bros example, we use <a href="https://developer.apple.com/library/safari/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html" target="_blank">local storage</a> instead. This is done by overriding <code>Backbone.World</code> methods <code>save</code> and <code>fetch</code>. See file <code>src/local-storage.js</code> for details. </p> </div> </div> <div id="performance" class="row"> <div class="col-md-12"> <h1>Performance and Debugging</h1> <p> HTML5 canvas has come a long way in terms on performance. Browser implementations of canvas now offer impressive performance. On mobile, Apple leads the pack being able to sustain a 60fps for the Super Mario Bros example. However on Android, frame rates drop fast to the 30s when the background needs to be redrawn. On Surface performance seems good on newer models, however on first generation RT models, as slow as on Android tablets. </p> <p> This being said, there are things you can do to ensure the best performance. </p> <h4>Keep cycle time below 16ms</h4> <p> That is the time you have between redraws, 60 times a second. The <code>Backbone.Engine</code> will report the frame rate (fps), and cycle time (ct) if you add and attach a <code>Backbone.DebugPanel</code>. Make sure to use it. If you see <code>fps</code> go down while <code>ct</code> goes up, then your <code>update</code> and <code>draw</code> times must be too long. You can time the <code>update</code> time to pinpoint the issue. </p> <h4>Play well with Javascript Garbage Collection</h4> <p> You can't avoid it. You will leak memory. Every call made by requestAnimationFrame creates a function scope. It does so 60 times a second and it will need to be garbage collected. The browser will pause to collect garbage.

    You can however control the leakage rate. Try to create objects upfront, and pool resources as much as possible. That's why sprite sheets are shared among sprites. If you ever see that your game jerks, at an even interval (i.e. every 30s), then you are probably being hit by the garbage collector recuperating large amounts of memory (>10MB). </p> <p> You can use the Timeline tool in Chrome/Safari Developer Tools to identify this. Record a session and once done, you can apply a filter <code>gc</code> to filter on garbage collection events. You will notice they are at evenly spaced intervals. On my machine, for Super Mario Bros, 3.5MB is collected every 4s on average. There is no jerk. No jerk on a tablet means healthy memory management. </p> <p> Some further references and good resources on performance: </p> <ul> <li><a href="http://blog.artillery.com/2012/10/browser-garbage-collection-and-framerate.html" target="_blank">Browser Garbage Collection and Frame Rate</a></li> <li><a href="https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript" target="_blank">How to write low garbage real-time Javascript</a></li> <li><a href="http://www.html5rocks.com/en/tutorials/canvas/performance/" target="_blank">Improving HTML5 Canvas Performance</a></li> </ul> </div> </div> <div id="publishing" class="row"> <div class="col-md-12"> <h1>Publishing your Game</h1> <h2>On the Web</h2> <p> If you forked this repo, your game is already published on the web on your Github page under <code>[username].github.io/backbone-game-engine</code>. </p> <p> If you own an iPad or iPhone, you can add it to the home screen as a Web app. It will open in full-screen and if you've implemented an Application Cache, it will work offline too.

    On iOS and Android

    Backbone Game Engine was built to run in CocoonJS canvas+. You can try out Super Mario Bros level 1-1 in the CocoonJS launcher by pointing to the zip file at this URL: http://martindrapeau.github.io/cocoon-mario/cocoon-mario.zip.

    http://martindrapeau.github.io/cocoon-mario/cocoon-mario.zip
    

    Checkout the Github repo cocoon-mario. It can be used as the basis for your own native game on iOS or Android.

    Change Log

    0.40 - TBD

    • Upcoming release to include bug fixes, improvements and new features to come following the release to iOS of Ludo's Quest.</li> </ul> <h4>0.30 - 2015-03-22</h4> <ul> <li>Backbone.Element - a rudimentary DOM element with image, text and animations.</li> <li>Backbone.World now uses a QuadTree for collision detection.</li> <li>Removed dependence on hammer.js. Backbone.Engine now triggers tap and key events.</li> <li>Complete rewrite of Backbone.Input. Removed its pause button.</li> <li>Complete rewrite of Backbone.Character.</li> <li>Complete rewrite of Backbone.Hero.</li> <li>Backbone.Editor now resizes sprites to fit in the specified tileWidth and tileHeight.</li> <li>Rewrite of adjustViewport global function to work cross-device.</li> <li>Official support of CocoonJS canvas+.</li> </ul> <h4>0.21 - 2015-02-06</h4> <ul> <li>Sprite padding</li> <li>More efficient gamepad drawing</li> <li>Editor: paging, shrink large sprites, highlight tiles</li> <li>World: z-index, tap event,key event, fixed background image, improved sprite lookup, bug fixes</li> </ul> <h4>0.20 - 2014-12-31</h4> <p> Major improvements including: <ul> <li>Performance improvements.</li> <li>Fast sprite lookup.</li> <li>Faster dynamic and static drawing.</li> <li>Efficient collision detection.</li> <li>Character and hero knockout and dying.</li> <li>Bug fixes.</li> </ul> </p> <h4>0.11 - 2014-11-12</h4> <p> Adjust viewport on orientation change, and center canvas. </p> <h4>0.10 - 2014-05-19</h4> <p> Initial release. </p> </div> </div> </div> <div class="col-md-3"> <div id="sidebar" class="bs-sidebar affix"> <ul class="nav bs-sidenav"> <li class="active"><a href="#introduction">Introduction</a></li> <li><a href="#getting-started">Getting Started</a></li> <li><a href="#documentation">Reference</a></li> <li><a href="#documentation-Engine">&nbsp;&nbsp;Backbone.Engine</a></li> <li><a href="#documentation-SpriteSheet">&nbsp;&nbsp;Backbone.SpriteSheet</a></li> <li><a href="#documentation-SpriteSheetCollection">&nbsp;&nbsp;Backbone.SpriteSheetCollection</a></li> <li><a href="#documentation-Sprite">&nbsp;&nbsp;Backbone.Sprite</a></li> <li><a href="#documentation-Input">&nbsp;&nbsp;Backbone.Input</a></li> <li><a href="#documentation-World">&nbsp;&nbsp;Backbone.World</a></li> <li><a href="#documentation-WorldEditor">&nbsp;&nbsp;Backbone.WorldEditor</a></li> <li><a href="#documentation-Character">&nbsp;&nbsp;Backbone.Character</a></li> <li><a href="#documentation-Hero">&nbsp;&nbsp;Backbone.Hero</a></li> <li><a href="#documentation-Camera">&nbsp;&nbsp;Backbone.Camera</a></li> <li><a href="#documentation-Clock">&nbsp;&nbsp;Backbone.Clock</a></li> <li><a href="#documentation-Element">&nbsp;&nbsp;Backbone.Element</a></li> <li><a href="#documentation-Button">&nbsp;&nbsp;Backbone.Button</a></li> <li><a href="#documentation-DebugPanel">&nbsp;&nbsp;Backbone.DebugPanel</a></li> <li><a href="#documentation-Shapes">&nbsp;&nbsp;Shape functions</a></li> <li><a href="#mobile-devices">Mobile Devices</a></li> <li><a href="#going-offline">Going Offline</a></li> <li><a href="#persistence">Persistence</a></li> <li><a href="#performance">Performance</a></li> <li><a href="#publishing">Publishing</a></li> <li><a href="#change-log">Change Log</a></li> </ul> </div> </div> </div> </div> <br/> <footer class="navbar navbar-default"> <p class="navbar-text navbar-left"> &copy; 2014 <a href="http://martindrapeau.tumblr.com/">Martin Drapeau.</a> <a href="https://github.com/martindrapeau/backbone-game-engine/blob/gh-pages/LICENSE">Licensed under MIT.</a> </p> <p class="navbar-text navbar-right">Written in Montréal, Canada.</p> <p class="navbar-text navbar-right">&nbsp;</p> </footer> </body> </html>

      制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】_第4张图片

      源码下载

      获取源码,公众号回复【制作温馨浪漫爱心表白动画特效】,即可。更多最新Java面试题加群、见群公告。~

      不会还有人没 点赞 + 关注 + 收藏 吧!

      制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】_第5张图片

      系列推荐:

      Java 实现 捕鱼达人 小游戏【附源码】

      Java 实现 贪吃蛇 小游戏【附源码】

      Java 实现 1024 小游戏【附源码】

      Java实现一个坦克大战的小游戏【附源码】

      Java实现一个打飞机的小游戏【附源码】

      Java 实现 植物大战僵尸 小游戏【附源码】

      查看更多博主首页更多实战项目 >>>

      项目源码获取方法

      点赞本文,然后私信我,我免费分享给你哈~

      源码获取:

      大家点赞、收藏、关注、评论啦 、查看微信公众号获取联系方式


      精彩专栏推荐订阅:在下方专栏


      Java项目精品实战案例《101套》


      web前端期末大作业网页实战《365套》

    你可能感兴趣的:(java项目精品实战案例,web期末大作业,小项目,动画,html5,jquery)