User prompt
How to play kısmına fişeklerle ilgili bilgi ekle
User prompt
Oyuncu oyunu kazanınca veya kaybedince tüm toplar patlasin pu topların patlaması puana tki etmesin ve yerlerine yeni toplar gelmesin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yatay fişeģi oyundan kaldır
User prompt
Oyun başlangıcında bir tane dikey düzlem fişeği bir tanede yatay düzlem fişeğı bu.unsun ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Patlama efekti ekle fişeklere ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Timeout.tick error: gem.fallTo is not a function' in or related to this line: 'gem.fallTo(newY, function () {' Line Number: 1812
User prompt
Ve bu iki fişek 5 tane topun patlaması sonucu oluşucak
User prompt
Oyuna bir iki adet fişek ekle bu fişeklere tıklandığı zaman biri yatay düzlemdeki tüm topları diğeri ise dikey düzlemdeki topları yokedecek ve bu iki fişek ayrı ayrı assetlere sahip olsun
User prompt
Play time sayacı ana menüde de çalışmaya devam etsin ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Play time sayacı 00:00:00 dan oyuncunun oyunda bulunduğu ana kadar sürecek ve ne kadar oyunda kaldığını hesaplıcak ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Sağ üst köşeye zaman yerleştir bu zaman kişinin oyunda geçirdiği süreyi hesaplıcak bir kronometre olucak ve sadece ana menüde görülebilicek ayrıca oyuncu oyundan çıkarsa zaman durucak oyuna girdiği an kaydedilicek ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Herhangi bir oyun kazanıldığı veya süre bittiğinden dolayı kaybedildiğinde oyun bitmesin ana menüye aktarılsın oyuncu
User prompt
1.level 1000 puan olunca 2.level 2000 3.level 3000 ve diger leveller ayni dogrultuda ilerlicek
User prompt
Levels butonunun içine 1 den 10 a kadar 10 tane buton koy butonların adları 1 den 10 a kadar sırayla
User prompt
Tüm level butonlarını sil
User prompt
Level adlarını "Level 1" "Level 2" "Level 3" "Level 4" "Level 5" "Level 6" "Level 7" "Level 8" "Level 9" "Level 10" olarak degistir 10 bolum var unutma
User prompt
Level adlarını Level 1 Level 2 Level 3 Level 4 Level 5 Level 6 Level 7 Level 8 Level 9 Level 10 olarak değiştir
User prompt
Level ve story mode arasına boşluk koy
User prompt
Story mode un hemen altına Levels Butonu ekle bu butona basınca bir ekran açılıcak o ekranda ise 1 den 10 a kadar üzerinde sayılar yazılı butonlar olucak her butona basıldığinda yeni oyun başlıcak 1 den 9 a kadar oyunlar kazanılınca oyun bitmicek onuncu level kazanıldığı an oyun sona erecek
User prompt
Oyun esnasında toplar patlamalar sonucu birbirlerinin içine geçiyor birbirlerinin içine geçen toplarda hareket edemiyor topların birbirlerinin içine geçmemesini sağla
User prompt
Açılan ekrandaki konuşma baloncuğuna "Thank you very much, I promise that this help will not go unrewarded." Yazsın
User prompt
Oyuncu 5000 puan topladığı an kalan topların kombo yapmasina izin verme
User prompt
Hala birkaç top gözüküyor
User prompt
When the player reaches 5000 points, the game screen will disappear, leaving only the character speech bubble and the menu return button, which are exclusive to story mode.
User prompt
After the player collects 5000 points, only the character speech bubble and the "BACK TO MENU" button will appear on the page that opens
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BlankScreen = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 9,
scaleY: 12
});
background.x = 1024;
background.y = 1366;
background.alpha = 0.95;
self.addChild(background);
var titleText = new Text2('JUST JOKING', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Add some content to the blank screen
var contentText = new Text2('Click the green button', {
size: 80,
fill: 0x00FF00
});
contentText.anchor.set(0.5, 0.5);
contentText.x = 1024;
contentText.y = 800;
self.addChild(contentText);
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
backButton.x = 1024;
backButton.y = 2300;
self.addChild(backButton);
var backText = new Text2('BACK', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 2300;
self.addChild(backText);
backButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideBlankScreen();
};
return self;
});
var FeedbackScreen = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 9,
scaleY: 12
});
background.x = 1024;
background.y = 1366;
background.alpha = 0.95;
self.addChild(background);
var titleText = new Text2('FEEDBACK', {
size: 120,
fill: 0xFFAA00
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Feedback form instructions
var instructions = ['We would love to hear your thoughts!', '', 'What did you think of the game?', '• Was it fun and engaging?', '• Were the controls easy to use?', '• How was the difficulty level?', '• Any suggestions for improvement?', '', 'Thank you for playing MAVUS BABA!', 'Your feedback helps us make better games.', '', 'Contact us at:', 'INSTAGRAM: abdurrahim_scu'];
var yOffset = 650;
for (var i = 0; i < instructions.length; i++) {
var instructionText = new Text2(instructions[i], {
size: instructions[i] === '' ? 30 : instructions[i].startsWith('Contact') || instructions[i].includes('@') ? 50 : instructions[i].startsWith('•') ? 45 : instructions[i] === 'We would love to hear your thoughts!' ? 70 : instructions[i] === 'Thank you for playing MAVUS BABA!' ? 65 : 55,
fill: instructions[i].includes('@') ? 0x44FF44 : instructions[i].startsWith('•') ? 0xFFFF44 : instructions[i] === 'Thank you for playing MAVUS BABA!' ? 0xFFAA00 : 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = yOffset + i * 80;
self.addChild(instructionText);
}
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
backButton.x = 1024;
backButton.y = 2300;
self.addChild(backButton);
var backText = new Text2('BACK', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 2300;
self.addChild(backText);
backButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideFeedbackScreen();
};
return self;
});
var Gem = Container.expand(function () {
var self = Container.call(this);
self.gemType = 0;
self.gridX = 0;
self.gridY = 0;
self.graphics = null;
self.isSelected = false;
self.isMatched = false;
self.isFalling = false;
self.isBomb = false;
self.init = function (type, gx, gy) {
self.gemType = type;
self.gridX = gx;
self.gridY = gy;
var gemTypes = ['gemRed', 'gemBlue', 'gemGreen', 'gemYellow', 'gemPurple', 'gemOrange', 'gemBomb'];
if (type === 6) {
self.isBomb = true;
}
self.graphics = self.attachAsset(gemTypes[type], {
anchorX: 0.5,
anchorY: 0.5
});
self.updatePosition();
};
self.updatePosition = function () {
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var startY = 400;
// Force exact grid alignment to prevent overlapping
var exactX = startX + self.gridX * CELL_SIZE + CELL_SIZE / 2;
var exactY = startY + self.gridY * CELL_SIZE + CELL_SIZE / 2;
self.x = exactX;
self.y = exactY;
};
self.setSelected = function (selected) {
self.isSelected = selected;
if (selected) {
self.graphics.alpha = 0.7;
tween(self.graphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
} else {
self.graphics.alpha = 1.0;
tween(self.graphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
};
self.fallTo = function (newY, callback) {
self.isFalling = true;
self.gridY = newY;
var newPosY = 400 + newY * CELL_SIZE + CELL_SIZE / 2;
// Ensure gem position is properly aligned to grid
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var correctX = startX + self.gridX * CELL_SIZE + CELL_SIZE / 2;
self.x = correctX; // Force correct X position to prevent overlap
tween(self, {
y: newPosY
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
self.isFalling = false;
// Double-check final position alignment
self.x = correctX;
self.y = newPosY;
if (callback) callback();
}
});
};
self.destroy = function () {
self.isMatched = true;
// Play explosion sound effect
LK.getSound('explosion').play();
// Create explosion effect with scaling and rotation
tween(self.graphics, {
scaleX: 1.8,
scaleY: 1.8,
rotation: Math.PI * 2,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
self.explodeBomb = function () {
if (!self.isBomb) return;
// Create dramatic bomb explosion effect
tween(self.graphics, {
scaleX: 3,
scaleY: 3,
rotation: Math.PI * 4,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
// Add pulsing effect before explosion
tween(self.graphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.graphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
// Mark gems in 3x3 area for destruction
var gemsToDestroy = [];
for (var dx = -1; dx <= 1; dx++) {
for (var dy = -1; dy <= 1; dy++) {
var targetX = self.gridX + dx;
var targetY = self.gridY + dy;
if (targetX >= 0 && targetX < GRID_SIZE && targetY >= 0 && targetY < GRID_SIZE) {
if (grid[targetX][targetY] && !grid[targetX][targetY].isMatched) {
gemsToDestroy.push({
x: targetX,
y: targetY
});
}
}
}
}
// Destroy gems with delay and explosion effects
for (var i = 0; i < gemsToDestroy.length; i++) {
(function (destroyData, index) {
LK.setTimeout(function () {
if (grid[destroyData.x][destroyData.y]) {
var gemToExplode = grid[destroyData.x][destroyData.y];
// Play explosion sound for each destroyed gem
LK.getSound('explosion').play();
// Create explosion effect for each gem
tween(gemToExplode.graphics, {
scaleX: 2.0,
scaleY: 2.0,
rotation: Math.PI * (1 + Math.random()),
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (gemToExplode.parent) {
gemToExplode.parent.removeChild(gemToExplode);
}
}
});
grid[destroyData.x][destroyData.y] = null;
}
}, i * 80);
})(gemsToDestroy[i], i);
}
// Add explosion score - in extreme mode, only count gems of the selected type
var scoringGems = gemsToDestroy.length;
if (gameMode === 'extreme') {
scoringGems = 0;
for (var j = 0; j < gemsToDestroy.length; j++) {
var destroyData = gemsToDestroy[j];
if (grid[destroyData.x] && grid[destroyData.x][destroyData.y] && grid[destroyData.x][destroyData.y].gemType === extremeGemType) {
scoringGems++;
}
}
}
var explosionScore = scoringGems * 50 * multiplier;
score += explosionScore;
updateScore();
// Play explosion sound
LK.getSound('explosion').play();
// Wait for all destruction then cascade and fill empty spaces
LK.setTimeout(function () {
cascadeGems();
// Ensure empty spaces are filled after bomb explosion
LK.setTimeout(function () {
fillEmptySpaces();
}, 100);
}, 500);
};
self.down = function (x, y, obj) {
if (!self.isFalling && !isProcessing) {
if (self.isBomb) {
isProcessing = true;
self.explodeBomb();
} else {
selectGem(self);
}
}
};
return self;
});
var HowToPlayScreen = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 9,
scaleY: 12
});
background.x = 1024;
background.y = 1366;
background.alpha = 0.95;
self.addChild(background);
var titleText = new Text2('HOW TO PLAY', {
size: 120,
fill: 0x44FF44
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Game instructions text
var instructions = ['Match 3 or more gems of the same color', 'to clear them and earn points!', '', '• Tap gems to select them', '• Select adjacent gems to swap', '• Create cascades for bonus points', '• Match 4+ gems to create bombs', '• Bombs destroy 3x3 areas', '• Score multiplier increases with points', '• You have 60 seconds to score big!', '', 'EXTREME MODE:', 'Only one gem type scores points!'];
var yOffset = 650;
for (var i = 0; i < instructions.length; i++) {
var instructionText = new Text2(instructions[i], {
size: instructions[i] === '' ? 30 : instructions[i].startsWith('EXTREME') ? 80 : 55,
fill: instructions[i].startsWith('EXTREME') ? 0xFF4444 : instructions[i].startsWith('•') ? 0xFFFF44 : 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = yOffset + i * 90;
self.addChild(instructionText);
}
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
backButton.x = 1024;
backButton.y = 2300;
self.addChild(backButton);
var backText = new Text2('BACK', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 2300;
self.addChild(backText);
backButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideHowToPlayScreen();
};
return self;
});
var LevelsScreen = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 9,
scaleY: 12
});
background.x = 1024;
background.y = 1366;
background.alpha = 0.95;
self.addChild(background);
var titleText = new Text2('SELECT LEVEL', {
size: 120,
fill: 0x00AAFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Create level buttons in a grid layout (2x5)
var levelButtons = [];
var startX = 1024 - 250; // Center the grid
var startY = 700;
var buttonSpacing = 250;
var rowSpacing = 200;
for (var level = 1; level <= 10; level++) {
var col = (level - 1) % 2; // 2 columns
var row = Math.floor((level - 1) / 2); // 5 rows
var levelButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
levelButton.x = startX + col * buttonSpacing;
levelButton.y = startY + row * rowSpacing;
self.addChild(levelButton);
var levelText = new Text2(level.toString(), {
size: 100,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelButton.x;
levelText.y = levelButton.y;
self.addChild(levelText);
// Create closure to capture level number
(function (levelNum, button) {
button.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
currentLevel = levelNum;
gameMode = 'level';
startGame();
};
})(level, levelButton);
levelButtons.push(levelButton);
}
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
backButton.x = 1024;
backButton.y = 2300;
self.addChild(backButton);
var backText = new Text2('BACK', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 2300;
self.addChild(backText);
backButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideLevelsScreen();
};
return self;
});
var OptionsMenu = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 6
});
background.x = 1024;
background.y = 1366;
background.alpha = 0.9;
self.addChild(background);
var titleText = new Text2('Options', {
size: 150,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
self.addChild(titleText);
// Music Volume Toggle Button
var musicVolumeButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 0.6
});
musicVolumeButton.x = 1024;
musicVolumeButton.y = 1000;
self.addChild(musicVolumeButton);
// Get current music volume state
var isMusicOn = storage.musicVolume === undefined ? true : storage.musicVolume > 0;
var musicVolumeText = new Text2(isMusicOn ? 'Music: ON' : 'Music: OFF', {
size: 80,
fill: 0xFFFFFF
});
musicVolumeText.anchor.set(0.5, 0.5);
musicVolumeText.x = 1024;
musicVolumeText.y = 1000;
self.addChild(musicVolumeText);
musicVolumeButton.down = function (x, y, obj) {
// Toggle music volume
var currentVolume = storage.musicVolume === undefined ? 1.0 : storage.musicVolume;
if (currentVolume > 0) {
// Turn music off
storage.musicVolume = 0;
musicVolumeText.setText('Music: OFF');
LK.stopMusic();
} else {
// Turn music on
storage.musicVolume = 1.0;
musicVolumeText.setText('Music: ON');
// Play appropriate music based on game state
if (gameState === 'playing') {
LK.playMusic('background', {
fade: {
start: 0,
end: 0.9,
duration: 500
}
});
} else if (gameState === 'menu' || gameState === 'options') {
LK.playMusic('background', {
fade: {
start: 0,
end: 0.8,
duration: 500
}
});
}
}
};
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
backButton.x = 1024;
backButton.y = 1200;
self.addChild(backButton);
var backText = new Text2('Back', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 1200;
self.addChild(backText);
backButton.down = function (x, y, obj) {
hideOptionsMenu();
};
return self;
});
var StartScreen = Container.expand(function () {
var self = Container.call(this);
// Create animated star background
var stars = [];
for (var i = 0; i < 50; i++) {
var star = self.attachAsset('starBg', {
anchorX: 0.5,
anchorY: 0.5
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.8 + 0.2;
stars.push(star);
// Animate each star with twinkling effect
tween(star, {
alpha: Math.random() * 0.3 + 0.1
}, {
duration: Math.random() * 2000 + 1000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
// Add gentle floating movement
tween(star, {
y: star.y + (Math.random() * 100 - 50)
}, {
duration: Math.random() * 4000 + 2000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
// Create 3D effect with shadow layers
var titleShadow3 = new Text2('MAVUS BABA', {
size: 200,
fill: 0x000000
});
titleShadow3.anchor.set(0.5, 0.5);
titleShadow3.x = 1032;
titleShadow3.y = 808;
self.addChild(titleShadow3);
var titleShadow2 = new Text2('MAVUS BABA', {
size: 200,
fill: 0x333333
});
titleShadow2.anchor.set(0.5, 0.5);
titleShadow2.x = 1028;
titleShadow2.y = 804;
self.addChild(titleShadow2);
var titleShadow1 = new Text2('MAVUS BABA', {
size: 200,
fill: 0x666666
});
titleShadow1.anchor.set(0.5, 0.5);
titleShadow1.x = 1026;
titleShadow1.y = 802;
self.addChild(titleShadow1);
var titleText = new Text2('MAVUS BABA', {
size: 200,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
self.addChild(titleText);
// Add 3D glow animation
tween(titleText, {
alpha: 0.8
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
alpha: 1.0
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
var startButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
startButton.x = 1024;
startButton.y = 1200;
self.addChild(startButton);
// Create 3D effect for Start text
var startShadow2 = new Text2('START', {
size: 100,
fill: 0x000000
});
startShadow2.anchor.set(0.5, 0.5);
startShadow2.x = 1028;
startShadow2.y = 1204;
self.addChild(startShadow2);
var startShadow1 = new Text2('START', {
size: 100,
fill: 0x444444
});
startShadow1.anchor.set(0.5, 0.5);
startShadow1.x = 1026;
startShadow1.y = 1202;
self.addChild(startShadow1);
var startText = new Text2('START', {
size: 100,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 1024;
startText.y = 1200;
self.addChild(startText);
var optionsButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
optionsButton.x = 1024;
optionsButton.y = 1500;
self.addChild(optionsButton);
// Create 3D effect for Options text
var optionsShadow2 = new Text2('OPTIONS', {
size: 100,
fill: 0x000000
});
optionsShadow2.anchor.set(0.5, 0.5);
optionsShadow2.x = 1028;
optionsShadow2.y = 1504;
self.addChild(optionsShadow2);
var optionsShadow1 = new Text2('OPTIONS', {
size: 100,
fill: 0x444444
});
optionsShadow1.anchor.set(0.5, 0.5);
optionsShadow1.x = 1026;
optionsShadow1.y = 1502;
self.addChild(optionsShadow1);
var optionsText = new Text2('OPTIONS', {
size: 100,
fill: 0xFFFFFF
});
optionsText.anchor.set(0.5, 0.5);
optionsText.x = 1024;
optionsText.y = 1500;
self.addChild(optionsText);
// Add "MADE BY MAVUS DONDURMA" text to bottom left corner
var madeByText = new Text2('MADE BY MAVUS DONDURMA', {
size: 60,
fill: 0xCCCCCC
});
madeByText.anchor.set(0, 1);
madeByText.x = 150;
madeByText.y = 2580;
self.addChild(madeByText);
// Add version text under "Made by Mavus Dondurma"
var versionText = new Text2('Version 1.0', {
size: 40,
fill: 0x888888
});
versionText.anchor.set(0, 1);
versionText.x = 150;
versionText.y = 2630;
self.addChild(versionText);
startButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
startGame();
};
optionsButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
showOptionsMenu();
};
var extremeButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
extremeButton.x = 1024;
extremeButton.y = 1800;
self.addChild(extremeButton);
// Create 3D effect for Extreme Mode text
var extremeShadow2 = new Text2('EXTREME MODE', {
size: 80,
fill: 0x000000
});
extremeShadow2.anchor.set(0.5, 0.5);
extremeShadow2.x = 1028;
extremeShadow2.y = 1804;
self.addChild(extremeShadow2);
var extremeShadow1 = new Text2('EXTREME MODE', {
size: 80,
fill: 0x444444
});
extremeShadow1.anchor.set(0.5, 0.5);
extremeShadow1.x = 1026;
extremeShadow1.y = 1802;
self.addChild(extremeShadow1);
var extremeText = new Text2('EXTREME MODE', {
size: 80,
fill: 0xFF4444
});
extremeText.anchor.set(0.5, 0.5);
extremeText.x = 1024;
extremeText.y = 1800;
self.addChild(extremeText);
extremeButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
gameMode = 'extreme';
startGame();
};
var storyButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
storyButton.x = 1024;
storyButton.y = 2100;
self.addChild(storyButton);
// Create 3D effect for Story Mode text
var storyShadow2 = new Text2('STORY MODE', {
size: 80,
fill: 0x000000
});
storyShadow2.anchor.set(0.5, 0.5);
storyShadow2.x = 1028;
storyShadow2.y = 2104;
self.addChild(storyShadow2);
var storyShadow1 = new Text2('STORY MODE', {
size: 80,
fill: 0x444444
});
storyShadow1.anchor.set(0.5, 0.5);
storyShadow1.x = 1026;
storyShadow1.y = 2102;
self.addChild(storyShadow1);
var storyText = new Text2('STORY MODE', {
size: 80,
fill: 0x44FF44
});
storyText.anchor.set(0.5, 0.5);
storyText.x = 1024;
storyText.y = 2100;
self.addChild(storyText);
storyButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
// Hide all start screen elements
self.visible = false;
showStoryMode();
};
var levelsButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
levelsButton.x = 1024;
levelsButton.y = 2300;
self.addChild(levelsButton);
// Create 3D effect for Levels text
var levelsShadow2 = new Text2('LEVELS', {
size: 80,
fill: 0x000000
});
levelsShadow2.anchor.set(0.5, 0.5);
levelsShadow2.x = 1028;
levelsShadow2.y = 2304;
self.addChild(levelsShadow2);
var levelsShadow1 = new Text2('LEVELS', {
size: 80,
fill: 0x444444
});
levelsShadow1.anchor.set(0.5, 0.5);
levelsShadow1.x = 1026;
levelsShadow1.y = 2302;
self.addChild(levelsShadow1);
var levelsText = new Text2('LEVELS', {
size: 80,
fill: 0x00AAFF
});
levelsText.anchor.set(0.5, 0.5);
levelsText.x = 1024;
levelsText.y = 2300;
self.addChild(levelsText);
levelsButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
showLevelsScreen();
};
// How to Play button at bottom right
var howToPlayButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
howToPlayButton.x = 1700;
howToPlayButton.y = 2400;
self.addChild(howToPlayButton);
// Create 3D effect for How to Play text
var howToPlayShadow2 = new Text2('HOW TO PLAY', {
size: 60,
fill: 0x000000
});
howToPlayShadow2.anchor.set(0.5, 0.5);
howToPlayShadow2.x = 1704;
howToPlayShadow2.y = 2404;
self.addChild(howToPlayShadow2);
var howToPlayShadow1 = new Text2('HOW TO PLAY', {
size: 60,
fill: 0x444444
});
howToPlayShadow1.anchor.set(0.5, 0.5);
howToPlayShadow1.x = 1702;
howToPlayShadow1.y = 2402;
self.addChild(howToPlayShadow1);
var howToPlayText = new Text2('HOW TO PLAY', {
size: 60,
fill: 0x44FF44
});
howToPlayText.anchor.set(0.5, 0.5);
howToPlayText.x = 1700;
howToPlayText.y = 2400;
self.addChild(howToPlayText);
howToPlayButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
showHowToPlayScreen();
};
// Feedback button at bottom right under How to Play
var feedbackButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
feedbackButton.x = 1700;
feedbackButton.y = 2550;
self.addChild(feedbackButton);
// Create 3D effect for Feedback text
var feedbackShadow2 = new Text2('FEEDBACK', {
size: 60,
fill: 0x000000
});
feedbackShadow2.anchor.set(0.5, 0.5);
feedbackShadow2.x = 1704;
feedbackShadow2.y = 2554;
self.addChild(feedbackShadow2);
var feedbackShadow1 = new Text2('FEEDBACK', {
size: 60,
fill: 0x444444
});
feedbackShadow1.anchor.set(0.5, 0.5);
feedbackShadow1.x = 1702;
feedbackShadow1.y = 2552;
self.addChild(feedbackShadow1);
var feedbackText = new Text2('FEEDBACK', {
size: 60,
fill: 0xFFAA00
});
feedbackText.anchor.set(0.5, 0.5);
feedbackText.x = 1700;
feedbackText.y = 2550;
self.addChild(feedbackText);
feedbackButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
showFeedbackScreen();
};
// Green smiley ball button above how to play button
var greenButton = LK.getAsset('greenSmileyBall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
greenButton.x = 1600;
greenButton.y = 2200;
self.addChild(greenButton);
greenButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
// Stop the continuous shake effect
stopContinuousShake();
// Flash the screen green to indicate the button was clicked
LK.effects.flashScreen(0x00FF00, 1000);
// Create a visual feedback effect
tween(greenButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(greenButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
}
});
};
// Blank button with red smiley ball
var blankButton = LK.getAsset('redSmileyBall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
blankButton.x = 1800;
blankButton.y = 2200;
self.addChild(blankButton);
// Face features removed - now just a plain red ball
blankButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
// Start continuous screen shake effect
startContinuousShake();
showBlankScreen();
};
return self;
});
var StoryModeScreen = Container.expand(function () {
var self = Container.call(this);
// Create animated star background (same as start screen but dimmer)
var stars = [];
for (var i = 0; i < 30; i++) {
var star = self.attachAsset('starBg', {
anchorX: 0.5,
anchorY: 0.5
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.3 + 0.1; // Dimmer stars
stars.push(star);
// Animate each star with gentle twinkling
tween(star, {
alpha: Math.random() * 0.2 + 0.05
}, {
duration: Math.random() * 3000 + 2000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
// Add the alien character at bottom of screen
var alien = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 1,
scaleX: 3,
scaleY: 3
});
alien.x = 1024;
alien.y = 2400;
// Add gentle floating animation to alien
tween(alien, {
y: alien.y - 20
}, {
duration: 2000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
// Add larger speech bubble background
var speechBubble = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 1,
scaleX: 6,
scaleY: 2.5,
alpha: 0.9
});
speechBubble.x = 1024;
speechBubble.y = 1200;
self.addChild(speechBubble);
// Add speech text - split into multiple lines for better readability
var speechLines = ["Hello, I've been stuck in this", "universe for a long time.", "My chance of escape depends on you.", "", "If you win this game, I can escape,", "but remember, you only have", "one chance."];
var speechTexts = [];
for (var i = 0; i < speechLines.length; i++) {
if (speechLines[i] === '') {
continue; // Skip empty lines for spacing
}
var speechText = new Text2(speechLines[i], {
size: 60,
fill: 0xFFFFFF
});
speechText.anchor.set(0.5, 0.5);
speechText.x = 1024;
speechText.y = 680 + i * 70; // Position each line with 70px spacing
self.addChild(speechText);
speechTexts.push(speechText);
}
// Add back button (invisible initially, appears after a delay) - positioned at bottom left
var backButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6,
alpha: 0
});
backButton.x = 700;
backButton.y = 2600;
self.addChild(backButton);
var backText = new Text2('BACK', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 700;
backText.y = 2600;
backText.alpha = 0;
self.addChild(backText);
// Add Go! button next to back button - positioned at bottom right
var goButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6,
alpha: 0
});
goButton.x = 1348;
goButton.y = 2600;
self.addChild(goButton);
var goText = new Text2('GO!', {
size: 80,
fill: 0x44FF44
});
goText.anchor.set(0.5, 0.5);
goText.x = 1348;
goText.y = 2600;
goText.alpha = 0;
self.addChild(goText);
// Fade in both buttons after 3 seconds
LK.setTimeout(function () {
tween(backButton, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
tween(backText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
tween(goButton, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
tween(goText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}, 3000);
backButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideStoryMode();
};
goButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
// Hide story mode screen completely
self.visible = false;
gameMode = 'story';
startGame();
};
return self;
});
var StorySuccessScreen = Container.expand(function () {
var self = Container.call(this);
// Create animated star background (same as story mode but brighter)
var stars = [];
for (var i = 0; i < 40; i++) {
var star = self.attachAsset('starBg', {
anchorX: 0.5,
anchorY: 0.5
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.5 + 0.3; // Brighter stars
stars.push(star);
// Animate each star with twinkling effect
tween(star, {
alpha: Math.random() * 0.3 + 0.2
}, {
duration: Math.random() * 2000 + 1000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
// Add the alien character at bottom of screen
var alien = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 1,
scaleX: 3,
scaleY: 3
});
alien.x = 1024;
alien.y = 2400;
// Add celebratory floating animation to alien
tween(alien, {
y: alien.y - 30
}, {
duration: 1500,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
// Add larger speech bubble background
var speechBubble = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 1,
scaleX: 6,
scaleY: 2.5,
alpha: 0.9
});
speechBubble.x = 1024;
speechBubble.y = 1200;
self.addChild(speechBubble);
// Add speech text in the speech bubble
var speechText = new Text2('Thank you very much, I promise that this help will not go unrewarded.', {
size: 60,
fill: 0xFFFFFF
});
speechText.anchor.set(0.5, 0.5);
speechText.x = 1024;
speechText.y = 850;
self.addChild(speechText);
var speechTexts = [];
speechTexts.push(speechText);
// Add back to menu button at bottom center
var menuButton = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.7,
alpha: 0
});
menuButton.x = 1024;
menuButton.y = 2600;
self.addChild(menuButton);
var menuText = new Text2('BACK TO MENU', {
size: 80,
fill: 0xFFFFFF
});
menuText.anchor.set(0.5, 0.5);
menuText.x = 1024;
menuText.y = 2600;
menuText.alpha = 0;
self.addChild(menuText);
// Fade in button after 4 seconds
LK.setTimeout(function () {
tween(menuButton, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
tween(menuText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}, 4000);
menuButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
hideStorySuccessScreen();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var GRID_SIZE = 8;
var CELL_SIZE = 200;
var GEM_TYPES = 6;
var BOMB_TYPE = 6;
var grid = [];
var selectedGem = null;
var score = 0;
var multiplier = 1;
var isProcessing = false;
var cascadeCount = 0;
var gameTimeLeft = 60;
var gameTimer = null;
var timerTxt = null;
var gameMode = 'normal'; // 'normal', 'extreme', 'story', or 'level'
var currentLevel = 1;
var levelsScreen = null;
var extremeGemType = 0; // Only this gem type scores points in extreme mode
var extremeGemTxt = null;
// Game state management
var gameState = 'menu'; // 'menu', 'playing', 'options'
var startScreen = null;
var optionsMenu = null;
var gameElements = [];
// Spaceship for background animation
var spaceship = null;
// UFO for background animation
var ufo = null;
// Score display will be created when game starts
var scoreTxt = null;
var multiplierTxt = null;
// Initialize grid
function initializeGrid() {
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var startY = 400;
// Create background cells
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
var cell = LK.getAsset('gridCell', {
anchorX: 0,
anchorY: 0,
alpha: 0.95
});
cell.x = startX + x * CELL_SIZE;
cell.y = startY + y * CELL_SIZE;
game.addChild(cell);
}
}
// Initialize grid array
for (var x = 0; x < GRID_SIZE; x++) {
grid[x] = [];
for (var y = 0; y < GRID_SIZE; y++) {
grid[x][y] = null;
}
}
// Fill grid with gems
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
createGem(x, y);
}
}
// Remove initial matches
removeInitialMatches();
}
function createGem(x, y) {
var gem = new Gem();
var gemType = Math.floor(Math.random() * GEM_TYPES);
gem.init(gemType, x, y);
grid[x][y] = gem;
game.addChild(gem);
return gem;
}
function removeInitialMatches() {
var hasMatches = true;
var attempts = 0;
while (hasMatches && attempts < 50) {
hasMatches = false;
attempts++;
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x][y] && hasMatchAt(x, y)) {
// Regenerate this gem
var oldGem = grid[x][y];
if (oldGem.parent) {
oldGem.parent.removeChild(oldGem);
}
createGem(x, y);
hasMatches = true;
}
}
}
}
}
function selectGem(gem) {
if (selectedGem === gem) {
// Deselect
selectedGem.setSelected(false);
selectedGem = null;
return;
}
if (selectedGem === null) {
// First selection
selectedGem = gem;
gem.setSelected(true);
} else {
// Second selection - check if adjacent
if (areAdjacent(selectedGem, gem)) {
swapGems(selectedGem, gem);
}
selectedGem.setSelected(false);
selectedGem = null;
}
}
function areAdjacent(gem1, gem2) {
var dx = Math.abs(gem1.gridX - gem2.gridX);
var dy = Math.abs(gem1.gridY - gem2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
function swapGems(gem1, gem2) {
if (isProcessing) return;
isProcessing = true;
// Store positions
var tempX = gem1.gridX;
var tempY = gem1.gridY;
// Update grid positions
gem1.gridX = gem2.gridX;
gem1.gridY = gem2.gridY;
gem2.gridX = tempX;
gem2.gridY = tempY;
// Update grid array
grid[gem1.gridX][gem1.gridY] = gem1;
grid[gem2.gridX][gem2.gridY] = gem2;
// Animate swap
var gem1NewX = gem1.x;
var gem1NewY = gem1.y;
gem1.updatePosition();
var gem2NewX = gem2.x;
var gem2NewY = gem2.y;
gem2.updatePosition();
gem1.x = gem2NewX;
gem1.y = gem2NewY;
gem2.x = gem1NewX;
gem2.y = gem1NewY;
tween(gem1, {
x: gem1NewX,
y: gem1NewY
}, {
duration: 300
});
tween(gem2, {
x: gem2NewX,
y: gem2NewY
}, {
duration: 300,
onFinish: function onFinish() {
checkForMatches();
}
});
}
function hasMatchAt(x, y) {
if (!grid[x] || !grid[x][y]) return false;
var gemType = grid[x][y].gemType;
// Check horizontal
var hCount = 1;
// Check left
for (var i = x - 1; i >= 0 && grid[i][y] && grid[i][y].gemType === gemType; i--) {
hCount++;
}
// Check right
for (var i = x + 1; i < GRID_SIZE && grid[i][y] && grid[i][y].gemType === gemType; i++) {
hCount++;
}
if (hCount >= 3) return true;
// Check vertical
var vCount = 1;
// Check up
for (var i = y - 1; i >= 0 && grid[x][i] && grid[x][i].gemType === gemType; i--) {
vCount++;
}
// Check down
for (var i = y + 1; i < GRID_SIZE && grid[x][i] && grid[x][i].gemType === gemType; i++) {
vCount++;
}
return vCount >= 3;
}
function checkForMatches() {
var matches = [];
// Find all matches
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x][y] && hasMatchAt(x, y)) {
matches.push({
x: x,
y: y
});
}
}
}
if (matches.length > 0) {
cascadeCount++;
LK.getSound('match').play();
// Calculate score - in extreme mode, only count matches of the selected gem type
var scoringMatches = matches;
if (gameMode === 'extreme') {
scoringMatches = [];
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
if (grid[match.x] && grid[match.x][match.y] && grid[match.x][match.y].gemType === extremeGemType) {
scoringMatches.push(match);
}
}
}
var points = scoringMatches.length * 10 * multiplier * cascadeCount;
score += points;
updateScore();
// Create bomb if match is 4 or more gems
var shouldCreateBomb = matches.length >= 4;
var bombPosition = null;
if (shouldCreateBomb && matches.length > 0) {
bombPosition = matches[Math.floor(Math.random() * matches.length)];
}
// Mark matched gems for destruction
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
if (grid[match.x][match.y]) {
grid[match.x][match.y].destroy();
grid[match.x][match.y] = null;
}
}
// Create bomb after destruction
if (shouldCreateBomb && bombPosition) {
LK.setTimeout(function () {
if (grid[bombPosition.x][bombPosition.y] === null) {
var bomb = new Gem();
bomb.init(BOMB_TYPE, bombPosition.x, bombPosition.y);
grid[bombPosition.x][bombPosition.y] = bomb;
game.addChild(bomb);
// Animate bomb creation
bomb.graphics.scaleX = 0;
bomb.graphics.scaleY = 0;
tween(bomb.graphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut
});
}
}, 200);
}
// Wait for destruction animation then cascade
LK.setTimeout(function () {
cascadeGems();
}, 400);
} else {
cascadeCount = 0;
isProcessing = false;
}
}
function cascadeGems() {
var needsCascade = false;
var fallPromises = 0;
// Process each column from left to right
for (var x = 0; x < GRID_SIZE; x++) {
// Compact the column - move all existing gems down to fill gaps
var compactedGems = [];
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x][y] !== null) {
compactedGems.push(grid[x][y]);
grid[x][y] = null;
}
}
// Place compacted gems at the bottom of the column
var startY = GRID_SIZE - compactedGems.length;
for (var i = 0; i < compactedGems.length; i++) {
var gem = compactedGems[i];
var newY = startY + i;
var oldY = gem.gridY;
if (oldY !== newY) {
needsCascade = true;
grid[x][newY] = gem;
// Ensure gem X position is correct before falling to prevent overlap
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var exactX = startX + x * CELL_SIZE + CELL_SIZE / 2;
gem.x = exactX; // Force correct X position immediately
fallPromises++;
gem.fallTo(newY, function () {
fallPromises--;
if (fallPromises === 0) {
// Always fill empty spaces after cascading
fillEmptySpaces();
}
});
} else {
// Gem doesn't need to move - ensure correct position
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var exactX = startX + x * CELL_SIZE + CELL_SIZE / 2;
var exactY = 400 + newY * CELL_SIZE + CELL_SIZE / 2;
gem.x = exactX;
gem.y = exactY;
grid[x][newY] = gem;
}
}
}
// Always ensure empty spaces are filled, regardless of cascade
fillEmptySpaces();
if (needsCascade) {
LK.getSound('cascade').play();
}
}
function fillEmptySpaces() {
var newGemsCreated = 0;
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x][y] === null) {
createGem(x, y);
newGemsCreated++;
// Calculate exact positions to prevent overlapping
var startX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var exactX = startX + x * CELL_SIZE + CELL_SIZE / 2;
var exactY = 400 + y * CELL_SIZE + CELL_SIZE / 2;
// Start gem above the screen and animate it falling
var startY = 400 - newGemsCreated * CELL_SIZE;
grid[x][y].x = exactX; // Force correct X position
grid[x][y].y = startY;
tween(grid[x][y], {
y: exactY
}, {
duration: 500 + newGemsCreated * 50,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Ensure final position is exactly aligned
if (grid[x] && grid[x][y]) {
grid[x][y].x = exactX;
grid[x][y].y = exactY;
}
}
});
}
}
}
// Check for new matches after a delay
LK.setTimeout(function () {
checkForMatches();
}, 600);
}
function updateScore() {
if (scoreTxt) {
scoreTxt.setText('Score: ' + score);
}
// Update multiplier based on score
var newMultiplier = 1;
if (score >= 2500) newMultiplier = 5;else if (score >= 1000) newMultiplier = 4;else if (score >= 500) newMultiplier = 3;else if (score >= 100) newMultiplier = 2;
if (newMultiplier !== multiplier) {
multiplier = newMultiplier;
if (multiplierTxt) {
multiplierTxt.setText('Multiplier: x' + multiplier);
}
LK.effects.flashScreen(0x00ff00, 500);
}
// Win condition - check if we're in story mode or levels mode
if (score >= 5000) {
if (gameMode === 'story') {
// Clear game timer
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Stop all gem processing to prevent further combos
isProcessing = true;
// Show story success screen
showStorySuccessScreen();
} else if (gameMode === 'level') {
// Clear game timer
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Stop all gem processing to prevent further combos
isProcessing = true;
if (currentLevel < 10) {
// Levels 1-9: Continue to next level
currentLevel++;
// Brief pause then start next level
LK.setTimeout(function () {
startGame();
}, 1000);
} else {
// Level 10: Game ends
LK.showYouWin();
}
} else {
LK.showYouWin();
}
}
}
// Start continuous shake when game opens
startContinuousShake();
// Initialize start screen instead of game
showStartScreen();
game.update = function () {
// Game loop - handle any continuous updates here
};
function showStartScreen() {
gameState = 'menu';
gameMode = 'normal'; // Reset to normal mode when returning to menu
if (startScreen) {
game.removeChild(startScreen);
}
// Clear game timer if it exists
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Clear all game elements when returning to menu
for (var i = 0; i < gameElements.length; i++) {
if (gameElements[i].parent) {
gameElements[i].parent.removeChild(gameElements[i]);
}
}
gameElements = [];
// Clear grid elements
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x] && grid[x][y] && grid[x][y].parent) {
grid[x][y].parent.removeChild(grid[x][y]);
}
}
}
// Clear all children from game to ensure clean slate
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
startScreen = new StartScreen();
game.addChild(startScreen);
// Start spaceship animation
createSpaceship();
// Start UFO animation
createUfo();
// Start background music for start screen
var musicVolume = storage.musicVolume === undefined ? 1.0 : storage.musicVolume;
if (musicVolume > 0) {
LK.playMusic('background', {
fade: {
start: 0,
end: musicVolume * 0.8,
duration: 2000
}
});
}
}
function startGame() {
gameState = 'playing';
if (startScreen) {
game.removeChild(startScreen);
startScreen = null;
}
if (optionsMenu) {
game.removeChild(optionsMenu);
optionsMenu = null;
}
// Clear any existing game elements
for (var i = 0; i < gameElements.length; i++) {
if (gameElements[i].parent) {
gameElements[i].parent.removeChild(gameElements[i]);
}
}
gameElements = [];
// Reset game state
grid = [];
selectedGem = null;
score = 0;
multiplier = 1;
isProcessing = false;
cascadeCount = 0;
gameTimeLeft = 60;
// Set up extreme mode if selected
if (gameMode === 'extreme') {
extremeGemType = Math.floor(Math.random() * GEM_TYPES);
// Start continuous shake for extreme mode
startContinuousShake();
}
// Clear existing timer
if (gameTimer) {
LK.clearInterval(gameTimer);
}
// Start countdown timer
gameTimer = LK.setInterval(function () {
gameTimeLeft--;
if (timerTxt) {
timerTxt.setText('Time: ' + gameTimeLeft);
}
// Change color when time is running low
if (gameTimeLeft <= 10 && timerTxt) {
timerTxt.fill = 0xFF0000;
} else if (gameTimeLeft <= 30 && timerTxt) {
timerTxt.fill = 0xFF8800;
}
// Game over when time runs out
if (gameTimeLeft <= 0) {
LK.clearInterval(gameTimer);
gameTimer = null;
LK.showGameOver();
}
}, 1000);
// Create animated star background for gameplay
for (var i = 0; i < 50; i++) {
var star = LK.getAsset('starBg', {
anchorX: 0.5,
anchorY: 0.5
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.8 + 0.2;
game.addChild(star);
gameElements.push(star);
// Animate each star with twinkling effect
tween(star, {
alpha: Math.random() * 0.3 + 0.1
}, {
duration: Math.random() * 2000 + 1000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
// Add gentle floating movement
tween(star, {
y: star.y + (Math.random() * 100 - 50)
}, {
duration: Math.random() * 4000 + 2000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
// Initialize score display
scoreTxt = new Text2('Score: 0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(scoreTxt);
gameElements.push(scoreTxt);
multiplierTxt = new Text2('Multiplier: x1', {
size: 70,
fill: 0xFFFF00
});
multiplierTxt.anchor.set(0.5, 1);
multiplierTxt.y = -120;
LK.gui.bottom.addChild(multiplierTxt);
gameElements.push(multiplierTxt);
timerTxt = new Text2('Time: 60', {
size: 100,
fill: 0xFF4444
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
gameElements.push(timerTxt);
// Add extreme mode indicator if in extreme mode
if (gameMode === 'extreme') {
var gemTypeNames = ['Red', 'Blue', 'Green', 'Yellow', 'Purple', 'Orange'];
extremeGemTxt = new Text2('EXTREME MODE - Only ' + gemTypeNames[extremeGemType] + ' gems score!', {
size: 60,
fill: 0xFF4444
});
extremeGemTxt.anchor.set(0.5, 0);
extremeGemTxt.y = 120;
LK.gui.top.addChild(extremeGemTxt);
gameElements.push(extremeGemTxt);
}
// Add level indicator if in levels mode
if (gameMode === 'level') {
var levelIndicator = new Text2('LEVEL ' + currentLevel, {
size: 80,
fill: 0x00AAFF
});
levelIndicator.anchor.set(0.5, 0);
levelIndicator.y = 120;
LK.gui.top.addChild(levelIndicator);
gameElements.push(levelIndicator);
}
// Create menu button
var menuButton = LK.getAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
menuButton.x = 1800;
menuButton.y = 200;
menuButton.alpha = 0.8;
game.addChild(menuButton);
gameElements.push(menuButton);
// Create menu button text
var menuButtonText = new Text2('MENU', {
size: 60,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.x = 1800;
menuButtonText.y = 200;
game.addChild(menuButtonText);
gameElements.push(menuButtonText);
// Add click handler for menu button
menuButton.down = function (x, y, obj) {
// Clear game timer
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Return to main menu
showStartScreen();
};
// Initialize the game
initializeGrid();
updateScore();
// Apply sound volume settings
updateAllSoundVolumes();
// Start background music with current volume setting
var musicVolume = storage.musicVolume === undefined ? 1.0 : storage.musicVolume;
if (musicVolume > 0) {
LK.playMusic('background', {
fade: {
start: 0,
end: musicVolume * 0.9,
duration: 1000
}
});
}
// Continue spaceship animation during gameplay
if (!spaceship || !spaceship.parent) {
createSpaceship();
}
// Continue UFO animation during gameplay
if (!ufo || !ufo.parent) {
createUfo();
}
}
function showOptionsMenu() {
gameState = 'options';
if (optionsMenu) {
game.removeChild(optionsMenu);
}
optionsMenu = new OptionsMenu();
game.addChild(optionsMenu);
}
function hideOptionsMenu() {
gameState = 'menu';
if (optionsMenu) {
game.removeChild(optionsMenu);
optionsMenu = null;
}
}
function createSpaceship() {
if (spaceship) {
game.removeChild(spaceship);
}
spaceship = LK.getAsset('spaceship', {
anchorX: 0.5,
anchorY: 0.5
});
// Start from left side, random Y position
spaceship.x = -100;
spaceship.y = Math.random() * 1800 + 400; // Random position between 400 and 2200
spaceship.alpha = 0.3;
game.addChild(spaceship);
// Animate spaceship moving across screen
tween(spaceship, {
x: 2148 // Move to right edge
}, {
duration: Math.random() * 8000 + 12000,
// 12-20 seconds to cross screen
easing: tween.linear,
onFinish: function onFinish() {
// When spaceship reaches right edge, create a new one
LK.setTimeout(function () {
createSpaceship();
}, Math.random() * 5000 + 2000); // Wait 2-7 seconds before next spaceship
}
});
}
function createUfo() {
if (ufo) {
game.removeChild(ufo);
}
ufo = LK.getAsset('ufo', {
anchorX: 0.5,
anchorY: 0.5
});
// Start from right side, random Y position
ufo.x = 2148;
ufo.y = Math.random() * 1200 + 300; // Random position between 300 and 1500
ufo.alpha = 0.4;
game.addChild(ufo);
// Animate UFO moving across screen from right to left
tween(ufo, {
x: -150 // Move to left edge
}, {
duration: Math.random() * 10000 + 15000,
// 15-25 seconds to cross screen
easing: tween.linear,
onFinish: function onFinish() {
// When UFO reaches left edge, create a new one
LK.setTimeout(function () {
createUfo();
}, Math.random() * 8000 + 3000); // Wait 3-11 seconds before next UFO
}
});
// Add subtle bobbing motion to UFO
tween(ufo, {
y: ufo.y + 30
}, {
duration: 2000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
var howToPlayScreen = null;
function showHowToPlayScreen() {
gameState = 'howtoplay';
if (howToPlayScreen) {
game.removeChild(howToPlayScreen);
}
howToPlayScreen = new HowToPlayScreen();
game.addChild(howToPlayScreen);
}
function hideHowToPlayScreen() {
gameState = 'menu';
if (howToPlayScreen) {
game.removeChild(howToPlayScreen);
howToPlayScreen = null;
}
}
var feedbackScreen = null;
function showFeedbackScreen() {
gameState = 'feedback';
if (feedbackScreen) {
game.removeChild(feedbackScreen);
}
feedbackScreen = new FeedbackScreen();
game.addChild(feedbackScreen);
}
function hideFeedbackScreen() {
gameState = 'menu';
if (feedbackScreen) {
game.removeChild(feedbackScreen);
feedbackScreen = null;
}
}
var blankScreen = null;
var isShaking = false;
var shakeTimer = null;
function startContinuousShake() {
if (isShaking) return; // Already shaking
isShaking = true;
function performShake() {
if (!isShaking) return;
var shakeIntensity = 15;
var shakeX = (Math.random() - 0.5) * shakeIntensity;
var shakeY = (Math.random() - 0.5) * shakeIntensity;
tween(game, {
x: shakeX,
y: shakeY
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
// Continue shaking if still enabled
if (isShaking) {
shakeTimer = LK.setTimeout(performShake, 20);
} else {
// Reset position when shaking stops
tween(game, {
x: 0,
y: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
}
});
}
performShake();
}
function stopContinuousShake() {
isShaking = false;
if (shakeTimer) {
LK.clearTimeout(shakeTimer);
shakeTimer = null;
}
}
function showBlankScreen() {
gameState = 'blank';
if (blankScreen) {
game.removeChild(blankScreen);
}
blankScreen = new BlankScreen();
game.addChild(blankScreen);
}
function hideBlankScreen() {
gameState = 'menu';
if (blankScreen) {
game.removeChild(blankScreen);
blankScreen = null;
}
}
var storyModeScreen = null;
function showStoryMode() {
gameState = 'story';
if (storyModeScreen) {
game.removeChild(storyModeScreen);
}
storyModeScreen = new StoryModeScreen();
game.addChild(storyModeScreen);
}
function hideStoryMode() {
gameState = 'menu';
if (storyModeScreen) {
game.removeChild(storyModeScreen);
storyModeScreen = null;
}
// Show start screen again when returning from story mode
if (startScreen) {
startScreen.visible = true;
}
}
var storySuccessScreen = null;
function showStorySuccessScreen() {
gameState = 'story_success';
// Hide all game elements first
for (var i = 0; i < gameElements.length; i++) {
if (gameElements[i].parent) {
gameElements[i].parent.removeChild(gameElements[i]);
}
}
gameElements = [];
// Clear grid elements
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (grid[x] && grid[x][y] && grid[x][y].parent) {
grid[x][y].parent.removeChild(grid[x][y]);
}
}
}
// Clear spaceship and UFO if they exist
if (spaceship && spaceship.parent) {
spaceship.parent.removeChild(spaceship);
spaceship = null;
}
if (ufo && ufo.parent) {
ufo.parent.removeChild(ufo);
ufo = null;
}
// Clear all game children to ensure clean slate
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
if (storySuccessScreen) {
game.removeChild(storySuccessScreen);
}
storySuccessScreen = new StorySuccessScreen();
game.addChild(storySuccessScreen);
}
function hideStorySuccessScreen() {
gameState = 'menu';
if (storySuccessScreen) {
game.removeChild(storySuccessScreen);
storySuccessScreen = null;
}
// Return to main menu
showStartScreen();
}
function showLevelsScreen() {
gameState = 'levels';
if (levelsScreen) {
game.removeChild(levelsScreen);
}
levelsScreen = new LevelsScreen();
game.addChild(levelsScreen);
}
function hideLevelsScreen() {
gameState = 'menu';
if (levelsScreen) {
game.removeChild(levelsScreen);
levelsScreen = null;
}
}
function updateAllSoundVolumes() {
var musicVolume = storage.musicVolume === undefined ? 1.0 : storage.musicVolume;
var soundEffectsVolume = storage.soundEffectsVolume === undefined ? 1.0 : storage.soundEffectsVolume;
// Re-initialize sound assets with new volumes
// Update background music volume if it's playing
if (musicVolume > 0) {
if (gameState === 'playing') {
LK.stopMusic();
LK.playMusic('background', {
fade: {
start: 0,
end: musicVolume * 0.9,
duration: 500
}
});
} else if (gameState === 'menu') {
LK.stopMusic();
LK.playMusic('background', {
fade: {
start: 0,
end: musicVolume * 0.8,
duration: 500
}
});
}
} else {
LK.stopMusic();
}
} ===================================================================
--- original.js
+++ change.js
@@ -814,34 +814,34 @@
scaleX: 2,
scaleY: 0.8
});
levelsButton.x = 1024;
- levelsButton.y = 2250;
+ levelsButton.y = 2300;
self.addChild(levelsButton);
// Create 3D effect for Levels text
var levelsShadow2 = new Text2('LEVELS', {
size: 80,
fill: 0x000000
});
levelsShadow2.anchor.set(0.5, 0.5);
levelsShadow2.x = 1028;
- levelsShadow2.y = 2254;
+ levelsShadow2.y = 2304;
self.addChild(levelsShadow2);
var levelsShadow1 = new Text2('LEVELS', {
size: 80,
fill: 0x444444
});
levelsShadow1.anchor.set(0.5, 0.5);
levelsShadow1.x = 1026;
- levelsShadow1.y = 2252;
+ levelsShadow1.y = 2302;
self.addChild(levelsShadow1);
var levelsText = new Text2('LEVELS', {
size: 80,
fill: 0x00AAFF
});
levelsText.anchor.set(0.5, 0.5);
levelsText.x = 1024;
- levelsText.y = 2250;
+ levelsText.y = 2300;
self.addChild(levelsText);
levelsButton.down = function (x, y, obj) {
LK.getSound('buttonClick').play();
showLevelsScreen();
red smiley ball. In-Game asset. 2d. High contrast. No shadows
Blue smiley ball. In-Game asset. 2d. High contrast. No shadows
Green smiley face. In-Game asset. 2d. High contrast. No shadows
Orange smiley ball. In-Game asset. 2d. High contrast. No shadows
Purple smiley ball. In-Game asset. 2d. High contrast. No shadows
Yellow smiley ball. In-Game asset. 2d. High contrast. No shadows
Bomba. In-Game asset. 2d. High contrast. No shadows
Star. In-Game asset. 2d. High contrast. No shadows
Spaceship. In-Game asset. 2d. High contrast. No shadows
A UFO with aliens inside. In-Game asset. 2d. High contrast. No shadows
Red smiley face. In-Game asset. 2d. High contrast. No shadows
Green smiley ball. In-Game asset. 2d. High contrast. No shadows
Male Cyber Character. In-Game asset. 2d. High contrast. No shadows
Vertical rocket. In-Game asset. 2d. High contrast. No shadows