Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

craters.js

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

craters.js - npm Package Compare versions

Comparing version 1.0.4 to 1.0.5

dist/craters.js

41

app/craters/craters.js

@@ -1,28 +0,23 @@

/** Craters.js micro game framework
* This module contains the basics fundamental starting point calling game loop, which handles
* updating the game state and re-rendering the canvas
* (using the updated state) at the configured FPS.
*/
var game = require('./game.js'),
entity = require('./entity.js'),
loader = require('./loader.js'),
sound = require('./sound.js');
// Craters.js micro game framework
// This module contains the basics fundamental starting point calling game loop, which handles
// updating the game state and re-rendering the canvas
// (using the updated state) at the configured FPS.
var Boundary = function numberBoundary(min, max) {
return Math.min( Math.max(this, min), max );
import { game } from './game.js'
import { entity, sprite } from './entity.js'
import { loader } from './loader.js'
import { sound } from './sound.js'
const Boundary = function numberBoundary (min, max) {
return Math.min(Math.max(this, min), max)
}
// Expose methods
Number.prototype.boundary = Boundary;
Number.prototype.boundary = Boundary
(function(window){ "use strict";
class craters {
static version () {
return '0.0.0.3'
}
}
window.craters = {
version:'0.0.0.2',
game: game,
entity: entity.entity,
sprite: entity.sprite,
loader: loader,
sound: sound
}
})(window);
export { craters, loader, game, entity, sprite, sound }

@@ -1,117 +0,124 @@

(function(window) { "use strict";
class entity {
constructor () {
// Setup the defaults if no parameters are given
// Type represents the collision detector's handling
this.type = this.type || 'dynamic'
class entity {
constructor () {
// Setup the defaults if no parameters are given
// Type represents the collision detector's handling
this.type = this.type || 'dynamic'
// Collision represents the type of collision
// another object will receive upon colliding
this.collision = this.collision || 'elastic';
this.state = {
size: {x: 10, y: 10},
pos: {x: 0, y: 0},
vel: {x: 0, y: 0},
accel: {x: 0, y: 0},
radius: 10,
angle: 0
}
this.entities = [];
}
update () {
// update the sub entities if there's any
// by firing off the update function one by one
for(var entity = 0; entity < this.entities.length; entity ++) {
this.entities[entity].update();
}
switch (this.type) {
case 'dynamic':
this.state.vel.x += this.state.accel.x;
this.state.vel.y += this.state.accel.y;
this.state.pos.x += this.state.vel.x;
this.state.pos.y += this.state.vel.y;
break;
case 'kinematic':
this.state.vel.x += this.state.accel.x;
this.state.vel.y += this.state.accel.y;
this.state.pos.x += this.state.vel.x;
this.state.pos.y += this.state.vel.y;
break;
}
}
render () {
for(var entity = 0; entity < this.entities.length; entity ++) {
this.entities[entity].render();
}
}
}
// Collision represents the type of collision
// another object will receive upon colliding
this.collision = this.collision || 'elastic'
this.state = {
class sprite extends entity {
constructor (scope, args) {
super();
this.scope = scope;
this.state = {
cord: args.pos || {x:0, y:0},
pos: {x:0, y:0},
size: args.size || {x:0, y:0},
frames: args.frames || [],
angle: args.angle || 0,
image: args.image || new Image(),
delay: args.delay || 5,
tick: args.tick || 0,
orientation: args.orientation || 'horizontal'
}
}
update () {
if (this.state.tick <= 0) {
if(this.orientation == 'vertical') {
this.state.pos.y = this.state.frames.shift()
this.state.frames.push(this.state.pos.y)
} else {
this.state.pos.x = this.state.frames.shift()
this.state.frames.push(this.state.pos.x)
}
this.state.tick = this.state.delay;
}
this.state.tick--;
}
render () {
super.render(this);
this.scope.context.save();
this.scope.context.translate(this.state.pos.x + (this.state.size.x / 2), this.state.pos.y + (this.state.size.y / 2));
this.scope.context.rotate((this.state.angle) * (Math.PI / 180));
this.scope.context.translate(- (this.state.pos.x + (this.state.size.x / 2)), - (this.state.pos.y + (this.state.size.y / 2)));
this.scope.context.drawImage(this.state.image,
(this.state.pos.x * this.state.size.x), (this.state.pos.y * this.state.size.y), this.state.size.x, this.state.size.y,
this.state.cord.x, this.state.cord.y, this.state.size.x, this.state.size.y);
this.scope.context.restore();
}
}
size: {
x: 10,
y: 10
},
pos: {
x: 0,
y: 0
},
vel: {
x: 0,
y: 0
},
accel: {
x: 0,
y: 0
},
radius: 10,
angle: 0
}
module.exports = { entity, sprite }
this.entities = []
}
})(window);
update () {
// update the sub entities if there's any
// by firing off the update function one by one
for (var entity = 0; entity < this.entities.length; entity++) {
this.entities[entity].update()
}
switch (this.type) {
case 'dynamic':
this.state.vel.x += this.state.accel.x
this.state.vel.y += this.state.accel.y
this.state.pos.x += this.state.vel.x
this.state.pos.y += this.state.vel.y
break
case 'kinematic':
this.state.vel.x += this.state.accel.x
this.state.vel.y += this.state.accel.y
this.state.pos.x += this.state.vel.x
this.state.pos.y += this.state.vel.y
break
}
}
render () {
for (var entity = 0; entity < this.entities.length; entity++) {
this.entities[entity].render()
}
}
}
class sprite extends entity {
constructor (scope, args) {
super()
this.scope = scope
this.state = {
cord: args.pos || {
x: 0,
y: 0
},
pos: {
x: 0,
y: 0
},
size: args.size || {
x: 0,
y: 0
},
frames: args.frames || [],
angle: args.angle || 0,
image: args.image || new Image(),
delay: args.delay || 5,
tick: args.tick || 0,
orientation: args.orientation || 'horizontal'
}
}
update () {
if (this.state.tick <= 0) {
if (this.orientation == 'vertical') {
this.state.pos.y = this.state.frames.shift()
this.state.frames.push(this.state.pos.y)
} else {
this.state.pos.x = this.state.frames.shift()
this.state.frames.push(this.state.pos.x)
}
this.state.tick = this.state.delay
}
this.state.tick--
}
render () {
super.render(this)
this.scope.context.save()
this.scope.context.translate(this.state.pos.x + (this.state.size.x / 2), this.state.pos.y + (this.state.size.y / 2))
this.scope.context.rotate((this.state.angle) * (Math.PI / 180))
this.scope.context.translate(-(this.state.pos.x + (this.state.size.x / 2)), -(this.state.pos.y + (this.state.size.y / 2)))
this.scope.context.drawImage(this.state.image,
(this.state.pos.x * this.state.size.x), (this.state.pos.y * this.state.size.y), this.state.size.x, this.state.size.y,
this.state.cord.x, this.state.cord.y, this.state.size.x, this.state.size.y)
this.scope.context.restore()
}
}
export { entity, sprite }

@@ -1,199 +0,193 @@

(function(window){ "use strict";
class game {
constructor(game, width, height, frames, debug) {
this.game = game || 'body';
this.constants = {
gravity: {
x: 0,
y: 100
},
width: width,
height: height,
frames: frames,
debug: debug,
bgcolor: 'rgba(0,0,0,0)',
color: '#ff0',
font: '1em Arial'
};
this.state = {
entities: []
};
// Generate a canvas and store it as our viewport
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d');
// Pass our canvas' context to our getPixelRatio method
var backingStores = ['webkitBackingStorePixelRatio','mozBackingStorePixelRatio','msBackingStorePixelRatio','oBackingStorePixelRatio','backingStorePixelRatio'];
var deviceRatio = window.devicePixelRatio;
// Iterate through our backing store props and determine the proper backing ratio.
var backingRatio = backingStores.reduce(function(prev, curr) {
return (context.hasOwnProperty(curr) ? context[curr] : 1); });
// Return the proper pixel ratio by dividing the device ratio by the backing ratio
var ratio = deviceRatio / backingRatio;
// Set the canvas' width then downscale via CSS
canvas.width = Math.round(this.constants.width * ratio);
canvas.height = Math.round(this.constants.height * ratio);
canvas.style.width = this.constants.width +'px';
canvas.style.height = this.constants.height +'px';
// Scale the context so we get accurate pixel density
context.setTransform(ratio, 0, 0, ratio, 0, 0);
this.viewport = canvas;
this.viewport.id = "gameViewport";
// Get and store the canvas context as a global
this.context = this.viewport.getContext('2d');
// Append viewport into our game within the dom
this.game = document.querySelector(this.game);
this.game.insertBefore(this.viewport, this.game.firstChild);
// Initiate core modules with the current scope
this.loop = new loop( this );
this.intitiate ();
}
intitiate () {
}
update (scope, now) {
var state = scope.state || [];
var entities = state.entities;
for (var entity = 0; entity < entities.length; entity++) {
// Fire off each active entities `render` method
entities[entity].update();
}
}
render (scope, now) {
// Setup globals
var w = scope.constants.width,
h = scope.constants.height;
// Clear out the canvas
scope.context.font = scope.constants.font;
scope.context.save();
scope.context.clearRect(0, 0, w, h);
scope.context.fillStyle = scope.constants.bgcolor;
scope.context.fillRect(0, 0, w, h);
scope.context.fill();
scope.context.restore();
// Spit out some text
scope.context.fillStyle = scope.constants.color;
// If we want to show the FPS, then render it in the top right corner.
if (scope.constants.debug) {
scope.context.fillText('fps : ' + scope.loop.fps, w - 100, 50);
}
// If there are entities, iterate through them and call their `render` methods
var state = scope.state || [];
var entities = state.entities;
for (var entity = 0; entity < entities.length; entity++) {
// Fire off each active entities `render` method
entities[entity].render();
}
}
};
class loop {
constructor ( scope ) {
return this.loop(scope);
}
loop (scope) {
var loop = {};
// Initialize timer variables so we can calculate FPS
var fps = scope.constants.frames,
fpsInterval = 1000 / fps,
before = window.performance.now(),
// Set up an object to contain our alternating FPS calculations
cycles = {
new: {
frameCount: 0,
startTime: before,
sinceStart: 0
},
old: {
frameCount: 0,
startTime: before,
sineStart: 0
}
},
// Alternating Frame Rate vars
resetInterval = 5,
resetState = 'new';
loop.fps = 0;
// Main game rendering loop
loop.main = function mainLoop( tframe ) {
// Request a new Animation Frame
// setting to `stopLoop` so animation can be stopped via
// `window.cancelAnimationFrame( loop.stopLoop )`
loop.stopLoop = window.requestAnimationFrame( loop.main );
// How long ago since last loop?
var now = tframe,
elapsed = now - before,
activeCycle, targetResetInterval;
// If it's been at least our desired interval, render
if (elapsed > fpsInterval) {
// Set before = now for next frame, also adjust for
// specified fpsInterval not being a multiple of rAF's interval (16.7ms)
// ( http://stackoverflow.com/a/19772220 )
before = now - (elapsed % fpsInterval);
// Increment the vals for both the active and the alternate FPS calculations
for (var calc in cycles) {
++cycles[calc].frameCount;
cycles[calc].sinceStart = now - cycles[calc].startTime;
}
// Choose the correct FPS calculation, then update the exposed fps value
activeCycle = cycles[resetState];
loop.fps = Math.round(1000 / (activeCycle.sinceStart / activeCycle.frameCount) * 100) / 100;
// If our frame counts are equal....
targetResetInterval = (cycles.new.frameCount === cycles.old.frameCount
? resetInterval * fps // Wait our interval
: (resetInterval * 2) * fps); // Wait double our interval
// If the active calculation goes over our specified interval,
// reset it to 0 and flag our alternate calculation to be active
// for the next series of animations.
if (activeCycle.frameCount > targetResetInterval) {
cycles[resetState].frameCount = 0;
cycles[resetState].startTime = now;
cycles[resetState].sinceStart = 0;
resetState = (resetState === 'new' ? 'old' : 'new');
}
// Update the game state
scope.update(scope, now );
// Render the next frame
scope.render(scope, now);
}
};
// Start off main loop
loop.main();
return loop;
}
}
class game {
constructor (game, width, height, frames, debug) {
this.game = game || 'body'
this.constants = {
gravity: {
x: 0,
y: 100
},
module.exports = game
})(window);
width: width,
height: height,
frames: frames,
debug: debug,
bgcolor: 'rgba(0,0,0,0)',
color: '#ff0',
font: '1em Arial'
}
this.state = {
entities: []
}
// Generate a canvas and store it as our viewport
var canvas = document.createElement('canvas')
var context = canvas.getContext('2d')
// Pass our canvas' context to our getPixelRatio method
var backingStores = ['webkitBackingStorePixelRatio', 'mozBackingStorePixelRatio', 'msBackingStorePixelRatio', 'oBackingStorePixelRatio', 'backingStorePixelRatio']
var deviceRatio = window.devicePixelRatio
// Iterate through our backing store props and determine the proper backing ratio.
var backingRatio = backingStores.reduce(function (prev, curr) {
return (context.hasOwnProperty(curr) ? context[curr] : 1)
})
// Return the proper pixel ratio by dividing the device ratio by the backing ratio
var ratio = deviceRatio / backingRatio
// Set the canvas' width then downscale via CSS
canvas.width = Math.round(this.constants.width * ratio)
canvas.height = Math.round(this.constants.height * ratio)
canvas.style.width = this.constants.width + 'px'
canvas.style.height = this.constants.height + 'px'
// Scale the context so we get accurate pixel density
context.setTransform(ratio, 0, 0, ratio, 0, 0)
this.viewport = canvas
this.viewport.id = 'gameViewport'
// Get and store the canvas context as a global
this.context = this.viewport.getContext('2d')
// Append viewport into our game within the dom
this.game = document.querySelector(this.game)
this.game.insertBefore(this.viewport, this.game.firstChild)
// Initiate core modules with the current scope
this.loop = new loop(this)
this.intitiate()
}
intitiate () {
}
update (scope, now) {
var state = scope.state || []
var entities = state.entities
for (var entity = 0; entity < entities.length; entity++) {
// Fire off each active entities `render` method
entities[entity].update()
}
}
render (scope, now) {
// Setup globals
var w = scope.constants.width
var h = scope.constants.height
// Clear out the canvas
scope.context.font = scope.constants.font
scope.context.save()
scope.context.clearRect(0, 0, w, h)
scope.context.fillStyle = scope.constants.bgcolor
scope.context.fillRect(0, 0, w, h)
scope.context.fill()
scope.context.restore()
// Spit out some text
scope.context.fillStyle = scope.constants.color
// If we want to show the FPS, then render it in the top right corner.
if (scope.constants.debug) {
scope.context.fillText('fps : ' + scope.loop.fps, w - 100, 50)
}
// If there are entities, iterate through them and call their `render` methods
var state = scope.state || []
var entities = state.entities
for (var entity = 0; entity < entities.length; entity++) {
// Fire off each active entities `render` method
entities[entity].render()
}
}
};
class loop {
constructor (scope) {
return this.loop(scope)
}
loop (scope) {
var loop = {}
// Initialize timer variables so we can calculate FPS
var fps = scope.constants.frames
var fpsInterval = 1000 / fps
var before = window.performance.now()
// Set up an object to contain our alternating FPS calculations
var cycles = {
new: {
frameCount: 0,
startTime: before,
sinceStart: 0
},
old: {
frameCount: 0,
startTime: before,
sineStart: 0
}
}
// Alternating Frame Rate vars
var resetInterval = 5
var resetState = 'new'
loop.fps = 0
// Main game rendering loop
loop.main = function mainLoop (tframe) {
// Request a new Animation Frame
// setting to `stopLoop` so animation can be stopped via
// `window.cancelAnimationFrame( loop.stopLoop )`
loop.stopLoop = window.requestAnimationFrame(loop.main)
// How long ago since last loop?
var now = tframe
var elapsed = now - before
var activeCycle
var targetResetInterval
// If it's been at least our desired interval, render
if (elapsed > fpsInterval) {
// Set before = now for next frame, also adjust for
// specified fpsInterval not being a multiple of rAF's interval (16.7ms)
// ( http://stackoverflow.com/a/19772220 )
before = now - (elapsed % fpsInterval)
// Increment the vals for both the active and the alternate FPS calculations
for (var calc in cycles) {
++cycles[calc].frameCount
cycles[calc].sinceStart = now - cycles[calc].startTime
}
// Choose the correct FPS calculation, then update the exposed fps value
activeCycle = cycles[resetState]
loop.fps = Math.round(1000 / (activeCycle.sinceStart / activeCycle.frameCount) * 100) / 100
// If our frame counts are equal....
targetResetInterval = (cycles.new.frameCount === cycles.old.frameCount
? resetInterval * fps // Wait our interval
: (resetInterval * 2) * fps) // Wait double our interval
// If the active calculation goes over our specified interval,
// reset it to 0 and flag our alternate calculation to be active
// for the next series of animations.
if (activeCycle.frameCount > targetResetInterval) {
cycles[resetState].frameCount = 0
cycles[resetState].startTime = now
cycles[resetState].sinceStart = 0
resetState = (resetState === 'new' ? 'old' : 'new')
}
// Update the game state
scope.update(scope, now)
// Render the next frame
scope.render(scope, now)
}
}
// Start off main loop
loop.main()
return loop
}
}
export { game }

@@ -1,21 +0,16 @@

"use strict";
class input() {
constructor {
class input () {
constructor {
this.isPressed = {};
// Set up `onkeydown` event handler.
document.onkeydown = function (ev) {
this.isPressed[ev.keyCode] = true;
};
// Set up `onkeyup` event handler.
document.onkeyup = function (ev) {
this.isPressed[ev.keyCode] = false;
};
}
this.isPressed = {}
// Set up `onkeydown` event handler.
document.onkeydown = function(ev) {
this.isPressed[ev.keyCode] = true
}
// Set up `onkeyup` event handler.
document.onkeyup = function(ev) {
this.isPressed[ev.keyCode] = false
}
}
}
module.exports = input;
export { input }

@@ -1,40 +0,49 @@

(function(window){ "use strict";
// TODO callback
class loader {
constructor () {
this.resourceCache = {};
}
load(resource) {
var that = this;
if(resource instanceof Array) {
resource.forEach(function(url) {
that.fetch(url);
});
}
else {
that.fetch(resource);
}
}
fetch(url) {
var that = this;
if(that.resourceCache[url]) {
return that.resourceCache[url];
}
else {
var img = new Image();
img.src = url;
that.resourceCache[url] = img;
}
}
};
module.exports = loader
})(window);
class loader {
constructor () {
this.rescache = {}
}
load (res, cbk) {
var that = this
if (res instanceof Array) {
res.forEach(function (url) {
that.rescache[url] = false
that.fetch(url, cbk)
})
} else {
that.rescache[url] = false
that.fetch(res, cbk)
}
}
fetch (url, cbk) {
var that = this
if (that.rescache[url]) {
return that.rescache[url]
} else {
var img = new Image()
img.onload = function () {
that.rescache[url] = img
that.ready(cbk)
}
img.src = url
}
}
ready (cbk) {
var that = this
if (typeof cbk === 'function') {
var ready = true
for (var item in that.rescache) {
if (that.rescache.hasOwnProperty(item) && !that.rescache[item]) {
ready = false
}
}
if (ready) cbk()
}
}
}
export { loader }

@@ -1,87 +0,83 @@

(function(window){ "use strict";
// modified soundbox.js lib
class sound {
constructor () {
this.sounds = {} // The loaded sounds and their instances
this.instances = [] // Sounds that are currently playing
this.default_volume = 1
}
constructor () {
this.sounds = {}; // The loaded sounds and their instances
this.instances = []; // Sounds that are currently playing
this.default_volume = 1;
}
load (sound_name, path, callback) {
this.sounds[sound_name] = new Audio(path);
if(typeof callback == "function")
this.sounds[sound_name].addEventListener("canplaythrough", callback);
else
return new Promise((resolve, reject) => {
this.sounds[sound_name].addEventListener("canplaythrough", resolve);
this.sounds[sound_name].addEventListener("error", reject);
});
};
remove (sound_name) {
if(typeof this.sounds != "undefined")
delete this.sounds[sound_name];
};
unlock ( sound_name, callback, volume , loop ) {
var that = this;
var events = ['touchstart', 'touchend', 'mousedown', 'keydown'];
var unlock = function unlock() {
events.forEach(function (event) {
document.body.removeEventListener(event, unlock)
});
that.play( sound_name, callback, volume , loop );
};
events.forEach(function (event) {
document.body.addEventListener(event, unlock, false)
});
}
play ( sound_name, callback, volume , loop ) {
loop = loop || false;
if(typeof this.sounds[sound_name] == "undefined") {
console.error("Can't find sound called '" + sound_name + "'.");
return false;
}
var soundInstance = this.sounds[sound_name].cloneNode(true);
soundInstance.volume = typeof volume === 'number' ? volume : this.default_volume;
soundInstance.loop = loop;
soundInstance.play();
this.instances.push(soundInstance);
// Don't forget to remove the instance from the instances array
soundInstance.addEventListener("ended", () => {
var index = this.instances.indexOf(soundInstance);
if(index != -1) this.instances.splice(index, 1);
});
// Attach the callback / promise
if(typeof callback == "function") {
soundInstance.addEventListener("ended", callback);
return true;
}
return new Promise((resolve, reject) => soundInstance.addEventListener("ended", resolve));
};
stop_all () {
// Pause all currently playing sounds
// Shallow clone the array to avoid issues with instances auto-removing themselves
var instances_to_stop = this.instances.slice();
for(var instance of instances_to_stop) {
instance.pause();
instance.dispatchEvent(new Event("ended"));
}
}
load (sound_name, path, callback) {
this.sounds[sound_name] = new Audio(path)
if (typeof callback === 'function') {
this.sounds[sound_name].addEventListener('canplaythrough', callback)
} else {
return new Promise((resolve, reject) => {
this.sounds[sound_name].addEventListener('canplaythrough', resolve)
this.sounds[sound_name].addEventListener('error', reject)
})
}
};
remove (sound_name) {
if (typeof this.sounds !== 'undefined') {
delete this.sounds[sound_name]
}
};
unlock (sound_name, callback, volume, loop) {
var that = this
var events = ['touchstart', 'touchend', 'mousedown', 'keydown']
var unlock = function unlock () {
events.forEach(function (event) {
document.body.removeEventListener(event, unlock)
})
that.play(sound_name, callback, volume, loop)
}
events.forEach(function (event) {
document.body.addEventListener(event, unlock, false)
})
}
play (sound_name, callback, volume, loop) {
loop = loop || false
if (typeof this.sounds[sound_name] === 'undefined') {
console.error("Can't find sound called '" + sound_name + "'.")
return false
}
var soundInstance = this.sounds[sound_name].cloneNode(true)
soundInstance.volume = typeof volume === 'number' ? volume : this.default_volume
soundInstance.loop = loop
soundInstance.play()
this.instances.push(soundInstance)
// Don't forget to remove the instance from the instances array
soundInstance.addEventListener('ended', () => {
var index = this.instances.indexOf(soundInstance)
if (index != -1) this.instances.splice(index, 1)
})
// Attach the callback / promise
if (typeof callback === 'function') {
soundInstance.addEventListener('ended', callback)
return true
}
return new Promise((resolve, reject) => soundInstance.addEventListener('ended', resolve))
};
stop_all () {
// Pause all currently playing sounds
// Shallow clone the array to avoid issues with instances auto-removing themselves
var instances_to_stop = this.instances.slice()
for (var instance of instances_to_stop) {
instance.pause()
instance.dispatchEvent(new Event('ended'))
}
}
}
module.exports = sound
})(window);
export { sound }

@@ -1,22 +0,18 @@

"use strict";
'use strict'
// load craters.js script tag works too
require('./craters/craters.js');
import { game } from './craters/craters.js'
class mygame extends craters.game {
intitiate () {
super.intitiate();
// now intitiate my game
}
render () {
super.render(this);
this.context.font = '2em Arial';
this.context.fillText('It\'s working.️', 65, (this.constants.height / 2), (this.constants.width));
}
class mygame extends game {
intitiate() {
super.intitiate()
// now intitiate my game
}
render() {
super.render(this)
this.context.font = '2em Arial'
this.context.fillText('It\'s working.️', 65, (this.constants.height / 2), (this.constants.width))
}
}
window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, true);
window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, true)

@@ -6,68 +6,66 @@ /** virtualJoystick Utility Module

*/
var virtualJoystick = function(opts)
{
opts = opts || {};
this._container = opts.container || document.body;
this._strokeStyle = opts.strokeStyle || 'cyan';
this._stickEl = opts.stickElement || this._buildJoystickStick();
this._baseEl = opts.baseElement || this._buildJoystickBase();
this._mouseSupport = opts.mouseSupport !== undefined ? opts.mouseSupport : false;
this._stationaryBase = opts.stationaryBase || false;
this._baseX = this._stickX = opts.baseX || 0
this._baseY = this._stickY = opts.baseY || 0
this._limitStickTravel = opts.limitStickTravel || false
this._stickRadius = opts.stickRadius !== undefined ? opts.stickRadius : 100
this._useCssTransform = opts.useCssTransform !== undefined ? opts.useCssTransform : false
var virtualJoystick = function (opts) {
opts = opts || {}
this._container = opts.container || document.body
this._strokeStyle = opts.strokeStyle || 'cyan'
this._stickEl = opts.stickElement || this._buildJoystickStick()
this._baseEl = opts.baseElement || this._buildJoystickBase()
this._mouseSupport = opts.mouseSupport !== undefined ? opts.mouseSupport : false
this._stationaryBase = opts.stationaryBase || false
this._baseX = this._stickX = opts.baseX || 0
this._baseY = this._stickY = opts.baseY || 0
this._limitStickTravel = opts.limitStickTravel || false
this._stickRadius = opts.stickRadius !== undefined ? opts.stickRadius : 100
this._useCssTransform = opts.useCssTransform !== undefined ? opts.useCssTransform : false
this._container.style.position = "relative"
this._container.style.position = 'relative'
this._container.appendChild(this._baseEl)
this._baseEl.style.position = "absolute"
this._baseEl.style.display = "none"
this._container.appendChild(this._stickEl)
this._stickEl.style.position = "absolute"
this._stickEl.style.display = "none"
this._container.appendChild(this._baseEl)
this._baseEl.style.position = 'absolute'
this._baseEl.style.display = 'none'
this._container.appendChild(this._stickEl)
this._stickEl.style.position = 'absolute'
this._stickEl.style.display = 'none'
this._pressed = false;
this._touchIdx = null;
if(this._stationaryBase === true){
this._baseEl.style.display = "";
this._baseEl.style.left = (this._baseX - this._baseEl.width /2)+"px";
this._baseEl.style.top = (this._baseY - this._baseEl.height/2)+"px";
}
this._transform = this._useCssTransform ? this._getTransformProperty() : false;
this._has3d = this._check3D();
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
this._$onTouchStart = __bind(this._onTouchStart , this);
this._$onTouchEnd = __bind(this._onTouchEnd , this);
this._$onTouchMove = __bind(this._onTouchMove , this);
this._container.addEventListener( 'touchstart' , this._$onTouchStart , false );
this._container.addEventListener( 'touchend' , this._$onTouchEnd , false );
this._container.addEventListener( 'touchmove' , this._$onTouchMove , false );
if( this._mouseSupport ){
this._$onMouseDown = __bind(this._onMouseDown , this);
this._$onMouseUp = __bind(this._onMouseUp , this);
this._$onMouseMove = __bind(this._onMouseMove , this);
this._container.addEventListener( 'mousedown' , this._$onMouseDown , false );
this._container.addEventListener( 'mouseup' , this._$onMouseUp , false );
this._container.addEventListener( 'mousemove' , this._$onMouseMove , false );
}
this._pressed = false
this._touchIdx = null
if (this._stationaryBase === true) {
this._baseEl.style.display = ''
this._baseEl.style.left = (this._baseX - this._baseEl.width / 2) + 'px'
this._baseEl.style.top = (this._baseY - this._baseEl.height / 2) + 'px'
}
this._transform = this._useCssTransform ? this._getTransformProperty() : false
this._has3d = this._check3D()
var __bind = function (fn, me) { return function () { return fn.apply(me, arguments) } }
this._$onTouchStart = __bind(this._onTouchStart, this)
this._$onTouchEnd = __bind(this._onTouchEnd, this)
this._$onTouchMove = __bind(this._onTouchMove, this)
this._container.addEventListener('touchstart', this._$onTouchStart, false)
this._container.addEventListener('touchend', this._$onTouchEnd, false)
this._container.addEventListener('touchmove', this._$onTouchMove, false)
if (this._mouseSupport) {
this._$onMouseDown = __bind(this._onMouseDown, this)
this._$onMouseUp = __bind(this._onMouseUp, this)
this._$onMouseMove = __bind(this._onMouseMove, this)
this._container.addEventListener('mousedown', this._$onMouseDown, false)
this._container.addEventListener('mouseup', this._$onMouseUp, false)
this._container.addEventListener('mousemove', this._$onMouseMove, false)
}
}
virtualJoystick.prototype.destroy = function()
{
this._container.removeChild(this._baseEl);
this._container.removeChild(this._stickEl);
virtualJoystick.prototype.destroy = function () {
this._container.removeChild(this._baseEl)
this._container.removeChild(this._stickEl)
this._container.removeEventListener( 'touchstart' , this._$onTouchStart , false );
this._container.removeEventListener( 'touchend' , this._$onTouchEnd , false );
this._container.removeEventListener( 'touchmove' , this._$onTouchMove , false );
if( this._mouseSupport ){
this._container.removeEventListener( 'mouseup' , this._$onMouseUp , false );
this._container.removeEventListener( 'mousedown' , this._$onMouseDown , false );
this._container.removeEventListener( 'mousemove' , this._$onMouseMove , false );
}
this._container.removeEventListener('touchstart', this._$onTouchStart, false)
this._container.removeEventListener('touchend', this._$onTouchEnd, false)
this._container.removeEventListener('touchmove', this._$onTouchMove, false)
if (this._mouseSupport) {
this._container.removeEventListener('mouseup', this._$onMouseUp, false)
this._container.removeEventListener('mousedown', this._$onMouseDown, false)
this._container.removeEventListener('mousemove', this._$onMouseMove, false)
}
}

@@ -78,5 +76,4 @@

*/
virtualJoystick.touchScreenAvailable = function()
{
return 'createTouch' in document ? true : false;
virtualJoystick.touchScreenAvailable = function () {
return 'createTouch' in document
}

@@ -87,236 +84,225 @@

*/
;(function(destObj){
destObj.addEventListener = function(event, fct){
if(this._events === undefined) this._events = {};
this._events[event] = this._events[event] || [];
this._events[event].push(fct);
return fct;
};
destObj.removeEventListener = function(event, fct){
if(this._events === undefined) this._events = {};
if( event in this._events === false ) return;
this._events[event].splice(this._events[event].indexOf(fct), 1);
};
destObj.dispatchEvent = function(event /* , args... */){
if(this._events === undefined) this._events = {};
if( this._events[event] === undefined ) return;
var tmpArray = this._events[event].slice();
for(var i = 0; i < tmpArray.length; i++){
var result = tmpArray[i].apply(this, Array.prototype.slice.call(arguments, 1))
if( result !== undefined ) return result;
}
return undefined
};
})(virtualJoystick.prototype);
;(function (destObj) {
destObj.addEventListener = function (event, fct) {
if (this._events === undefined) this._events = {}
this._events[event] = this._events[event] || []
this._events[event].push(fct)
return fct
}
destObj.removeEventListener = function (event, fct) {
if (this._events === undefined) this._events = {}
if (event in this._events === false) return
this._events[event].splice(this._events[event].indexOf(fct), 1)
}
destObj.dispatchEvent = function (event /* , args... */) {
if (this._events === undefined) this._events = {}
if (this._events[event] === undefined) return
var tmpArray = this._events[event].slice()
for (var i = 0; i < tmpArray.length; i++) {
var result = tmpArray[i].apply(this, Array.prototype.slice.call(arguments, 1))
if (result !== undefined) return result
}
return undefined
}
})(virtualJoystick.prototype)
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
// //
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
virtualJoystick.prototype.deltaX = function(){ return this._stickX - this._baseX; }
virtualJoystick.prototype.deltaY = function(){ return this._stickY - this._baseY; }
virtualJoystick.prototype.deltaX = function () { return this._stickX - this._baseX }
virtualJoystick.prototype.deltaY = function () { return this._stickY - this._baseY }
virtualJoystick.prototype.up = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaY >= 0 ) return false;
if( Math.abs(deltaX) > 2*Math.abs(deltaY) ) return false;
return true;
virtualJoystick.prototype.up = function () {
if (this._pressed === false) return false
var deltaX = this.deltaX()
var deltaY = this.deltaY()
if (deltaY >= 0) return false
if (Math.abs(deltaX) > 2 * Math.abs(deltaY)) return false
return true
}
virtualJoystick.prototype.down = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaY <= 0 ) return false;
if( Math.abs(deltaX) > 2*Math.abs(deltaY) ) return false;
return true;
virtualJoystick.prototype.down = function () {
if (this._pressed === false) return false
var deltaX = this.deltaX()
var deltaY = this.deltaY()
if (deltaY <= 0) return false
if (Math.abs(deltaX) > 2 * Math.abs(deltaY)) return false
return true
}
virtualJoystick.prototype.right = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaX <= 0 ) return false;
if( Math.abs(deltaY) > 2*Math.abs(deltaX) ) return false;
return true;
virtualJoystick.prototype.right = function () {
if (this._pressed === false) return false
var deltaX = this.deltaX()
var deltaY = this.deltaY()
if (deltaX <= 0) return false
if (Math.abs(deltaY) > 2 * Math.abs(deltaX)) return false
return true
}
virtualJoystick.prototype.left = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaX >= 0 ) return false;
if( Math.abs(deltaY) > 2*Math.abs(deltaX) ) return false;
return true;
virtualJoystick.prototype.left = function () {
if (this._pressed === false) return false
var deltaX = this.deltaX()
var deltaY = this.deltaY()
if (deltaX >= 0) return false
if (Math.abs(deltaY) > 2 * Math.abs(deltaX)) return false
return true
}
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
// //
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
virtualJoystick.prototype._onUp = function()
{
this._pressed = false;
this._stickEl.style.display = "none";
if(this._stationaryBase == false){
this._baseEl.style.display = "none";
this._baseX = this._baseY = 0;
this._stickX = this._stickY = 0;
}
virtualJoystick.prototype._onUp = function () {
this._pressed = false
this._stickEl.style.display = 'none'
if (this._stationaryBase == false) {
this._baseEl.style.display = 'none'
this._baseX = this._baseY = 0
this._stickX = this._stickY = 0
}
}
virtualJoystick.prototype._onDown = function(x, y)
{
this._pressed = true;
if(this._stationaryBase == false){
this._baseX = x;
this._baseY = y;
this._baseEl.style.display = "";
this._move(this._baseEl.style, (this._baseX - this._baseEl.width /2), (this._baseY - this._baseEl.height/2));
}
this._stickX = x;
this._stickY = y;
if(this._limitStickTravel === true){
var deltaX = this.deltaX();
var deltaY = this.deltaY();
var stickDistance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) );
if(stickDistance > this._stickRadius){
var stickNormalizedX = deltaX / stickDistance;
var stickNormalizedY = deltaY / stickDistance;
this._stickX = stickNormalizedX * this._stickRadius + this._baseX;
this._stickY = stickNormalizedY * this._stickRadius + this._baseY;
}
}
this._stickEl.style.display = "";
this._move(this._stickEl.style, (this._stickX - this._stickEl.width /2), (this._stickY - this._stickEl.height/2));
virtualJoystick.prototype._onDown = function (x, y) {
this._pressed = true
if (this._stationaryBase == false) {
this._baseX = x
this._baseY = y
this._baseEl.style.display = ''
this._move(this._baseEl.style, (this._baseX - this._baseEl.width / 2), (this._baseY - this._baseEl.height / 2))
}
this._stickX = x
this._stickY = y
if (this._limitStickTravel === true) {
var deltaX = this.deltaX()
var deltaY = this.deltaY()
var stickDistance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))
if (stickDistance > this._stickRadius) {
var stickNormalizedX = deltaX / stickDistance
var stickNormalizedY = deltaY / stickDistance
this._stickX = stickNormalizedX * this._stickRadius + this._baseX
this._stickY = stickNormalizedY * this._stickRadius + this._baseY
}
}
this._stickEl.style.display = ''
this._move(this._stickEl.style, (this._stickX - this._stickEl.width / 2), (this._stickY - this._stickEl.height / 2))
}
virtualJoystick.prototype._onMove = function(x, y)
{
if( this._pressed === true ){
this._stickX = x;
this._stickY = y;
if(this._limitStickTravel === true){
var deltaX = this.deltaX();
var deltaY = this.deltaY();
var stickDistance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) );
if(stickDistance > this._stickRadius){
var stickNormalizedX = deltaX / stickDistance;
var stickNormalizedY = deltaY / stickDistance;
this._stickX = stickNormalizedX * this._stickRadius + this._baseX;
this._stickY = stickNormalizedY * this._stickRadius + this._baseY;
}
}
this._move(this._stickEl.style, (this._stickX - this._stickEl.width /2), (this._stickY - this._stickEl.height/2));
}
virtualJoystick.prototype._onMove = function (x, y) {
if (this._pressed === true) {
this._stickX = x
this._stickY = y
if (this._limitStickTravel === true) {
var deltaX = this.deltaX()
var deltaY = this.deltaY()
var stickDistance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))
if (stickDistance > this._stickRadius) {
var stickNormalizedX = deltaX / stickDistance
var stickNormalizedY = deltaY / stickDistance
this._stickX = stickNormalizedX * this._stickRadius + this._baseX
this._stickY = stickNormalizedY * this._stickRadius + this._baseY
}
}
this._move(this._stickEl.style, (this._stickX - this._stickEl.width / 2), (this._stickY - this._stickEl.height / 2))
}
}
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
// bind touch events (and mouse events for debug) //
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
virtualJoystick.prototype._onMouseUp = function(event)
{
return this._onUp();
virtualJoystick.prototype._onMouseUp = function (event) {
return this._onUp()
}
virtualJoystick.prototype._onMouseDown = function(event)
{
event.preventDefault();
var x = event.clientX;
var y = event.clientY;
return this._onDown(x, y);
virtualJoystick.prototype._onMouseDown = function (event) {
event.preventDefault()
var x = event.clientX
var y = event.clientY
return this._onDown(x, y)
}
virtualJoystick.prototype._onMouseMove = function(event)
{
var x = event.clientX;
var y = event.clientY;
return this._onMove(x, y);
virtualJoystick.prototype._onMouseMove = function (event) {
var x = event.clientX
var y = event.clientY
return this._onMove(x, y)
}
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
// comment //
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
virtualJoystick.prototype._onTouchStart = function(event)
{
// if there is already a touch inprogress do nothing
if( this._touchIdx !== null ) return;
virtualJoystick.prototype._onTouchStart = function (event) {
// if there is already a touch inprogress do nothing
if (this._touchIdx !== null) return
// notify event for validation
var isValid = this.dispatchEvent('touchStartValidation', event);
if( isValid === false ) return;
// dispatch touchStart
this.dispatchEvent('touchStart', event);
// notify event for validation
var isValid = this.dispatchEvent('touchStartValidation', event)
if (isValid === false) return
event.preventDefault();
// get the first who changed
var touch = event.changedTouches[0];
// set the touchIdx of this joystick
this._touchIdx = touch.identifier;
// dispatch touchStart
this.dispatchEvent('touchStart', event)
// forward the action
var x = touch.pageX;
var y = touch.pageY;
return this._onDown(x, y)
event.preventDefault()
// get the first who changed
var touch = event.changedTouches[0]
// set the touchIdx of this joystick
this._touchIdx = touch.identifier
// forward the action
var x = touch.pageX
var y = touch.pageY
return this._onDown(x, y)
}
virtualJoystick.prototype._onTouchEnd = function(event)
{
// if there is no touch in progress, do nothing
if( this._touchIdx === null ) return;
virtualJoystick.prototype._onTouchEnd = function (event) {
// if there is no touch in progress, do nothing
if (this._touchIdx === null) return
// dispatch touchEnd
this.dispatchEvent('touchEnd', event);
// dispatch touchEnd
this.dispatchEvent('touchEnd', event)
// try to find our touch event
var touchList = event.changedTouches;
for(var i = 0; i < touchList.length && touchList[i].identifier !== this._touchIdx; i++);
// if touch event isnt found,
if( i === touchList.length) return;
// try to find our touch event
var touchList = event.changedTouches
for (var i = 0; i < touchList.length && touchList[i].identifier !== this._touchIdx; i++);
// if touch event isnt found,
if (i === touchList.length) return
// reset touchIdx - mark it as no-touch-in-progress
this._touchIdx = null;
// reset touchIdx - mark it as no-touch-in-progress
this._touchIdx = null
//??????
// no preventDefault to get click event on ios
event.preventDefault();
// ??????
// no preventDefault to get click event on ios
event.preventDefault()
return this._onUp()
return this._onUp()
}
virtualJoystick.prototype._onTouchMove = function(event)
{
// if there is no touch in progress, do nothing
if( this._touchIdx === null ) return;
virtualJoystick.prototype._onTouchMove = function (event) {
// if there is no touch in progress, do nothing
if (this._touchIdx === null) return
// try to find our touch event
var touchList = event.changedTouches;
for(var i = 0; i < touchList.length && touchList[i].identifier !== this._touchIdx; i++ );
// if touch event with the proper identifier isnt found, do nothing
if( i === touchList.length) return;
var touch = touchList[i];
// try to find our touch event
var touchList = event.changedTouches
for (var i = 0; i < touchList.length && touchList[i].identifier !== this._touchIdx; i++);
// if touch event with the proper identifier isnt found, do nothing
if (i === touchList.length) return
var touch = touchList[i]
event.preventDefault();
event.preventDefault()
var x = touch.pageX;
var y = touch.pageY;
return this._onMove(x, y)
var x = touch.pageX
var y = touch.pageY
return this._onMove(x, y)
}
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
// build default stickEl and baseEl //
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////

@@ -326,22 +312,21 @@ /**

*/
virtualJoystick.prototype._buildJoystickBase = function()
{
var canvas = document.createElement( 'canvas' );
canvas.width = 126;
canvas.height = 126;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = this._strokeStyle;
ctx.lineWidth = 6;
ctx.arc( canvas.width/2, canvas.width/2, 40, 0, Math.PI*2, true);
ctx.stroke();
virtualJoystick.prototype._buildJoystickBase = function () {
var canvas = document.createElement('canvas')
canvas.width = 126
canvas.height = 126
ctx.beginPath();
ctx.strokeStyle = this._strokeStyle;
ctx.lineWidth = 2;
ctx.arc( canvas.width/2, canvas.width/2, 60, 0, Math.PI*2, true);
ctx.stroke();
return canvas;
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.strokeStyle = this._strokeStyle
ctx.lineWidth = 6
ctx.arc(canvas.width / 2, canvas.width / 2, 40, 0, Math.PI * 2, true)
ctx.stroke()
ctx.beginPath()
ctx.strokeStyle = this._strokeStyle
ctx.lineWidth = 2
ctx.arc(canvas.width / 2, canvas.width / 2, 60, 0, Math.PI * 2, true)
ctx.stroke()
return canvas
}

@@ -352,80 +337,76 @@

*/
virtualJoystick.prototype._buildJoystickStick = function()
{
var canvas = document.createElement( 'canvas' );
canvas.width = 86;
canvas.height = 86;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = this._strokeStyle;
ctx.lineWidth = 6;
ctx.arc( canvas.width/2, canvas.width/2, 40, 0, Math.PI*2, true);
ctx.stroke();
return canvas;
virtualJoystick.prototype._buildJoystickStick = function () {
var canvas = document.createElement('canvas')
canvas.width = 86
canvas.height = 86
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.strokeStyle = this._strokeStyle
ctx.lineWidth = 6
ctx.arc(canvas.width / 2, canvas.width / 2, 40, 0, Math.PI * 2, true)
ctx.stroke()
return canvas
}
//////////////////////////////////////////////////////////////////////////////////
// move using translate3d method with fallback to translate > 'top' and 'left'
/// ///////////////////////////////////////////////////////////////////////////////
// move using translate3d method with fallback to translate > 'top' and 'left'
// modified from https://github.com/component/translate and dependents
//////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////
virtualJoystick.prototype._move = function(style, x, y)
{
if (this._transform) {
if (this._has3d) {
style[this._transform] = 'translate3d(' + x + 'px,' + y + 'px, 0)';
} else {
style[this._transform] = 'translate(' + x + 'px,' + y + 'px)';
}
} else {
style.left = x + 'px';
style.top = y + 'px';
}
virtualJoystick.prototype._move = function (style, x, y) {
if (this._transform) {
if (this._has3d) {
style[this._transform] = 'translate3d(' + x + 'px,' + y + 'px, 0)'
} else {
style[this._transform] = 'translate(' + x + 'px,' + y + 'px)'
}
} else {
style.left = x + 'px'
style.top = y + 'px'
}
}
virtualJoystick.prototype._getTransformProperty = function()
{
var styles = [
'webkitTransform',
'MozTransform',
'msTransform',
'OTransform',
'transform'
];
virtualJoystick.prototype._getTransformProperty = function () {
var styles = [
'webkitTransform',
'MozTransform',
'msTransform',
'OTransform',
'transform'
]
var el = document.createElement('p');
var style;
var el = document.createElement('p')
var style
for (var i = 0; i < styles.length; i++) {
style = styles[i];
if (null != el.style[style]) {
return style;
}
}
for (var i = 0; i < styles.length; i++) {
style = styles[i]
if (el.style[style] != null) {
return style
}
}
}
virtualJoystick.prototype._check3D = function()
{
var prop = this._getTransformProperty();
// IE8<= doesn't have `getComputedStyle`
if (!prop || !window.getComputedStyle) return module.exports = false;
var map = {
webkitTransform: '-webkit-transform',
OTransform: '-o-transform',
msTransform: '-ms-transform',
MozTransform: '-moz-transform',
transform: 'transform'
};
virtualJoystick.prototype._check3D = function () {
var prop = this._getTransformProperty()
// IE8<= doesn't have `getComputedStyle`
if (!prop || !window.getComputedStyle) return module.exports = false
// from: https://gist.github.com/lorenzopolidori/3794226
var el = document.createElement('div');
el.style[prop] = 'translate3d(1px,1px,1px)';
document.body.insertBefore(el, null);
var val = getComputedStyle(el).getPropertyValue(map[prop]);
document.body.removeChild(el);
var exports = null != val && val.length && 'none' != val;
return exports;
var map = {
webkitTransform: '-webkit-transform',
OTransform: '-o-transform',
msTransform: '-ms-transform',
MozTransform: '-moz-transform',
transform: 'transform'
}
// from: https://gist.github.com/lorenzopolidori/3794226
var el = document.createElement('div')
el.style[prop] = 'translate3d(1px,1px,1px)'
document.body.insertBefore(el, null)
var val = getComputedStyle(el).getPropertyValue(map[prop])
document.body.removeChild(el)
var exports = val != null && val.length && val != 'none'
return exports
}
module.exports = virtualJoystick;
module.exports = virtualJoystick

@@ -1,1 +0,1 @@

!function(t){var e={};function s(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)s.d(i,n,function(e){return t[e]}.bind(null,n));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=5)}([function(t,e,s){var i=s(1),n=s(2),o=s(3),r=s(4);Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)},function(t){"use strict";t.craters={version:"0.0.0.2",game:i,entity:n.entity,sprite:n.sprite,loader:o,sound:r}}(window)},function(t,e){!function(e){"use strict";class s{constructor(t){return this.loop(t)}loop(t){var s={},i=t.constants.frames,n=1e3/i,o=e.performance.now(),r={new:{frameCount:0,startTime:o,sinceStart:0},old:{frameCount:0,startTime:o,sineStart:0}},a="new";return s.fps=0,s.main=function(c){s.stopLoop=e.requestAnimationFrame(s.main);var h,u,d=c,l=d-o;if(l>n){for(var f in o=d-l%n,r)++r[f].frameCount,r[f].sinceStart=d-r[f].startTime;h=r[a],s.fps=Math.round(1e3/(h.sinceStart/h.frameCount)*100)/100,u=r.new.frameCount===r.old.frameCount?5*i:10*i,h.frameCount>u&&(r[a].frameCount=0,r[a].startTime=d,r[a].sinceStart=0,a="new"===a?"old":"new"),t.update(t,d),t.render(t,d)}},s.main(),s}}t.exports=class{constructor(t,i,n,o,r){this.game=t||"body",this.constants={gravity:{x:0,y:100},width:i,height:n,frames:o,debug:r,bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"},this.state={entities:[]};var a=document.createElement("canvas"),c=a.getContext("2d"),h=e.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return c.hasOwnProperty(e)?c[e]:1});a.width=Math.round(this.constants.width*h),a.height=Math.round(this.constants.height*h),a.style.width=this.constants.width+"px",a.style.height=this.constants.height+"px",c.setTransform(h,0,0,h,0,0),this.viewport=a,this.viewport.id="gameViewport",this.context=this.viewport.getContext("2d"),this.game=document.querySelector(this.game),this.game.insertBefore(this.viewport,this.game.firstChild),this.loop=new s(this),this.intitiate()}intitiate(){}update(t,e){for(var s=(t.state||[]).entities,i=0;i<s.length;i++)s[i].update()}render(t,e){var s=t.constants.width,i=t.constants.height;t.context.font=t.constants.font,t.context.save(),t.context.clearRect(0,0,s,i),t.context.fillStyle=t.constants.bgcolor,t.context.fillRect(0,0,s,i),t.context.fill(),t.context.restore(),t.context.fillStyle=t.constants.color,t.constants.debug&&t.context.fillText("fps : "+t.loop.fps,s-100,50);for(var n=(t.state||[]).entities,o=0;o<n.length;o++)n[o].render()}}}(window)},function(t,e){!function(e){"use strict";class s{constructor(){this.type=this.type||"dynamic",this.collision=this.collision||"elastic",this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0},this.entities=[]}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update();switch(this.type){case"dynamic":case"kinematic":this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}}t.exports={entity:s,sprite:class extends s{constructor(t,e){super(),this.scope=t,this.state={cord:e.pos||{x:0,y:0},pos:{x:0,y:0},size:e.size||{x:0,y:0},frames:e.frames||[],angle:e.angle||0,image:e.image||new Image,delay:e.delay||5,tick:e.tick||0,orientation:e.orientation||"horizontal"}}update(){this.state.tick<=0&&("vertical"==this.orientation?(this.state.pos.y=this.state.frames.shift(),this.state.frames.push(this.state.pos.y)):(this.state.pos.x=this.state.frames.shift(),this.state.frames.push(this.state.pos.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(this),this.scope.context.save(),this.scope.context.translate(this.state.pos.x+this.state.size.x/2,this.state.pos.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.pos.x+this.state.size.x/2),-(this.state.pos.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.pos.x*this.state.size.x,this.state.pos.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.cord.x,this.state.cord.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}}}(window)},function(t,e){!function(e){"use strict";t.exports=class{constructor(){this.resourceCache={}}load(t){var e=this;t instanceof Array?t.forEach(function(t){e.fetch(t)}):e.fetch(t)}fetch(t){if(this.resourceCache[t])return this.resourceCache[t];var e=new Image;e.src=t,this.resourceCache[t]=e}}}(window)},function(t,e){!function(e){"use strict";t.exports=class{constructor(){this.sounds={},this.instances=[],this.default_volume=1}load(t,e,s){if(this.sounds[t]=new Audio(e),"function"!=typeof s)return new Promise((e,s)=>{this.sounds[t].addEventListener("canplaythrough",e),this.sounds[t].addEventListener("error",s)});this.sounds[t].addEventListener("canplaythrough",s)}remove(t){void 0!==this.sounds&&delete this.sounds[t]}unlock(t,e,s,i){var n=this,o=["touchstart","touchend","mousedown","keydown"],r=function r(){o.forEach(function(t){document.body.removeEventListener(t,r)}),n.play(t,e,s,i)};o.forEach(function(t){document.body.addEventListener(t,r,!1)})}play(t,e,s,i){if(i=i||!1,void 0===this.sounds[t])return console.error("Can't find sound called '"+t+"'."),!1;var n=this.sounds[t].cloneNode(!0);return n.volume="number"==typeof s?s:this.default_volume,n.loop=i,n.play(),this.instances.push(n),n.addEventListener("ended",()=>{var t=this.instances.indexOf(n);-1!=t&&this.instances.splice(t,1)}),"function"==typeof e?(n.addEventListener("ended",e),!0):new Promise((t,e)=>n.addEventListener("ended",t))}stop_all(){var t=this.instances.slice();for(var e of t)e.pause(),e.dispatchEvent(new Event("ended"))}}}(window)},function(t,e,s){"use strict";s(0);window.game=new class extends craters.game{intitiate(){super.intitiate()}render(){super.render(this),this.context.font="2em Arial",this.context.fillText("It's working.️",65,this.constants.height/2,this.constants.width)}}("#container",window.innerWidth,window.innerHeight,60,!0)}]);
!function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([,function(t,e,n){"use strict";n.r(e);class i{constructor(t,e,n,i,r){this.game=t||"body",this.constants={gravity:{x:0,y:100},width:e,height:n,frames:i,debug:r,bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"},this.state={entities:[]};var a=document.createElement("canvas"),s=a.getContext("2d"),c=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return s.hasOwnProperty(e)?s[e]:1});a.width=Math.round(this.constants.width*c),a.height=Math.round(this.constants.height*c),a.style.width=this.constants.width+"px",a.style.height=this.constants.height+"px",s.setTransform(c,0,0,c,0,0),this.viewport=a,this.viewport.id="gameViewport",this.context=this.viewport.getContext("2d"),this.game=document.querySelector(this.game),this.game.insertBefore(this.viewport,this.game.firstChild),this.loop=new o(this),this.intitiate()}intitiate(){}update(t,e){for(var n=(t.state||[]).entities,i=0;i<n.length;i++)n[i].update()}render(t,e){var n=t.constants.width,i=t.constants.height;t.context.font=t.constants.font,t.context.save(),t.context.clearRect(0,0,n,i),t.context.fillStyle=t.constants.bgcolor,t.context.fillRect(0,0,n,i),t.context.fill(),t.context.restore(),t.context.fillStyle=t.constants.color,t.constants.debug&&t.context.fillText("fps : "+t.loop.fps,n-100,50);for(var o=(t.state||[]).entities,r=0;r<o.length;r++)o[r].render()}}class o{constructor(t){return this.loop(t)}loop(t){var e={},n=t.constants.frames,i=1e3/n,o=window.performance.now(),r={new:{frameCount:0,startTime:o,sinceStart:0},old:{frameCount:0,startTime:o,sineStart:0}},a="new";return e.fps=0,e.main=function(s){e.stopLoop=window.requestAnimationFrame(e.main);var c,u,l=s,f=l-o;if(f>i){for(var h in o=l-f%i,r)++r[h].frameCount,r[h].sinceStart=l-r[h].startTime;c=r[a],e.fps=Math.round(1e3/(c.sinceStart/c.frameCount)*100)/100,u=r.new.frameCount===r.old.frameCount?5*n:10*n,c.frameCount>u&&(r[a].frameCount=0,r[a].startTime=l,r[a].sinceStart=0,a="new"===a?"old":"new"),t.update(t,l),t.render(t,l)}},e.main(),e}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};window.game=new class extends i{intitiate(){super.intitiate()}render(){super.render(this),this.context.font="2em Arial",this.context.fillText("It's working.️",65,this.constants.height/2,this.constants.width)}}("#container",window.innerWidth,window.innerHeight,60,!0)}]);

@@ -7,2 +7,11 @@ #### v0.0.0.1

* loader
* sound
* sound
#### v0.0.0.3
* sprite is an entity
use case multi purpose use where image drawing is required i.e hub icons
`tip` pass a reference to entity pos and angle to keep entity synchronized with the sprite
the first argument is the scope,
* loader has a callback
use case starting the game after resource loading process is done
* ES modules
reduces bundle size by including only what you need

@@ -1,1 +0,1 @@

!function(t){var e={};function s(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)s.d(i,n,function(e){return t[e]}.bind(null,n));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e,s){var i=s(1),n=s(2),o=s(3),r=s(4);Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)},function(t){"use strict";t.craters={version:"0.0.0.2",game:i,entity:n.entity,sprite:n.sprite,loader:o,sound:r}}(window)},function(t,e){!function(e){"use strict";class s{constructor(t){return this.loop(t)}loop(t){var s={},i=t.constants.frames,n=1e3/i,o=e.performance.now(),r={new:{frameCount:0,startTime:o,sinceStart:0},old:{frameCount:0,startTime:o,sineStart:0}},a="new";return s.fps=0,s.main=function(c){s.stopLoop=e.requestAnimationFrame(s.main);var h,u,d=c,l=d-o;if(l>n){for(var f in o=d-l%n,r)++r[f].frameCount,r[f].sinceStart=d-r[f].startTime;h=r[a],s.fps=Math.round(1e3/(h.sinceStart/h.frameCount)*100)/100,u=r.new.frameCount===r.old.frameCount?5*i:10*i,h.frameCount>u&&(r[a].frameCount=0,r[a].startTime=d,r[a].sinceStart=0,a="new"===a?"old":"new"),t.update(t,d),t.render(t,d)}},s.main(),s}}t.exports=class{constructor(t,i,n,o,r){this.game=t||"body",this.constants={gravity:{x:0,y:100},width:i,height:n,frames:o,debug:r,bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"},this.state={entities:[]};var a=document.createElement("canvas"),c=a.getContext("2d"),h=e.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return c.hasOwnProperty(e)?c[e]:1});a.width=Math.round(this.constants.width*h),a.height=Math.round(this.constants.height*h),a.style.width=this.constants.width+"px",a.style.height=this.constants.height+"px",c.setTransform(h,0,0,h,0,0),this.viewport=a,this.viewport.id="gameViewport",this.context=this.viewport.getContext("2d"),this.game=document.querySelector(this.game),this.game.insertBefore(this.viewport,this.game.firstChild),this.loop=new s(this),this.intitiate()}intitiate(){}update(t,e){for(var s=(t.state||[]).entities,i=0;i<s.length;i++)s[i].update()}render(t,e){var s=t.constants.width,i=t.constants.height;t.context.font=t.constants.font,t.context.save(),t.context.clearRect(0,0,s,i),t.context.fillStyle=t.constants.bgcolor,t.context.fillRect(0,0,s,i),t.context.fill(),t.context.restore(),t.context.fillStyle=t.constants.color,t.constants.debug&&t.context.fillText("fps : "+t.loop.fps,s-100,50);for(var n=(t.state||[]).entities,o=0;o<n.length;o++)n[o].render()}}}(window)},function(t,e){!function(e){"use strict";class s{constructor(){this.type=this.type||"dynamic",this.collision=this.collision||"elastic",this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0},this.entities=[]}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update();switch(this.type){case"dynamic":case"kinematic":this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}}t.exports={entity:s,sprite:class extends s{constructor(t,e){super(),this.scope=t,this.state={cord:e.pos||{x:0,y:0},pos:{x:0,y:0},size:e.size||{x:0,y:0},frames:e.frames||[],angle:e.angle||0,image:e.image||new Image,delay:e.delay||5,tick:e.tick||0,orientation:e.orientation||"horizontal"}}update(){this.state.tick<=0&&("vertical"==this.orientation?(this.state.pos.y=this.state.frames.shift(),this.state.frames.push(this.state.pos.y)):(this.state.pos.x=this.state.frames.shift(),this.state.frames.push(this.state.pos.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(this),this.scope.context.save(),this.scope.context.translate(this.state.pos.x+this.state.size.x/2,this.state.pos.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.pos.x+this.state.size.x/2),-(this.state.pos.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.pos.x*this.state.size.x,this.state.pos.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.cord.x,this.state.cord.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}}}(window)},function(t,e){!function(e){"use strict";t.exports=class{constructor(){this.resourceCache={}}load(t){var e=this;t instanceof Array?t.forEach(function(t){e.fetch(t)}):e.fetch(t)}fetch(t){if(this.resourceCache[t])return this.resourceCache[t];var e=new Image;e.src=t,this.resourceCache[t]=e}}}(window)},function(t,e){!function(e){"use strict";t.exports=class{constructor(){this.sounds={},this.instances=[],this.default_volume=1}load(t,e,s){if(this.sounds[t]=new Audio(e),"function"!=typeof s)return new Promise((e,s)=>{this.sounds[t].addEventListener("canplaythrough",e),this.sounds[t].addEventListener("error",s)});this.sounds[t].addEventListener("canplaythrough",s)}remove(t){void 0!==this.sounds&&delete this.sounds[t]}unlock(t,e,s,i){var n=this,o=["touchstart","touchend","mousedown","keydown"],r=function r(){o.forEach(function(t){document.body.removeEventListener(t,r)}),n.play(t,e,s,i)};o.forEach(function(t){document.body.addEventListener(t,r,!1)})}play(t,e,s,i){if(i=i||!1,void 0===this.sounds[t])return console.error("Can't find sound called '"+t+"'."),!1;var n=this.sounds[t].cloneNode(!0);return n.volume="number"==typeof s?s:this.default_volume,n.loop=i,n.play(),this.instances.push(n),n.addEventListener("ended",()=>{var t=this.instances.indexOf(n);-1!=t&&this.instances.splice(t,1)}),"function"==typeof e?(n.addEventListener("ended",e),!0):new Promise((t,e)=>n.addEventListener("ended",t))}stop_all(){var t=this.instances.slice();for(var e of t)e.pause(),e.dispatchEvent(new Event("ended"))}}}(window)}]);
!function(t){var e={};function s(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)s.d(i,n,function(e){return t[e]}.bind(null,n));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e,s){"use strict";s.r(e),s.d(e,"craters",function(){return h}),s.d(e,"entity",function(){return o}),s.d(e,"game",function(){return i}),s.d(e,"loader",function(){return a}),s.d(e,"sound",function(){return c}),s.d(e,"sprite",function(){return r});class i{constructor(t,e,s,i,o){this.game=t||"body",this.constants={gravity:{x:0,y:100},width:e,height:s,frames:i,debug:o,bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"},this.state={entities:[]};var r=document.createElement("canvas"),a=r.getContext("2d"),c=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return a.hasOwnProperty(e)?a[e]:1});r.width=Math.round(this.constants.width*c),r.height=Math.round(this.constants.height*c),r.style.width=this.constants.width+"px",r.style.height=this.constants.height+"px",a.setTransform(c,0,0,c,0,0),this.viewport=r,this.viewport.id="gameViewport",this.context=this.viewport.getContext("2d"),this.game=document.querySelector(this.game),this.game.insertBefore(this.viewport,this.game.firstChild),this.loop=new n(this),this.intitiate()}intitiate(){}update(t,e){for(var s=(t.state||[]).entities,i=0;i<s.length;i++)s[i].update()}render(t,e){var s=t.constants.width,i=t.constants.height;t.context.font=t.constants.font,t.context.save(),t.context.clearRect(0,0,s,i),t.context.fillStyle=t.constants.bgcolor,t.context.fillRect(0,0,s,i),t.context.fill(),t.context.restore(),t.context.fillStyle=t.constants.color,t.constants.debug&&t.context.fillText("fps : "+t.loop.fps,s-100,50);for(var n=(t.state||[]).entities,o=0;o<n.length;o++)n[o].render()}}class n{constructor(t){return this.loop(t)}loop(t){var e={},s=t.constants.frames,i=1e3/s,n=window.performance.now(),o={new:{frameCount:0,startTime:n,sinceStart:0},old:{frameCount:0,startTime:n,sineStart:0}},r="new";return e.fps=0,e.main=function(a){e.stopLoop=window.requestAnimationFrame(e.main);var c,h,u=a,d=u-n;if(d>i){for(var l in n=u-d%i,o)++o[l].frameCount,o[l].sinceStart=u-o[l].startTime;c=o[r],e.fps=Math.round(1e3/(c.sinceStart/c.frameCount)*100)/100,h=o.new.frameCount===o.old.frameCount?5*s:10*s,c.frameCount>h&&(o[r].frameCount=0,o[r].startTime=u,o[r].sinceStart=0,r="new"===r?"old":"new"),t.update(t,u),t.render(t,u)}},e.main(),e}}class o{constructor(){this.type=this.type||"dynamic",this.collision=this.collision||"elastic",this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0},this.entities=[]}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update();switch(this.type){case"dynamic":case"kinematic":this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}}class r extends o{constructor(t,e){super(),this.scope=t,this.state={cord:e.pos||{x:0,y:0},pos:{x:0,y:0},size:e.size||{x:0,y:0},frames:e.frames||[],angle:e.angle||0,image:e.image||new Image,delay:e.delay||5,tick:e.tick||0,orientation:e.orientation||"horizontal"}}update(){this.state.tick<=0&&("vertical"==this.orientation?(this.state.pos.y=this.state.frames.shift(),this.state.frames.push(this.state.pos.y)):(this.state.pos.x=this.state.frames.shift(),this.state.frames.push(this.state.pos.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(this),this.scope.context.save(),this.scope.context.translate(this.state.pos.x+this.state.size.x/2,this.state.pos.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.pos.x+this.state.size.x/2),-(this.state.pos.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.pos.x*this.state.size.x,this.state.pos.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.cord.x,this.state.cord.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}class a{constructor(){this.rescache={}}load(t,e){var s=this;t instanceof Array?t.forEach(function(t){s.rescache[t]=!1,s.fetch(t,e)}):(s.rescache[url]=!1,s.fetch(t,e))}fetch(t,e){var s=this;if(s.rescache[t])return s.rescache[t];var i=new Image;i.onload=function(){s.rescache[t]=i,s.ready(e)},i.src=t}ready(t){if("function"==typeof t){var e=!0;for(var s in this.rescache)this.rescache.hasOwnProperty(s)&&!this.rescache[s]&&(e=!1);e&&t()}}}class c{constructor(){this.sounds={},this.instances=[],this.default_volume=1}load(t,e,s){if(this.sounds[t]=new Audio(e),"function"!=typeof s)return new Promise((e,s)=>{this.sounds[t].addEventListener("canplaythrough",e),this.sounds[t].addEventListener("error",s)});this.sounds[t].addEventListener("canplaythrough",s)}remove(t){void 0!==this.sounds&&delete this.sounds[t]}unlock(t,e,s,i){var n=this,o=["touchstart","touchend","mousedown","keydown"],r=function r(){o.forEach(function(t){document.body.removeEventListener(t,r)}),n.play(t,e,s,i)};o.forEach(function(t){document.body.addEventListener(t,r,!1)})}play(t,e,s,i){if(i=i||!1,void 0===this.sounds[t])return console.error("Can't find sound called '"+t+"'."),!1;var n=this.sounds[t].cloneNode(!0);return n.volume="number"==typeof s?s:this.default_volume,n.loop=i,n.play(),this.instances.push(n),n.addEventListener("ended",()=>{var t=this.instances.indexOf(n);-1!=t&&this.instances.splice(t,1)}),"function"==typeof e?(n.addEventListener("ended",e),!0):new Promise((t,e)=>n.addEventListener("ended",t))}stop_all(){var t=this.instances.slice();for(var e of t)e.pause(),e.dispatchEvent(new Event("ended"))}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};class h{static version(){return"0.0.0.3"}}}]);

@@ -0,10 +1,5 @@

import { game, entity, sprite, loader } from 'craters.js';
"use strict";
var media = new craters.loader;
media.load([
'./src/media/bug.png',
'./src/media/bolt.png'
]);
class mygame extends craters.game {
class mygame extends game {

@@ -34,4 +29,3 @@ intitiate () {

class ladybug extends craters.entity {
// extend the entity class
class ladybug extends entity {
constructor (scope, name) {

@@ -43,7 +37,7 @@ super();

scope.state.entities.push(new craters.sprite(scope, {pos: this.state.pos, size: this.state.size, frames: [0, 1, 2], image: media.fetch('./src/media/bug.png')}))
scope.state.entities.push(new sprite(scope, {pos: this.state.pos, size: this.state.size, frames: [0, 1, 2], image: media.fetch('./src/media/bug.png')}))
}
}
class boltbug extends craters.entity {
class boltbug extends entity {
constructor (scope, args) {

@@ -55,6 +49,13 @@ super();

scope.state.entities.push(new craters.sprite(scope, {size: {x: 214, y: 282}, pos: this.state.pos , frames: [0, 1, 2], image: media.fetch('./src/media/bolt.png'), angle: this.state.angle}))
scope.state.entities.push(new sprite(scope, {size: {x: 214, y: 282}, pos: this.state.pos , frames: [0, 1, 2], image: media.fetch('./src/media/bolt.png'), angle: this.state.angle}))
}
}
window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, false);
// what this does is , it loads all resources
// and later , it starts the game if all files were loaded
var media = new loader;
media.load([
'./src/media/bug.png',
'./src/media/bolt.png'
], function() { window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, false)});
{
"name": "craters.js",
"version": "1.0.4",
"description": "a micro game engine",
"main": "./app/game.js",
"version": "1.0.5",
"description": "A Compact Game Engine that helps you build fast, modern HTML5 Games",
"main": "./index.js",
"scripts": {
"test": ""
"test": "",
"build": "rollup --config && webpack"
},

@@ -14,7 +15,7 @@ "repository": {

"keywords": [
"node",
"nodejs",
"javascript",
"library",
"game-engine"
"node",
"nodejs",
"javascript",
"library",
"game-engine"
],

@@ -26,3 +27,5 @@ "author": "John Swana",

},
"homepage": "https://github.com/swashvirus/craters.js#readme"
"homepage": "https://github.com/swashvirus/craters.js#readme",
"dependencies": {
}
}
# Craters.js ☄️
![npm bundle size](https://img.shields.io/bundlephobia/minzip/craters.js)
![es modules](https://img.shields.io/badge/es-modules-lightblue)
![](craters.gif)

@@ -13,2 +16,4 @@

- ES modules
reduces bundle size
- Sound.js

@@ -37,31 +42,34 @@ sound system loads sounds methods

```bash sudo git clone https://github.com/swashvirus/craters.js.git ```
clone repository
```bash
git clone https://github.com/swashvirus/craters.js.git
```
npm install
```npm install craters.js ```
```bash
npm install craters.js
```
##### writing the demo game yourself
```javascript
"use strict";
// load craters.js script tag works too
require('./craters/craters.js');
'use strict';
// bundled versions can be found in the dist
// import { game } from 'craters.js' // npm package
import { game } from './craters/craters.js'
class mygame extends craters.game {
intitiate () {
super.intitiate();
// now intitiate my game
}
render () {
super.render(this);
this.context.font = '2em Arial';
this.context.fillText('It\'s working.️', 65, (this.constants.height / 2), (this.constants.width));
}
class mygame extends game {
intitiate() {
super.intitiate()
// now intitiate my game
}
render() {
super.render(this)
this.context.font = '2em Arial'
this.context.fillText('It\'s working.️', 65, (this.constants.height / 2), (this.constants.width))
}
}
window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, true);
window.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, true)
```
Let's make craters a reality contribute even a missing colon
const path = require('path');
module.exports = {
entry: {'build/game': './app/game.js', 'dist/craters': './app/craters/craters.js'},
output: {
path: path.resolve(__dirname, './'),
filename: '[name].min.js'
}
entry: {
'./build/game': './app/game.js',
'./dist/craters': './dist/craters'
},
output: {
path: path.resolve(__dirname, './'),
filename: '[name].min.js'
}
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc