npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@pabrick/roger

v1.1.2

Published

An easy javascript library for frame by frame animation with spritesheets

Downloads

15

Readme

@pabrick/roger npm version

roger

The easiest animation library for frame by frame animations

Roger is a personal project made entirely in EcmaScript by Pablo (Pabrick) Jiménez Beneyto. It focuses on providing an easy animation library for pixelart and browser games, using CSS properties manipulation in spritesheets used as backgrounds. I decided to create it from scratch instead of using other game engines or libraries such as PhaserJS.

I also use this chance to try out all new features that EcmaScript6 brings as I can't use them in my day-to-day work.

How it works

Let's begin with basics:

Sprite

An image used in a videogame (old school at least) is called a sprite. The sprites are grouped in a bigger image known as a spritesheet.

Sprite

Spritesheet

The spritesheets are stored in the memory as square blocks, if the image isn't square, the computer will make it square anyway, that's why it's better to create square spritesheets to better use the space. The sprites within the spritesheet can all have the same size or different sizes.

Spritesheet

NOTE: CURRENTLY I only have developed spritesheets that have same sized sprites.

Animation

When we play several images one after another in a certain time, it looks like the images are moving, and that's called animation.

Animation

I like to take advantage of that, so instead of changing one image by another I just set the whole spritesheet as a background, crop just one sprite size and move the background very fast like a pattern in a window.

Animation

Doing that the computer uses the GPU (CSS) instead the CPU (JS) to create the animation.

Because an animation is a group of images or sprites, different combinations can make different animations. So a spritesheet can have many animations within itself. We only have to set which sprites compose the animation.

Animation

Toon

A toon is an object that groups different animations. As a true fan of ActionScript I wanted to bring back the idea of the DisplayObject but as object is a reserved word I decide to name them after the cartoon characters in "Who Framed Roger Rabbit". A hero for example can have different animations like: walk, run, attack, duck, etc.

Clock

If we have different toons and different animations we may want (and should) synchronize them all. Every animation has to follow the beat like if it were following a metronome. That will help us to control the animations and that's why we need a clock. Our clock (or clocks) have to know wich animations beat every time it ticks. So we have to add the toons with the animations to the clock like if it were windup key of these toons.

Install

With npm:

npm i @pabrick/roger

Usage

import Roger from '@pabrick/roger';

We create and idle sprite passing the spritesheet url, the sprite size and the sprite position.

let mySprite = new Roger.Sprite(
  'img/damn_pablos_heads.png',
  { w: 54, h: 90 },
  { x: 0, y: 0 }
);

We define the spritesheet for our animations passing the spritesheet url, the spritesheet size and the sprite sizes.

let mySpriteSheet = new Roger.RegularSheet(
  'img/damn_pablos_heads.png',
  { w: 512, h: 512 },
  { w: 54, h: 90 }
);

NOTE: We are using RegularSheet because all our sprites have the same size, otherwise we should use Sheet and pass an array of sprite sizes. Unfortunately Sheet class development is not finished yet.

If our idle sprite uses the same spritesheet as our animations, we can use that instance when we create the sprite:

let mySprite = new Roger.Sprite(
  mySpriteSheet.url,
  { w: 54, h: 90 },
  { x: 0, y: 0 }
);

Now we can create our animation with the proper parameters:

let myAnimation = new Roger.Animation('blink', mySpriteSheet, [0, 1, 2, 1, 0], {
  delay: 10,
  loops: 3,
  direction: 'forward',
  callback: () => {
    console.log('blink complete!');
  },
});
  • Name of the animation
  • Instance of the spritesheet
  • Array with the positions of the sprites that compose the animation
  • Options or configuration of the animation (optional):
    • delay: time before animation starts [default: 0]
    • loops: number of times an animation repeats (-1 for inifite loops) [default: infinite]
    • direction: how the animation plays (forward, backward or random) [default: forward]
    • callback: function that executes as the animation ends [default: none]

All the parameters in the options are optional, so you only need to add the ones that you want to change from its default configuration. Their default values are:

  • delay: no delay (0)
  • loops: infinite (-1)
  • direction: forward
  • callback: none

NOTE: Random animations play in infinite loops because the animation does not know which is its last sprite.

We can now create our toon and add an animation.

let myToon = new Roger.Toon('pablo', pabloIdleSprite);
myToon.add(myAnimation);

Finally we only need to create our clock with the delta we want to use as a parameter (0.1 seconds in our case). Add our toon to the clock's update queue and make it start working!

let myClock = new Roger.Clock(0.1);
myClock.addToList(myToon);
myClock.start();

API

Roger.Sprite

Constructor:

Roger.Sprite (url, size, position)
  • url: {string} path of the spritesheet.
  • size: {object} width and height of the sprite.
  • position: {object} top position (row) and left position .(column) on the spritesheet from 0.0.

Getters:

  • url: {string} path of the spritesheet
  • w: {number} width of the sprite
  • h: {number} height of the sprite
  • x: {number} top position (row) on the spritesheet from 0.0
  • y: {number} left position (column) on the spritesheet from 0.0

Roger.Sheet & Roger.RegularSheet

Constructor:

Roger.Sheet (url, size, sprites)
Roger.RegularSheet (url, size, sprites)
  • url: {string} path of the spritesheet.
  • size: {object} width and height of the spritesheet.
  • sprites: {array} sizes of each sprite.

Getters:

  • url: {string} path of the spritesheet.

Methods:

  • getSprite: {number} returns the sprite in that position.

Roger.Animation

Constructor:

Roger.Animation (name, spriteSheet, frameList, options)
  • name: {string} name of the animation.
  • spriteSheet: {Roger.Sheet || Roger.RegularSheet} instance of the spriteSheet.
  • frameList: {array} the number of the sprites that compose the animation.
  • options: {object} (optional) how animation is configured.

NOTE: if no options are provided, default options are NO DELAY, INFINITE LOOP and play FORWARD.

Getters:

  • url: {string} path of the spritesheet.
  • name: {string} name of the animation.
  • hasCallback: {boolean} get if the animation has a function when it ends.
  • hasFinished: {boolean} get if animation has finished.

Methods:

  • setOption: {object} set new options for the animation.
  • getSprite: {number} returns the sprite in that position.
  • executeCallback: execute the function linked to the animation ends.

Roger.AnimationOptions

Constructor:

Roger.AnimationOptions (delay, loops, direction, callback)
  • delay {number} time before the animation starts
  • repeat {number} number of times the animation repeats
  • direction {string} order of the frames
  • callback {Function} function executed after the animation ends

Roger.Toon

Constructor:

Roger.Toon (id, idle)
  • name: {string} name of the animation.
  • idle: {Roger.Sprite} (optional) sprite by default when toon has no animation loaded.

Methods:

  • update:
  • add: {Roger.Animation} make an animation as part of this toon.
  • play: {string} plays the animation with the name provided.
  • stop: stops the current animation, showing the idle sprite.

Roger.Clock

Roger.Clock (delta)
  • delta: {number} time in seconds for each tick or step.

Methods:

  • init: initilize the clock without starting.
  • initWith: {number} initilize the clock with a number without starting.
  • start: initilize AND starts the clock.
  • startWith: {number} initilize with a number AND starts the clock.
  • pause: pause the clock.
  • stop: stops the clock.
  • update: makes the clock ticks.
  • updateWith: {number} update the clock manually. No need of init or start. Pause doesn't work with this option.
  • addToList: {Roger.Toon} add and toon to the update queue.
  • clearList: empty the update queue.
  • setDebugMode: {boolean} log by console the delta.

License

MIT

THANKS!