/****
* Classes
****/
var BonusIndicator = Container.expand(function (score, color) {
var self = Container.call(this);
color = Math.round(color);
var hsv = rgbToHsv(color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF);
var outlineColor = hsv[0] > .08 && hsv[0] < .55 ? 0x0 : 0xffffff;
var scoreLabel = new Text2(score.toString(), {
size: 150,
fill: '#' + color.toString(16).padStart(6, '0'),
font: 'Impact',
stroke: '#' + outlineColor.toString(16).padStart(6, '0'),
strokeThickness: 15
});
scoreLabel.anchor.set(.5, 0);
self.addChild(scoreLabel);
self.speedX = Math.random() * 16 - 8;
self.speedY = -20;
self.rotationSpeed = self.speedX > 0 ? 0.01 : -0.01;
self._move_migrated = function () {
self.x += self.speedX;
self.y += self.speedY;
self.speedY += 0.5;
self.speedX *= 0.99;
self.rotation += self.rotationSpeed;
if (self.y > game.height + 100) {
self.destroy();
}
};
});
var Countdown = Container.expand(function () {
var self = Container.call(this);
var countdownLabel = new Text2('', {
size: 300,
fill: '#ffffff',
font: 'Impact',
stroke: '#000000',
strokeThickness: 15
});
countdownLabel.anchor.set(.5, .5);
self.addChild(countdownLabel);
self.x = 2048 / 2;
self.y = 2732 / 2;
self.countdown = function () {
var countdownTexts = ['Ready', 'Set', 'Go'];
var index = 0;
countdownLabel.setText(countdownTexts[index]);
var countdownInterval = LK.setInterval(function () {
if (index >= countdownTexts.length - 1) {
LK.clearInterval(countdownInterval);
self.destroy();
return;
}
self.scale.set(1, 1);
LK.getSound('countdown').play();
index++;
countdownLabel.setText(countdownTexts[index]);
}, 700);
LK.setTimeout(function () {
gameStarted = true;
}, 1500);
LK.getSound('countdown').play();
};
self.update = function () {
var ns = self.scale.x;
ns *= .99;
self.scale.set(ns, ns);
};
});
var OverhangPlate = Container.expand(function (width, direction, color) {
var self = Container.call(this);
var plateGraphics = self.attachAsset('plate', {
anchorX: 0.5,
anchorY: 0.5
});
plateGraphics.width = width;
plateGraphics.tint = color;
self.speedX = direction === 'right' ? 5 : -5;
self.speedY = -20;
self.rotationSpeed = direction === 'right' ? 0.01 : -0.01;
self._move_migrated = function () {
self.x += self.speedX;
self.y += self.speedY;
self.speedY += 0.5;
self.speedX *= 0.99;
self.rotation += self.rotationSpeed;
};
});
var Plate = Container.expand(function (targetWidth) {
var self = Container.call(this);
var plateGraphics = self.attachAsset('plate', {
anchorX: 0.5,
anchorY: 0.5
});
plateGraphics.width = targetWidth;
self.colorIndex = 0;
self.hsvToRgb = function (h, s, v) {
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
}
return (r * 255 << 16) + (g * 255 << 8) + b * 255;
};
self.updateColor = function () {
var h = self.colorIndex / 32;
var s = 1;
var v = 1;
self.color = hsvToRgb(h, s, v);
plateGraphics.tint = self.color;
self.colorIndex = (self.colorIndex + 1) % 32;
var bgColor = self.hsvToRgb(h, s, v / 4);
game.setBackgroundColor(bgColor);
};
self.updateColor();
self.speed = 22.5;
self._move_migrated = function () {
self.x -= self.speed;
};
self.stack = function () {
self.speed = 0;
};
self.slide = function () {
self.x = 2048 + self.width / 2;
};
self.hasOverlapped = false;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
function hsvToRgb(h, s, v) {
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
}
return (r * 255 << 16) + (g * 255 << 8) + b * 255;
}
function rgbToHsv(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h,
s,
v = max;
var d = max - min;
s = max == 0 ? 0 : d / max;
if (max == min) {
h = 0; // achromatic
} else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h, s, v];
}
var scoreTxt = new Text2('0', {
size: 150,
fill: '#ffffff',
font: 'Impact'
});
scoreTxt.anchor.set(.5, 0);
LK.gui.top.addChild(scoreTxt);
var plateContainer = new Container();
plateContainer.targetY = 0;
game.addChild(plateContainer);
var currentPlateWidth = 1000;
var plates = [];
var plateColorIndex = 0;
var firstPlate = new Plate(currentPlateWidth);
firstPlate.x = 2048 / 2;
firstPlate.y = 2732 - firstPlate.height / 2;
firstPlate.speed = 0;
firstPlate.colorIndex = plateColorIndex;
firstPlate.updateColor();
plates.push(firstPlate);
plateContainer.addChild(firstPlate);
var newPlate = new Plate(currentPlateWidth);
newPlate.slide();
newPlate.y = 2732 - plates.length * newPlate.height - newPlate.height / 2;
plateColorIndex++;
newPlate.colorIndex = plateColorIndex;
newPlate.updateColor();
plates.push(newPlate);
plateContainer.addChild(newPlate);
var bonusCount = 1;
game.on('down', function (x, y, obj) {
if (!gameStarted) {
return;
}
var topPlate = plates[plates.length - 2];
if (newPlate.x < topPlate.x + topPlate.width && newPlate.x + newPlate.width > topPlate.x) {
var overhang = newPlate.x + newPlate.width / 2 - (topPlate.x + topPlate.width / 2);
var overhangSide = overhang > 0 ? 'right' : 'left';
overhang = Math.abs(overhang);
newPlate.stack();
if (overhang > 22) {
bonusCount = 1;
LK.getSound('place').play();
currentPlateWidth -= overhang;
var overhangPlate = new OverhangPlate(overhang, overhangSide, newPlate.color);
overhangPlate.x = overhangSide === 'right' ? newPlate.x + newPlate.width / 2 : newPlate.x - newPlate.width / 2;
overhangPlate.y = newPlate.y;
plateContainer.addChildAt(overhangPlate, 0);
newPlate.width -= overhang;
if (overhangSide === 'right') {
newPlate.x -= overhang / 2;
overhangPlate.x -= overhang / 2;
} else {
newPlate.x += overhang / 2;
overhangPlate.x += overhang / 2;
}
}
var nextPlate = new Plate(currentPlateWidth);
plateContainer.addChild(nextPlate);
nextPlate.slide();
nextPlate.y = 2732 - plates.length * newPlate.height - newPlate.height / 2;
plateColorIndex++;
nextPlate.colorIndex = plateColorIndex;
nextPlate.updateColor();
plates.push(nextPlate);
if (overhang <= 22) {
newPlate.x = topPlate.x;
LK.getSound('perfect').play();
bonusCount++;
var bonusIndicator = new BonusIndicator('+' + bonusCount, newPlate.color);
plateContainer.addChild(bonusIndicator);
bonusIndicator.y = newPlate.y;
bonusIndicator.x = newPlate.x;
}
if (plates.length > 17) {
plateContainer.targetY += newPlate.height;
}
var newScore = LK.getScore() + bonusCount;
scoreTxt.setText(newScore);
LK.setScore(newScore);
newPlate = nextPlate;
} else {
LK.getSound('gameover').play();
LK.showGameOver();
}
});
var countdown = new Countdown();
game.addChild(countdown);
countdown.countdown();
var gameStarted = false;
LK.on('tick', function () {
if (!gameStarted) {
return;
}
for (var i = 0; i < plateContainer.children.length; i++) {
var plate = plateContainer.children[i];
plate._move_migrated();
if (plate instanceof OverhangPlate && (plate.x < -plate.width / 2 || plate.x > 2048 + plate.width / 2 || plate.y > 2732 + plate.height / 2)) {
plate.destroy();
}
if (newPlate.x < -newPlate.width / 2) {
LK.getSound('gameover').play();
LK.showGameOver();
}
var topPlate = plates[plates.length - 2];
if (newPlate.x < topPlate.x + topPlate.width && !newPlate.hasOverlapped) {
LK.getSound('slide').play();
newPlate.hasOverlapped = true;
}
}
if (plateContainer.y !== plateContainer.targetY) {
plateContainer.y += (plateContainer.targetY - plateContainer.y) * 0.1;
}
});