EaselJS BitmapAnimation has delay when using gotoAndPlay

I have created a requirejs module that enhances the functionality of a BitmapAnimation by allowing it to move around the stage at a specific speed and transition to another looped animation once reaching its destination.

The issue I am encountering is a noticeable delay between calling gotoAndPlay and seeing any changes on the stage. Despite logging the methods that trigger gotoAndPlay, the animations do not switch as quickly as expected.

Below is an abstract object example:

'use strict';

/**
 * AbstractCharacter
 * Provides common functionality for all characters
 */

define(['easeljs'], function () {
    var AbstractCharacter = function (model) {
        this.model = model;

        // modified from original code
        // for improved encapsulation
        this._s = new createjs.SpriteSheet(model.ssInit);

        // add reversed frames
        createjs.SpriteSheetUtils.addFlippedFrames(this._s, true, false, false), 

        this.initialize();
    };

    AbstractCharacter.prototype = Object.create(createjs.BitmapAnimation.prototype);
    AbstractCharacter.prototype.constructor = AbstractCharacter;

    // constant for speed
    AbstractCharacter.prototype.SPEED = 10;

    // taken from Flash CS6
    AbstractCharacter.prototype.BitmapAnimation_initialize = AbstractCharacter.prototype.initialize;

    /**
     * Moves a character to a destination and sets their state at the end of the move
     * @param  {object} destination coordinates {x:XX}
     * @param  {string} nextAction  the next action to perform
     * @return {null}
     */
    AbstractCharacter.prototype.moveTo = function(destination, nextAction) {
        nextAction = nextAction || 'idle';

        if (destination) {
            if (destination.x < this.x) {
                this.walkLeft();
            } else {
                this.walkRight();
            }

            this.destination = destination;
            this.nextAction = nextAction;
        }
    };

    /**
     * Public method to perform action
     * @param  {string} room   current room name where character resides
     * @param  {string} action action name
     * @param  {object} params parameters needed by the action
     * @return {null}
     */
    AbstractCharacter.prototype.action = function(room, action, params) {
        switch (action) {
            case 'walk' :
                this.moveTo(params, 'idle');
                break;

            case 'talk' :
                this.moveTo(params, 'talk');
                break;

            case 'sleep' :
                this.moveTo(this.model.actions.room[room].sleep, 'sleep');
                break;
        }
    };

    /**
     * Callback for each frame of animation using easeljs
     * @return {null}
     */
    AbstractCharacter.prototype.onTick = function() {
        if (this.destination) {
...

EDIT: The lag issue only affects Chrome - IE9 and Firefox17 are running smoothly.

EDIT: By using the following code instead of extending my abstractcharacter, the animations play without any delays or lags:

    var test = new createjs.BitmapAnimation(new createjs.SpriteSheet({
        images: [model.assets['mycharacters']], 
        frames: [[0,0,129,344,0,74,327],[129,0,129,345,0,74,327], ...

Answer №1

After some investigation, I've identified the root of the problem:

// upon further review
createjs.SpriteSheetUtils.addFlippedFrames(this._s, true, false, false), 

The issue seems to stem from compatibility issues with Chrome - potentially due to the large size of my spritesheet. To troubleshoot, I will experiment with dividing the spritesheet into smaller segments.

This complication may be related to an existing problem noted when using multiple images, as detailed in this resource: Stuttering animation when spanning multiple sprite sheets in easeljs

Answer №2

After some adjustments, my abstract class now utilizes scaleX = -1 instead of flipped frames, resulting in a smoother operation. It's worth noting that there may be a slight increase in CPU usage, but testing will confirm this. In the worst-case scenario, I may need to include additional frames in the assets.

Cheers!

'use strict';

/**
 * AbstractCharacter
 * Provides common functionality for all characters
 * @author  Allandt Bik-Elliott
 * @version 0.1
 */

define(['easeljs'], function () {
    var AbstractCharacter = function (model) {
        this.model = model;

        // changed from original code
        // allows better encapsulation
        this._s = new createjs.SpriteSheet(model.ssInit);

        // add reversed frames
        // NOTE: removed because there is lag switching between spritesheets
        //createjs.SpriteSheetUtils.addFlippedFrames(this._s, true, false, false), 

        this.initialize();
    };

    AbstractCharacter.prototype = Object.create(createjs.BitmapAnimation.prototype);
    AbstractCharacter.prototype.constructor = AbstractCharacter;

    // speed constant
    AbstractCharacter.prototype.SPEED = 10;

    // from Flash CS6
    AbstractCharacter.prototype.BitmapAnimation_initialize = AbstractCharacter.prototype.initialize;

    /**
     * moves a character to a destination and sets their state at the end of the move
     * @param  {object} destination destination coordinates {x:XX}
     * @param  {string} nextAction  the next action to perform
     * @return {null}
     */
    AbstractCharacter.prototype.moveTo = function(destination, nextAction) {
        nextAction = nextAction || 'idle';

        if (destination) {
            if (destination.x < this.x) {
                this.walkLeft();
            } else {
                this.walkRight();
            }

            this.model.destination = destination;
            this.model.nextAction = nextAction;
        }
    };

    /**
     * public method to perform action
     * @param  {string} room   name of the current room the character is in
     * @param  {string} action action name
     * @param  {object} params any parameters required by the action
     * @return {null}
     */
    AbstractCharacter.prototype.act = function(room, action, actionparams) {
        //console.log(action);
        switch (action) {
            case 'walk' :
                this.moveTo(actionparams, 'idle');
                break;

            case 'talk' :
                this.moveTo(actionparams, 'talk');
                break;

            case 'sleep' :
                this.moveTo(this.model.actions.room[room].sleep, 'sleep');
                break;


        }
    };

    /**
     * onTick callback for use with easeljs
     * @return {null}
     */
    AbstractCharacter.prototype.onTick = function() {
        if (this.model.destination) {
            var destination = this.model.destination, 
                speed;

            if (destination.x < this.x) {
                speed = -this.SPEED;

                if (this.x + speed < destination.x) {
                    this.endMove(destination);
                } else {
                    this.x += speed;
                }
            } else {
                speed = this.SPEED;

                if (this.x + speed > destination.x) {
                    this.endMove(destination);
                } else {
                    this.x += speed;
                }
            }
        }
    };

    /**
     * finishes move by calling nextAction() and clearing away desination and nextAction vars
     * @param  {object} destination format {x:XX}
     * @return {null}
     */
    AbstractCharacter.prototype.endMove = function(destination) {
        //console.log('ending move');
        this.x = destination.x;
        this[this.model.nextAction]();

        this.model.destination = null;
        this.model.nextAction = null;
    };

    /**
     * these methods come from Flash CS6
     * the only difference is that I've removed
     * the reference to the Object prototype
     *
     * scaleX used instead of flipped frames
     */
    AbstractCharacter.prototype.initialize = function() {
        this.BitmapAnimation_initialize(this._s);
        this.idle();
    };

    AbstractCharacter.prototype.idle = function(){
        //console.log('idle');
        this.gotoAndPlay("idle");
        this.scaleX = 1;
    };

    AbstractCharacter.prototype.idleLeft = function(){
        //console.log('idle left');
        this.gotoAndPlay("idleside");
        this.scaleX = 1;
    };

    AbstractCharacter.prototype.idleRight = function(){
        //console.log('idle right');
        // this.gotoAndPlay("idleside_h");
        this.gotoAndPlay("idleside");
        this.scaleX = -1;
    };

    AbstractCharacter.prototype.walkLeft = function(){
        //console.log('walk left');
        this.gotoAndPlay("walk");
        this.scaleX = 1;
    };

    AbstractCharacter.prototype.walkRight = function(){
        //console.log('walk right');
        // this.gotoAndPlay("walk_h");
        this.gotoAndPlay("walk");
        this.scaleX = -1;
    };

    AbstractCharacter.prototype.talk = function(){
        //console.log('talk');
        this.gotoAndPlay("talk");
        this.scaleX = 1;
    };

    AbstractCharacter.prototype.sleep = function(){
        //console.log('sleep');
        this.gotoAndPlay("sleep");
        this.scaleX = 1;
    };

    // public interface
    return AbstractCharacter;
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The functionality of JQuery's .hover() is disabled once an HTML onClick() event is activated

I am currently working on a webpage and attempting to incorporate JQuery into it for the first time. However, I seem to be encountering some issues that I believe might have simple solutions. Background Information My JQuery code only contains one event l ...

Ways to incorporate NPM packages into your browser projects using TypeScript

This is the current setup: index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <script src="../node_modules/systemjs/dist/system.js"></script> <script src="../node_modules/lodash/in ...

Is it possible to create a webpage where the header and footer remain static, while the content in the body can be dynamically changed

I am in the process of creating a webpage where main.html will load a page with a static header and footer that remains unchanged when navigation links are clicked. I'd like to achieve this using Javascript, with the body content being sourced from an ...

Selenium: The function moveToElement is not valid for the driver.actions() method

After creating all my tests using Selenium IDE, I decided to export them to JavaScript Mocha for running in travis. While the tests run smoothly in Selenium IDE and can be exported, I encountered an issue when trying to run them which resulted in the erro ...

Token does not function properly on Fetch request sent to PHP script

I have a pair of files: one is revealing a session token, while the other is responding to a javascript fetch. The first file goes like this: <?php session_start(); unset($_SESSION['sessionToken']); $_SESSION['sessionToken'] = vsprin ...

Can anyone explain to me why the data I'm passing as props to the React functional component is displaying as undefined?

I have encountered an issue with a pre-made React component where I am unable to see the data being passed as props when I console log it. I am unsure if I am passing the prop correctly, as I have used the same prop successfully in other class-based comp ...

How can a tab be created using a link within a tab using jquery easyui?

Tabs documentation My goal is to add a new tab from a link within an existing tab. For instance, in tab A, there should be a link "open tab B" that when clicked, adds tab B. I have attempted to create a tab with a link outside of the tab (which works). ...

Having trouble retrieving data from a JSON object that has been stringified. This issue is arising in my project that utilizes Quasar

I successfully converted an excel spreadsheet into a JSON object by using the xml2js parseString() method, followed by JSON.stringify to format the result. After reviewing the data in the console, it appears that I should be able to easily iterate through ...

Error in jQuery and Canvas Image Crop: The index or size is invalid, exceeding the permissible limit

Recently, I downloaded and installed the Canvas Image Crop plugin from CodeCanyon but encountered a problem specifically on firefox. An error message kept popping up whenever I tried to upload certain images: "Index or size is negative or greater than the ...

Ways to create distance between repeated cards in a loop. My method involves utilizing ajax, jquery, and bootstrap

view image description here What is the best way to create some space between these closely aligned cards? .done((todos) => { todos.forEach(el => { console.log(el) $("#todo-list").append(` <d ...

Once the stripe token is generated, proceed to submit the form

Having issues submitting a form using jQuery with the Stripe.js plugin. I need to submit the form after creating a Stripe token. The jQuery validation is working correctly, but I'm getting an error message in the console saying "object is not a functi ...

A useful tip for emphasizing tags that have attributes with endings

Here is the HTML list I'm working with: <li class=​"info" data-info=​"" data-title=​"info 1" data-info-id=​"222643">…</li> <li class=​"info" data-info=​"" data-title=​"info 2" data-info-id=​"217145">…</li> ...

Tips on accessing the JS file api within an angular component.ts file

I've got a function in my JS file located at src/server/js/controller.js, and I'm trying to use that API within a component's ts file. I attempted the following code to achieve this but it doesn't seem to be working properly. controlle ...

Vue.JS is throwing a TypeError: Unable to employ the 'in' operator to look for 'undefined' within the Laravel Object

How can I successfully pass an object from Laravel to Vue.js and utilize it in a v-for="option in this.options"? Although I am able to transfer the object from my Laravel blade to the Vue.js component and view it in the console, I encounter an error when a ...

Utilizing JavaScript as the front-end client for a web application connected to the backend of

I am facing an interesting scenario with a coworker who has suggested using JavaScript in a Web client application (specifically EPiServer CMS) to manage all the documents in the backend (SharePoint Online). However, I am unable to figure out how to acce ...

How can I incorporate popups in React using mapbox-gl?

Currently utilizing mapbox-gl within React, everything seems to be functioning properly except for the integration of mapbox-gl's Popups. I have the function let Popup, but I am uncertain about how to incorporate it. renderMap() { if (this.props. ...

Console log messages not displaying in Express.js app method

const express = require("express"); const app = express(); app.listen(3000, function () { console.log("Server started at port 3000."); }); app.get("/", function (req, res) { console.log("Hello, world"); const truck = "drive"; res.send("Hello, ...

Create a jQuery script that generates clickable links when a user is mentioned in the

Hey there, I've been incorporating this fantastic plugin created by Hawkee into my project. It functions similarly to Twitter, allowing users to @mention others. However, I'm encountering issues with the output when using the following method: u ...

What is the best way to adjust the width of these elements for a perfect fit?

I'm currently working on a website where I have arranged squares in a grid layout. My goal is to make these squares perfect, with equal width and height. The only issue I'm encountering is that they tend to change between fitting two and three sq ...

The hidden textbox loses its value when submitting

I have a form with fields and a RequiredFieldValidator. Additionally, I have another textbox that is hidden which gets populated by a JavaScript function: <script type="text/javascript"> $(document).ready(function (sender, args) { $("#myTextFiel ...