Last active
April 13, 2017 22:21
-
-
Save illnyang/9d01ba1cda793f5501d4a15ec8eae2fc to your computer and use it in GitHub Desktop.
epic donttap src hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
(c) 2013-2014 GameMix Inc. All rights reserved. | |
*/ | |
(function() { | |
var requestAnimFrame = window.requestAnimFrame = function() { | |
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { | |
window.setTimeout(callback, 1e3 / 60) | |
} | |
}(); | |
var cancelAnimFrame = window.cancelAnimFrame = function() { | |
return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame || function() { | |
window.clearTimeout.apply(window, arguments) | |
} | |
}(); | |
navigator.vibrate = function() { | |
return navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate || navigator.oVibrate || navigator.msVibrate || (navigator.notification ? function(l) { | |
navigator.notification.vibrate(l) | |
} : null) || new Function | |
}(); | |
var console = function() { | |
return window.console || { | |
log: new Function, | |
debug: new Function, | |
warn: new Function, | |
error: new Function, | |
clear: new Function | |
} | |
}(); | |
var DOM = { | |
get: function(el) { | |
r = el == document || el == window || el instanceof HTMLElement ? el : document.getElementById(el); | |
if (r == null) { | |
console.log(el) | |
} | |
return r | |
}, | |
attr: function(el, attr, value) { | |
if (value) { | |
this.get(el).setAttribute(attr, value) | |
} else { | |
return this.get(el).getAttribute(attr) | |
} | |
}, | |
on: function(el, evt, handler) { | |
var split = evt.split(" "); | |
for (var i in split) { | |
this.get(el).addEventListener(split[i], handler, false) | |
} | |
}, | |
un: function(el, evt, handler) { | |
var split = evt.split(" "); | |
for (var i in split) { | |
this.get(el).removeEventListener(split[i], handler, false) | |
} | |
}, | |
show: function(el) { | |
this.get(el).style.display = "block" | |
}, | |
hide: function(el) { | |
this.get(el).style.display = "none" | |
}, | |
offset: function(el) { | |
el = this.get(el); | |
return { | |
x: el.clientLeft + window.scrollLeft, | |
y: el.clientTop + window.scrollTop | |
}; | |
var pos = { | |
x: 0, | |
y: 0 | |
}; | |
do { | |
pos.x += el.offsetLeft || 0; | |
pos.y += el.offsetTop || 0 | |
} while ((el = el.parentNode) !== null); | |
return pos | |
}, | |
query: function(query) { | |
if (!document.querySelectorAll) return null; | |
var q = document.querySelectorAll(query); | |
return q | |
}, | |
queryOne: function(query) { | |
if (!document.querySelector) return null; | |
var q = document.querySelector(query); | |
return q | |
}, | |
create: function(type) { | |
return document.createElement(type) | |
}, | |
positionRelativeTo: function(element, clientX, clientY) { | |
var offset = DOM.offset(element); | |
return { | |
x: clientX - offset.x, | |
y: clientY - offset.y | |
} | |
}, | |
fitScreen: function(element, ratio) { | |
var clientRatio = window.innerWidth / window.innerHeight; | |
var width, height; | |
if (clientRatio <= ratio) { | |
width = window.innerWidth; | |
height = width / ratio | |
} else { | |
height = window.innerHeight; | |
width = height * ratio | |
} | |
element = DOM.get(element); | |
element.style.width = width + "px"; | |
element.style.height = height + "px"; | |
return { | |
width: width, | |
height: height | |
} | |
}, | |
saveCanvas: function(element) { | |
var src = this.get(element); | |
var can = this.create("canvas"); | |
can.width = src.width; | |
can.height = src.height; | |
var c = can.getContext("2d"); | |
c.drawImage(src, 0, 0); | |
return can | |
}, | |
fadeIn: function(element, duration, callback) { | |
element = this.get(element); | |
duration = duration || 1e3; | |
this.show(element); | |
element.style.opacity = 0; | |
Util.interpolate(element.style, { | |
opacity: 1 | |
}, duration, callback) | |
}, | |
fadeOut: function(element, duration, callback) { | |
element = this.get(element); | |
duration = duration || 1e3; | |
this.show(element); | |
element.style.opacity = 1; | |
Util.interpolate(element.style, { | |
opacity: 0 | |
}, duration, function() { | |
DOM.hide(element); | |
if (callback) callback() | |
}) | |
}, | |
notify: function(htmlMessage, duration, container) { | |
container = container ? this.get(container) : document.body; | |
this.notification = this.notification || function() { | |
var block = DOM.create("div"); | |
container.appendChild(block); | |
DOM.applyStyle(block, { | |
zIndex: 999999, | |
position: "absolute", | |
bottom: "10px", | |
width: "100%", | |
textAlign: "center" | |
}); | |
var message = DOM.create("span"); | |
block.appendChild(message); | |
DOM.applyStyle(message, { | |
backgroundColor: "rgba(0,0,0,0.7)", | |
border: "1px solid white", | |
borderRadius: "3px", | |
margin: "auto", | |
color: "white", | |
padding: "2px", | |
paddingLeft: "10px", | |
paddingRight: "10px", | |
width: "50%", | |
fontSize: "0.7em", | |
boxShadow: "0px 0px 2px black" | |
}); | |
return { | |
block: block, | |
message: message, | |
queue: [], | |
add: function(message, duration) { | |
this.queue.push({ | |
message: message, | |
duration: duration | |
}); | |
if (this.queue.length == 1) { | |
this.applyOne() | |
} | |
}, | |
applyOne: function() { | |
var notif = this.queue[0]; | |
this.message.innerHTML = notif.message; | |
DOM.fadeIn(this.block, 500); | |
setTimeout(function() { | |
DOM.fadeOut(DOM.notification.block, 500, function() { | |
DOM.notification.queue.shift(); | |
if (DOM.notification.queue.length > 0) { | |
DOM.notification.applyOne() | |
} | |
}) | |
}, notif.duration + 500) | |
} | |
} | |
}(); | |
duration = duration || 3e3; | |
this.notification.add(htmlMessage, duration) | |
}, | |
applyStyle: function(element, style) { | |
element = this.get(element); | |
for (var i in style) { | |
element.style[i] = style[i] | |
} | |
}, | |
populate: function(elements) { | |
var res = {}; | |
for (var i in elements) { | |
res[i] = DOM.get(elements[i]); | |
if (!res[i]) console.log("Element #" + elements[i] + " not found") | |
} | |
return res | |
} | |
}; | |
var Util = { | |
preload: function(images, callbackProgress, callbackEnd, callbackError) { | |
var loadOne = function() { | |
if (remaining.length == 0) { | |
end(loaded) | |
} else { | |
var img = new Image; | |
img.onerror = function() { | |
console.log("Couldn't load " + src); | |
error(src) | |
}; | |
img.onload = function() { | |
if (this.complete) { | |
progress(this, 1 - remaining.length / nbImages); | |
setTimeout(loadOne, document.location.search.indexOf("fakelag") >= 0 ? 1e3 : 1) | |
} | |
}; | |
var src = remaining.pop(); | |
img.src = src; | |
loaded[src] = img | |
} | |
}; | |
var remaining = images.slice(0); | |
var end = callbackEnd || new Function; | |
var progress = callbackProgress || new Function; | |
var error = callbackError || new Function; | |
var nbImages = remaining.length; | |
var loaded = {}; | |
setTimeout(loadOne, 1) | |
}, | |
rand: function(min, max) { | |
return Math.random() * (max - min) + min | |
}, | |
randomPick: function() { | |
var i = parseInt(Util.rand(0, arguments.length)); | |
return arguments[i] | |
}, | |
limit: function(n, min, max) { | |
if (n < min) return min; | |
else if (n > max) return max; | |
else return n | |
}, | |
sign: function(n) { | |
if (n > 0) return 1; | |
else if (n == 0) return 0; | |
else return -1 | |
}, | |
cookie: { | |
set: function(name, value, ttl) { | |
if (ttl == undefined) ttl = 1e3 * 3600 * 24 * 365; | |
document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT"; | |
var expires = new Date; | |
expires.setTime(expires.getTime() + ttl); | |
document.cookie = [name + "=" + value + "; ", "expires=" + expires.toGMTString() + "; ", "path=/"].join("") | |
}, | |
get: function(name) { | |
var cookie = document.cookie.split("; "); | |
for (var i in cookie) { | |
var spl = cookie[i].split("="); | |
if (spl.length == 2 && spl[0] == name) { | |
return spl[1] | |
} | |
} | |
return undefined | |
} | |
}, | |
storage: window.localStorage ? { | |
getItem: function(item) { | |
return window.localStorage.getItem(item) | |
}, | |
setItem: function(item, value) { | |
try { | |
window.localStorage.setItem(item, value) | |
} catch (e) { | |
console.log("Local storage issue: " + e) | |
} | |
} | |
} : { | |
getItem: function(item) { | |
return Util.cookie.get(item) | |
}, | |
setItem: function(item, value) { | |
Util.cookie.set(item, value) | |
} | |
}, | |
merge: function(template, object) { | |
if (!object) { | |
return template | |
} | |
for (var i in template) { | |
if (!(i in object)) { | |
object[i] = template[i] | |
} else { | |
if (typeof template[i] == "object" && !(object[i] instanceof Array)) { | |
object[i] = arguments.callee.call(this, template[i], object[i]) | |
} | |
} | |
} | |
return object | |
}, | |
copyObject: function(obj) { | |
var res = {}; | |
for (var i in obj) { | |
res[i] = obj[i] | |
} | |
return res | |
}, | |
isTouchScreen: function() { | |
var bool = "orientation" in window || "orientation" in window.screen || "mozOrientation" in window.screen || "ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch || "ontouchstart" in document.documentElement; | |
if (bool) { | |
bool = bool && Detect.isMobile() | |
} | |
return bool || window.location.search.indexOf("touch") >= 0 | |
}, | |
distance: function(x1, y1, x2, y2) { | |
return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) | |
}, | |
arrayUnique: function(a) { | |
for (var i = 0; i < a.length; i++) { | |
var j = i + 1; | |
while (a[j]) { | |
if (a[i] == a[j]) { | |
a.splice(j, 1) | |
} else { | |
j++ | |
} | |
} | |
} | |
}, | |
analyzeParameters: function() { | |
var res = {}; | |
var tmp; | |
var params = window.location.search.substr(1).split("&"); | |
for (var i = 0; i < params.length; i++) { | |
tmp = params[i].split("="); | |
res[tmp[0]] = tmp[1] | |
} | |
return res | |
}, | |
interpolate: function(obj, props, duration, callback) { | |
var before = {}; | |
for (var i in props) { | |
before[i] = parseFloat(obj[i]) | |
} | |
var tStart = Date.now(); | |
(function() { | |
var now = Date.now(); | |
var prct = Math.min(1, (now - tStart) / duration); | |
for (var i in props) { | |
obj[i] = prct * (props[i] - before[i]) + before[i] | |
} | |
if (prct < 1) { | |
requestAnimFrame(arguments.callee) | |
} else { | |
if (callback) { | |
callback.call(obj) | |
} | |
} | |
})() | |
}, | |
addZeros: function(n, length) { | |
var res = n.toString(); | |
while (res.length < length) res = "0" + res; | |
return res | |
}, | |
formatDate: function(format, date, options) { | |
date = date || new Date; | |
options = Util.merge({ | |
months: ["January", "February", "March", "April", "May", "June", "August", "September", "October", "November", "December"] | |
}, options); | |
var res = ""; | |
var formatNext = false; | |
for (var i = 0; i < format.length; i++) { | |
if (format.charAt(i) == "%") { | |
formatNext = true | |
} else if (formatNext) { | |
formatNext = false; | |
switch (format.charAt(i)) { | |
case "%": | |
res += "%"; | |
break; | |
case "M": | |
res += options.months[date.getMonth()]; | |
break; | |
case "d": | |
res += date.getDate(); | |
break; | |
case "Y": | |
res += date.getFullYear(); | |
break; | |
case "m": | |
res += date.getMonth(); | |
break | |
} | |
} else { | |
res += format.charAt(i) | |
} | |
} | |
return res | |
}, | |
keyOf: function(object, element) { | |
for (var i in object) { | |
if (object[i] == element) { | |
return i | |
} | |
} | |
return null | |
} | |
}; | |
var Ajax = { | |
send: function(url, method, params, success, fail) { | |
var xhr; | |
if (window.XMLHttpRequest) { | |
xhr = new XMLHttpRequest | |
} else if (window.ActiveXObject) { | |
try { | |
xhr = new ActiveXObject("Msxml2.XMLHTTP") | |
} catch (e) { | |
xhr = new ActiveXObject("Microsoft.XMLHTTP") | |
} | |
} else { | |
console.log("AJAX not supported by your browser."); | |
return false | |
} | |
success = success || new Function; | |
fail = fail || new Function; | |
method = method.toUpperCase(); | |
params = params || {}; | |
var paramsArray = []; | |
for (var i in params) { | |
paramsArray.push(i + "=" + params[i]) | |
} | |
var paramsString = paramsArray.join("&"); | |
if (method == "GET") { | |
url += "?" + paramsString | |
} | |
xhr.open(method, url, true); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState != 4) return; | |
if (xhr.status != 200) { | |
fail(xhr.status, xhr.responseText) | |
} else { | |
success(xhr.status, xhr.responseText) | |
} | |
}; | |
if (method == "POST") { | |
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); | |
xhr.send(paramsString) | |
} else { | |
xhr.send(null) | |
} | |
} | |
}; | |
var ArrayManager = { | |
elements: [], | |
arrays: [], | |
remove: function(array, element) { | |
this.arrays.push(array); | |
this.elements.push(element) | |
}, | |
flush: function() { | |
var ind; | |
for (var i in this.arrays) { | |
ind = this.arrays[i].indexOf(this.elements[i]); | |
if (ind >= 0) { | |
this.arrays[i].splice(ind, 1) | |
} | |
} | |
this.arrays = []; | |
this.elements = [] | |
}, | |
init: function() { | |
this.arrays = []; | |
this.elements = [] | |
} | |
}; | |
var Encoder = { | |
buildString: function(tab) { | |
var s = "", | |
content; | |
for (var i in tab) { | |
content = tab[i].toString(); | |
content = content.replace(/=/g, " "); | |
content = content.replace(/\|/g, " "); | |
s += i + "=" + content + "|" | |
} | |
return s | |
}, | |
encode: function(hash) { | |
var str = Encoder.buildString(hash); | |
var key = ~~Util.rand(1, 255); | |
var encodedString = Encoder.encodeString(str, key); | |
return encodeURIComponent(encodedString) | |
}, | |
encodeString: function(s, cle) { | |
var enc = "", | |
c; | |
for (var i = 0; i < s.length; i++) { | |
c = s.charCodeAt(i); | |
enc += String.fromCharCode((c + cle) % 256) | |
} | |
enc = String.fromCharCode(cle) + enc; | |
return enc | |
} | |
}; | |
var Detect = { | |
agent: navigator.userAgent.toLowerCase(), | |
isMobile: function() { | |
return this.isAndroid() || this.isFirefoxOS() || this.isWindowsMobile() || this.isIOS() | |
}, | |
isAndroid: function() { | |
return this.agent.indexOf("android") >= 0 | |
}, | |
isFirefoxOS: function() { | |
return !this.isAndroid() && this.agent.indexOf("firefox") >= 0 && this.agent.indexOf("mobile") >= 0 | |
}, | |
isIOS: function() { | |
return this.agent.indexOf("ios") >= 0 || this.agent.indexOf("ipod") >= 0 || this.agent.indexOf("ipad") >= 0 || this.agent.indexOf("iphone") >= 0 | |
}, | |
isWindowsMobile: function() { | |
return this.agent.indexOf("windows") >= 0 && this.agent.indexOf("mobile") >= 0 || this.agent.indexOf("iemobile") >= 0 | |
}, | |
isTizen: function() { | |
return this.agent.indexOf("tizen") >= 0 | |
} | |
}; | |
var resourceManager = { | |
processImages: function(images) { | |
var canvas = DOM.create("canvas"); | |
var c = canvas.getContext("2d"); | |
resources.folder = resources.folder || ""; | |
R.image = R.image || {}; | |
if (resources.image) { | |
for (var i in resources.image) { | |
R.image[i] = images[resources.folder + resources.image[i]] | |
} | |
} | |
R.pattern = R.pattern || {}; | |
if (resources.pattern) { | |
for (var i in resources.pattern) { | |
R.pattern[i] = c.createPattern(images[resources.folder + resources.pattern[i]], "repeat") | |
} | |
} | |
R.sprite = R.sprite || {}; | |
if (resources.sprite) { | |
for (var i in resources.sprite) { | |
R.sprite[i] = this.createSprite(images[resources.folder + resources.sprite[i].sheet], resources.sprite[i]); | |
if (resources.sprite[i].pattern) { | |
R.pattern[i] = c.createPattern(R.sprite[i], "repeat") | |
} | |
} | |
} | |
R.animation = R.animation || {}; | |
if (resources.animation) { | |
for (var i in resources.animation) { | |
R.animation[i] = []; | |
for (var j = 0; j < resources.animation[i].length; j++) { | |
if (R.sprite[resources.animation[i][j]]) { | |
R.animation[i].push(R.sprite[resources.animation[i][j]]) | |
} else { | |
console.log("Error for animation " + i + ': sprite "' + resources.animation[i][j] + '" not found') | |
} | |
} | |
} | |
} | |
R.raw = R.raw || {}; | |
if (resources.raw) { | |
for (var i in resources.raw) { | |
R.raw[i] = resources.raw[i] instanceof Function ? resources.raw[i]() : resources.raw[i] | |
} | |
} | |
R.string = R.string || {}; | |
if (resources.string) { | |
var lang = this.getLanguage(resources.string); | |
if (!resources.string[lang]) { | |
var pp = function(obj) { | |
if (typeof obj == "string") { | |
return | |
} else { | |
var o = {}; | |
for (var i in obj) { | |
if (typeof obj[i] == "string") { | |
o[i] = "{" + i + "}" | |
} else { | |
o[i] = pp(obj[i]) | |
} | |
} | |
return o | |
} | |
}; | |
resources.string[lang] = pp(resources.string.en) | |
} | |
for (var i in resources.string[lang]) { | |
R.string[i] = resources.string[lang][i] | |
} | |
for (var i in R.string) { | |
if (i.charAt(0) == "$") { | |
try { | |
DOM.get(i.substring(1)).innerHTML = R.string[i] | |
} catch (e) { | |
console.log("DOM element " + i + " does not exist") | |
} | |
} | |
} | |
} | |
resources = null; | |
resourceManager = null | |
}, | |
createSprite: function(image, details) { | |
var canvas = DOM.create("canvas"); | |
var c = canvas.getContext("2d"); | |
canvas.width = details.width; | |
canvas.height = details.height; | |
c.drawImage(image, details.x, details.y, details.width, details.height, 0, 0, details.width, details.height); | |
return canvas | |
}, | |
getNecessaryImages: function() { | |
var res = []; | |
for (var i in resources.image) { | |
res.push(resources.folder + resources.image[i]) | |
} | |
for (var i in resources.pattern) { | |
res.push(resources.folder + resources.pattern[i]) | |
} | |
for (var i in resources.sprite) { | |
res.push(resources.folder + resources.sprite[i].sheet) | |
} | |
Util.arrayUnique(res); | |
return res | |
}, | |
getLanguage: function(languages) { | |
var lang = null; | |
var browser_language = null; | |
var params = Util.analyzeParameters(); | |
if (params.lang) { | |
return params.lang | |
} | |
if (navigator && navigator.userAgent && (browser_language = navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { | |
browser_language = browser_language[1] | |
} | |
if (!browser_language && navigator) { | |
if (navigator.language) { | |
browser_language = navigator.language | |
} else if (navigator.browserLanguage) { | |
browser_language = navigator.browserLanguage | |
} else if (navigator.systemLanguage) { | |
browser_language = navigator.systemLanguage | |
} else if (navigator.userLanguage) { | |
browser_language = navigator.userLanguage | |
} | |
browser_language = browser_language.substr(0, 2) | |
} | |
for (var i in languages) { | |
if (browser_language.indexOf(i) >= 0) { | |
lang = i; | |
break | |
} else if (!lang) { | |
lang = i | |
} | |
} | |
return lang | |
} | |
}; | |
var cycleManager = { | |
init: function(cycle, fpsMin) { | |
this.pause = false; | |
this.oncycle = cycle; | |
var hidden, visibilityChange; | |
if (typeof document.hidden !== "undefined") { | |
hidden = "hidden"; | |
visibilityChange = "visibilitychange" | |
} else if (typeof document.mozHidden !== "undefined") { | |
hidden = "mozHidden"; | |
visibilityChange = "mozvisibilitychange" | |
} else if (typeof document.msHidden !== "undefined") { | |
hidden = "msHidden"; | |
visibilityChange = "msvisibilitychange" | |
} else if (typeof document.webkitHidden !== "undefined") { | |
hidden = "webkitHidden"; | |
visibilityChange = "webkitvisibilitychange" | |
} | |
this.focus = true; | |
if (!hidden) { | |
DOM.on(window, "focus", function() { | |
cycleManager.focus = true | |
}); | |
DOM.on(window, "blur", function() { | |
cycleManager.focus = false | |
}) | |
} else { | |
DOM.on(document, visibilityChange, function() { | |
cycleManager.focus = !document[hidden] | |
}) | |
} | |
this.lastCycle = Date.now(); | |
this.fpsMin = fpsMin || 10; | |
this.framesUntilNextStat = 0; | |
this.lastStat = 0; | |
this.fakeLag = document.location.search.indexOf("fakelag") >= 0; | |
this.fps = 0; | |
this.requestId = null; | |
this.init = null; | |
this.resume(); | |
if (window.kik && kik.browser && kik.browser.on) { | |
kik.browser.on("background", function() { | |
cycleManager.stop() | |
}); | |
kik.browser.on("foreground", function() { | |
cycleManager.resume() | |
}) | |
} | |
}, | |
stop: function() { | |
this.pause = true; | |
cancelAnimFrame(this.requestId) | |
}, | |
resume: function() { | |
this.pause = false; | |
cancelAnimFrame(this.requestId); | |
(function() { | |
cycleManager.cycle(); | |
cycleManager.requestId = requestAnimFrame(arguments.callee) | |
})() | |
}, | |
cycle: function() { | |
var now = Date.now(); | |
var elapsed = Math.min((now - this.lastCycle) / 1e3, 1 / this.fpsMin); | |
this.lastCycle = now; | |
if (!this.pause) { | |
try { | |
this.oncycle(elapsed) | |
} catch (e) { | |
console.log("Error: " + e + " - ") | |
} | |
this.framesUntilNextStat--; | |
if (this.framesUntilNextStat <= 0) { | |
this.framesUntilNextStat = 60; | |
this.fps = ~~(60 * 1e3 / (Date.now() - this.lastStat + elapsed)); | |
this.lastStat = Date.now() | |
} | |
} | |
} | |
}; | |
var resizer = { | |
init: function(width, height, element, desktop) { | |
this.enabled = Util.isTouchScreen() || desktop; | |
this.targetWidth = width; | |
this.targetHeight = height; | |
this.element = element; | |
this.dimensions = { | |
width: width, | |
height: height | |
}; | |
this.scale = 1; | |
if (Util.isTouchScreen() || desktop) { | |
DOM.on(window, "resize orientationchange", function() { | |
resizer.resize() | |
}); | |
this.resize(); | |
this.toResize = null | |
} | |
this.init = null | |
}, | |
resize: function() { | |
if (!this.toResize && this.enabled) { | |
this.toResize = setTimeout(function() { | |
if (!resizer.enabled) return; | |
window.scrollTo(0, 1); | |
resizer.toResize = null; | |
resizer.dimensions = DOM.fitScreen(resizer.element, resizer.targetWidth / resizer.targetHeight); | |
resizer.scale = resizer.dimensions.height / resizer.targetHeight | |
}, 1e3) | |
} | |
} | |
}; | |
if (window.cordova) { | |
document.addEventListener("deviceready", function() { | |
cordova.exec(null, null, "SplashScreen", "hide", []); | |
DOM.notify('More HTML5 games available at <a style="color:white" href="' + GameParams.moregamesurl + '">' + GameParams.moregamesurl + "</a>", 3e3) | |
}, false) | |
} | |
if (!Function.prototype.bind) { | |
Function.prototype.bind = function(oThis) { | |
if (typeof this !== "function") { | |
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable") | |
} | |
var aArgs = Array.prototype.slice.call(arguments, 1), | |
fToBind = this, | |
fNOP = function() {}, | |
fBound = function() { | |
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))) | |
}; | |
fNOP.prototype = this.prototype; | |
fBound.prototype = new fNOP; | |
return fBound | |
} | |
} | |
window.originalOpen = window.open; | |
Number.prototype.mod = function(n) { | |
return (this % n + n) % n | |
}; | |
function extend(subClass, superClass) { | |
if (!subClass.extends || !subClass.extends[superClass]) { | |
for (var i in superClass.prototype) { | |
if (!subClass.prototype[i]) { | |
subClass.prototype[i] = superClass.prototype[i] | |
} | |
} | |
subClass.extends = subClass.extends || {}; | |
subClass.extends[superClass] = true | |
} | |
} | |
function extendPrototype(superClass, proto) { | |
var subProto = {}; | |
for (var i in superClass.prototype) { | |
subProto[i] = superClass.prototype[i] | |
} | |
for (var i in proto) { | |
subProto[i] = proto[i] | |
} | |
return subProto | |
} | |
function ResourceLoader(settings) { | |
this.settings = settings; | |
this.appCache = window.applicationCache; | |
this.finished = false; | |
this.message = null | |
} | |
ResourceLoader.prototype.load = function(end, canvas) { | |
this.endCallback = end; | |
this.canvasOutput = canvas; | |
if (!this.appCache || this.appCache.status === this.appCache.UNCACHED) { | |
this.loadResources() | |
} else { | |
this.loadCache() | |
} | |
}; | |
ResourceLoader.prototype.loadCache = function() { | |
this.message = "Updating..."; | |
this.appCache.addEventListener("checking", this.checkingCache.bind(this), false); | |
this.appCache.addEventListener("noupdate", this.loadResources.bind(this), false); | |
this.appCache.addEventListener("obsolete", this.loadResources.bind(this), false); | |
this.appCache.addEventListener("error", this.loadResources.bind(this), false); | |
this.appCache.addEventListener("cached", this.loadResources.bind(this), false); | |
this.appCache.addEventListener("downloading", this.updatingCache.bind(this), false); | |
this.appCache.addEventListener("progress", this.updatingCacheProgress.bind(this), false); | |
this.appCache.addEventListener("updateready", this.updatingCacheReady.bind(this), false); | |
if (this.appCache.status === this.appCache.IDLE) { | |
try { | |
this.appCache.update() | |
} catch (e) { | |
this.loadResources() | |
} | |
} | |
}; | |
ResourceLoader.prototype.checkingCache = function() { | |
if (!this.finished) { | |
this.showProgress(this.canvasOutput, 0) | |
} | |
}; | |
ResourceLoader.prototype.updatingCache = function(e) { | |
if (this.canvasOutput && !this.finished) { | |
this.showProgress(this.canvasOutput, 0) | |
} | |
}; | |
ResourceLoader.prototype.updatingCacheProgress = function(e) { | |
if (this.canvasOutput && !this.finished) { | |
this.showProgress(this.canvasOutput, e.loaded / e.total || 0) | |
} | |
}; | |
ResourceLoader.prototype.updatingCacheReady = function(e) { | |
if (!this.finished) { | |
this.finished = true; | |
try { | |
this.appCache.swapCache() | |
} catch (e) {} | |
location.reload() | |
} | |
}; | |
ResourceLoader.prototype.loadResources = function() { | |
this.message = "Loading assets. Please wait..."; | |
this.R = {}; | |
this.processLanguage(this.R); | |
var images = this.getNecessaryImages(); | |
var loader = this; | |
Util.preload(images, this.resourcesProgress.bind(this), this.resourcesLoaded.bind(this), this.resourcesError.bind(this)) | |
}; | |
ResourceLoader.prototype.resourcesError = function(imageSrc) { | |
alert("Could not load " + imageSrc + ".\nUnable to launch.") | |
}; | |
ResourceLoader.prototype.resourcesProgress = function(img, progress) { | |
if (this.canvasOutput && !this.finished) { | |
this.showProgress(this.canvasOutput, progress) | |
} | |
}; | |
ResourceLoader.prototype.resourcesLoaded = function(loadedImages) { | |
if (!this.finished) { | |
this.finished = true; | |
this.processImages(loadedImages, this.R); | |
this.endCallback(this.R) | |
} | |
}; | |
ResourceLoader.prototype.showProgress = function(canvas, progress) { | |
var ctx = canvas.getContext("2d"); | |
ctx.fillStyle = "#000"; | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
ctx.font = "10px Arial"; | |
ctx.fillStyle = "gray"; | |
ctx.textAlign = "center"; | |
ctx.textBaseline = "middle"; | |
ctx.fillText(this.message, canvas.width / 2, canvas.height / 2 - 20); | |
ctx.fillRect(0, canvas.height / 2 - 5, canvas.width, 10); | |
ctx.fillStyle = "white"; | |
ctx.fillRect(0, canvas.height / 2 - 5, progress * canvas.width, 10); | |
ctx.fillStyle = "black"; | |
ctx.textAlign = "right"; | |
ctx.fillText(~~(progress * 100) + "%", progress * canvas.width - 2, canvas.height / 2) | |
}; | |
ResourceLoader.prototype.createSprite = function(image, details) { | |
var canvas = document.createElement("canvas"); | |
var c = canvas.getContext("2d"); | |
canvas.width = details.width; | |
canvas.height = details.height; | |
c.drawImage(image, details.x, details.y, details.width, details.height, 0, 0, details.width, details.height); | |
return canvas | |
}; | |
ResourceLoader.prototype.getNecessaryImages = function() { | |
var res = []; | |
for (var i in this.settings.image) { | |
res.push(this.settings.folder + this.settings.image[i]) | |
} | |
for (var i in this.settings.pattern) { | |
res.push(this.settings.folder + this.settings.pattern[i]) | |
} | |
for (var i in this.settings.sprite) { | |
res.push(this.settings.folder + this.settings.sprite[i].sheet) | |
} | |
Util.arrayUnique(res); | |
return res | |
}; | |
ResourceLoader.prototype.getLanguage = function(languages) { | |
var lang = null; | |
var browser_language = null; | |
var params = Util.analyzeParameters(); | |
if (params.lang) { | |
return params.lang | |
} | |
if (navigator && navigator.userAgent && (browser_language = navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { | |
browser_language = browser_language[1] | |
} | |
if (!browser_language && navigator) { | |
if (navigator.language) { | |
browser_language = navigator.language | |
} else if (navigator.browserLanguage) { | |
browser_language = navigator.browserLanguage | |
} else if (navigator.systemLanguage) { | |
browser_language = navigator.systemLanguage | |
} else if (navigator.userLanguage) { | |
browser_language = navigator.userLanguage | |
} | |
browser_language = browser_language.substr(0, 2) | |
} | |
for (var i in languages) { | |
if (browser_language.indexOf(i) >= 0) { | |
lang = i; | |
break | |
} else if (!lang) { | |
lang = i | |
} | |
} | |
return lang | |
}; | |
ResourceLoader.prototype.processImages = function(images, R) { | |
var canvas = DOM.create("canvas"); | |
var c = canvas.getContext("2d"); | |
this.settings.folder = this.settings.folder || ""; | |
R.image = R.image || {}; | |
if (this.settings.image) { | |
for (var i in this.settings.image) { | |
R.image[i] = images[this.settings.folder + this.settings.image[i]] | |
} | |
} | |
R.pattern = R.pattern || {}; | |
if (this.settings.pattern) { | |
for (var i in this.settings.pattern) { | |
R.pattern[i] = c.createPattern(images[this.settings.folder + this.settings.pattern[i]], "repeat"); | |
R.pattern[i].width = images[this.settings.folder + this.settings.pattern[i]].width; | |
R.pattern[i].height = images[this.settings.folder + this.settings.pattern[i]].height | |
} | |
} | |
R.sprite = R.sprite || {}; | |
if (this.settings.sprite) { | |
for (var i in this.settings.sprite) { | |
R.sprite[i] = this.createSprite(images[this.settings.folder + this.settings.sprite[i].sheet], this.settings.sprite[i]); | |
if (this.settings.sprite[i].pattern) { | |
R.pattern[i] = c.createPattern(R.sprite[i], "repeat"); | |
R.pattern[i].width = R.sprite[i].width; | |
R.pattern[i].height = R.sprite[i].height | |
} | |
} | |
} | |
R.animation = R.animation || {}; | |
if (this.settings.animation) { | |
for (var i in this.settings.animation) { | |
R.animation[i] = []; | |
for (var j = 0; j < this.settings.animation[i].length; j++) { | |
if (R.sprite[this.settings.animation[i][j]]) { | |
R.animation[i].push(R.sprite[this.settings.animation[i][j]]) | |
} else { | |
console.log("Error for animation " + i + ': sprite "' + this.settings.animation[i][j] + '" not found') | |
} | |
} | |
} | |
} | |
R.raw = R.raw || {}; | |
if (this.settings.raw) { | |
for (var i in this.settings.raw) { | |
R.raw[i] = this.settings.raw[i] instanceof Function ? this.settings.raw[i]() : this.settings.raw[i] | |
} | |
} | |
}; | |
ResourceLoader.prototype.processLanguage = function(R) { | |
R.string = R.string || {}; | |
if (this.settings.string) { | |
this.language = this.getLanguage(this.settings.string); | |
if (!this.settings.string[this.language]) { | |
var pp = function(obj) { | |
if (typeof obj == "string") { | |
return | |
} else { | |
var o = {}; | |
for (var i in obj) { | |
if (typeof obj[i] == "string") { | |
o[i] = "{" + i + "}" | |
} else { | |
o[i] = pp(obj[i]) | |
} | |
} | |
return o | |
} | |
}; | |
this.settings.string[this.language] = pp(this.settings.string.en) | |
} | |
for (var i in this.settings.string[this.language]) { | |
R.string[i] = this.settings.string[this.language][i] | |
} | |
for (var i in R.string) { | |
if (i.charAt(0) == "$") { | |
try { | |
DOM.get(i.substring(1)).innerHTML = R.string[i] | |
} catch (e) { | |
console.log("DOM element " + i + " does not exist") | |
} | |
} | |
} | |
} | |
}; | |
function Resizer(options) { | |
this.delay = options.delay || 0; | |
this.element = options.element || null; | |
this.baseWidth = options.baseWidth; | |
this.baseHeight = options.baseHeight; | |
this.onResize = options.onResize; | |
this.enabled = true; | |
this.resizeTimeout = null | |
} | |
Resizer.prototype = { | |
needsResize: function(maxWidth, maxHeight) { | |
clearTimeout(this.resizeTimeout); | |
if (this.enabled) { | |
this.maxWidth = maxWidth; | |
this.maxHeight = maxHeight; | |
this.resizeTimeout = setTimeout(this.resize.bind(this), this.delay) | |
} | |
}, | |
resize: function() { | |
this.resizeTimeout = null; | |
var dimensions = this.getFittingDimensions(this.maxWidth, this.maxHeight); | |
this.element.style.width = dimensions.width + "px"; | |
this.element.style.height = dimensions.height + "px"; | |
if (this.onResize) { | |
this.onResize.call(this) | |
} | |
}, | |
scaleX: function() { | |
return parseInt(this.element.style.width) / this.baseWidth || 1 | |
}, | |
scaleY: function() { | |
return parseInt(this.element.style.height) / this.baseHeight || 1 | |
}, | |
getFittingDimensions: function(maxWidth, maxHeight) { | |
var availableRatio = maxWidth / maxHeight; | |
var baseRatio = this.baseWidth / this.baseHeight; | |
var ratioDifference = Math.abs(availableRatio - baseRatio); | |
var width, height; | |
if (ratioDifference <= .1) { | |
width = maxWidth; | |
height = maxHeight | |
} else if (availableRatio <= baseRatio) { | |
width = maxWidth; | |
height = width / baseRatio | |
} else { | |
height = maxHeight; | |
width = height * baseRatio | |
} | |
return { | |
width: width, | |
height: height | |
} | |
} | |
}; | |
(function() { | |
var cache = {}; | |
var ctx = null, | |
usingWebAudio = true, | |
noAudio = false; | |
try { | |
if (typeof AudioContext !== "undefined") { | |
ctx = new AudioContext | |
} else if (typeof webkitAudioContext !== "undefined") { | |
ctx = new webkitAudioContext | |
} else { | |
usingWebAudio = false | |
} | |
} catch (e) { | |
usingWebAudio = false | |
} | |
if (!usingWebAudio) { | |
if (typeof Audio !== "undefined") { | |
try { | |
new Audio | |
} catch (e) { | |
noAudio = true | |
} | |
} else { | |
noAudio = true | |
} | |
} | |
if (usingWebAudio) { | |
var masterGain = typeof ctx.createGain === "undefined" ? ctx.createGainNode() : ctx.createGain(); | |
masterGain.gain.value = 1; | |
masterGain.connect(ctx.destination) | |
} | |
var HowlerGlobal = function() { | |
this._volume = 1; | |
this._muted = false; | |
this.usingWebAudio = usingWebAudio; | |
this.noAudio = noAudio; | |
this._howls = [] | |
}; | |
HowlerGlobal.prototype = { | |
volume: function(vol) { | |
var self = this; | |
vol = parseFloat(vol); | |
if (vol >= 0 && vol <= 1) { | |
self._volume = vol; | |
if (usingWebAudio) { | |
masterGain.gain.value = vol | |
} | |
for (var key in self._howls) { | |
if (self._howls.hasOwnProperty(key) && self._howls[key]._webAudio === false) { | |
for (var i = 0; i < self._howls[key]._audioNode.length; i++) { | |
self._howls[key]._audioNode[i].volume = self._howls[key]._volume * self._volume | |
} | |
} | |
} | |
return self | |
} | |
return usingWebAudio ? masterGain.gain.value : self._volume | |
}, | |
mute: function() { | |
this._setMuted(true); | |
return this | |
}, | |
unmute: function() { | |
this._setMuted(false); | |
return this | |
}, | |
_setMuted: function(muted) { | |
var self = this; | |
self._muted = muted; | |
if (usingWebAudio) { | |
masterGain.gain.value = muted ? 0 : self._volume | |
} | |
for (var key in self._howls) { | |
if (self._howls.hasOwnProperty(key) && self._howls[key]._webAudio === false) { | |
for (var i = 0; i < self._howls[key]._audioNode.length; i++) { | |
self._howls[key]._audioNode[i].muted = muted | |
} | |
} | |
} | |
} | |
}; | |
var Howler = new HowlerGlobal; | |
var audioTest = null; | |
if (!noAudio) { | |
audioTest = new Audio; | |
var codecs = { | |
mp3: !!audioTest.canPlayType("audio/mpeg;").replace(/^no$/, ""), | |
opus: !!audioTest.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, ""), | |
ogg: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ""), | |
wav: !!audioTest.canPlayType('audio/wav; codecs="1"').replace(/^no$/, ""), | |
m4a: !!(audioTest.canPlayType("audio/x-m4a;") || audioTest.canPlayType("audio/aac;")).replace(/^no$/, ""), | |
mp4: !!(audioTest.canPlayType("audio/x-mp4;") || audioTest.canPlayType("audio/aac;")).replace(/^no$/, ""), | |
weba: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, "") | |
} | |
} | |
var Howl = function(o) { | |
var self = this; | |
self._autoplay = o.autoplay || false; | |
self._buffer = o.buffer || false; | |
self._duration = o.duration || 0; | |
self._format = o.format || null; | |
self._loop = o.loop || false; | |
self._loaded = false; | |
self._sprite = o.sprite || {}; | |
self._src = o.src || ""; | |
self._pos3d = o.pos3d || [0, 0, -.5]; | |
self._volume = o.volume !== undefined ? o.volume : 1; | |
self._urls = o.urls || []; | |
self._rate = o.rate || 1; | |
self._model = o.model || null; | |
self._onload = [o.onload || function() {}]; | |
self._onloaderror = [o.onloaderror || function() {}]; | |
self._onend = [o.onend || function() {}]; | |
self._onpause = [o.onpause || function() {}]; | |
self._onplay = [o.onplay || function() {}]; | |
self._onendTimer = []; | |
self._webAudio = usingWebAudio && !self._buffer; | |
self._audioNode = []; | |
if (self._webAudio) { | |
self._setupAudioNode() | |
} | |
Howler._howls.push(self); | |
self.load() | |
}; | |
Howl.prototype = { | |
load: function() { | |
var self = this, | |
url = null; | |
if (noAudio) { | |
self.on("loaderror"); | |
return | |
} | |
for (var i = 0; i < self._urls.length; i++) { | |
var ext, urlItem; | |
if (self._format) { | |
ext = self._format | |
} else { | |
urlItem = self._urls[i].toLowerCase().split("?")[0]; | |
ext = urlItem.match(/.+\.([^?]+)(\?|$)/); | |
ext = ext && ext.length >= 2 ? ext : urlItem.match(/data\:audio\/([^?]+);/); | |
if (ext) { | |
ext = ext[1] | |
} else { | |
self.on("loaderror"); | |
return | |
} | |
} | |
if (codecs[ext]) { | |
url = self._urls[i]; | |
break | |
} | |
} | |
if (!url) { | |
self.on("loaderror"); | |
return | |
} | |
self._src = url; | |
if (self._webAudio) { | |
loadBuffer(self, url) | |
} else { | |
var newNode = new Audio; | |
newNode.addEventListener("error", function() { | |
if (newNode.error && newNode.error.code === 4) { | |
HowlerGlobal.noAudio = true | |
} | |
self.on("loaderror", { | |
type: newNode.error ? newNode.error.code : 0 | |
}) | |
}, false); | |
self._audioNode.push(newNode); | |
newNode.src = url; | |
newNode._pos = 0; | |
newNode.preload = "auto"; | |
newNode.volume = Howler._muted ? 0 : self._volume * Howler.volume(); | |
cache[url] = self; | |
var listener = function() { | |
self._duration = Math.ceil(newNode.duration * 10) / 10; | |
if (Object.getOwnPropertyNames(self._sprite).length === 0) { | |
self._sprite = { | |
_default: [0, self._duration * 1e3] | |
} | |
} | |
if (!self._loaded) { | |
self._loaded = true; | |
self.on("load") | |
} | |
if (self._autoplay) { | |
self.play() | |
} | |
newNode.removeEventListener("canplaythrough", listener, false) | |
}; | |
newNode.addEventListener("canplaythrough", listener, false); | |
newNode.load() | |
} | |
return self | |
}, | |
urls: function(urls) { | |
var self = this; | |
if (urls) { | |
self.stop(); | |
self._urls = typeof urls === "string" ? [urls] : urls; | |
self._loaded = false; | |
self.load(); | |
return self | |
} else { | |
return self._urls | |
} | |
}, | |
play: function(sprite, callback) { | |
var self = this; | |
if (typeof sprite === "function") { | |
callback = sprite | |
} | |
if (!sprite || typeof sprite === "function") { | |
sprite = "_default" | |
} | |
if (!self._loaded) { | |
self.on("load", function() { | |
self.play(sprite, callback) | |
}); | |
return self | |
} | |
if (!self._sprite[sprite]) { | |
if (typeof callback === "function") callback(); | |
return self | |
} | |
self._inactiveNode(function(node) { | |
node._sprite = sprite; | |
var pos = node._pos > 0 ? node._pos : self._sprite[sprite][0] / 1e3, | |
duration = self._sprite[sprite][1] / 1e3 - node._pos; | |
var loop = !!(self._loop || self._sprite[sprite][2]); | |
var soundId = typeof callback === "string" ? callback : Math.round(Date.now() * Math.random()) + "", | |
timerId; | |
(function() { | |
var data = { | |
id: soundId, | |
sprite: sprite, | |
loop: loop | |
}; | |
timerId = setTimeout(function() { | |
if (!self._webAudio && loop) { | |
self.stop(data.id).play(sprite, data.id) | |
} | |
if (self._webAudio && !loop) { | |
self._nodeById(data.id).paused = true; | |
self._nodeById(data.id)._pos = 0 | |
} | |
if (!self._webAudio && !loop) { | |
self.stop(data.id) | |
} | |
self.on("end", soundId) | |
}, duration * 1e3); | |
self._onendTimer.push({ | |
timer: timerId, | |
id: data.id | |
}) | |
})(); | |
if (self._webAudio) { | |
var loopStart = self._sprite[sprite][0] / 1e3, | |
loopEnd = self._sprite[sprite][1] / 1e3; | |
node.id = soundId; | |
node.paused = false; | |
refreshBuffer(self, [loop, loopStart, loopEnd], soundId); | |
self._playStart = ctx.currentTime; | |
node.gain.value = self._volume; | |
if (typeof node.bufferSource.start === "undefined") { | |
node.bufferSource.noteGrainOn(0, pos, duration) | |
} else { | |
node.bufferSource.start(0, pos, duration) | |
} | |
} else { | |
if (node.readyState === 4 || !node.readyState && navigator.isCocoonJS) { | |
node.readyState = 4; | |
node.id = soundId; | |
node.currentTime = pos; | |
node.muted = Howler._muted || node.muted; | |
node.volume = self._volume * Howler.volume(); | |
setTimeout(function() { | |
node.play() | |
}, 0) | |
} else { | |
self._clearEndTimer(soundId); | |
(function() { | |
var sound = self, | |
playSprite = sprite, | |
fn = callback, | |
newNode = node; | |
var listener = function() { | |
sound.play(playSprite, fn); | |
newNode.removeEventListener("canplaythrough", listener, false) | |
}; | |
newNode.addEventListener("canplaythrough", listener, false) | |
})(); | |
return self | |
} | |
} | |
self.on("play"); | |
if (typeof callback === "function") callback(soundId); | |
return self | |
}); | |
return self | |
}, | |
pause: function(id) { | |
var self = this; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.pause(id) | |
}); | |
return self | |
} | |
self._clearEndTimer(id); | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
activeNode._pos = self.pos(null, id); | |
if (self._webAudio) { | |
if (!activeNode.bufferSource || activeNode.paused) { | |
return self | |
} | |
activeNode.paused = true; | |
if (typeof activeNode.bufferSource.stop === "undefined") { | |
activeNode.bufferSource.noteOff(0) | |
} else { | |
activeNode.bufferSource.stop(0) | |
} | |
} else { | |
activeNode.pause() | |
} | |
} | |
self.on("pause"); | |
return self | |
}, | |
stop: function(id) { | |
var self = this; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.stop(id) | |
}); | |
return self | |
} | |
self._clearEndTimer(id); | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
activeNode._pos = 0; | |
if (self._webAudio) { | |
if (!activeNode.bufferSource || activeNode.paused) { | |
return self | |
} | |
activeNode.paused = true; | |
if (typeof activeNode.bufferSource.stop === "undefined") { | |
activeNode.bufferSource.noteOff(0) | |
} else { | |
activeNode.bufferSource.stop(0) | |
} | |
} else if (!isNaN(activeNode.duration)) { | |
activeNode.pause(); | |
activeNode.currentTime = 0 | |
} | |
} | |
return self | |
}, | |
mute: function(id) { | |
var self = this; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.mute(id) | |
}); | |
return self | |
} | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
if (self._webAudio) { | |
activeNode.gain.value = 0 | |
} else { | |
activeNode.muted = true | |
} | |
} | |
return self | |
}, | |
unmute: function(id) { | |
var self = this; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.unmute(id) | |
}); | |
return self | |
} | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
if (self._webAudio) { | |
activeNode.gain.value = self._volume | |
} else { | |
activeNode.muted = false | |
} | |
} | |
return self | |
}, | |
volume: function(vol, id) { | |
var self = this; | |
vol = parseFloat(vol); | |
if (vol >= 0 && vol <= 1) { | |
self._volume = vol; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.volume(vol, id) | |
}); | |
return self | |
} | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
if (self._webAudio) { | |
activeNode.gain.value = vol | |
} else { | |
activeNode.volume = vol * Howler.volume() | |
} | |
} | |
return self | |
} else { | |
return self._volume | |
} | |
}, | |
loop: function(loop) { | |
var self = this; | |
if (typeof loop === "boolean") { | |
self._loop = loop; | |
return self | |
} else { | |
return self._loop | |
} | |
}, | |
sprite: function(sprite) { | |
var self = this; | |
if (typeof sprite === "object") { | |
self._sprite = sprite; | |
return self | |
} else { | |
return self._sprite | |
} | |
}, | |
pos: function(pos, id) { | |
var self = this; | |
if (!self._loaded) { | |
self.on("load", function() { | |
self.pos(pos) | |
}); | |
return typeof pos === "number" ? self : self._pos || 0 | |
} | |
pos = parseFloat(pos); | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
if (pos >= 0) { | |
self.pause(id); | |
activeNode._pos = pos; | |
self.play(activeNode._sprite, id); | |
return self | |
} else { | |
return self._webAudio ? activeNode._pos + (ctx.currentTime - self._playStart) : activeNode.currentTime | |
} | |
} else if (pos >= 0) { | |
return self | |
} else { | |
for (var i = 0; i < self._audioNode.length; i++) { | |
if (self._audioNode[i].paused && self._audioNode[i].readyState === 4) { | |
return self._webAudio ? self._audioNode[i]._pos : self._audioNode[i].currentTime | |
} | |
} | |
} | |
}, | |
pos3d: function(x, y, z, id) { | |
var self = this; | |
y = typeof y === "undefined" || !y ? 0 : y; | |
z = typeof z === "undefined" || !z ? -.5 : z; | |
if (!self._loaded) { | |
self.on("play", function() { | |
self.pos3d(x, y, z, id) | |
}); | |
return self | |
} | |
if (x >= 0 || x < 0) { | |
if (self._webAudio) { | |
var activeNode = id ? self._nodeById(id) : self._activeNode(); | |
if (activeNode) { | |
self._pos3d = [x, y, z]; | |
activeNode.panner.setPosition(x, y, z); | |
activeNode.panner.panningModel = self._model || "HRTF" | |
} | |
} | |
} else { | |
return self._pos3d | |
} | |
return self | |
}, | |
fade: function(from, to, len, callback, id) { | |
var self = this, | |
diff = Math.abs(from - to), | |
dir = from > to ? "down" : "up", | |
steps = diff / .01, | |
stepTime = len / steps; | |
if (!self._loaded) { | |
self.on("load", function() { | |
self.fade(from, to, len, callback, id) | |
}); | |
return self | |
} | |
self.volume(from, id); | |
for (var i = 1; i <= steps; i++) { | |
(function() { | |
var change = self._volume + (dir === "up" ? .01 : -.01) * i, | |
vol = Math.round(1e3 * change) / 1e3, | |
toVol = to; | |
setTimeout(function() { | |
self.volume(vol, id); | |
if (vol === toVol) { | |
if (callback) callback() | |
} | |
}, stepTime * i) | |
})() | |
} | |
}, | |
fadeIn: function(to, len, callback) { | |
return this.volume(0).play().fade(0, to, len, callback) | |
}, | |
fadeOut: function(to, len, callback, id) { | |
var self = this; | |
return self.fade(self._volume, to, len, function() { | |
if (callback) callback(); | |
self.pause(id); | |
self.on("end") | |
}, id) | |
}, | |
_nodeById: function(id) { | |
var self = this, | |
node = self._audioNode[0]; | |
for (var i = 0; i < self._audioNode.length; i++) { | |
if (self._audioNode[i].id === id) { | |
node = self._audioNode[i]; | |
break | |
} | |
} | |
return node | |
}, | |
_activeNode: function() { | |
var self = this, | |
node = null; | |
for (var i = 0; i < self._audioNode.length; i++) { | |
if (!self._audioNode[i].paused) { | |
node = self._audioNode[i]; | |
break | |
} | |
} | |
self._drainPool(); | |
return node | |
}, | |
_inactiveNode: function(callback) { | |
var self = this, | |
node = null; | |
for (var i = 0; i < self._audioNode.length; i++) { | |
if (self._audioNode[i].paused && self._audioNode[i].readyState === 4) { | |
callback(self._audioNode[i]); | |
node = true; | |
break | |
} | |
} | |
self._drainPool(); | |
if (node) { | |
return | |
} | |
var newNode; | |
if (self._webAudio) { | |
newNode = self._setupAudioNode(); | |
callback(newNode) | |
} else { | |
self.load(); | |
newNode = self._audioNode[self._audioNode.length - 1]; | |
newNode.addEventListener(navigator.isCocoonJS ? "canplaythrough" : "loadedmetadata", function() { | |
callback(newNode) | |
}) | |
} | |
}, | |
_drainPool: function() { | |
var self = this, | |
inactive = 0, | |
i; | |
for (i = 0; i < self._audioNode.length; i++) { | |
if (self._audioNode[i].paused) { | |
inactive++ | |
} | |
} | |
for (i = self._audioNode.length - 1; i >= 0; i--) { | |
if (inactive <= 5) { | |
break | |
} | |
if (self._audioNode[i].paused) { | |
if (self._webAudio) { | |
self._audioNode[i].disconnect(0) | |
} | |
inactive--; | |
self._audioNode.splice(i, 1) | |
} | |
} | |
}, | |
_clearEndTimer: function(soundId) { | |
var self = this, | |
index = 0; | |
for (var i = 0; i < self._onendTimer.length; i++) { | |
if (self._onendTimer[i].id === soundId) { | |
index = i; | |
break | |
} | |
} | |
var timer = self._onendTimer[index]; | |
if (timer) { | |
clearTimeout(timer.timer); | |
self._onendTimer.splice(index, 1) | |
} | |
}, | |
_setupAudioNode: function() { | |
var self = this, | |
node = self._audioNode, | |
index = self._audioNode.length; | |
node[index] = typeof ctx.createGain === "undefined" ? ctx.createGainNode() : ctx.createGain(); | |
node[index].gain.value = self._volume; | |
node[index].paused = true; | |
node[index]._pos = 0; | |
node[index].readyState = 4; | |
node[index].connect(masterGain); | |
node[index].panner = ctx.createPanner(); | |
node[index].panner.panningModel = self._model || "equalpower"; | |
node[index].panner.setPosition(self._pos3d[0], self._pos3d[1], self._pos3d[2]); | |
node[index].panner.connect(node[index]); | |
return node[index] | |
}, | |
on: function(event, fn) { | |
var self = this, | |
events = self["_on" + event]; | |
if (typeof fn === "function") { | |
events.push(fn) | |
} else { | |
for (var i = 0; i < events.length; i++) { | |
if (fn) { | |
events[i].call(self, fn) | |
} else { | |
events[i].call(self) | |
} | |
} | |
} | |
return self | |
}, | |
off: function(event, fn) { | |
var self = this, | |
events = self["_on" + event], | |
fnString = fn.toString(); | |
for (var i = 0; i < events.length; i++) { | |
if (fnString === events[i].toString()) { | |
events.splice(i, 1); | |
break | |
} | |
} | |
return self | |
}, | |
unload: function() { | |
var self = this; | |
var nodes = self._audioNode; | |
for (var i = 0; i < self._audioNode.length; i++) { | |
if (!nodes[i].paused) { | |
self.stop(nodes[i].id) | |
} | |
if (!self._webAudio) { | |
nodes[i].src = "" | |
} else { | |
nodes[i].disconnect(0) | |
} | |
} | |
for (i = 0; i < self._onendTimer.length; i++) { | |
clearTimeout(self._onendTimer[i].timer) | |
} | |
var index = Howler._howls.indexOf(self); | |
if (index !== null && index >= 0) { | |
Howler._howls.splice(index, 1) | |
} | |
delete cache[self._src]; | |
self = null | |
} | |
}; | |
if (usingWebAudio) { | |
var loadBuffer = function(obj, url) { | |
if (url in cache) { | |
obj._duration = cache[url].duration; | |
loadSound(obj) | |
} else { | |
var xhr = new XMLHttpRequest; | |
xhr.open("GET", url, true); | |
xhr.responseType = "arraybuffer"; | |
xhr.onload = function() { | |
ctx.decodeAudioData(xhr.response, function(buffer) { | |
if (buffer) { | |
cache[url] = buffer; | |
loadSound(obj, buffer) | |
} | |
}, function(err) { | |
obj.on("loaderror") | |
}) | |
}; | |
xhr.onerror = function() { | |
if (obj._webAudio) { | |
obj._buffer = true; | |
obj._webAudio = false; | |
obj._audioNode = []; | |
delete obj._gainNode; | |
obj.load() | |
} | |
}; | |
try { | |
xhr.send() | |
} catch (e) { | |
xhr.onerror() | |
} | |
} | |
}; | |
var loadSound = function(obj, buffer) { | |
obj._duration = buffer ? buffer.duration : obj._duration; | |
if (Object.getOwnPropertyNames(obj._sprite).length === 0) { | |
obj._sprite = { | |
_default: [0, obj._duration * 1e3] | |
} | |
} | |
if (!obj._loaded) { | |
obj._loaded = true; | |
obj.on("load") | |
} | |
if (obj._autoplay) { | |
obj.play() | |
} | |
}; | |
var refreshBuffer = function(obj, loop, id) { | |
var node = obj._nodeById(id); | |
node.bufferSource = ctx.createBufferSource(); | |
node.bufferSource.buffer = cache[obj._src]; | |
node.bufferSource.connect(node.panner); | |
node.bufferSource.loop = loop[0]; | |
if (loop[0]) { | |
node.bufferSource.loopStart = loop[1]; | |
node.bufferSource.loopEnd = loop[1] + loop[2] | |
} | |
node.bufferSource.playbackRate.value = obj._rate | |
} | |
} | |
if (typeof define === "function" && define.amd) { | |
define(function() { | |
return { | |
Howler: Howler, | |
Howl: Howl | |
} | |
}) | |
} | |
if (typeof exports !== "undefined") { | |
exports.Howler = Howler; | |
exports.Howl = Howl | |
} | |
if (typeof window !== "undefined") { | |
window.Howler = Howler; | |
window.Howl = Howl | |
} | |
})(); | |
(function(g, m, a, p, i) { | |
g["GameMixAPIName"] = i; | |
g[i] = g[i] || function(f) { | |
g[i].q = g[i].q || []; | |
g[i].q.push(f) | |
}; | |
g[i]({ | |
apiDomain: p | |
}); | |
var s = m.createElement(a), | |
d = m.getElementsByTagName(a)[0]; | |
s.type = "text/javascript"; | |
s.async = true; | |
s.src = p + "/v1/gm.js"; | |
d.parentNode.insertBefore(s, d) | |
})(window, document, "script", "http://gmapi.gamemix.com", "gmapi"); | |
gmapi("donttap"); | |
window.googletag = window.googletag || {}; | |
googletag.cmd = googletag.cmd || []; | |
(function() { | |
var gads = document.createElement("script"); | |
gads.async = true; | |
gads.type = "text/javascript"; | |
var useSSL = "https:" == document.location.protocol; | |
gads.src = (useSSL ? "https:" : "http:") + "//www.googletagservices.com/tag/js/gpt.js"; | |
var node = document.getElementsByTagName("script")[0]; | |
node.parentNode.insertBefore(gads, node) | |
})(); | |
function Area(x, y, w, h, settings) { | |
this.x = x; | |
this.y = y; | |
this.width = w; | |
this.height = h; | |
this.enabled = true; | |
settings = settings || {}; | |
this.onactionperformed = settings.actionPerformed; | |
this.onactionstart = settings.actionStart; | |
this.onactioncancel = settings.actionCancel | |
} | |
Area.prototype = { | |
contains: function(x, y) { | |
return x >= this.x && y >= this.y && x <= this.x + this.width && y <= this.y + this.height | |
}, | |
actionPerformed: function(x, y) { | |
if (this.onactionperformed) { | |
this.onactionperformed(x, y) | |
} | |
}, | |
actionStart: function(x, y) { | |
if (this.onactionstart) { | |
this.onactionstart(x, y) | |
} | |
}, | |
actionCancel: function(x, y) { | |
if (this.onactioncancel) { | |
this.onactioncancel(x, y) | |
} | |
} | |
}; | |
function Screen(game) { | |
this.game = game; | |
this.areas = []; | |
this.currentActionArea = null; | |
this.view = null | |
} | |
Screen.prototype = { | |
cycle: function(elapsed) {}, | |
touchStart: function(x, y) { | |
for (var i in this.areas) { | |
if (this.areas[i].enabled && this.areas[i].contains(x, y)) { | |
this.currentActionArea = this.areas[i]; | |
this.currentActionArea.actionStart(x, y); | |
break | |
} | |
} | |
}, | |
touchMove: function(x, y) { | |
if (this.currentActionArea && !this.currentActionArea.contains(x, y)) { | |
this.currentActionArea.actionCancel(x, y); | |
this.currentActionArea = null | |
} | |
}, | |
touchEnd: function(x, y) { | |
if (this.currentActionArea && this.currentActionArea.contains(x, y)) { | |
this.currentActionArea.actionPerformed(x, y) | |
} | |
this.currentActionArea = null | |
}, | |
create: function() {}, | |
destroy: function() {}, | |
addArea: function(area) { | |
this.areas.push(area) | |
}, | |
areaContains: function(x, y) { | |
for (var i in this.areas) { | |
if (this.areas[i].enabled && this.areas[i].contains(x, y)) { | |
return true | |
} | |
} | |
return false | |
}, | |
getId: function() { | |
return undefined | |
} | |
}; | |
function DisplayableObject() { | |
this.parent = null; | |
this.x = this.y = 0; | |
this.rotation = 0; | |
this.scaleX = this.scaleY = 1; | |
this.alpha = 1; | |
this.visible = true | |
} | |
DisplayableObject.prototype = { | |
applyTransforms: function(c) { | |
if (this.x != 0 || this.y != 0) c.translate(this.x, this.y); | |
if (this.scaleX != 1 || this.scaleY != 1) c.scale(this.scaleX, this.scaleY); | |
if (this.rotation != 0) c.rotate(this.rotation); | |
if (this.alpha != 1) c.globalAlpha *= this.alpha | |
}, | |
doRender: function(c) { | |
if (this.visible && this.alpha > .01 && this.scaleX != 0 && this.scaleY != 0) { | |
c.save(); | |
this.applyTransforms(c); | |
this.render(c); | |
c.restore() | |
} | |
}, | |
render: function(c) { | |
throw new Error("Rendering undefined") | |
}, | |
remove: function() { | |
if (this.parent) { | |
this.parent.removeChild(this) | |
} | |
}, | |
leaves: function() { | |
return 1 | |
} | |
}; | |
function DisplayableContainer() { | |
DisplayableObject.call(this); | |
this.children = [] | |
} | |
DisplayableContainer.prototype = extendPrototype(DisplayableObject, { | |
render: function(c) { | |
var i = -1; | |
while (this.children[++i]) { | |
this.children[i].doRender(c) | |
} | |
}, | |
addChild: function(child) { | |
if (child.parent) { | |
child.parent.removeChild(child) | |
} | |
this.children.push(child); | |
child.parent = this; | |
child.parentIndex = this.children.length - 1 | |
}, | |
removeChild: function(child) { | |
if (!isNaN(child.parentIndex)) { | |
this.children.splice(child.parentIndex, 1); | |
for (var i = child.parentIndex; i < this.children.length; i++) { | |
this.children[i].parentIndex-- | |
} | |
child.parent = null; | |
child.parentIndex = null | |
} | |
}, | |
clear: function() { | |
for (var i in this.children) { | |
this.children[i].parent = null; | |
this.children[i].parentIndex = null | |
} | |
this.children = [] | |
}, | |
leaves: function() { | |
var total = 0; | |
for (var i in this.children) { | |
total += this.children[i].leaves() | |
} | |
return total | |
} | |
}); | |
function DisplayableRectangle() { | |
DisplayableContainer.call(this); | |
this.color = "#000"; | |
this.width = 0; | |
this.height = 0 | |
} | |
DisplayableRectangle.prototype = extendPrototype(DisplayableContainer, { | |
render: function(c) { | |
c.fillStyle = this.color; | |
c.fillRect(0, 0, this.width, this.height); | |
DisplayableContainer.prototype.render.call(this, c) | |
} | |
}); | |
function DisplayableShape(drawFunction) { | |
DisplayableObject.call(this); | |
this.drawFunction = drawFunction | |
} | |
DisplayableShape.prototype = extendPrototype(DisplayableObject, { | |
render: function(c) { | |
this.drawFunction(c) | |
} | |
}); | |
function DisplayableTextField() { | |
DisplayableObject.call(this); | |
this.text = null; | |
this.font = "12pt Arial"; | |
this.textAlign = "left"; | |
this.textBaseline = "top"; | |
this.color = "#000"; | |
this.shadowColor = null; | |
this.shadowOffsetX = 0; | |
this.shadowOffsetY = 0 | |
} | |
DisplayableTextField.prototype = extendPrototype(DisplayableObject, { | |
render: function(c) { | |
if (this.text != null && this.text.toString().length > 0) { | |
c.font = this.font; | |
c.textAlign = this.textAlign; | |
c.textBaseline = this.textBaseline; | |
if (this.shadowColor) { | |
c.fillStyle = this.shadowColor; | |
c.fillText(this.text, this.shadowOffsetX, this.shadowOffsetY) | |
} | |
c.fillStyle = this.color; | |
c.fillText(this.text, 0, 0) | |
} | |
} | |
}); | |
function DisplayableImage() { | |
DisplayableObject.call(this); | |
this.image = null; | |
this.anchorX = this.anchorY = 0 | |
} | |
DisplayableImage.prototype = extendPrototype(DisplayableObject, { | |
render: function(c) { | |
c.drawImage(this.image, this.anchorX, this.anchorY) | |
} | |
}); | |
function Tween(object, property, from, to, duration, delay, onFinish) { | |
this.object = object; | |
this.delayLeft = delay || 0; | |
this.duration = duration; | |
this.elapsed = 0; | |
this.property = property; | |
this.from = from; | |
this.to = to; | |
this.onFinish = onFinish; | |
this.finished = false; | |
object[property] = from | |
} | |
Tween.prototype = { | |
cycle: function(e) { | |
if (this.delayLeft > 0) { | |
this.delayLeft -= e; | |
this.object[this.property] = this.from | |
} | |
if (this.delayLeft <= 0) { | |
this.elapsed += e; | |
if (this.elapsed >= this.duration) { | |
this.finish() | |
} else { | |
this.progress() | |
} | |
} | |
}, | |
finish: function() { | |
if (!this.finished) { | |
this.finished = true; | |
this.delayLeft = 0; | |
this.elapsed = this.duration; | |
this.object[this.property] = this.to; | |
if (this.onFinish) { | |
this.onFinish.call(this) | |
} | |
} | |
}, | |
isFinished: function() { | |
return this.elapsed >= this.duration | |
}, | |
progress: function() { | |
var prct = this.duration > 0 ? this.elapsed / this.duration : 1; | |
this.object[this.property] = prct * (this.to - this.from) + this.from | |
} | |
}; | |
var TweenPool = { | |
tweens: [], | |
cycle: function(e) { | |
var i = 0; | |
while (this.tweens[i]) { | |
this.tweens[i].cycle(e); | |
if (!this.tweens[i].isFinished()) { | |
i++ | |
} else { | |
this.tweens.splice(i, 1) | |
} | |
} | |
}, | |
remove: function(tw) { | |
var index = this.tweens.indexOf(tw); | |
if (index >= 0) { | |
this.tweens.splice(index, 1) | |
} | |
}, | |
add: function(tw) { | |
this.tweens.push(tw) | |
} | |
}; | |
function Button(settings, action) { | |
DisplayableObject.call(this); | |
this.pressed = false; | |
this.action = action; | |
this.width = settings.width || 300; | |
this.height = settings.height || 80; | |
this.bgColor = settings.bgColor || "#ffffff"; | |
this.borderColor = settings.lineColor || "#000"; | |
this.borderRadius = settings.borderRadius || 10; | |
this.textColor = settings.textColor || "#000"; | |
this.fontSize = settings.fontSize || 40; | |
this.outlineColor = settings.outlineColor || "#000"; | |
this.outlineWidth = settings.outlineWidth || 0; | |
this.id = settings.id || undefined; | |
this.setContent(settings.content) | |
} | |
Button.prototype = extendPrototype(DisplayableObject, { | |
setContent: function(arg0) { | |
this.text = this.image = null; | |
if (typeof arg0 == "string") { | |
this.type = "button"; | |
this.text = arg0; | |
this.id = this.text | |
} else { | |
this.type = "image"; | |
this.image = arg0; | |
this.width = arg0.width; | |
this.height = arg0.height | |
} | |
}, | |
render: function(c) { | |
if (this.text) { | |
c.save(); | |
c.translate(.5, .5); | |
c.globalAlpha *= this.pressed ? .5 : 1; | |
c.beginPath(); | |
c.fillStyle = this.bgColor; | |
c.strokeStyle = this.borderColor; | |
c.lineWidth = 2; | |
c.moveTo(0, this.borderRadius); | |
c.arc(this.borderRadius, this.borderRadius, this.borderRadius, Math.PI, -Math.PI / 2, false); | |
c.arc(this.width - this.borderRadius, this.borderRadius, this.borderRadius, -Math.PI / 2, 0, false); | |
c.arc(this.width - this.borderRadius, this.height - this.borderRadius, this.borderRadius, 0, Math.PI / 2, false); | |
c.arc(this.borderRadius, this.height - this.borderRadius, this.borderRadius, Math.PI / 2, Math.PI, false); | |
c.closePath(); | |
c.fill(); | |
c.stroke(); | |
c.restore(); | |
c.font = this.fontSize + "pt Bariol"; | |
c.textAlign = "center"; | |
c.textBaseline = "middle"; | |
c.fillStyle = this.textColor; | |
c.fillText(this.text, this.width / 2, this.height / 2); | |
if (this.outlineWidth > 0) { | |
c.lineWidth = this.outlineWidth; | |
c.strokeStyle = this.outlineColor; | |
c.strokeText(this.text, this.width / 2, this.height / 2 + 3) | |
} | |
} else { | |
c.globalAlpha *= this.pressed ? .5 : 1; | |
c.drawImage(this.image, 0, 0, this.image.width, this.image.height, 0, 0, this.width, this.height) | |
} | |
}, | |
getArea: function() { | |
var me = this; | |
return new Area(this.x, this.y, this.width, this.height, { | |
actionStart: function() { | |
me.pressed = true | |
}, | |
actionPerformed: function() { | |
me.pressed = false; | |
me.action(); | |
Tracker.event("button-clicked", "button-" + me.id) | |
}, | |
actionCancel: function() { | |
me.pressed = false | |
} | |
}) | |
} | |
}); | |
var P = { | |
width: 640, | |
height: 960, | |
gridWidth: 4, | |
gridHeight: 4, | |
leaderboardKey: "tap-lb", | |
gameURL: "http://www.donttap.com/", | |
facebookShareURL: "https://www.facebook.com/sharer/sharer.php?t=%text%&u=%url%", | |
twitterShareURL: "https://twitter.com/intent/tweet?text=%text%", | |
cocoon: !!window.isCocoon, | |
inAppGames: window.location.href.indexOf("inappgames") !== -1 || window.location.href.indexOf("utm_source=ubersocialios") !== -1 && window.location.href.indexOf("utm_medium=inapp") !== -1 | |
}; | |
var AdsSettings = { | |
ads: { | |
tablet: { | |
slot: "/20973361/whiteblock_iPad_300x600", | |
width: 300, | |
height: 600, | |
interval: 6, | |
check: function() { | |
return navigator.userAgent.toLowerCase().indexOf("ipad") >= 0 | |
} | |
}, | |
mobile: { | |
slot: "/20973361/whiteblock_mobile_300x250", | |
width: 300, | |
height: 250, | |
interval: 4, | |
check: function() { | |
return Util.isTouchScreen() | |
} | |
}, | |
web: { | |
slot: "/20973361/whiteblock_desktop_300x600", | |
width: 300, | |
height: 600, | |
interval: 5, | |
check: function() { | |
return true | |
} | |
} | |
} | |
}; | |
window.addToHomeConfig = { | |
touchIcon: true, | |
autostart: false | |
}; | |
var resources = { | |
folder: "img/", | |
image: { | |
menu_bg: "menu-bg.png", | |
end_bg: "end-bg.png", | |
character: "character.png", | |
logo: "logo.png", | |
button_fb: "fb.png", | |
button_twitter: "twitter.png", | |
button_fb_clean: "fb-clean.png", | |
button_twitter_clean: "twitter-clean.png", | |
gameover_bg: "gameover-bg.png", | |
button_kik_white: "kik-white.png", | |
button_kik_black: "kik-black.png", | |
button_menu_white: "menu-white.png", | |
button_menu_black: "menu-black.png", | |
button_retry: "retry.png", | |
bubble: "bubble.png", | |
domain: "domain.png" | |
} | |
}; | |
DOM.on(window, "load", function() { | |
DOM.un(window, "load", arguments.callee); | |
can = DOM.get("gamecanvas"); | |
can.width = P.width; | |
can.height = P.height; | |
ctx = can.getContext("2d"); | |
window.resizer = new Resizer({ | |
element: DOM.get("viewport"), | |
delay: 10, | |
baseWidth: P.width, | |
baseHeight: P.height, | |
onResize: function() { | |
window.scrollTo(0, 1) | |
} | |
}); | |
var getDimensionsAndResize = function() { | |
var w = window.innerWidth; | |
var h = window.innerHeight; | |
window.resizer.needsResize(w, h) | |
}; | |
if (!P.cocoon) { | |
DOM.on(window, "resize orientationchange", getDimensionsAndResize); | |
getDimensionsAndResize() | |
} | |
if (document.location.search.indexOf("domconsole") >= 0) { | |
window.console = new DOMConsole | |
} | |
Tracker.stage("screen-loading"); | |
var loader = new ResourceLoader(resources); | |
loader.load(function(res) { | |
R = res; | |
if (Util.isTouchScreen()) { | |
window.scrollTo(0, 1) | |
} | |
new Game(resizer) | |
}, can) | |
}); | |
function Game() { | |
Game.instance = this; | |
window.G = this; | |
this.curScreen = null; | |
var me = this; | |
this.lastCycleDate = Date.now(); | |
this.frameCount = 0; | |
this.leaderboard = new LocalLeaderboard; | |
this.leaderboard.load(); | |
var mode; | |
if (window.kik && kik.message) { | |
Tracker.event("kik-message", "kik-message-open"); | |
if (kik.message.mode) { | |
switch (kik.message.mode) { | |
case "endurance": | |
mode = new EnduranceMode(this); | |
break; | |
case "pattern": | |
mode = new PatternMode(this); | |
break; | |
case "frenzy": | |
mode = new FrenzyMode(this); | |
break | |
} | |
} | |
} | |
if (mode) { | |
this.newGame(mode) | |
} else { | |
this.menu() | |
} | |
cycleManager.init(this.cycle.bind(this)); | |
DOM.on(document.body, "touchstart mousedown", this.handleDownEvent.bind(this)); | |
DOM.on(document.body, "touchmove mousemove", this.handleMoveEvent.bind(this)); | |
DOM.on(document.body, "touchend mouseup touchcancel", this.handleUpEvent.bind(this)); | |
DOM.on("ad-close-button", "click touchend", this.closeAd.bind(this)); | |
DOM.on("ad-over", "click touchend", this.closeAd.bind(this)); | |
this.kikInit(); | |
var sounds = ["a6", "a7", "a8", "c6", "c7", "c8", "c9", "d6", "d7", "d8", "f6", "f7", "f8", "g6", "g7", "g8"]; | |
var s; | |
this.sounds = []; | |
for (var i in sounds) { | |
s = new Howl({ | |
urls: ["sound/" + sounds[i] + ".mp3", "sound/" + sounds[i] + ".ogg"], | |
volume: 1 | |
}); | |
this.sounds.push(s) | |
} | |
this.initAds() | |
} | |
Game.prototype = { | |
setScreen: function(screen, noTransition, isOverlay) { | |
if (this.curScreen) { | |
this.curScreen.destroy() | |
} | |
var suffix; | |
if (location.search.indexOf("amazon") >= 0) { | |
suffix = "amazon" | |
} else if (P.cocoon) { | |
if (Detect.isAndroid()) { | |
suffix = "nativeandroid" | |
} else { | |
suffix = "nativeios" | |
} | |
} else { | |
if (window.kik && kik.send) { | |
suffix = "kik" | |
} else if ("standalone" in window.navigator && window.navigator.standalone) { | |
suffix = "homescreen" | |
} else { | |
suffix = "nonkik" | |
} | |
} | |
Tracker.stage("screen-" + screen.getId() + "-" + suffix); | |
this.curScreen = screen; | |
this.curScreen.create(); | |
this.stage = this.curScreen.view | |
}, | |
cycle: function(elapsed) { | |
this.lastCycleDate = Date.now(); | |
var before = Date.now(); | |
this.curScreen.cycle(elapsed); | |
TweenPool.cycle(elapsed); | |
ctx.fillStyle = "#000"; | |
ctx.fillRect(0, 0, P.width, P.height); | |
var between = Date.now(); | |
this.stage.doRender(ctx); | |
var after = Date.now(); | |
if (P.showFrameRate) { | |
ctx.textAlign = "left"; | |
ctx.fillStyle = "#ffffff"; | |
ctx.fillText("FPS: " + cycleManager.fps, 10, 10); | |
ctx.fillText("Total: " + (after - before), 10, 20); | |
ctx.fillText("Cycle: " + (between - before), 10, 30); | |
ctx.fillText("Render: " + (after - between), 10, 40); | |
ctx.fillText("Theoretical: " + Math.round(1e3 / Math.max(1, after - before)), 10, 50); | |
ctx.fillText("Size: " + this.stage.leaves(), 10, 60) | |
} | |
}, | |
getPosition: function(e) { | |
if (e.touches) e = e.touches[e.touches.length - 1]; | |
var canRect = can.getBoundingClientRect(); | |
if (!P.cocoon) { | |
res = { | |
x: (e.clientX - canRect.left) / (canRect.width / P.width), | |
y: (e.clientY - canRect.top) / (canRect.height / P.height) | |
} | |
} else { | |
res = { | |
x: e.clientX, | |
y: e.clientY | |
} | |
} | |
return res | |
}, | |
handleDownEvent: function(e) { | |
if (Date.now() - this.lastCycleDate >= 1e3) { | |
cycleManager.stop(); | |
cycleManager.resume() | |
} | |
var evtType = e.type.indexOf("touch") >= 0 ? "touch" : "mouse"; | |
this.inputType = this.inputType || evtType; | |
if (evtType != this.inputType) return; | |
if (this.adOpen) return; | |
this.down = true; | |
this.lastEvent = this.getPosition(e); | |
this.curScreen.touchStart(this.lastEvent.x, this.lastEvent.y); | |
if (evtType == "touch") {} | |
}, | |
handleMoveEvent: function(e) { | |
this.lastEvent = this.getPosition(e); | |
if (this.down) { | |
e.preventDefault(); | |
this.curScreen.touchMove(this.lastEvent.x, this.lastEvent.y) | |
} | |
if (this.inputType == "touch") { | |
e.preventDefault() | |
} | |
}, | |
handleUpEvent: function(e) { | |
if (this.down) { | |
this.curScreen.touchEnd(this.lastEvent.x, this.lastEvent.y); | |
this.down = false; | |
this.lastEvent = null | |
} | |
window.scrollTo(0, 1) | |
}, | |
newGame: function(mode, isRetry) { | |
this.lastMode = mode; | |
this.setScreen(new GameplayScreen(this, this.lastMode)); | |
addToHome.close(); | |
if (!Detect.isIOS() && P.cocoon) { | |
CocoonJS.Ad.hideBanner() | |
} | |
}, | |
gameOver: function() { | |
Tracker.event("end-mode", "end-mode-" + this.lastMode.getId()); | |
this.setScreen(new EndScreen(this, this.lastMode)); | |
window.gmga("gamedone"); | |
this.gamesToNextAd--; | |
if (this.gamesToNextAd <= 0) { | |
this.showAd() | |
} | |
addToHome.show(); | |
if (this.lastMode.isSuccess()) { | |
var lb = this.lastMode.getLeaderboardId(); | |
var score = this.lastMode.getLeaderboardScore(); | |
gmapi(function(api) { | |
api.game.leaderboard.sendScore(score, { | |
levelName: lb | |
}) | |
}) | |
} | |
if (!Detect.isIOS() && P.cocoon) { | |
this.showCocoonAd() | |
} | |
}, | |
menu: function() { | |
this.lastMode = null; | |
this.setScreen(new MenuScreen(this)) | |
}, | |
retry: function() { | |
this.newGame(this.lastMode, true) | |
}, | |
getSocialText: function() { | |
if (this.lastMode && this.lastMode.isSuccess()) { | |
return this.lastMode.getSocialText() | |
} else { | |
return "Play #DontTap on your phone, tablet, and desktop computer at " + P.gameURL + "! #WhiteTile" | |
} | |
}, | |
open: function(url) { | |
if (P.cocoon) { | |
CocoonJS.App.openURL.apply(CocoonJS.App, arguments) | |
} else { | |
window.open.apply(window, arguments) | |
} | |
}, | |
shareKik: function() { | |
Tracker.event("share", "share-kik-" + (this.lastMode && this.lastMode.isSuccess() ? "score" : "generic")); | |
var title = this.getSocialText(); | |
var data = {}; | |
if (this.lastMode && this.lastMode.isSuccess()) { | |
data.mode = this.lastMode.getId(); | |
data.score = this.lastMode.getScore() | |
} | |
kik.send({ | |
title: title, | |
text: "Can you beat me?", | |
pic: "promo/kik-icon.png", | |
data: data | |
}) | |
}, | |
shareFacebook: function(mode) { | |
Tracker.event("share", "share-facebook-" + (this.lastMode && this.lastMode.isSuccess() ? "score" : "generic")); | |
var url = P.facebookShareURL.replace("%text%", encodeURIComponent(this.getSocialText())).replace("%url%", encodeURIComponent(P.gameURL)); | |
this.open(url, "shareFbWindow", "width=650,height=440,scrollbars=yes,location=no") | |
}, | |
shareTwitter: function(mode) { | |
Tracker.event("share", "share-twitter-" + (this.lastMode && this.lastMode.isSuccess() ? "score" : "generic")); | |
var url = P.twitterShareURL.replace("%text%", encodeURIComponent(this.getSocialText())); | |
this.open(url, "shareTwitterWindow", "width=450,height=450,scrollbars=yes,location=no") | |
}, | |
rate: function() { | |
if (Util.isAndroid()) { | |
CocoonJS.App.openURL(P.googlePlayURL) | |
} else { | |
CocoonJS.App.openURL(P.appStoreURL) | |
} | |
}, | |
kikInit: function() { | |
if (window.kik) { | |
if (kik.browser) { | |
if (kik.browser.setOrientationLock) { | |
kik.browser.setOrientationLock("portrait") | |
} | |
if (kik.browser.statusBar) { | |
kik.browser.statusBar(false) | |
} | |
} | |
if (kik.metrics && kik.metrics.enableGoogleAnalytics) { | |
kik.metrics.enableGoogleAnalytics() | |
} | |
} | |
}, | |
playSound: function(n) { | |
this.sounds[n].play() | |
}, | |
initCocoonAds: function() { | |
console.log("Initializing cocoon ads"); | |
var me = this; | |
CocoonJS.Ad.onFullScreenShown.addEventListener(function() {}); | |
CocoonJS.Ad.onFullScreenHidden.addEventListener(function() { | |
CocoonJS.Ad.refreshFullScreen() | |
}); | |
CocoonJS.Ad.onFullScreenReady.addEventListener(function() {}); | |
CocoonJS.Ad.preloadFullScreen() | |
}, | |
showCocoonAd: function() { | |
console.log("Show a cocoon ad"); | |
CocoonJS.Ad.showFullScreen(); | |
return true | |
}, | |
initGoogleAds: function() { | |
var me = this; | |
googletag.cmd.push(function() { | |
me.adSlot = googletag.defineSlot(me.adSettings.slot, [me.adSettings.width, me.adSettings.height], "ad").addService(googletag.pubads()); | |
googletag.pubads().enableSingleRequest(); | |
googletag.enableServices(); | |
googletag.display("ad"); | |
me.adCreated = true | |
}); | |
var container = DOM.get("ad-container"); | |
container.style.width = this.adSettings.width + "px"; | |
container.style.height = this.adSettings.height + "px" | |
}, | |
getAdInterval: function() { | |
return this.adSettings.interval | |
}, | |
initAds: function() { | |
if (!this.adsInitted) { | |
this.adsInitted = true; | |
for (var i in AdsSettings.ads) { | |
if (AdsSettings.ads[i].check()) { | |
this.adSettings = AdsSettings.ads[i]; | |
break | |
} | |
} | |
if (this.adSettings) { | |
if (P.cocoon) { | |
this.initCocoonAds() | |
} else { | |
this.initGoogleAds() | |
} | |
this.gamesToNextAd = this.getAdInterval() | |
} | |
} | |
}, | |
closeAd: function() { | |
if (this.adOpen) { | |
if (P.cocoon) { | |
CocoonJS.Ad.hideBanner() | |
} else { | |
this.adOpen = false; | |
ga("send", "event", "ad", "close", "close-ad"); | |
DOM.hide("ad-over"); | |
var me = this; | |
googletag.cmd.push(function() { | |
googletag.pubads().refresh([me.adSettings.slot]) | |
}) | |
} | |
} | |
}, | |
showAd: function() { | |
if (this.adsInitted) { | |
console.log("showing ad?"); | |
var res; | |
if (P.cocoon) { | |
res = this.showCocoonAd() | |
} else { | |
DOM.show("ad-over"); | |
this.adOpen = true; | |
res = true | |
} | |
if (res) { | |
ga("send", "event", "ad", "show", "show-ad"); | |
this.gamesToNextAd = this.getAdInterval() | |
} | |
} | |
} | |
}; | |
var Tracker = { | |
suffix: function() { | |
if ("standalone" in window.navigator && navigator.standalone) { | |
return "-homescreen" | |
} else if (window.cordova || P.cocoon) { | |
return "-native" | |
} else if (window.kik && kik.send) { | |
return "-kik" | |
} else if (P.amazon) { | |
return "-amazon" | |
} else { | |
return "-web" | |
} | |
}, | |
event: function(eventCategory, eventLabel, eventValue) { | |
if (window.cordova && window.gaPlugin) { | |
gaPlugin.trackEvent(function() { | |
console.log("Sent event data") | |
}, function(e) { | |
console.log("Error while sending event data: " + e) | |
}, "gameevent", eventCategory + this.suffix(), eventLabel + this.suffix(), eventValue || 0) | |
} else if (window.ga) { | |
ga("send", "event", "gameevent", eventCategory + this.suffix(), eventLabel + this.suffix(), eventValue || 0) | |
} | |
}, | |
stage: function(stageLabel) { | |
var page = "/stage-" + stageLabel + this.suffix(); | |
if (window.cordova && window.gaPlugin) { | |
gaPlugin.trackPage(function() { | |
console.log("Sent page view") | |
}, function(e) { | |
console.log("Error while sending page view: " + e) | |
}, page) | |
} else if (window.ga) { | |
ga("send", "pageview", page) | |
} | |
} | |
}; | |
function LocalLeaderboard() { | |
this.scores = {} | |
} | |
LocalLeaderboard.prototype = { | |
load: function() { | |
var json = Util.storage.getItem(P.leaderboardKey); | |
if (json) { | |
this.scores = JSON.parse(json) | |
} else { | |
this.scores = {} | |
} | |
}, | |
save: function() { | |
Util.storage.setItem(P.leaderboardKey, JSON.stringify(this.scores)) | |
}, | |
getScores: function(mode) { | |
return this.scores[mode.getId()] || [] | |
}, | |
addScore: function(mode, score) { | |
var i; | |
if (!this.scores[mode.getId()]) { | |
this.scores[mode.getId()] = [] | |
} | |
i = 0; | |
while (i < this.scores[mode.getId()].length && mode.compareScores(score, this.scores[mode.getId()][i].score) < 0) { | |
i++ | |
} | |
this.scores[mode.getId()].splice(i, 0, { | |
score: score, | |
date: Date.now() | |
}); | |
this.save() | |
}, | |
getHighscore: function(mode) { | |
if (!this.scores[mode.getId()]) { | |
return 0 | |
} | |
return this.scores[mode.getId()][0] || null | |
} | |
}; | |
function GameMode() {} | |
GameMode.prototype = { | |
initialize: function(screen) { | |
this.screen = screen | |
}, | |
launch: function() { | |
this.screen.showMessage("Tap the black tiles!") | |
}, | |
tappedHighlighted: function(tile) {}, | |
tappedWrong: function(tile) {}, | |
cycle: function(e) {}, | |
getScore: function() { | |
return 0 | |
}, | |
getFormattedScore: function(s) { | |
return s.toString() | |
}, | |
end: function(reason) { | |
this.screen.over(reason) | |
}, | |
getId: function() { | |
return null | |
}, | |
getInstructions: function() { | |
return null | |
}, | |
getBgColor: function() { | |
return "#000" | |
}, | |
getGaugeValue: function() { | |
return .5 | |
}, | |
getTimeValue: function() { | |
return 0 | |
}, | |
isSuccess: function() { | |
return true | |
}, | |
getScoreType: function() { | |
return "points" | |
}, | |
compareScores: function(s1, s2) { | |
return s1 - s2 | |
}, | |
getLeaderboardId: function() { | |
return null | |
}, | |
getLeaderboardScore: function() { | |
return 0 | |
} | |
}; | |
function EnduranceMode() { | |
GameMode.call(this) | |
} | |
EnduranceMode.prototype = extendPrototype(GameMode, { | |
getId: function() { | |
return "endurance" | |
}, | |
getInstructions: function() { | |
return ["10 seconds for", "every 40 taps"] | |
}, | |
initialize: function(screen) { | |
GameMode.prototype.initialize.call(this, screen); | |
this.score = 0; | |
this.timeLeft = 0; | |
this.gaugeValue = 0; | |
this.powerUpMode = false | |
}, | |
launch: function() { | |
GameMode.prototype.launch.call(this); | |
this.refill(); | |
var ind; | |
for (var i = 0; i < 3; i++) { | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight() | |
} | |
}, | |
refill: function() { | |
this.timeLeft += 10; | |
this.tilesToRefill = 40; | |
this.screen.showMessage("+10 seconds"); | |
this.screen.showAddTime(10) | |
}, | |
cycle: function(e) { | |
this.timeLeft -= e; | |
if (this.timeLeft <= 0) { | |
this.end("Time's up") | |
} else { | |
this.gaugeValue = Math.max(0, this.gaugeValue - e * .3) | |
} | |
}, | |
getScore: function() { | |
return this.score | |
}, | |
tappedHighlighted: function(tile) { | |
tile.disable(); | |
this.screen.showOk(tile, "+1"); | |
if (!this.powerUpMode) { | |
var ind; | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (ind == this.screen.tiles.indexOf(tile) || this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight(); | |
this.gaugeValue = Math.min(1, this.gaugeValue + .08); | |
if (this.gaugeValue == 1) { | |
this.powerUp() | |
} | |
} else { | |
var fullWhite = true; | |
for (var i = 0; i < this.screen.tiles.length; i++) { | |
if (this.screen.tiles[i].isHighlighted()) { | |
fullWhite = false; | |
break | |
} | |
} | |
if (fullWhite) { | |
this.powerUpMode = false; | |
for (var i = 0; i < 3; i++) { | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight() | |
} | |
} | |
} | |
this.tilesToRefill--; | |
if (this.tilesToRefill <= 0) { | |
this.refill() | |
} | |
this.score++ | |
}, | |
powerUp: function() { | |
this.powerUpMode = true; | |
this.gaugeValue = 0; | |
for (var i = 0; i < this.screen.tiles.length; i++) { | |
(function(t) { | |
setTimeout(function() { | |
t.highlight() | |
}, Math.random() * 500) | |
})(this.screen.tiles[i]) | |
} | |
this.screen.showMessage("Uber power up") | |
}, | |
tappedWrong: function(tile) { | |
this.screen.showError(tile); | |
this.end(["You tapped", "a white tile!"]) | |
}, | |
getGaugeValue: function() { | |
return this.gaugeValue | |
}, | |
getTimeValue: function() { | |
return this.timeLeft | |
}, | |
getSocialText: function() { | |
return "I scored " + this.score + " in Endurance playing Don't Tap! Can you beat me? Let's play: " + P.gameURL + " #donttap #whitetile" | |
}, | |
getLeaderboardId: function() { | |
return "endurance" | |
}, | |
getLeaderboardScore: function() { | |
return this.score | |
} | |
}); | |
function FrenzyMode() { | |
GameMode.call(this) | |
} | |
FrenzyMode.prototype = extendPrototype(GameMode, { | |
getId: function() { | |
return "frenzy" | |
}, | |
getInstructions: function() { | |
return ["30 seconds,", "nothing more"] | |
}, | |
initialize: function(screen) { | |
GameMode.prototype.initialize.call(this, screen); | |
this.score = 0; | |
this.timeLeft = 30; | |
this.gaugeValue = 0 | |
}, | |
launch: function() { | |
GameMode.prototype.launch.call(this); | |
var ind; | |
for (var i = 0; i < 3; i++) { | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight() | |
} | |
}, | |
cycle: function(e) { | |
this.timeLeft -= e; | |
if (this.timeLeft <= 0) { | |
this.end("Time's up") | |
} else { | |
this.gaugeValue = Math.max(0, this.gaugeValue - e * .3) | |
} | |
}, | |
getScore: function() { | |
return this.score | |
}, | |
tappedHighlighted: function(tile) { | |
var multiplier = Math.max(1, Math.ceil(this.gaugeValue * 5)); | |
var t = null; | |
if (multiplier > 1) { | |
t = "x" + multiplier | |
} | |
this.score += multiplier; | |
tile.disable(); | |
this.screen.showOk(tile, "+" + multiplier); | |
var ind; | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (ind == this.screen.tiles.indexOf(tile) || this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight(); | |
this.gaugeValue = Math.min(1, this.gaugeValue + .08) | |
}, | |
tappedWrong: function(tile) { | |
this.screen.showError(tile); | |
this.end(["You tapped", "a white tile!"]) | |
}, | |
getBgColor: function() { | |
return "#ffffff" | |
}, | |
getGaugeValue: function() { | |
return this.gaugeValue | |
}, | |
getTimeValue: function() { | |
return this.timeLeft | |
}, | |
getSocialText: function() { | |
return "I scored " + this.score + " in Frenzy playing Don't Tap! Can you beat me? Let's play: " + P.gameURL + " #donttap #whitetile" | |
}, | |
getLeaderboardId: function() { | |
return "frenzy" | |
}, | |
getLeaderboardScore: function() { | |
return this.score | |
} | |
}); | |
function PatternMode() { | |
GameMode.call(this) | |
} | |
PatternMode.prototype = extendPrototype(GameMode, { | |
getId: function() { | |
return "pattern" | |
}, | |
getInstructions: function() { | |
return ["Clear all", "the patterns"] | |
}, | |
initialize: function(screen) { | |
GameMode.prototype.initialize.call(this, screen); | |
this.score = 0; | |
this.time = 0; | |
this.gaugeValue = 0; | |
this.patternsToClear = 15 | |
}, | |
nextPattern: function() { | |
this.newPattern(this.patternSize()) | |
}, | |
patternSize: function() { | |
return 4 | |
}, | |
newPattern: function(size) { | |
for (var i = 0; i < size && i < this.screen.tiles.length; i++) { | |
do { | |
ind = ~~(Math.random() * this.screen.tiles.length) | |
} while (this.screen.tiles[ind].isHighlighted()); | |
this.screen.tiles[ind].highlight() | |
} | |
}, | |
allWhite: function() { | |
for (var i = 0; i < this.screen.tiles.length; i++) { | |
if (this.screen.tiles[i].isHighlighted()) { | |
return false | |
} | |
} | |
return true | |
}, | |
launch: function() { | |
GameMode.prototype.launch.call(this); | |
this.nextPattern() | |
}, | |
cycle: function(e) { | |
this.time += e; | |
this.gaugeValue = Math.max(0, this.gaugeValue - e * .3) | |
}, | |
getTimeValue: function() { | |
return this.time | |
}, | |
tappedHighlighted: function(tile) { | |
tile.disable(); | |
this.screen.showOk(tile); | |
if (this.allWhite()) { | |
this.patternsToClear--; | |
if (this.patternsToClear > 0) { | |
this.nextPattern() | |
} else { | |
this.end("All clear") | |
} | |
} | |
this.score++; | |
this.gaugeValue = Math.min(1, this.gaugeValue + .08) | |
}, | |
tappedWrong: function(tile) { | |
this.screen.showError(tile); | |
this.end(["You tapped", "a white tile!"]) | |
}, | |
getBgColor: function() { | |
return "#333333" | |
}, | |
getGaugeValue: function() { | |
return this.gaugeValue | |
}, | |
isSuccess: function() { | |
return this.patternsToClear == 0 | |
}, | |
getScore: function() { | |
return this.time | |
}, | |
getScoreType: function() { | |
return "time" | |
}, | |
getFormattedScore: function(s) { | |
return Math.round(s * 100) / 100 | |
}, | |
compareScores: function(s1, s2) { | |
return s2 - s1 | |
}, | |
getSocialText: function() { | |
return "I cleared all the tiles in " + this.getFormattedScore(this.time) + "s in Patterns playing Don't Tap! Can you beat me? Let's play: " + P.gameURL + " #donttap #whitetile" | |
}, | |
getLeaderboardId: function() { | |
return "pattern" | |
}, | |
getLeaderboardScore: function() { | |
return this.time * 1e3 | |
} | |
}); | |
function MenuScreen(game) { | |
Screen.call(this, game) | |
} | |
MenuScreen.prototype = extendPrototype(Screen, { | |
create: function() { | |
this.view = new DisplayableContainer; | |
this.bg = new DisplayableImage; | |
this.bg.image = R.image.menu_bg; | |
this.view.addChild(this.bg); | |
var character = new DisplayableImage; | |
character.image = R.image.character; | |
character.x = 300; | |
character.y = 500; | |
this.view.addChild(character); | |
var logo = new DisplayableImage; | |
logo.image = R.image.logo; | |
logo.x = 100; | |
logo.y = 100; | |
this.view.addChild(logo); | |
var domain = new DisplayableImage; | |
domain.image = R.image.domain; | |
domain.x = (P.width - domain.image.width) / 2; | |
domain.y = P.height - 50; | |
this.view.addChild(domain); | |
var me = this; | |
this.enduranceButton = new Button({ | |
content: "Endurance", | |
bgColor: "#000", | |
textColor: "#ffffff", | |
width: 270, | |
height: 92 | |
}, function() { | |
me.game.newGame(new EnduranceMode) | |
}); | |
this.enduranceButton.x = 64; | |
this.enduranceButton.y = 514; | |
this.view.addChild(this.enduranceButton); | |
this.addArea(this.enduranceButton.getArea()); | |
this.frenzyButton = new Button({ | |
content: "Frenzy", | |
width: 270, | |
height: 92 | |
}, function() { | |
me.game.newGame(new FrenzyMode) | |
}); | |
this.frenzyButton.x = 64; | |
this.frenzyButton.y = 726; | |
this.view.addChild(this.frenzyButton); | |
this.addArea(this.frenzyButton.getArea()); | |
this.patternButton = new Button({ | |
content: "Pattern", | |
bgColor: "#333333", | |
textColor: "#ffffff", | |
width: 270, | |
height: 92 | |
}, function() { | |
me.game.newGame(new PatternMode) | |
}); | |
this.patternButton.x = 64; | |
this.patternButton.y = 620; | |
this.view.addChild(this.patternButton); | |
this.addArea(this.patternButton.getArea()); | |
if (!P.inAppGames) { | |
this.fbButton = new Button({ | |
content: R.image.button_fb, | |
id: "facebook-menu" | |
}, function() { | |
me.game.shareFacebook() | |
}); | |
this.fbButton.x = 104; | |
this.fbButton.y = 832; | |
this.view.addChild(this.fbButton); | |
this.addArea(this.fbButton.getArea()); | |
this.twitterButton = new Button({ | |
content: R.image.button_twitter, | |
id: "twitter-menu" | |
}, function() { | |
me.game.shareTwitter() | |
}); | |
this.twitterButton.x = 212; | |
this.twitterButton.y = 832; | |
this.view.addChild(this.twitterButton); | |
this.addArea(this.twitterButton.getArea()) | |
} | |
if (P.cocoon) { | |
this.rateButton = new Button({ | |
content: "Rate!", | |
bgColor: "#000", | |
textColor: "#ffffff", | |
width: 90, | |
height: 30, | |
fontSize: 18 | |
}, function() { | |
me.game.rate() | |
}); | |
this.rateButton.x = 55; | |
this.rateButton.y = 363 | |
} | |
TweenPool.add(new Tween(character, "x", P.width, character.x, .3, .5)); | |
TweenPool.add(new Tween(logo, "alpha", 0, 1, .5, 1.5)); | |
TweenPool.add(new Tween(this.enduranceButton, "alpha", 0, 1, .3, 2)); | |
TweenPool.add(new Tween(this.patternButton, "alpha", 0, 1, .3, 2.3)); | |
TweenPool.add(new Tween(this.frenzyButton, "alpha", 0, 1, .3, 2.6)); | |
if (P.cocoon) TweenPool.add(new Tween(this.rateButton, "alpha", 0, 1, .3, 2.9)); | |
if (this.twitterButton) { | |
TweenPool.add(new Tween(this.twitterButton, "alpha", 0, 1, .3, 2.9)) | |
} | |
if (this.fbButton) { | |
TweenPool.add(new Tween(this.fbButton, "alpha", 0, 1, .3, 2.9)) | |
} | |
var versionArea = new Area(200, 340, 200, 100, { | |
actionPerformed: function() { | |
version.visible = true | |
} | |
}); | |
this.addArea(versionArea); | |
var version = new DisplayableTextField; | |
this.view.addChild(version); | |
with(version) { | |
text = window.gameVersion; | |
x = P.width - 5; | |
y = P.height - 5; | |
textAlign = "right"; | |
textBaseline = "bottom"; | |
color = "black"; | |
font = "20pt Arial"; | |
visible = false | |
} | |
}, | |
destroy: function() {}, | |
getId: function() { | |
return "menu" | |
} | |
}); | |
function GameplayScreen(game, mode) { | |
Screen.call(this, game); | |
this.mode = mode | |
} | |
GameplayScreen.prototype = extendPrototype(Screen, { | |
create: function() { | |
this.view = new DisplayableContainer; | |
this.background = new DisplayableRectangle; | |
this.background.color = this.mode.getBgColor(); | |
this.background.width = P.width; | |
this.background.height = P.height; | |
this.view.addChild(this.background); | |
this.tilesContainer = new DisplayableRectangle; | |
this.tilesContainer.width = P.width * (window.kik && kik.send ? .8 : 1); | |
this.tilesContainer.height = this.tilesContainer.width; | |
this.tilesContainer.x = (P.width - this.tilesContainer.width) / 2; | |
this.tilesContainer.y = (P.height - this.tilesContainer.height) / 2; | |
this.view.addChild(this.tilesContainer); | |
this.tiles = []; | |
this.tileMatrix = []; | |
var t, tWidth = ~~(this.tilesContainer.width / P.gridWidth), | |
tHeight = ~~(this.tilesContainer.height / P.gridHeight), | |
me = this; | |
for (var i = 0; i < P.gridWidth; i++) { | |
this.tileMatrix.push([]); | |
for (var j = 0; j < P.gridHeight; j++) { | |
t = new Tile(function() { | |
me.tilePressed(this) | |
}); | |
t.x = this.tilesContainer.x + i * tWidth; | |
t.y = this.tilesContainer.y + j * tHeight; | |
t.width = tWidth; | |
t.height = tHeight; | |
this.view.addChild(t); | |
this.addArea(t.getArea()); | |
this.tiles.push(t); | |
this.tileMatrix[i].push(t) | |
} | |
} | |
var labelY = 32; | |
var labelSize = 16; | |
var valueY = 80; | |
var valueSize = 52; | |
var scoreValueSize = 72; | |
var scoreValueY = 90; | |
this.scoreLabel = new DisplayableTextField; | |
this.scoreLabel.visible = this.mode.getScoreType() == "points"; | |
this.view.addChild(this.scoreLabel); | |
with(this.scoreLabel) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = P.width / 2; | |
y = labelY; | |
color = "#bababa"; | |
font = labelSize + "pt Bariol"; | |
text = "SCORE" | |
} | |
this.scoreTf = new DisplayableTextField; | |
this.scoreTf.visible = this.mode.getScoreType() == "points"; | |
this.view.addChild(this.scoreTf); | |
with(this.scoreTf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = P.width / 2; | |
y = scoreValueY; | |
color = "#ff0000"; | |
font = scoreValueSize + "pt Bariol"; | |
color = "#1ba7c0" | |
} | |
this.timeLabel = new DisplayableTextField; | |
this.view.addChild(this.timeLabel); | |
with(this.timeLabel) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = P.width - 100; | |
y = labelY; | |
color = "#bababa"; | |
font = labelSize + "pt Bariol"; | |
text = "TIME" | |
} | |
this.timeTf = new DisplayableTextField; | |
this.view.addChild(this.timeTf); | |
with(this.timeTf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = P.width - 100; | |
y = valueY; | |
color = "#f1ac37"; | |
font = valueSize + "pt Bariol" | |
} | |
this.highscoreLabel = new DisplayableTextField; | |
this.view.addChild(this.highscoreLabel); | |
with(this.highscoreLabel) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = 100; | |
y = labelY; | |
color = "#bababa"; | |
font = labelSize + "pt Bariol"; | |
text = "HI-SCORE" | |
} | |
this.highscoreTf = new DisplayableTextField; | |
this.view.addChild(this.highscoreTf); | |
with(this.highscoreTf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = 100; | |
y = valueY; | |
color = "#bababa"; | |
font = valueSize + "pt Bariol"; | |
var hs = this.game.leaderboard.getHighscore(this.mode); | |
text = hs ? this.mode.getFormattedScore(hs.score) : 0 | |
} | |
switch (this.mode.getScoreType()) { | |
case "points": | |
this.highscoreTf.x = this.highscoreLabel.x = 100; | |
this.timeLabel.x = this.timeTf.x = P.width - 100; | |
this.scoreLabel.x = this.scoreTf.x = P.width / 2; | |
break; | |
case "time": | |
this.timeLabel.x = this.timeTf.x = P.width * 2 / 3; | |
this.highscoreLabel.x = this.highscoreTf.x = P.width / 3; | |
break | |
} | |
this.gauge = new GaugeView; | |
this.gauge.width = ~~(P.width * .75); | |
this.gauge.height = 16; | |
this.gauge.x = (P.width - this.gauge.width) / 2; | |
this.gauge.y = P.height - 60; | |
this.view.addChild(this.gauge); | |
this.message = new DisplayableTextField; | |
this.view.addChild(this.message); | |
with(this.message) { | |
color = "#ffa500"; | |
font = "52pt Bariol"; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = P.width / 2; | |
y = P.height / 2 - 40; | |
visible = false | |
} | |
var countDown = new DisplayableRectangle; | |
countDown.width = P.width; | |
countDown.height = P.height; | |
countDown.color = "rgba(0,0,0,0.9)"; | |
this.view.addChild(countDown); | |
var instructions = new DisplayableTextField; | |
with(instructions) { | |
x = P.width / 2; | |
y = P.height / 2 + 120; | |
color = "#00abcd"; | |
textBaseline = "middle"; | |
textAlign = "center"; | |
font = "20pt Bariol"; | |
text = this.mode.getInstructions() | |
} | |
var messageQueue = [this.mode.getInstructions()].concat(3, 2, 1); | |
var countDownTfContainer = new DisplayableContainer; | |
countDownTfContainer.x = P.width / 2; | |
countDownTfContainer.y = P.height / 2; | |
this.view.addChild(countDownTfContainer); | |
var me = this; | |
var count = 3; | |
var down = function() { | |
if (messageQueue.length > 0) { | |
var msg = messageQueue.shift(); | |
if (!(msg instanceof Array)) { | |
msg = [msg] | |
} | |
countDownTfContainer.clear(); | |
var tf, lineSize = 96; | |
for (var i = 0; i < msg.length; i++) { | |
tf = new DisplayableTextField; | |
countDownTfContainer.addChild(tf); | |
with(tf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
font = (msg[i].toString().length < 5 ? 160 : 60) + "pt Bariol"; | |
color = "#00abcd"; | |
text = msg[i].toString(); | |
y = lineSize / 2 + (i - msg.length / 2) * lineSize | |
} | |
} | |
setTimeout(arguments.callee, 1e3); | |
TweenPool.add(new Tween(countDownTfContainer, "scaleX", 1, 0, .2, .8)); | |
TweenPool.add(new Tween(countDownTfContainer, "scaleY", 1, 0, .2, .8)); | |
TweenPool.add(new Tween(countDownTfContainer, "alpha", 1, 0, .2, .8)) | |
} else { | |
TweenPool.add(new Tween(countDown, "alpha", 1, 0, .2, 0, function() { | |
this.object.remove() | |
})); | |
me.launch() | |
} | |
}; | |
down(); | |
this.mode.initialize(this); | |
this.shakeTime = 0; | |
if (window.crossPromo) { | |
window.crossPromo.hide() | |
} | |
}, | |
destroy: function() { | |
if (window.crossPromo) { | |
window.crossPromo.show() | |
} | |
}, | |
launch: function() { | |
this.launched = true; | |
this.mode.launch(); | |
this.showMessage("Tap the black tiles!") | |
}, | |
tilePressed: function(tile) { | |
if (!this.isOver && this.launched) { | |
if (tile.isHighlighted()) { | |
this.mode.tappedHighlighted(tile) | |
} else { | |
this.mode.tappedWrong(tile) | |
} | |
} | |
}, | |
updateGauge: function() { | |
this.gauge.value = this.mode.getGaugeValue() | |
}, | |
updateDisplayedScore: function() { | |
this.previouslyDisplayedScore = this.previouslyDisplayedScore || 0; | |
var s = this.mode.getScore(); | |
this.scoreTf.text = s.toString(); | |
if (s > this.previouslyDisplayedScore) { | |
this.animateScore() | |
} | |
this.previouslyDisplayedScore = s | |
}, | |
updateDisplayedTime: function() { | |
var t = this.mode.getTimeValue(); | |
if (isNaN(t)) { | |
this.timeTf.text = null | |
} else { | |
this.timeTf.text = Util.addZeros(Math.ceil(t), 2); | |
if (t > 5) { | |
this.timeTf.color = "#f1ac37" | |
} else { | |
this.timeTf.color = ~~(t * 2 % 2) == 0 ? "#ff0000" : "#f1ac37" | |
} | |
} | |
}, | |
animateScore: function() { | |
this.timeScoreAnimated = .3; | |
TweenPool.add(new Tween(this.scoreTf, "scaleX", 2, 1, .3)); | |
TweenPool.add(new Tween(this.scoreTf, "scaleY", 2, 1, .3)) | |
}, | |
cycle: function(e) { | |
if (!this.isOver && this.launched) { | |
this.mode.cycle(e); | |
this.updateDisplayedScore(); | |
this.updateDisplayedTime(); | |
this.updateGauge() | |
} | |
this.timeScoreAnimated -= e; | |
this.scoreTf.color = this.timeScoreAnimated > 0 ? "#00ff00" : "#1ba7c0"; | |
this.view.x = 0; | |
this.view.y = 0; | |
this.shakeTime -= e; | |
if (this.shakeTime > 0) { | |
this.view.x = ~~Util.rand(-10, 10); | |
this.view.y = ~~Util.rand(-10, 10) | |
} | |
}, | |
showMessage: function(t) { | |
this.message.visible = true; | |
this.message.text = t; | |
TweenPool.add(new Tween(this.message, "scaleX", 0, 1, .2)); | |
TweenPool.add(new Tween(this.message, "scaleY", 0, 1, .2)); | |
clearTimeout(this.toClearMessage); | |
this.toClearMessage = setTimeout(this.hideMessage.bind(this), 2e3) | |
}, | |
showBubbleMessage: function(a) { | |
a = a instanceof Array ? a : [a]; | |
this.hideMessage(); | |
var container = new DisplayableContainer; | |
container.x = P.width / 2; | |
container.y = P.height / 2; | |
this.view.addChild(container); | |
var bubble = new DisplayableImage; | |
bubble.image = R.image.bubble; | |
bubble.anchorX = -bubble.image.width / 2; | |
bubble.anchorY = -bubble.image.height / 2; | |
container.addChild(bubble); | |
TweenPool.add(new Tween(container, "scaleX", 0, 1, .2)); | |
TweenPool.add(new Tween(container, "scaleY", 0, 1, .2)); | |
var tf, lineSize = 48; | |
for (var i = 0; i < a.length; i++) { | |
tf = new DisplayableTextField; | |
container.addChild(tf); | |
with(tf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
font = "40pt Bariol"; | |
color = "#ffffff"; | |
text = a[i]; | |
y = lineSize / 2 + (i - a.length / 2) * lineSize | |
} | |
} | |
}, | |
hideMessage: function() { | |
this.message.visible = false | |
}, | |
over: function(reason) { | |
this.isOver = true; | |
this.showBubbleMessage(reason); | |
setTimeout(this.game.gameOver.bind(this.game), 1e3); | |
if (this.mode.isSuccess()) { | |
this.game.leaderboard.addScore(this.mode, this.mode.getScore()) | |
} | |
}, | |
shake: function() { | |
this.shakeTime = .5; | |
if (!P.cocoon) { | |
navigator.vibrate(500) | |
} | |
}, | |
showError: function(tile) { | |
var error = new DisplayableRectangle; | |
error.color = "#ff0000"; | |
error.x = tile.x; | |
error.y = tile.y; | |
error.width = tile.width; | |
error.height = tile.height; | |
tile.parent.addChild(error); | |
TweenPool.add(new Tween(error, "alpha", 1, 0, .2)); | |
this.shake() | |
}, | |
showOk: function(tile, msg, msgColor) { | |
var indic = new DisplayableRectangle; | |
indic.color = "#00ff00"; | |
indic.x = tile.x; | |
indic.y = tile.y; | |
indic.width = tile.width; | |
indic.height = tile.height; | |
tile.parent.addChild(indic); | |
TweenPool.add(new Tween(indic, "alpha", 1, 0, .2)); | |
this.lastTap = Date.now(); | |
if (msg) { | |
var tf = new DisplayableTextField; | |
tile.parent.addChild(tf); | |
with(tf) { | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = tile.x + tile.width / 2; | |
y = tile.y + tile.height / 2; | |
color = msgColor || "red"; | |
text = msg; | |
font = "40pt Bariol" | |
} | |
TweenPool.add(new Tween(tf, "alpha", 1, 0, .2)) | |
} | |
this.game.playSound(this.tiles.indexOf(tile)) | |
}, | |
showAddTime: function(t) { | |
var tf = new DisplayableTextField; | |
this.view.addChild(tf); | |
with(tf) { | |
text = "+" + t; | |
color = this.timeTf.color; | |
font = this.timeTf.font; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
x = this.timeTf.x; | |
y = this.timeTf.y + 100 | |
} | |
TweenPool.add(new Tween(tf, "y", tf.y, this.timeTf.y, .2, 0, function() { | |
this.object.remove() | |
})) | |
}, | |
getId: function() { | |
return "gameplay-" + this.mode.getId() | |
} | |
}); | |
function EndScreen(game, mode) { | |
Screen.call(this, game); | |
this.mode = mode | |
} | |
EndScreen.prototype = extendPrototype(Screen, { | |
create: function() { | |
this.view = new DisplayableContainer; | |
this.backgroundColor = new DisplayableRectangle; | |
this.backgroundColor.width = P.width; | |
this.backgroundColor.height = P.height; | |
this.backgroundColor.color = this.mode.getBgColor(); | |
this.view.addChild(this.backgroundColor); | |
this.background = new DisplayableImage; | |
this.background.image = R.image.gameover_bg; | |
this.background.alpha = 0; | |
this.view.addChild(this.background); | |
var char = new DisplayableImage; | |
char.image = R.image.end_bg; | |
char.x = P.width - char.image.width - 100; | |
char.y = P.height - char.image.height - 100; | |
this.view.addChild(char); | |
var textColor = this.mode.getBgColor() == "#ffffff" ? "#000" : "#ffffff"; | |
var valueColor1 = "#178fff"; | |
var valueColor2 = "#178fff"; | |
var youScored = new DisplayableTextField; | |
this.view.addChild(youScored); | |
with(youScored) { | |
x = 384; | |
y = 194; | |
textAlign = "right"; | |
textBaseline = "middle"; | |
color = textColor; | |
font = "56pt Bariol"; | |
text = "You scored " | |
} | |
var score = new DisplayableTextField; | |
this.view.addChild(score); | |
with(score) { | |
x = 384; | |
y = 194; | |
textAlign = "left"; | |
textBaseline = "middle"; | |
color = valueColor1; | |
font = "68pt Bariol"; | |
text = this.mode.getScore().toString() | |
} | |
if (!this.mode.isSuccess()) { | |
youScored.text = "You failed"; | |
youScored.textAlign = "center"; | |
youScored.x = P.width / 2; | |
score.text = "" | |
} else { | |
youScored.text = "You scored "; | |
score.text = this.mode.getFormattedScore(this.mode.getScore()) | |
} | |
var dateLabel = new DisplayableTextField; | |
this.view.addChild(dateLabel); | |
with(dateLabel) { | |
x = P.width / 3; | |
y = 280; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
color = textColor; | |
font = "28pt Bariol"; | |
text = "DATE" | |
} | |
var scoreLabel = new DisplayableTextField; | |
this.view.addChild(scoreLabel); | |
with(scoreLabel) { | |
x = P.width * 2 / 3; | |
y = 280; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
color = textColor; | |
font = "28pt Bariol"; | |
text = "SCORE" | |
} | |
var scores = this.game.leaderboard.getScores(this.mode); | |
var date, score, nextY = dateLabel.y + 50; | |
for (var i = 0; i < 8; i++) { | |
date = new DisplayableTextField; | |
this.view.addChild(date); | |
with(date) { | |
x = P.width / 3; | |
y = nextY; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
font = "36pt Bariol" | |
} | |
score = new DisplayableTextField; | |
this.view.addChild(score); | |
with(score) { | |
x = P.width * 2 / 3; | |
y = nextY; | |
textAlign = "center"; | |
textBaseline = "middle"; | |
font = "36pt Bariol" | |
} | |
score.color = date.color = i % 2 == 0 ? valueColor1 : valueColor2; | |
if (scores[i]) { | |
score.text = this.mode.getFormattedScore(scores[i].score); | |
var d = new Date(scores[i].date); | |
date.text = d.getMonth() + 1 + "/" + d.getDate() + "/" + d.getFullYear() | |
} else { | |
score.text = date.text = "--" | |
} | |
nextY += 50 | |
} | |
var sc = this; | |
var buttons = []; | |
var button_suffix = this.mode.getBgColor() == "#ffffff" ? "_black" : "_white"; | |
buttons.push(new Button({ | |
content: R.image.button_retry, | |
id: "retry-end" | |
}, function() { | |
sc.game.retry() | |
})); | |
buttons.push(new Button({ | |
content: R.image["button_menu" + button_suffix], | |
id: "menu-end" | |
}, function() { | |
sc.game.menu() | |
})); | |
if (window.kik && kik.send) { | |
buttons.push(new Button({ | |
content: R.image["button_kik" + button_suffix], | |
id: "kik-end" | |
}, function() { | |
sc.game.shareKik() | |
})) | |
} | |
for (var i = 0; i < buttons.length; i++) { | |
buttons[i].x = P.width / 2 + 40 + (i - buttons.length / 2) * (buttons[i].width + 80); | |
buttons[i].y = 800 - buttons[i].height / 2; | |
this.view.addChild(buttons[i]); | |
this.addArea(buttons[i].getArea()) | |
} | |
if (!P.inAppGames) { | |
this.fbButton = new Button({ | |
content: R.image.button_fb_clean, | |
id: "facebook-end" | |
}, function() { | |
sc.game.shareFacebook() | |
}); | |
this.fbButton.x = P.width - this.fbButton.width - 40; | |
this.fbButton.y = 40; | |
this.view.addChild(this.fbButton); | |
this.addArea(this.fbButton.getArea()); | |
this.twitterButton = new Button({ | |
content: R.image.button_twitter_clean, | |
id: "twitter-end" | |
}, function() { | |
sc.game.shareTwitter() | |
}); | |
this.twitterButton.x = this.fbButton.x - this.twitterButton.width - 40; | |
this.twitterButton.y = 40; | |
this.view.addChild(this.twitterButton); | |
this.addArea(this.twitterButton.getArea()) | |
} | |
}, | |
destroy: function() {}, | |
getId: function() { | |
return "end" | |
} | |
}); | |
function Tile(onClick) { | |
DisplayableRectangle.call(this); | |
this.color = "#ffffff"; | |
this.highlightAlpha = 0; | |
this.highlightTween = null; | |
this.onClick = onClick | |
} | |
Tile.prototype = extendPrototype(DisplayableRectangle, { | |
getArea: function() { | |
return new Area(this.x, this.y, this.width, this.height, { | |
actionStart: this.actionStart.bind(this), | |
actionCancel: this.actionCancel.bind(this) | |
}) | |
}, | |
actionStart: function() { | |
this.onClick.call(this) | |
}, | |
actionCancel: function() {}, | |
highlight: function() { | |
this.highlighted = true; | |
this.highlightAlpha = 1; | |
if (this.highlightTween) { | |
this.highlightTween.finish() | |
} | |
this.highlightTween = new Tween(this, "highlightAlpha", 0, 1, .2); | |
TweenPool.add(this.highlightTween) | |
}, | |
disable: function() { | |
this.highlighted = false; | |
if (this.highlightTween) { | |
this.highlightTween.finish() | |
} | |
this.highlightAlpha = 0 | |
}, | |
isHighlighted: function() { | |
return this.highlighted | |
}, | |
render: function(c) { | |
DisplayableRectangle.prototype.render.call(this, c); | |
c.globalAlpha = this.highlightAlpha; | |
c.fillStyle = "#000"; | |
c.fillRect(0, 0, this.width, this.height); | |
c.globalAlpha = 1; | |
c.strokeStyle = "#b8b8b8"; | |
c.strokeRect(.5, .5, this.width - 1, this.height - 1) | |
} | |
}); | |
function LeaderboardView(scores) { | |
DisplayableContainer.call(this); | |
this.scores = scores; | |
this.populate() | |
} | |
LeaderboardView.prototype = extendPrototype(DisplayableContainer, { | |
populate: function() { | |
var dateTf, scoreTf, nextY = 0; | |
for (var i = 0; i < 5; i++) { | |
dateTf = new DisplayableTextField; | |
this.addChild(dateTf); | |
with(dateTf) { | |
color = "#ffffff"; | |
textAlign = "right"; | |
x = P.width / 2 - 5; | |
y = nextY; | |
font = "10pt Arial"; | |
textBaseline = "top"; | |
text = "1/1/1" | |
} | |
nextY += 20 | |
} | |
} | |
}); | |
function SinView() { | |
DisplayableShape.call(this, this.drawCurve.bind(this)); | |
this.amplitude = 0 | |
} | |
SinView.prototype = extendPrototype(DisplayableShape, { | |
drawCurve: function(c) { | |
c.strokeStyle = "#ffffff"; | |
c.beginPath(); | |
c.moveTo(0, 0); | |
var a; | |
for (var x = 0; x < P.width; x++) { | |
a = (1 - Math.abs(x - P.width / 2) / (P.width / 2)) * this.amplitude; | |
c.lineTo(x, Math.sin(Date.now() / 50 + x * Math.PI / 5) * a * 20) | |
} | |
c.stroke() | |
} | |
}); | |
function GaugeView() { | |
DisplayableObject.call(this); | |
this.width = 100; | |
this.height = 3; | |
this.value = 0 | |
} | |
GaugeView.prototype = extendPrototype(DisplayableObject, { | |
render: function(c) { | |
c.fillStyle = "#1076a8"; | |
c.fillRect(0, 0, this.width, this.height); | |
c.fillStyle = "#33e4fb"; | |
c.fillRect(1, 1, (this.width - 2) * this.value, this.height - 2) | |
} | |
}); | |
var addToHome = function(w) { | |
var nav = w.navigator, | |
isIDevice = "platform" in nav && /iphone|ipod|ipad/gi.test(nav.platform), | |
isIPad, isRetina, isSafari, isStandalone, OSVersion, startX = 0, | |
startY = 0, | |
lastVisit = 0, | |
isExpired, isSessionActive, isReturningVisitor, balloon, overrideChecks, positionInterval, closeTimeout, options = { | |
autostart: true, | |
returningVisitor: false, | |
animationIn: "drop", | |
animationOut: "fade", | |
startDelay: 2e3, | |
lifespan: 15e3, | |
bottomOffset: 14, | |
expire: 0, | |
message: "", | |
touchIcon: false, | |
arrow: true, | |
hookOnLoad: true, | |
closeButton: true, | |
iterations: 100 | |
}, | |
intl = { | |
ar: '<span dir="rtl">قم بتثبيت هذا التطبيق على <span dir="ltr">%device:</span>انقر<span dir="ltr">%icon</span> ØŒ<strong>ثم اضÙÙ‡ الى الشاشة الرئيسية.</strong></span>', | |
ca_es: "Per instal·lar aquesta aplicació al vostre %device premeu %icon i llavors <strong>Afegir a pantalla d'inici</strong>.", | |
cs_cz: "Pro instalaci aplikace na Váš %device, stisknÄ›te %icon a v nabÃdce <strong>PÅ™idat na plochu</strong>.", | |
da_dk: "Tilføj denne side til din %device: tryk på %icon og derefter <strong>Føj til hjemmeskærm</strong>.", | |
de_de: "Installieren Sie diese App auf Ihrem %device: %icon antippen und dann <strong>Zum Home-Bildschirm</strong>.", | |
el_gr: "Εγκαταστήσετε αυτήν την ΕφαÏμογή στήν συσκευή σας %device: %icon μετά πατάτε <strong>Î Ïοσθήκη σε ΑφετηÏία</strong>.", | |
en_us: "Install this web app on your %device: tap %icon and then <strong>Add to Home Screen</strong>.", | |
es_es: "Para instalar esta app en su %device, pulse %icon y seleccione <strong>Añadir a pantalla de inicio</strong>.", | |
fi_fi: "Asenna tämä web-sovellus laitteeseesi %device: paina %icon ja sen jälkeen valitse <strong>Lisää Koti-valikkoon</strong>.", | |
fr_fr: "Ajoutez cette application sur votre %device en cliquant sur %icon, puis <strong>Ajouter à l'écran d'accueil</strong>.", | |
he_il: '<span dir="rtl">התקן ×פליקציה זו על ×”-%device שלך: הקש %icon ו××– <strong>הוסף למסך הבית</strong>.</span>', | |
hr_hr: "Instaliraj ovu aplikaciju na svoj %device: klikni na %icon i odaberi <strong>Dodaj u poÄetni zaslon</strong>.", | |
hu_hu: "TelepÃtse ezt a web-alkalmazást az Ön %device-jára: nyomjon a %icon-ra majd a <strong>FÅ‘képernyÅ‘höz adás</strong> gombra.", | |
it_it: "Installa questa applicazione sul tuo %device: premi su %icon e poi <strong>Aggiungi a Home</strong>.", | |
ja_jp: "ã“ã®ã‚¦ã‚§ãƒ–アプリをã‚ãªãŸã®%deviceã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã«ã¯%iconをタップã—ã¦<strong>ホーム画é¢ã«è¿½åŠ </strong>ã‚’é¸ã‚“ã§ãã ã•ã„。", | |
ko_kr: '%deviceì— ì›¹ì•±ì„ ì„¤ì¹˜í•˜ë ¤ë©´ %iconì„ í„°ì¹˜ 후 "í™ˆí™”ë©´ì— ì¶”ê°€"를 ì„ íƒí•˜ì„¸ìš”', | |
nb_no: "Installer denne appen på din %device: trykk på %icon og deretter <strong>Legg til på Hjem-skjerm</strong>", | |
nl_nl: "Installeer deze webapp op uw %device: tik %icon en dan <strong>Voeg toe aan beginscherm</strong>.", | |
pl_pl: "Aby zainstalować tę aplikacje na %device: naciśnij %icon a następnie <strong>Dodaj jako ikonę</strong>.", | |
pt_br: "Instale este aplicativo em seu %device: aperte %icon e selecione <strong>Adicionar à Tela Inicio</strong>.", | |
pt_pt: "Para instalar esta aplicação no seu %device, prima o %icon e depois em <strong>Adicionar ao ecrã principal</strong>.", | |
ru_ru: "УÑтановите Ñто веб-приложение на ваш %device: нажмите %icon, затем <strong>Добавить в «Домой»</strong>.", | |
sv_se: "Lägg till denna webbapplikation på din %device: tryck på %icon och därefter <strong>Lägg till på hemskärmen</strong>.", | |
th_th: "ติดตั้งเว็บà¹à¸à¸žà¸¯ นี้บน %device ขà¸à¸‡à¸„ุณ: à¹à¸•à¸° %icon à¹à¸¥à¸° <strong>เพิ่มที่หน้าจà¸à¹‚ฮม</strong>", | |
tr_tr: "Bu uygulamayı %device'a eklemek için %icon simgesine sonrasında <strong>Ana Ekrana Ekle</strong> düğmesine basın.", | |
uk_ua: "Ð’Ñтановіть цей веб Ñайт на Ваш %device: натиÑніть %icon, а потім <strong>Ðа початковий екран</strong>.", | |
zh_cn: "您å¯ä»¥å°†æ¤åº”用安装到您的 %device 上。请按 %icon 然åŽé€‰æ‹©<strong>æ·»åŠ è‡³ä¸»å±å¹•</strong>。", | |
zh_tw: "您å¯ä»¥å°‡æ¤æ‡‰ç”¨ç¨‹å¼å®‰è£åˆ°æ‚¨çš„ %device 上。請按 %icon 然後點é¸<strong>åŠ å…¥ä¸»ç•«é¢èž¢å¹•</strong>。" | |
}; | |
function init() { | |
if (!isIDevice) return; | |
var now = Date.now(), | |
i; | |
if (w.addToHomeConfig) { | |
for (i in w.addToHomeConfig) { | |
options[i] = w.addToHomeConfig[i] | |
} | |
} | |
if (!options.autostart) options.hookOnLoad = false; | |
isIPad = /ipad/gi.test(nav.platform); | |
isRetina = w.devicePixelRatio && w.devicePixelRatio > 1; | |
isSafari = /Safari/i.test(nav.appVersion) && !/CriOS/i.test(nav.appVersion); | |
isStandalone = nav.standalone; | |
OSVersion = nav.appVersion.match(/OS (\d+_\d+)/i); | |
OSVersion = OSVersion && OSVersion[1] ? +OSVersion[1].replace("_", ".") : 0; | |
lastVisit = +w.localStorage.getItem("addToHome"); | |
isSessionActive = w.sessionStorage.getItem("addToHomeSession"); | |
isReturningVisitor = options.returningVisitor ? lastVisit && lastVisit + 28 * 24 * 60 * 60 * 1e3 > now : true; | |
if (!lastVisit) lastVisit = now; | |
isExpired = isReturningVisitor && lastVisit <= now; | |
if (options.hookOnLoad) w.addEventListener("load", loaded, false); | |
else if (!options.hookOnLoad && options.autostart) loaded() | |
} | |
function loaded() { | |
w.removeEventListener("load", loaded, false); | |
if (!isReturningVisitor) w.localStorage.setItem("addToHome", Date.now()); | |
else if (options.expire && isExpired) w.localStorage.setItem("addToHome", Date.now() + options.expire * 6e4); | |
if (!overrideChecks && (!isSafari || !isExpired || isSessionActive || isStandalone || !isReturningVisitor)) return; | |
var touchIcon = "", | |
platform = nav.platform.split(" ")[0], | |
language = nav.language.replace("-", "_"); | |
balloon = document.createElement("div"); | |
balloon.id = "addToHomeScreen"; | |
balloon.style.cssText += "left:-9999px;-webkit-transition-property:-webkit-transform,opacity;-webkit-transition-duration:0;-webkit-transform:translate3d(0,0,0);position:" + (OSVersion < 5 ? "absolute" : "fixed"); | |
if (options.message in intl) { | |
language = options.message; | |
options.message = "" | |
} | |
if (options.message === "") { | |
options.message = language in intl ? intl[language] : intl["en_us"] | |
} | |
if (options.touchIcon) { | |
touchIcon = isRetina ? document.querySelector('head link[rel^=apple-touch-icon][sizes="114x114"],head link[rel^=apple-touch-icon][sizes="144x144"],head link[rel^=apple-touch-icon]') : document.querySelector('head link[rel^=apple-touch-icon][sizes="57x57"],head link[rel^=apple-touch-icon]'); | |
if (touchIcon) { | |
touchIcon = '<span style="background-image:url(' + touchIcon.href + ')" class="addToHomeTouchIcon"></span>' | |
} | |
} | |
balloon.className = (OSVersion >= 7 ? "addToHomeIOS7 " : "") + (isIPad ? "addToHomeIpad" : "addToHomeIphone") + (touchIcon ? " addToHomeWide" : ""); | |
balloon.innerHTML = touchIcon + options.message.replace("%device", platform).replace("%icon", OSVersion >= 4.2 ? '<span class="addToHomeShare"></span>' : '<span class="addToHomePlus">+</span>') + (options.arrow ? '<span class="addToHomeArrow"' + (OSVersion >= 7 && isIPad && touchIcon ? ' style="margin-left:-32px"' : "") + "></span>" : "") + (options.closeButton ? '<span class="addToHomeClose">×</span>' : ""); | |
document.body.appendChild(balloon); | |
if (options.closeButton) { | |
balloon.addEventListener("click", clicked, false); | |
balloon.querySelector(".addToHomeClose").addEventListener("touchstart", close, false) | |
} | |
if (!isIPad && OSVersion >= 6) window.addEventListener("orientationchange", orientationCheck, false); | |
setTimeout(show, options.startDelay) | |
} | |
function show() { | |
var duration, iPadXShift = 208; | |
if (isIPad) { | |
if (OSVersion < 5) { | |
startY = w.scrollY; | |
startX = w.scrollX | |
} else if (OSVersion < 6) { | |
iPadXShift = 160 | |
} else if (OSVersion >= 7) { | |
iPadXShift = 143 | |
} | |
balloon.style.top = startY + options.bottomOffset + "px"; | |
balloon.style.left = Math.max(startX + iPadXShift - Math.round(balloon.offsetWidth / 2), 9) + "px"; | |
switch (options.animationIn) { | |
case "drop": | |
duration = "0.6s"; | |
balloon.style.webkitTransform = "translate3d(0," + -(w.scrollY + options.bottomOffset + balloon.offsetHeight) + "px,0)"; | |
break; | |
case "bubble": | |
duration = "0.6s"; | |
balloon.style.opacity = "0"; | |
balloon.style.webkitTransform = "translate3d(0," + (startY + 50) + "px,0)"; | |
break; | |
default: | |
duration = "1s"; | |
balloon.style.opacity = "0" | |
} | |
} else { | |
startY = w.innerHeight + w.scrollY; | |
if (OSVersion < 5) { | |
startX = Math.round((w.innerWidth - balloon.offsetWidth) / 2) + w.scrollX; | |
balloon.style.left = startX + "px"; | |
balloon.style.top = startY - balloon.offsetHeight - options.bottomOffset + "px" | |
} else { | |
balloon.style.left = "50%"; | |
balloon.style.marginLeft = -Math.round(balloon.offsetWidth / 2) - (w.orientation % 180 && OSVersion >= 6 && OSVersion < 7 ? 40 : 0) + "px"; | |
balloon.style.bottom = options.bottomOffset + "px" | |
} | |
switch (options.animationIn) { | |
case "drop": | |
duration = "1s"; | |
balloon.style.webkitTransform = "translate3d(0," + -(startY + options.bottomOffset) + "px,0)"; | |
break; | |
case "bubble": | |
duration = "0.6s"; | |
balloon.style.webkitTransform = "translate3d(0," + (balloon.offsetHeight + options.bottomOffset + 50) + "px,0)"; | |
break; | |
default: | |
duration = "1s"; | |
balloon.style.opacity = "0" | |
} | |
} | |
balloon.offsetHeight; | |
balloon.style.webkitTransitionDuration = duration; | |
balloon.style.opacity = "1"; | |
balloon.style.webkitTransform = "translate3d(0,0,0)"; | |
balloon.addEventListener("webkitTransitionEnd", transitionEnd, false); | |
closeTimeout = setTimeout(close, options.lifespan) | |
} | |
function manualShow(override) { | |
if (!isIDevice || balloon) return; | |
overrideChecks = override; | |
loaded() | |
} | |
function close() { | |
clearInterval(positionInterval); | |
clearTimeout(closeTimeout); | |
closeTimeout = null; | |
if (!balloon) return; | |
var posY = 0, | |
posX = 0, | |
opacity = "1", | |
duration = "0"; | |
if (options.closeButton) balloon.removeEventListener("click", clicked, false); | |
if (!isIPad && OSVersion >= 6) window.removeEventListener("orientationchange", orientationCheck, false); | |
if (OSVersion < 5) { | |
posY = isIPad ? w.scrollY - startY : w.scrollY + w.innerHeight - startY; | |
posX = isIPad ? w.scrollX - startX : w.scrollX + Math.round((w.innerWidth - balloon.offsetWidth) / 2) - startX | |
} | |
balloon.style.webkitTransitionProperty = "-webkit-transform,opacity"; | |
switch (options.animationOut) { | |
case "drop": | |
if (isIPad) { | |
duration = "0.4s"; | |
opacity = "0"; | |
posY += 50 | |
} else { | |
duration = "0.6s"; | |
posY += balloon.offsetHeight + options.bottomOffset + 50 | |
} | |
break; | |
case "bubble": | |
if (isIPad) { | |
duration = "0.8s"; | |
posY -= balloon.offsetHeight + options.bottomOffset + 50 | |
} else { | |
duration = "0.4s"; | |
opacity = "0"; | |
posY -= 50 | |
} | |
break; | |
default: | |
duration = "0.8s"; | |
opacity = "0" | |
} | |
balloon.addEventListener("webkitTransitionEnd", transitionEnd, false); | |
balloon.style.opacity = opacity; | |
balloon.style.webkitTransitionDuration = duration; | |
balloon.style.webkitTransform = "translate3d(" + posX + "px," + posY + "px,0)" | |
} | |
function clicked() { | |
w.sessionStorage.setItem("addToHomeSession", "1"); | |
isSessionActive = true; | |
close() | |
} | |
function transitionEnd() { | |
balloon.removeEventListener("webkitTransitionEnd", transitionEnd, false); | |
balloon.style.webkitTransitionProperty = "-webkit-transform"; | |
balloon.style.webkitTransitionDuration = "0.2s"; | |
if (!closeTimeout) { | |
balloon.parentNode.removeChild(balloon); | |
balloon = null; | |
return | |
} | |
if (OSVersion < 5 && closeTimeout) positionInterval = setInterval(setPosition, options.iterations) | |
} | |
function setPosition() { | |
var matrix = new WebKitCSSMatrix(w.getComputedStyle(balloon, null).webkitTransform), | |
posY = isIPad ? w.scrollY - startY : w.scrollY + w.innerHeight - startY, | |
posX = isIPad ? w.scrollX - startX : w.scrollX + Math.round((w.innerWidth - balloon.offsetWidth) / 2) - startX; | |
if (posY == matrix.m42 && posX == matrix.m41) return; | |
balloon.style.webkitTransform = "translate3d(" + posX + "px," + posY + "px,0)" | |
} | |
function reset() { | |
w.localStorage.removeItem("addToHome"); | |
w.sessionStorage.removeItem("addToHomeSession") | |
} | |
function orientationCheck() { | |
balloon.style.marginLeft = -Math.round(balloon.offsetWidth / 2) - (w.orientation % 180 && OSVersion >= 6 && OSVersion < 7 ? 40 : 0) + "px" | |
} | |
init(); | |
return { | |
show: manualShow, | |
close: close, | |
reset: reset | |
} | |
}(window); | |
(function() { | |
if (!P.cocoon) { | |
(function(i, s, o, g, r, a, m) { | |
i["GoogleAnalyticsObject"] = r; | |
i[r] = i[r] || function() { | |
(i[r].q = i[r].q || []).push(arguments) | |
}, i[r].l = 1 * new Date; | |
a = s.createElement(o), m = s.getElementsByTagName(o)[0]; | |
a.async = 1; | |
a.src = g; | |
m.parentNode.insertBefore(a, m) | |
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga") | |
} else if (!window.cordova) { | |
var interfaceReady = false; | |
var queue = []; | |
var flushQueue = function() { | |
var cmd; | |
while (cmd = queue.shift()) { | |
forwardCmd(cmd) | |
} | |
}; | |
var forwardCmd = function(cmd) { | |
console.log("Sending " + cmd + " to the Webview"); | |
CocoonJS.App.forwardAsync(cmd) | |
}; | |
var addToQueue = function(cmd) { | |
queue.push(cmd); | |
if (interfaceReady) { | |
flushQueue() | |
} | |
}; | |
window.gaInterfaceIsReady = function() { | |
CocoonJS.App.forwardAsync("CocoonJS.App.show(0, 0, " + window.innerWidth * window.devicePixelRatio + "," + window.innerHeight * window.devicePixelRatio + ");"); | |
interfaceReady = true; | |
flushQueue() | |
}; | |
console.log("Creating GAI interface"); | |
CocoonJS.App.loadInTheWebView("http://more.gamemix.com/cocoonoverlay.html?currentGame=donttap"); | |
window.ga = function() { | |
var args = ""; | |
for (var i = 0; i < arguments.length; i++) { | |
if (i > 0) { | |
args += "," | |
} | |
args += JSON.stringify(arguments[i]) | |
} | |
var cmd = "window.ga(" + args + ")"; | |
addToQueue(cmd) | |
} | |
} | |
ga("require", "displayfeatures"); | |
ga("create", "UA-50290430-1"); | |
(function(g, m, c, d, a) { | |
g["GameMixGA"] = a; | |
g[a] = g[a] || function(f) { | |
g[a].q = g[a].q || []; | |
g[a].q.push(f) | |
}; | |
g[a]({ | |
gmgaDomain: d | |
}); | |
var s = m.createElement(c), | |
p = m.getElementsByTagName(c)[0]; | |
s.type = "text/javascript"; | |
s.async = true; | |
s.src = d + "/client/gmga.js"; | |
p.parentNode.insertBefore(s, p) | |
})(window, document, "script", "http://gmga.gamemix.com", "gmga"); | |
gmga("donttap") | |
})() | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment