var Bubble = Container.expand(function (bubbles) { var self = Container.call(this); self.xWidth = 210; self.xHeight = 210; self.getSameTypeBubbles = function () { var sameTypeBubbles = []; var stack = [this]; while (stack.length) { var currentBubble = stack.pop(); sameTypeBubbles.push(currentBubble); var neighbors = this.getNeighbors(currentBubble); for (var i = 0; i < neighbors.length; i++) { if (neighbors[i].type === this.type && !sameTypeBubbles.includes(neighbors[i]) && !stack.includes(neighbors[i])) { stack.push(neighbors[i]); } } } return sameTypeBubbles; }; self.arrayX = 0; self.arrayY = 0; self.type = Math.floor(Math.random() * Math.min(8, Math.floor(LK.moves / 25) + 3)); var bubbleGraphics = self.createAsset('bubble', 'Bubble Graphics', .5, .5); var colors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF, 0x00FFFF, 0xFF00FF]; bubbleGraphics.tint = colors[self.type]; self.move = function (isFirstLoop) { if (isFirstLoop) { var targetY = self.arrayY * (self.xHeight + 4) + self.xHeight / 2; if (self.y < targetY) { self.speed = self.speed || 0; self.speed += 2; self.y = Math.min(self.y + self.speed, targetY); } else { self.y = targetY; self.speed = 0; } } if (self.arrayY < bubbles[0].length - 1 && !bubbles[self.arrayX][self.arrayY + 1]) { bubbles[self.arrayX][self.arrayY] = null; self.arrayY++; bubbles[self.arrayX][self.arrayY] = self; return true; } return false; }; self.on('down', function () { this.pop(bubbles); }); self.pop = function () { var sameTypeBubbles = []; var stack = [this]; while (stack.length) { var currentBubble = stack.pop(); sameTypeBubbles.push(currentBubble); var neighbors = this.getNeighbors(currentBubble); for (var i = 0; i < neighbors.length; i++) { if (neighbors[i].type === this.type && !sameTypeBubbles.includes(neighbors[i]) && !stack.includes(neighbors[i])) { stack.push(neighbors[i]); } } } if (sameTypeBubbles.length >= 3) { for (var i = 0; i < sameTypeBubbles.length; i++) { sameTypeBubbles[i].destroy(); } LK.score += sameTypeBubbles.length >= 3 ? Math.pow(sameTypeBubbles.length, 2) : 0; LK.moves++; } }; self.getNeighbors = function (bubble) { var neighbors = []; var positions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; for (var i = 0; i < positions.length; i++) { var x = positions[i][0] + bubble.arrayX; var y = positions[i][1] + bubble.arrayY; if (x >= 0 && x < bubbles.length && y >= 0 && y < bubbles[0].length && bubbles[x][y]) { neighbors.push(bubbles[x][y]); } } return neighbors; }; }); var Game = Container.expand(function () { var self = Container.call(this); LK.score = 0; LK.moves = 0; LK.stageContainer.setBackgroundColor(0xfff1e7); var scoreLabel = new Text2('0', { size: 150, fill: '#000000', dropShadow: true, dropShadowColor: '#ffffff', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6, font: 'Impact' }); scoreLabel.anchor.set(0.5, 0); LK.gui.topCenter.addChild(scoreLabel); var bubbles = new Array(9).fill().map(() => new Array(9).fill(null)); var gameBoard = new Container(); gameBoard.x = 61; gameBoard.y = 511; self.addChild(gameBoard); var spawnBubble = function () { for (var i = 0; i < 9; i++) { for (var j = 0; j < 9; j++) { var newBubble = new Bubble(bubbles); newBubble.arrayX = i; newBubble.arrayY = j; newBubble.x = i * (newBubble.xWidth + 4) + newBubble.xWidth / 2; newBubble.y = j * (newBubble.xHeight + 4) + newBubble.xHeight / 2; bubbles[i][j] = newBubble; gameBoard.addChild(newBubble); } } }; spawnBubble(); var changes = false; LK.on('tick', function () { var isFirstLoop = true; do { changes = false; for (var i = bubbles.length - 1; i >= 0; i--) { for (var j = bubbles[i].length - 1; j >= 0; j--) { if (bubbles[i][j]) { if (bubbles[i][j].move(isFirstLoop)) { changes = true; } if (bubbles[i][j] && !bubbles[i][j].parent) { bubbles[i][j] = null; } else if (bubbles[i][j] && bubbles[i][j].arrayY < bubbles[0].length - 1 && !bubbles[i][j].parent) { bubbles[i][j] = null; } } } } self.checkTopRowAndInsertBubble(); isFirstLoop = false; } while (changes); if (!self.checkThreeConnectedBubbles()) { if (!self.gameOverCalled) { self.gameOverCalled = true; LK.setTimeout(function () { LK.showGameOver(); }, 3000); } } scoreLabel.setText(LK.score); }); self.checkTopRowAndInsertBubble = function () { for (var i = 0; i < bubbles.length; i++) { if (!bubbles[i][0]) { var newBubble = new Bubble(bubbles); newBubble.arrayX = i; newBubble.arrayY = 0; newBubble.x = i * (newBubble.xWidth + 4) + newBubble.xWidth / 2; newBubble.y = Math.min(...bubbles[i].map(bubble => bubble ? bubble.y : 0)) - newBubble.xHeight - gameBoard.y; bubbles[i][0] = newBubble; gameBoard.addChild(newBubble); break; } } }; self.checkThreeConnectedBubbles = function () { for (var i = 0; i < bubbles.length; i++) { for (var j = 0; j < bubbles[i].length; j++) { if (bubbles[i][j]) { var sameTypeBubbles = bubbles[i][j].getSameTypeBubbles(); if (sameTypeBubbles.length >= 3) { return true; } } } } return false; }; });
var Bubble = Container.expand(function (bubbles) {
var self = Container.call(this);
self.xWidth = 210;
self.xHeight = 210;
self.getSameTypeBubbles = function () {
var sameTypeBubbles = [];
var stack = [this];
while (stack.length) {
var currentBubble = stack.pop();
sameTypeBubbles.push(currentBubble);
var neighbors = this.getNeighbors(currentBubble);
for (var i = 0; i < neighbors.length; i++) {
if (neighbors[i].type === this.type && !sameTypeBubbles.includes(neighbors[i]) && !stack.includes(neighbors[i])) {
stack.push(neighbors[i]);
}
}
}
return sameTypeBubbles;
};
self.arrayX = 0;
self.arrayY = 0;
self.type = Math.floor(Math.random() * Math.min(8, Math.floor(LK.moves / 25) + 3));
var bubbleGraphics = self.createAsset('bubble', 'Bubble Graphics', .5, .5);
var colors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF, 0x00FFFF, 0xFF00FF];
bubbleGraphics.tint = colors[self.type];
self.move = function (isFirstLoop) {
if (isFirstLoop) {
var targetY = self.arrayY * (self.xHeight + 4) + self.xHeight / 2;
if (self.y < targetY) {
self.speed = self.speed || 0;
self.speed += 2;
self.y = Math.min(self.y + self.speed, targetY);
} else {
self.y = targetY;
self.speed = 0;
}
}
if (self.arrayY < bubbles[0].length - 1 && !bubbles[self.arrayX][self.arrayY + 1]) {
bubbles[self.arrayX][self.arrayY] = null;
self.arrayY++;
bubbles[self.arrayX][self.arrayY] = self;
return true;
}
return false;
};
self.on('down', function () {
this.pop(bubbles);
});
self.pop = function () {
var sameTypeBubbles = [];
var stack = [this];
while (stack.length) {
var currentBubble = stack.pop();
sameTypeBubbles.push(currentBubble);
var neighbors = this.getNeighbors(currentBubble);
for (var i = 0; i < neighbors.length; i++) {
if (neighbors[i].type === this.type && !sameTypeBubbles.includes(neighbors[i]) && !stack.includes(neighbors[i])) {
stack.push(neighbors[i]);
}
}
}
if (sameTypeBubbles.length >= 3) {
for (var i = 0; i < sameTypeBubbles.length; i++) {
sameTypeBubbles[i].destroy();
}
LK.score += sameTypeBubbles.length >= 3 ? Math.pow(sameTypeBubbles.length, 2) : 0;
LK.moves++;
}
};
self.getNeighbors = function (bubble) {
var neighbors = [];
var positions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
for (var i = 0; i < positions.length; i++) {
var x = positions[i][0] + bubble.arrayX;
var y = positions[i][1] + bubble.arrayY;
if (x >= 0 && x < bubbles.length && y >= 0 && y < bubbles[0].length && bubbles[x][y]) {
neighbors.push(bubbles[x][y]);
}
}
return neighbors;
};
});
var Game = Container.expand(function () {
var self = Container.call(this);
LK.score = 0;
LK.moves = 0;
LK.stageContainer.setBackgroundColor(0xfff1e7);
var scoreLabel = new Text2('0', {
size: 150,
fill: '#000000',
dropShadow: true,
dropShadowColor: '#ffffff',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6,
font: 'Impact'
});
scoreLabel.anchor.set(0.5, 0);
LK.gui.topCenter.addChild(scoreLabel);
var bubbles = new Array(9).fill().map(() => new Array(9).fill(null));
var gameBoard = new Container();
gameBoard.x = 61;
gameBoard.y = 511;
self.addChild(gameBoard);
var spawnBubble = function () {
for (var i = 0; i < 9; i++) {
for (var j = 0; j < 9; j++) {
var newBubble = new Bubble(bubbles);
newBubble.arrayX = i;
newBubble.arrayY = j;
newBubble.x = i * (newBubble.xWidth + 4) + newBubble.xWidth / 2;
newBubble.y = j * (newBubble.xHeight + 4) + newBubble.xHeight / 2;
bubbles[i][j] = newBubble;
gameBoard.addChild(newBubble);
}
}
};
spawnBubble();
var changes = false;
LK.on('tick', function () {
var isFirstLoop = true;
do {
changes = false;
for (var i = bubbles.length - 1; i >= 0; i--) {
for (var j = bubbles[i].length - 1; j >= 0; j--) {
if (bubbles[i][j]) {
if (bubbles[i][j].move(isFirstLoop)) {
changes = true;
}
if (bubbles[i][j] && !bubbles[i][j].parent) {
bubbles[i][j] = null;
} else if (bubbles[i][j] && bubbles[i][j].arrayY < bubbles[0].length - 1 && !bubbles[i][j].parent) {
bubbles[i][j] = null;
}
}
}
}
self.checkTopRowAndInsertBubble();
isFirstLoop = false;
} while (changes);
if (!self.checkThreeConnectedBubbles()) {
if (!self.gameOverCalled) {
self.gameOverCalled = true;
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
}
scoreLabel.setText(LK.score);
});
self.checkTopRowAndInsertBubble = function () {
for (var i = 0; i < bubbles.length; i++) {
if (!bubbles[i][0]) {
var newBubble = new Bubble(bubbles);
newBubble.arrayX = i;
newBubble.arrayY = 0;
newBubble.x = i * (newBubble.xWidth + 4) + newBubble.xWidth / 2;
newBubble.y = Math.min(...bubbles[i].map(bubble => bubble ? bubble.y : 0)) - newBubble.xHeight - gameBoard.y;
bubbles[i][0] = newBubble;
gameBoard.addChild(newBubble);
break;
}
}
};
self.checkThreeConnectedBubbles = function () {
for (var i = 0; i < bubbles.length; i++) {
for (var j = 0; j < bubbles[i].length; j++) {
if (bubbles[i][j]) {
var sameTypeBubbles = bubbles[i][j].getSameTypeBubbles();
if (sameTypeBubbles.length >= 3) {
return true;
}
}
}
}
return false;
};
});