Skip to content

Instantly share code, notes, and snippets.

@illnyang
Last active April 13, 2017 22:21
Show Gist options
  • Save illnyang/9d01ba1cda793f5501d4a15ec8eae2fc to your computer and use it in GitHub Desktop.
Save illnyang/9d01ba1cda793f5501d4a15ec8eae2fc to your computer and use it in GitHub Desktop.
epic donttap src hack
/*
(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