craters.js
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1371801
39
1310
73
1