|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var jaws = (function(jaws) { |
|
|
|
var title |
|
var log_tag |
|
|
|
jaws.title = function(value) { |
|
if(value) { return (title.innerHTML = value) } |
|
return title.innerHTML |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.unpack = function() { |
|
var make_global = ["Sprite", "SpriteList", "Animation", "Viewport", "SpriteSheet", "Parallax", "TileMap", "Rect", "pressed"] |
|
|
|
make_global.forEach( function(item, array, total) { |
|
if(window[item]) { jaws.log(item + "already exists in global namespace") } |
|
else { window[item] = jaws[item] } |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
jaws.log = function(msg, add) { |
|
if(log_tag) { |
|
msg += "<br />" |
|
if(add) { log_tag.innerHTML = log_tag.innerHTML.toString() + msg } |
|
else { log_tag.innerHTML = msg } |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.init = function(options) { |
|
|
|
title = document.getElementsByTagName('title')[0] |
|
jaws.url_parameters = getUrlParameters() |
|
|
|
|
|
|
|
|
|
|
|
|
|
log_tag = document.getElementById('jaws-log') |
|
if(jaws.url_parameters["debug"]) { |
|
if(!log_tag) { |
|
log_tag = document.createElement("div") |
|
log_tag.style.cssText = "overflow: auto; color: #aaaaaa; width: 300px; height: 150px; margin: 40px auto 0px auto; padding: 5px; border: #444444 1px solid; clear: both; font: 10px verdana; text-align: left;" |
|
document.body.appendChild(log_tag) |
|
} |
|
} |
|
|
|
jaws.canvas = document.getElementsByTagName('canvas')[0] |
|
if(jaws.canvas) { |
|
jaws.context = jaws.canvas.getContext('2d'); |
|
} |
|
else { |
|
jaws.dom = document.getElementById("canvas") |
|
jaws.dom.style.position = "relative" |
|
} |
|
|
|
jaws.width = jaws.canvas ? jaws.canvas.width : jaws.dom.offsetWidth |
|
jaws.height = jaws.canvas ? jaws.canvas.height : jaws.dom.offsetHeigh |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function findOrCreateCanvas() { |
|
jaws.canvas = document.getElementsByTagName('canvas')[0] |
|
if(!jaws.canvas) { |
|
jaws.canvas = document.createElement("canvas") |
|
jaws.canvas.width = 500 |
|
jaws.canvas.height = 300 |
|
document.body.appendChild(jaws.canvas) |
|
jaws.log("creating canvas", true) |
|
} |
|
else { |
|
jaws.log("found canvas", true) |
|
} |
|
jaws.context = jaws.canvas.getContext('2d'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.start = function(game_state, options) { |
|
var wanted_fps = (options && options.fps) || 60 |
|
|
|
jaws.init() |
|
jaws.log("setupInput()", true) |
|
jaws.setupInput() |
|
|
|
|
|
function assetLoaded(src, percent_done) { |
|
jaws.log( percent_done + "%: " + src, true) |
|
} |
|
|
|
|
|
function assetError(src) { |
|
jaws.log( "Error loading: " + src) |
|
} |
|
|
|
|
|
function assetsLoaded() { |
|
jaws.log("all assets loaded", true) |
|
|
|
|
|
|
|
if( game_state && jaws.isFunction(game_state) ) { game_state = new game_state } |
|
if(!game_state) { game_state = window } |
|
|
|
jaws.gameloop = new jaws.GameLoop(game_state.setup, game_state.update, game_state.draw, wanted_fps) |
|
jaws.game_state = game_state |
|
jaws.gameloop.start() |
|
} |
|
|
|
jaws.log("assets.loadAll()", true) |
|
if(jaws.assets.length() > 0) { jaws.assets.loadAll({onload:assetLoaded, onerror:assetError, onfinish:assetsLoaded}) } |
|
else { assetsLoaded() } |
|
} |
|
|
|
|
|
|
|
|
|
|
|
jaws.switchGameState = function(game_state) { |
|
jaws.gameloop.stop() |
|
|
|
jaws.clearKeyCallbacks() |
|
|
|
if(jaws.isFunction(game_state)) { game_state = new game_state } |
|
|
|
jaws.previous_game_state = jaws.game_state |
|
jaws.game_state = game_state |
|
jaws.gameloop = new jaws.GameLoop(game_state.setup, game_state.update, game_state.draw, jaws.gameloop.fps) |
|
jaws.gameloop.start() |
|
} |
|
|
|
|
|
jaws.forceArray = function(obj) { |
|
return Array.isArray(obj) ? obj : [obj] |
|
} |
|
|
|
|
|
jaws.clear = function() { |
|
jaws.context.clearRect(0,0,jaws.width,jaws.height) |
|
} |
|
|
|
|
|
jaws.isImage = function(obj) { |
|
return Object.prototype.toString.call(obj) === "[object HTMLImageElement]" |
|
} |
|
|
|
|
|
jaws.isCanvas = function(obj) { |
|
return Object.prototype.toString.call(obj) === "[object HTMLCanvasElement]" |
|
} |
|
|
|
|
|
jaws.isDrawable = function(obj) { |
|
return jaws.isImage(obj) || jaws.isCanvas(obj) |
|
} |
|
|
|
|
|
jaws.isString = function(obj) { |
|
return (typeof obj == 'string') |
|
} |
|
|
|
|
|
jaws.isArray = function(obj) { |
|
return !(obj.constructor.toString().indexOf("Array") == -1) |
|
} |
|
|
|
|
|
jaws.isFunction = function(obj) { |
|
return (Object.prototype.toString.call(obj) === "[object Function]") |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function getUrlParameters() { |
|
var vars = [], hash; |
|
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); |
|
for(var i = 0; i < hashes.length; i++) { |
|
hash = hashes[i].split('='); |
|
vars.push(hash[0]); |
|
vars[hash[0]] = hash[1]; |
|
} |
|
return vars; |
|
} |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
var pressed_keys = {} |
|
var keycode_to_string = [] |
|
var on_keydown_callbacks = [] |
|
var on_keyup_callbacks = [] |
|
|
|
|
|
|
|
|
|
jaws.setupInput = function() { |
|
var k = [] |
|
|
|
k[8] = "backspace" |
|
k[9] = "tab" |
|
k[13] = "enter" |
|
k[16] = "shift" |
|
k[17] = "ctrl" |
|
k[18] = "alt" |
|
k[19] = "pause" |
|
k[20] = "capslock" |
|
k[27] = "esc" |
|
k[32] = "space" |
|
k[33] = "pageup" |
|
k[34] = "pagedown" |
|
k[35] = "end" |
|
k[36] = "home" |
|
k[37] = "left" |
|
k[38] = "up" |
|
k[39] = "right" |
|
k[40] = "down" |
|
k[45] = "insert" |
|
k[46] = "delete" |
|
|
|
k[91] = "leftwindowkey" |
|
k[92] = "rightwindowkey" |
|
k[93] = "selectkey" |
|
k[106] = "multiply" |
|
k[107] = "add" |
|
k[109] = "subtract" |
|
k[110] = "decimalpoint" |
|
k[111] = "divide" |
|
|
|
k[144] = "numlock" |
|
k[145] = "scrollock" |
|
k[186] = "semicolon" |
|
k[187] = "equalsign" |
|
k[188] = "comma" |
|
k[189] = "dash" |
|
k[190] = "period" |
|
k[191] = "forwardslash" |
|
k[192] = "graveaccent" |
|
k[219] = "openbracket" |
|
k[220] = "backslash" |
|
k[221] = "closebracket" |
|
k[222] = "singlequote" |
|
|
|
var numpadkeys = ["numpad1","numpad2","numpad3","numpad4","numpad5","numpad6","numpad7","numpad8","numpad9"] |
|
var fkeys = ["f1","f2","f3","f4","f5","f6","f7","f8","f9"] |
|
var numbers = ["0","1","2","3","4","5","6","7","8","9"] |
|
var letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] |
|
for(var i = 0; numbers[i]; i++) { k[48+i] = numbers[i] } |
|
for(var i = 0; letters[i]; i++) { k[65+i] = letters[i] } |
|
for(var i = 0; numpadkeys[i]; i++) { k[96+i] = numpadkeys[i] } |
|
for(var i = 0; fkeys[i]; i++) { k[112+i] = fkeys[i] } |
|
|
|
keycode_to_string = k |
|
|
|
window.onkeydown = function(e) { handleKeyDown(e) } |
|
window.onkeyup = function(e) { handleKeyUp(e) } |
|
window.onkeypress = function(e) {}; |
|
} |
|
|
|
|
|
function handleKeyUp(e) { |
|
event = (e) ? e : window.event |
|
var human_name = keycode_to_string[event.keyCode] |
|
pressed_keys[human_name] = false |
|
if(on_keyup_callbacks[human_name]) { |
|
on_keyup_callbacks[human_name]() |
|
e.preventDefault() |
|
} |
|
if(prevent_default_keys[human_name]) { e.preventDefault() } |
|
} |
|
|
|
|
|
function handleKeyDown(e) { |
|
event = (e) ? e : window.event |
|
var human_name = keycode_to_string[event.keyCode] |
|
pressed_keys[human_name] = true |
|
if(on_keydown_callbacks[human_name]) { |
|
on_keydown_callbacks[human_name]() |
|
e.preventDefault() |
|
} |
|
if(prevent_default_keys[human_name]) { e.preventDefault() } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
var prevent_default_keys = [] |
|
jaws.preventDefaultKeys = function(array_of_strings) { |
|
array_of_strings.forEach( function(item, index) { |
|
prevent_default_keys[item] = true |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
jaws.pressed = function(string) { |
|
return pressed_keys[string] |
|
} |
|
|
|
jaws.on_keydown = function(key, callback) { |
|
if(jaws.isArray(key)) { |
|
for(var i=0; key[i]; i++) { |
|
on_keydown_callbacks[key[i]] = callback |
|
} |
|
} |
|
else { |
|
on_keydown_callbacks[key] = callback |
|
} |
|
} |
|
|
|
jaws.on_keyup = function(key, callback) { |
|
if(jaws.isArray(key)) { |
|
for(var i=0; key[i]; i++) { |
|
on_keyup_callbacks[key[i]] = callback |
|
} |
|
} |
|
else { |
|
on_keyup_callbacks[key] = callback |
|
} |
|
} |
|
|
|
|
|
jaws.clearKeyCallbacks = function() { |
|
on_keyup_callbacks = [] |
|
on_keydown_callbacks = [] |
|
} |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Assets = function() { |
|
this.loaded = [] |
|
this.loading = [] |
|
this.src_list = [] |
|
this.data = [] |
|
|
|
this.image_to_canvas = true |
|
this.fuchia_to_transparent = true |
|
this.root = "" |
|
|
|
this.file_type = {} |
|
this.file_type["json"] = "json" |
|
this.file_type["wav"] = "audio" |
|
this.file_type["mp3"] = "audio" |
|
this.file_type["ogg"] = "audio" |
|
this.file_type["png"] = "image" |
|
this.file_type["jpg"] = "image" |
|
this.file_type["jpeg"] = "image" |
|
this.file_type["gif"] = "image" |
|
this.file_type["bmp"] = "image" |
|
this.file_type["tiff"] = "image" |
|
var that = this |
|
|
|
this.length = function() { |
|
return this.src_list.length |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.get = function(src) { |
|
if(jaws.isArray(src)) { |
|
return src.map( function(i) { return that.data[i] } ) |
|
} |
|
else { |
|
if(this.loaded[src]) { return this.data[src] } |
|
else { jaws.log("No such asset: " + src) } |
|
} |
|
} |
|
|
|
this.isLoading = function(src) { |
|
return this.loading[src] |
|
} |
|
|
|
this.isLoaded = function(src) { |
|
return this.loaded[src] |
|
} |
|
|
|
this.getPostfix = function(src) { |
|
postfix_regexp = /\.([a-zA-Z]+)/; |
|
return postfix_regexp.exec(src)[1] |
|
} |
|
|
|
this.getType = function(src) { |
|
var postfix = this.getPostfix(src) |
|
return (this.file_type[postfix] ? this.file_type[postfix] : postfix) |
|
} |
|
|
|
|
|
this.add = function(src) { |
|
if(jaws.isArray(src)) { for(var i=0; src[i]; i++) { this.add(src[i]) } } |
|
else { src = this.root + src; this.src_list.push(src) } |
|
return this |
|
} |
|
|
|
|
|
this.loadAll = function(options) { |
|
this.load_count = 0 |
|
this.error_count = 0 |
|
|
|
|
|
this.onload = options.onload |
|
this.onerror = options.onerror |
|
this.onfinish = options.onfinish |
|
|
|
for(i=0; this.src_list[i]; i++) { |
|
this.load(this.src_list[i]) |
|
} |
|
} |
|
|
|
|
|
this.getOrLoad = function(src, onload, onerror) { |
|
if(this.data[src]) { onload() } |
|
else { this.load(src, onload, onerror) } |
|
} |
|
|
|
|
|
this.load = function(src, onload, onerror) { |
|
var asset = {} |
|
asset.src = src |
|
asset.onload = onload |
|
asset.onerror = onerror |
|
this.loading[src] = true |
|
|
|
switch(this.getType(asset.src)) { |
|
case "image": |
|
var src = asset.src + "?" + parseInt(Math.random()*10000000) |
|
asset.image = new Image() |
|
asset.image.asset = asset |
|
asset.image.onload = this.assetLoaded |
|
asset.image.onerror = this.assetError |
|
asset.image.src = src |
|
break; |
|
case "audio": |
|
var src = asset.src + "?" + parseInt(Math.random()*10000000) |
|
asset.audio = new Audio(src) |
|
asset.audio.asset = asset |
|
this.data[asset.src] = asset.audio |
|
asset.audio.addEventListener("canplay", this.assetLoaded, false); |
|
asset.audio.addEventListener("error", this.assetError, false); |
|
asset.audio.load() |
|
break; |
|
default: |
|
var src = asset.src + "?" + parseInt(Math.random()*10000000) |
|
var req = new XMLHttpRequest() |
|
req.asset = asset |
|
req.onreadystatechange = this.assetLoaded |
|
req.open('GET', src, true) |
|
req.send(null) |
|
break; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.assetLoaded = function(e) { |
|
var asset = this.asset |
|
var src = asset.src |
|
var filetype = that.getType(asset.src) |
|
|
|
|
|
that.loaded[src] = true |
|
that.loading[src] = false |
|
|
|
|
|
if(filetype == "json") { |
|
if (this.readyState != 4) { return } |
|
that.data[asset.src] = JSON.parse(this.responseText) |
|
} |
|
else if(filetype == "image") { |
|
var new_image = that.image_to_canvas ? imageToCanvas(asset.image) : asset.image |
|
if(that.fuchia_to_transparent && that.getPostfix(asset.src) == "bmp") { new_image = fuchiaToTransparent(new_image) } |
|
that.data[asset.src] = new_image |
|
} |
|
else if(filetype == "audio") { |
|
asset.audio.removeEventListener("canplay", that.assetLoaded, false); |
|
that.data[asset.src] = asset.audio |
|
} |
|
|
|
that.load_count++ |
|
if(asset.onload) { asset.onload() } |
|
that.processCallbacks(asset) |
|
} |
|
|
|
this.assetError = function(e) { |
|
var asset = this.asset |
|
that.error_count++ |
|
if(asset.onerror) { asset.onerror(asset) } |
|
that.processCallbacks(asset) |
|
} |
|
|
|
this.processCallbacks = function(asset) { |
|
var percent = parseInt( (that.load_count+that.error_count) / that.src_list.length * 100) |
|
if(that.onload) { that.onload(asset.src, percent) } |
|
|
|
|
|
if(percent==100) { |
|
if(that.onfinish) { that.onfinish() } |
|
that.onload = null |
|
that.onerror = null |
|
that.onfinish = null |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function imageToCanvas(image) { |
|
var canvas = document.createElement("canvas") |
|
canvas.src = image.src |
|
canvas.width = image.width |
|
canvas.height = image.height |
|
|
|
var context = canvas.getContext("2d") |
|
context.drawImage(image, 0, 0, image.width, image.height) |
|
return canvas |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function fuchiaToTransparent(image) { |
|
canvas = jaws.isImage(image) ? imageToCanvas(image) : image |
|
var context = canvas.getContext("2d") |
|
var img_data = context.getImageData(0,0,canvas.width,canvas.height) |
|
var pixels = img_data.data |
|
for(var i = 0; i < pixels.length; i += 4) { |
|
if(pixels[i]==255 && pixels[i+1]==0 && pixels[i+2]==255) { |
|
pixels[i+3] = 0 |
|
} |
|
} |
|
context.putImageData(img_data,0,0); |
|
return canvas |
|
} |
|
|
|
|
|
function retroScale(image, factor) { |
|
canvas = jaws.isImage(image) ? imageToCanvas(image) : image |
|
var context = canvas.getContext("2d") |
|
var img_data = context.getImageData(0,0,canvas.width,canvas.height) |
|
var pixels = img_data.data |
|
|
|
var canvas2 = document.createElement("canvas") |
|
canvas2.width = image.width * factor |
|
canvas2.height = image.height * factor |
|
var context2 = canvas.getContext("2d") |
|
var img_data2 = context2.getImageData(0,0,canvas2.width,canvas2.height) |
|
var pixels2 = img_data2.data |
|
|
|
for (var x = 0; x < canvas.width * factor; x++) { |
|
for (var y = 0; y < canvas.height * factor; y++) { |
|
pixels2[x*y] = pixels[x*y / factor] |
|
pixels2[x*y+1] = pixels[x*y+1 / factor] |
|
pixels2[x*y+2] = pixels[x*y+2 / factor] |
|
pixels2[x*y+3] = pixels[x*y+3 / factor] |
|
} |
|
} |
|
|
|
context2.putImageData(img_data2,0,0); |
|
return canvas2 |
|
} |
|
|
|
jaws.assets = new jaws.Assets() |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.GameLoop = function(setup, update, draw, wanted_fps) { |
|
this.ticks = 0 |
|
this.tick_duration = 0 |
|
this.fps = 0 |
|
|
|
var update_id |
|
var paused = false |
|
var that = this |
|
var mean_value = new MeanValue(20) |
|
|
|
this.start = function() { |
|
jaws.log("gameloop start", true) |
|
this.current_tick = (new Date()).getTime(); |
|
this.last_tick = (new Date()).getTime(); |
|
if(setup) { setup() } |
|
update_id = setInterval(this.loop, 1000 / wanted_fps); |
|
jaws.log("gameloop loop", true) |
|
} |
|
|
|
this.loop = function() { |
|
that.current_tick = (new Date()).getTime(); |
|
that.tick_duration = that.current_tick - that.last_tick |
|
|
|
that.fps = mean_value.add(1000/that.tick_duration).get() |
|
|
|
if(!paused) { |
|
if(update) { update() } |
|
if(draw) { draw() } |
|
that.ticks++ |
|
} |
|
|
|
that.last_tick = that.current_tick; |
|
} |
|
|
|
this.pause = function() { paused = true } |
|
this.unpause = function() { paused = false } |
|
|
|
this.stop = function() { |
|
if(update_id) { clearInterval(update_id); } |
|
} |
|
} |
|
|
|
function MeanValue(size) { |
|
this.size = size |
|
this.values = new Array(this.size) |
|
this.value |
|
|
|
this.add = function(value) { |
|
if(this.values.length > this.size) { |
|
this.values.splice(0,1) |
|
this.value = 0 |
|
for(var i=0; this.values[i]; i++) { |
|
this.value += this.values[i] |
|
} |
|
this.value = this.value / this.size |
|
} |
|
this.values.push(value) |
|
|
|
return this |
|
} |
|
|
|
this.get = function() { |
|
return parseInt(this.value) |
|
} |
|
|
|
} |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
jaws.Rect = function(x,y,width,height) { |
|
this.x = x |
|
this.y = y |
|
this.width = width |
|
this.height = height |
|
this.right = x + width |
|
this.bottom = y + height |
|
} |
|
|
|
jaws.Rect.prototype.getPosition = function() { |
|
return [this.x, this.y] |
|
} |
|
|
|
jaws.Rect.prototype.move = function(x,y) { |
|
this.x += x |
|
this.y += y |
|
this.right += x |
|
this.bottom += y |
|
} |
|
|
|
jaws.Rect.prototype.moveTo = function(x,y) { |
|
this.x = x |
|
this.y = y |
|
this.right = this.x + this.width |
|
this.bottom = this.y + this.height |
|
return this |
|
} |
|
|
|
jaws.Rect.prototype.resize = function(width,height) { |
|
this.width += width |
|
this.height += height |
|
this.right = this.x + this.width |
|
this.bottom = this.y + this.height |
|
return this |
|
} |
|
|
|
jaws.Rect.prototype.resizeTo = function(width,height) { |
|
this.width = width |
|
this.height = height |
|
this.right = this.x + this.width |
|
this.bottom = this.y + this.height |
|
return this |
|
} |
|
|
|
|
|
jaws.Rect.prototype.draw = function() { |
|
jaws.context.strokeStyle = "red" |
|
jaws.context.strokeRect(this.x, this.y, this.width, this.height) |
|
return this |
|
} |
|
|
|
|
|
jaws.Rect.prototype.collidePoint = function(x, y) { |
|
return (x >= this.x && x <= this.right && y >= this.y && y <= this.bottom) |
|
} |
|
|
|
|
|
jaws.Rect.prototype.collideRect = function(rect) { |
|
return ((this.x >= rect.x && this.x <= rect.right) || (rect.x >= this.x && rect.x <= this.right)) && |
|
((this.y >= rect.y && this.y <= rect.bottom) || (rect.y >= this.y && rect.y <= this.bottom)) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Rect.prototype.toString = function() { return "[Rect " + this.x + ", " + this.y + ", " + this.width + ", " + this.height + "]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
|
|
if(typeof module !== "undefined" && ('exports' in module)) { module.exports = jaws.Rect } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var jaws = (function(jaws) { |
|
|
|
jaws.Sprite = function(options) { |
|
this.options = options |
|
this.set(options) |
|
this.context = options.context || jaws.context |
|
if(!this.context) { this.createDiv() } |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.set = function(options) { |
|
this.scale_factor_x = this.scale_factor_y = (options.scale || 1) |
|
if(!options.anchor_x == undefined) {this.anchor_x = options.anchor_x} |
|
if(!options.anchor_y == undefined) {this.anchor_y = options.anchor_y} |
|
this.x = options.x || 0 |
|
this.y = options.y || 0 |
|
this.alpha = options.alpha || 1 |
|
this.angle = options.angle || 0 |
|
this.flipped = options.flipped || false |
|
this.anchor(options.anchor || "top_left") |
|
options.image && this.setImage(options.image) |
|
this.cacheOffsets() |
|
return this |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Sprite.prototype.setImage = function(value) { |
|
var that = this |
|
|
|
|
|
if(jaws.isDrawable(value)) { |
|
this.image = value |
|
return this.cacheOffsets() |
|
} |
|
|
|
else { |
|
|
|
if(jaws.assets.isLoaded(value)) { this.image = jaws.assets.get(value); this.cacheOffsets(); } |
|
|
|
|
|
else { jaws.assets.load(value, function() { that.image = jaws.assets.get(value); that.cacheOffsets(); }) } |
|
} |
|
return this |
|
} |
|
jaws.Sprite.prototype.flip = function() { this.flipped = this.flipped ? false : true; return this } |
|
jaws.Sprite.prototype.flipTo = function(value) { this.flipped = value; return this } |
|
jaws.Sprite.prototype.rotate = function(value) { this.angle += value; return this } |
|
jaws.Sprite.prototype.rotateTo = function(value) { this.angle = value; return this } |
|
jaws.Sprite.prototype.moveTo = function(x,y) { this.x = x; this.y = y; return this } |
|
jaws.Sprite.prototype.move = function(x,y) { if(x) this.x += x; if(y) this.y += y; return this } |
|
jaws.Sprite.prototype.scale = function(value) { this.scale_factor_x *= value; this.scale_factor_y *= value; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.scaleTo = function(value) { this.scale_factor_x = this.scale_factor_y = value; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.scaleWidth = function(value) { this.scale_factor_x *= value; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.scaleHeight = function(value) { this.scale_factor_y *= value; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.setX = function(value) { this.x = value; return this } |
|
jaws.Sprite.prototype.setY = function(value) { this.y = value; return this } |
|
jaws.Sprite.prototype.setWidth = function(value) { this.scale_factor_x = value/this.image.width; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.setHeight = function(value) { this.scale_factor_y = value/this.image.height; return this.cacheOffsets() } |
|
jaws.Sprite.prototype.resize = function(width, height) { |
|
this.scale_factor_x = (this.width + width) / this.image.width |
|
this.scale_factor_y = (this.height + height) / this.image.height |
|
return this.cacheOffsets() |
|
} |
|
jaws.Sprite.prototype.resizeTo = function(width, height) { |
|
this.scale_factor_x = width / this.image.width |
|
this.scale_factor_y = height / this.image.height |
|
return this.cacheOffsets() |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Sprite.prototype.anchor = function(value) { |
|
var anchors = { |
|
top_left: [0,0], |
|
left_top: [0,0], |
|
center_left: [0,0.5], |
|
left_center: [0,0.5], |
|
bottom_left: [0,1], |
|
left_bottom: [0,1], |
|
top_center: [0.5,0], |
|
center_top: [0.5,0], |
|
center_center: [0.5,0.5], |
|
center: [0.5,0.5], |
|
bottom_center: [0.5,1], |
|
center_bottom: [0.5,1], |
|
top_right: [1,0], |
|
right_top: [1,0], |
|
center_right: [1,0.5], |
|
right_center: [1,0.5], |
|
bottom_right: [1,1], |
|
right_bottom: [1,1] |
|
} |
|
|
|
if(a = anchors[value]) { |
|
this.anchor_x = a[0] |
|
this.anchor_y = a[1] |
|
if(this.image) this.cacheOffsets(); |
|
} |
|
return this |
|
} |
|
|
|
jaws.Sprite.prototype.cacheOffsets = function() { |
|
if(!this.image) { return } |
|
|
|
this.width = this.image.width * this.scale_factor_x |
|
this.height = this.image.height * this.scale_factor_y |
|
this.left_offset = this.width * this.anchor_x |
|
this.top_offset = this.height * this.anchor_y |
|
this.right_offset = this.width * (1.0 - this.anchor_x) |
|
this.bottom_offset = this.height * (1.0 - this.anchor_y) |
|
|
|
if(this.cached_rect) this.cached_rect.resizeTo(this.width, this.height); |
|
return this |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.rect = function() { |
|
if(!this.cached_rect) this.cached_rect = new jaws.Rect(this.x, this.top, this.width, this.height) |
|
this.cached_rect.moveTo(this.x - this.left_offset, this.y - this.top_offset) |
|
return this.cached_rect |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.createDiv = function() { |
|
this.div = document.createElement("div") |
|
this.div.style.position = "absolute" |
|
if(this.image) { |
|
this.div.style.width = this.image.width + "px" |
|
this.div.style.height = this.image.height + "px" |
|
this.div.style.backgroundImage = "url(" + this.image.src + ")" |
|
} |
|
if(jaws.dom) { jaws.dom.appendChild(this.div) } |
|
this.updateDiv() |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.updateDiv = function() { |
|
this.div.style.left = this.x + "px" |
|
this.div.style.top = this.y + "px" |
|
|
|
var transform = "" |
|
transform += "rotate(" + this.angle + "deg) " |
|
if(this.flipped) { transform += "scale(-" + this.scale_factor_x + "," + this.scale_factor_y + ")"; } |
|
else { transform += "scale(" + this.scale_factor_x + "," + this.scale_factor_y + ")"; } |
|
|
|
this.div.style.MozTransform = transform |
|
this.div.style.WebkitTransform = transform |
|
this.div.style.transform = transform |
|
return this |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.draw = function() { |
|
if(!this.image) { return this } |
|
if(jaws.dom) { return this.updateDiv() } |
|
|
|
this.context.save() |
|
this.context.translate(this.x, this.y) |
|
if(this.angle!=0) { jaws.context.rotate(this.angle * Math.PI / 180) } |
|
this.flipped && this.context.scale(-1, 1) |
|
this.context.globalAlpha = this.alpha |
|
this.context.translate(-this.left_offset, -this.top_offset) |
|
this.context.drawImage(this.image, 0, 0, this.width, this.height) |
|
this.context.restore() |
|
return this |
|
} |
|
|
|
|
|
jaws.Sprite.prototype.asCanvasContext = function() { |
|
var canvas = document.createElement("canvas") |
|
canvas.width = this.width |
|
canvas.height = this.height |
|
|
|
var context = canvas.getContext("2d") |
|
context.mozImageSmoothingEnabled = jaws.context.mozImageSmoothingEnabled |
|
|
|
context.drawImage(this.image, 0, 0, this.width, this.height) |
|
return context |
|
} |
|
|
|
jaws.Sprite.prototype.toString = function() { return "[Sprite " + this.x + ", " + this.y + "," + this.width + "," + this.height + "]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.SpriteList = function() {} |
|
jaws.SpriteList.prototype = new Array |
|
|
|
jaws.SpriteList.prototype.remove = function(obj) { |
|
var index = this.indexOf(obj) |
|
if(index > -1) { this.splice(index, 1) } |
|
} |
|
|
|
jaws.SpriteList.prototype.draw = function() { |
|
for(i=0; this[i]; i++) { |
|
this[i].draw() |
|
} |
|
} |
|
|
|
jaws.SpriteList.prototype.drawIf = function(condition) { |
|
for(i=0; this[i]; i++) { |
|
if( condition(this[i]) ) { this[i].draw() } |
|
} |
|
} |
|
|
|
jaws.SpriteList.prototype.update = function() { |
|
for(i=0; this[i]; i++) { |
|
this[i].update() |
|
} |
|
} |
|
|
|
jaws.SpriteList.prototype.updateIf = function(condition) { |
|
for(i=0; this[i]; i++) { |
|
if( condition(this[i]) ) { this[i].update() } |
|
} |
|
} |
|
|
|
jaws.SpriteList.prototype.deleteIf = function(condition) { |
|
for(var i=0; this[i]; i++) { |
|
if( condition(this[i]) ) { this.splice(i,1) } |
|
} |
|
} |
|
jaws.SpriteList.prototype.toString = function() { return "[SpriteList " + this.length + " sprites]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
function cutImage(image, x, y, width, height) { |
|
var cut = document.createElement("canvas") |
|
cut.width = width |
|
cut.height = height |
|
|
|
var ctx = cut.getContext("2d") |
|
ctx.drawImage(image, x, y, width, height, 0, 0, cut.width, cut.height) |
|
|
|
return cut |
|
}; |
|
|
|
|
|
jaws.SpriteSheet = function(options) { |
|
this.image = jaws.isDrawable(options.image) ? options.image : jaws.assets.data[options.image] |
|
this.orientation = options.orientation || "right" |
|
this.frame_size = options.frame_size || [32,32] |
|
this.frames = [] |
|
|
|
var index = 0 |
|
for(var x=0; x < this.image.width; x += this.frame_size[0]) { |
|
for(var y=0; y < this.image.height; y += this.frame_size[1]) { |
|
this.frames.push( cutImage(this.image, x, y, this.frame_size[0], this.frame_size[1]) ) |
|
} |
|
} |
|
} |
|
|
|
jaws.SpriteSheet.prototype.toString = function() { return "[SpriteSheet " + this.frames.length + " frames]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
jaws.Parallax = function(options) { |
|
this.scale = options.scale || 1 |
|
this.repeat_x = options.repeat_x |
|
this.repeat_y = options.repeat_y |
|
this.camera_x = options.camera_x || 0 |
|
this.camera_y = options.camera_y || 0 |
|
this.layers = [] |
|
} |
|
|
|
jaws.Parallax.prototype.draw = function(options) { |
|
var layer, save_x, save_y; |
|
|
|
for(var i=0; i < this.layers.length; i++) { |
|
layer = this.layers[i] |
|
|
|
save_x = layer.x |
|
save_y = layer.y |
|
|
|
layer.x = -(this.camera_x / layer.damping) |
|
layer.y = -(this.camera_y / layer.damping) |
|
|
|
while(this.repeat_x && layer.x > 0) { layer.x -= layer.width } |
|
while(this.repeat_y && layer.y > 0) { layer.y -= layer.width } |
|
|
|
while(this.repeat_x && layer.x < jaws.width) { |
|
while(this.repeat_y && layer.y < jaws.height) { |
|
layer.draw() |
|
layer.y += layer.height |
|
} |
|
layer.y = save_y |
|
layer.draw() |
|
layer.x += (layer.width-1) |
|
} |
|
while(layer.repeat_y && !layer.repeat_x && layer.y < jaws.height) { |
|
layer.draw() |
|
layer.y += layer.height |
|
} |
|
layer.x = save_x |
|
} |
|
} |
|
jaws.Parallax.prototype.addLayer = function(options) { |
|
var layer = new jaws.ParallaxLayer(options) |
|
layer.scale(this.scale) |
|
this.layers.push(layer) |
|
} |
|
jaws.Parallax.prototype.toString = function() { return "[Parallax " + this.x + ", " + this.y + ". " + this.layers.length + " layers]" } |
|
|
|
jaws.ParallaxLayer = function(options) { |
|
this.damping = options.damping || 0 |
|
jaws.Sprite.call(this, options) |
|
} |
|
jaws.ParallaxLayer.prototype = jaws.Sprite.prototype |
|
jaws.Parallax.prototype.toString = function() { return "[ParallaxLayer " + this.x + ", " + this.y + "]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Animation = function(options) { |
|
this.options = options |
|
this.frames = options.frames || [] |
|
this.frame_duration = options.frame_duration || 100 |
|
this.index = options.index || 0 |
|
this.loop = options.loop || 1 |
|
this.bounce = options.bounce || 0 |
|
this.frame_direction = 1 |
|
|
|
if(options.sprite_sheet) { |
|
var image = (jaws.isDrawable(options.sprite_sheet) ? options.sprite_sheet : jaws.assets.get(options.sprite_sheet)) |
|
var sprite_sheet = new jaws.SpriteSheet({image: image, frame_size: options.frame_size}) |
|
this.frames = sprite_sheet.frames |
|
} |
|
|
|
|
|
this.current_tick = (new Date()).getTime(); |
|
this.last_tick = (new Date()).getTime(); |
|
this.sum_tick = 0 |
|
} |
|
|
|
|
|
|
|
jaws.Animation.prototype.update = function() { |
|
this.current_tick = (new Date()).getTime(); |
|
this.sum_tick += (this.current_tick - this.last_tick); |
|
this.last_tick = this.current_tick; |
|
|
|
if(this.sum_tick > this.frame_duration) { |
|
this.index += this.frame_direction |
|
this.sum_tick = 0 |
|
} |
|
if( (this.index >= this.frames.length) || (this.index <= 0) ) { |
|
if(this.bounce) { |
|
this.frame_direction = -this.frame_direction |
|
this.index += this.frame_direction*2 |
|
} |
|
else if(this.loop) { |
|
this.index = 0 |
|
} |
|
} |
|
return this |
|
} |
|
|
|
|
|
jaws.Animation.prototype.slice = function(start, stop) { |
|
var o = {} |
|
o.frame_duration = this.frame_duration |
|
o.loop = this.loop |
|
o.bounce = this.bounce |
|
o.frame_direction = this.frame_direction |
|
o.frames = this.frames.slice().slice(start, stop) |
|
return new jaws.Animation(o) |
|
}; |
|
|
|
|
|
jaws.Animation.prototype.next = function() { |
|
this.update() |
|
return this.frames[this.index] |
|
}; |
|
|
|
|
|
jaws.Animation.prototype.currentFrame = function() { |
|
return this.frames[this.index] |
|
}; |
|
|
|
jaws.Animation.prototype.toString = function() { return "[Animation, " + this.frames.length + " frames]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.Viewport = function(options) { |
|
this.options = options |
|
this.context = options.context || jaws.context |
|
this.width = options.width || jaws.width |
|
this.height = options.height || jaws.height |
|
this.max_x = options.max_x || jaws.width |
|
this.max_y = options.max_y || jaws.height |
|
|
|
this.verifyPosition = function() { |
|
var max = this.max_x - this.width |
|
if(this.x < 0) { this.x = 0 } |
|
if(this.x > max) { this.x = max } |
|
|
|
var max = this.max_y - this.height |
|
if(this.y < 0) { this.y = 0 } |
|
if(this.y > max) { this.y = max } |
|
}; |
|
|
|
this.move = function(x, y) { |
|
x && (this.x += x) |
|
y && (this.y += y) |
|
this.verifyPosition() |
|
}; |
|
|
|
this.moveTo = function(x, y) { |
|
if(!(x==undefined)) { this.x = x } |
|
if(!(y==undefined)) { this.y = y } |
|
this.verifyPosition() |
|
}; |
|
|
|
this.isOutside = function(item) { |
|
return(!this.isInside(item)) |
|
}; |
|
|
|
this.isInside = function(item) { |
|
return( item.x >= this.x && item.x <= (this.x + this.width) && item.y >= this.y && item.y <= (this.y + this.height) ) |
|
}; |
|
|
|
this.centerAround = function(item) { |
|
this.x = (item.x - this.width / 2) |
|
this.y = (item.y - this.height / 2) |
|
this.verifyPosition() |
|
}; |
|
|
|
this.apply = function(func) { |
|
this.context.save() |
|
this.context.translate(-this.x, -this.y) |
|
func() |
|
this.context.restore() |
|
}; |
|
|
|
this.moveTo(options.x||0, options.y||0) |
|
} |
|
|
|
jaws.Viewport.prototype.toString = function() { return "[Viewport " + this.x + ", " + this.y + "," + this.width + "," + this.height + "]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
var jaws = (function(jaws) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.TileMap = function(options) { |
|
this.cell_size = options.cell_size || [32,32] |
|
this.size = options.size |
|
this.cells = new Array(this.size[0]) |
|
this.sortFunction = undefined |
|
|
|
for(var col=0; col < this.size[0]; col++) { |
|
this.cells[col] = new Array(this.size[1]) |
|
for(var row=0; row < this.size[1]; row++) { |
|
this.cells[col][row] = [] |
|
} |
|
} |
|
} |
|
|
|
|
|
jaws.TileMap.prototype.clear = function() { |
|
for(var col=0; col < this.size[0]; col++) { |
|
for(var row=0; row < this.size[1]; row++) { |
|
this.cells[col][row] = [] |
|
} |
|
} |
|
} |
|
|
|
|
|
jaws.TileMap.prototype.sortCells = function(sortFunction) { |
|
for(var col=0; col < this.size[0]; col++) { |
|
for(var row=0; row < this.size[1]; row++) { |
|
this.cells[col][row].sort( sortFunction ) |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.TileMap.prototype.push = function(obj) { |
|
if(obj.length) { |
|
for(var i=0; i < obj.length; i++) { this.push(obj[i]) } |
|
return obj |
|
} |
|
if(obj.rect) { |
|
return this.pushAsRect(obj, obj.rect()) |
|
} |
|
else { |
|
var col = parseInt(obj.x / this.cell_size[0]) |
|
var row = parseInt(obj.y / this.cell_size[1]) |
|
return this.pushToCell(col, row, obj) |
|
} |
|
|
|
} |
|
jaws.TileMap.prototype.pushAsPoint = function(obj) { |
|
if(Array.isArray(obj)) { |
|
for(var i=0; i < obj.length; i++) { this.pushAsPoint(obj[i]) } |
|
return obj |
|
} |
|
else { |
|
var col = parseInt(obj.x / this.cell_size[0]) |
|
var row = parseInt(obj.y / this.cell_size[1]) |
|
return this.pushToCell(col, row, obj) |
|
} |
|
} |
|
|
|
|
|
jaws.TileMap.prototype.pushAsRect = function(obj, rect) { |
|
var from_col = parseInt(rect.x / this.cell_size[0]) |
|
var to_col = parseInt((rect.right-1) / this.cell_size[0]) |
|
|
|
|
|
for(var col = from_col; col <= to_col; col++) { |
|
var from_row = parseInt(rect.y / this.cell_size[1]) |
|
var to_row = parseInt((rect.bottom-1) / this.cell_size[1]) |
|
|
|
|
|
for(var row = from_row; row <= to_row; row++) { |
|
|
|
this.pushToCell(col, row, obj) |
|
} |
|
} |
|
return obj |
|
} |
|
|
|
|
|
|
|
|
|
|
|
jaws.TileMap.prototype.pushToCell = function(col, row, obj) { |
|
this.cells[col][row].push(obj) |
|
if(this.sortFunction) this.cells[col][row].sort(this.sortFunction); |
|
return this |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
jaws.TileMap.prototype.at = function(x, y) { |
|
var col = parseInt(x / this.cell_size[0]) |
|
var row = parseInt(y / this.cell_size[1]) |
|
|
|
return this.cells[col][row] |
|
} |
|
|
|
|
|
jaws.TileMap.prototype.atRect = function(rect) { |
|
var objects = [] |
|
var items |
|
var from_col = parseInt(rect.x / this.cell_size[0]) |
|
var to_col = parseInt(rect.right / this.cell_size[0]) |
|
for(var col = from_col; col <= to_col; col++) { |
|
var from_row = parseInt(rect.y / this.cell_size[1]) |
|
var to_row = parseInt(rect.bottom / this.cell_size[1]) |
|
|
|
for(var row = from_row; row <= to_row; row++) { |
|
this.cells[col][row].forEach( function(item, total) { |
|
if(objects.indexOf(item) == -1) { objects.push(item) } |
|
}) |
|
} |
|
} |
|
return objects |
|
} |
|
|
|
|
|
jaws.TileMap.prototype.all = function() { |
|
var all = [] |
|
for(var col=0; col < this.size[0]; col++) { |
|
for(var row=0; row < this.size[1]; row++) { |
|
this.cells[col][row].forEach( function(element, total) { |
|
all.push(element) |
|
}); |
|
} |
|
} |
|
return all |
|
} |
|
|
|
|
|
|
|
|
|
jaws.TileMap.prototype.cell = function(col, row) { |
|
return this.cells[col][row] |
|
} |
|
|
|
jaws.TileMap.prototype.toString = function() { return "[TileMap " + this.size[0] + " cols, " + this.size[1] + " rows]" } |
|
|
|
return jaws; |
|
})(jaws || {}); |
|
|
|
|
|
if(typeof module !== "undefined" && ('exports' in module)) { module.exports = jaws.TileMap } |