User prompt
Bu butonun hemen üstüne yeşil gülen top görünümlü tıklandıgı zaman bir sekme açılan buton ekle
User prompt
Bu butona tıklandığında açılan sayfadaki Yeşil butona tıkla yazısını kaldır ve "Click the green button" ekle
User prompt
Bu buton açıldığinda çıkan sayfadaki başlığa "JUST JOKING" yaz ve bu başlığin altına Yeşil butona tıkla yazısi ekle
User prompt
Oyun açıldığındada devam etsin bu sarsılma ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bu ekran sarsılması oyuncunun oyundan ayrıldigı zamana kadar sürsün ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bu butona tıklayınca ekran sarsılmaya başlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bu butondaki yüzü sil
User prompt
Bu butonun görüntüsünü kırmızı gülen bir topla değiştir
User prompt
Bu butona basınca tıpkı diger butonlar gibi bir sekme açılsın
User prompt
Ana menüye bir tane Buton ekle üstünde herhangi bir yazı bulunmucak şekilde
User prompt
Made by Mavus dondurma yazisının altına version yazan bir yazı ekle
User prompt
Create a short sci-fi explosion sound effect that plays when a colored object is destroyed. The sound should be cosmic and synthetic, like a laser or star implosion. It should be punchy, fast, and futuristic — something you'd hear in a space-themed arcade game
User prompt
add a ufo to the background
User prompt
Add a UFO with an alien inside to the background of the game
User prompt
Feedbackte bulunan mail adresi yerine İNSTAGRAM:abdurrahim_scu ekle
User prompt
Under the How To Play button, put a button that allows the producer to express their opinions.
User prompt
Put a button at the bottom right of the main menu that will allow us to introduce the game and explain its gameplay.
User prompt
"Sound Effects" butonun "Options" dan kaldır
User prompt
Ses efektleri "Sound Effects" kapalı olmasına rağmen duyulmaya devam ediyor
User prompt
Oyunda bulunan butonlara basınca cıkan ses efektlerini açıp kapamak için ayarlar kismına bir buton ekle
User prompt
Add a button that says "Extreme Mode" under the "Options" button in the main menu. When you press this button, all the features that appear on the game screen when you press the "Play" button will be available, but only a randomly selected ball can be used to score points. The explosion of other balls will not add points to the Score section.
User prompt
Add a button that turns the music volume on and off when the "Options" button is clicked
User prompt
Remove the "Sound Volume" option when clicking the "Options" button
User prompt
When the menu button is clicked, the text and images on the game screen continue to appear.
User prompt
Add a button to the game screen that will return to the main menu. When this button is clicked, only the text and buttons on the main menu will appear.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
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;
self.x = startX + self.gridX * CELL_SIZE + CELL_SIZE / 2;
self.y = startY + self.gridY * CELL_SIZE + CELL_SIZE / 2;
};
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;
tween(self, {
y: newPosY
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
self.isFalling = false;
if (callback) callback();
}
});
};
self.destroy = function () {
self.isMatched = true;
// 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];
// 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 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 = 2632;
self.addChild(madeByText);
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();
};
// 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();
};
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' or 'extreme'
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;
fallPromises++;
gem.fallTo(newY, function () {
fallPromises--;
if (fallPromises === 0) {
// Always fill empty spaces after cascading
fillEmptySpaces();
}
});
} else {
// Gem doesn't need to move
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++;
// Start gem above the screen and animate it falling
var startY = 400 - newGemsCreated * CELL_SIZE;
grid[x][y].y = startY;
tween(grid[x][y], {
y: 400 + y * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 500 + newGemsCreated * 50,
easing: tween.bounceOut
});
}
}
}
// 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
if (score >= 5000) {
LK.showYouWin();
}
}
// 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);
}
// 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);
}
// 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;
}
}
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
@@ -692,26 +692,8 @@
showFeedbackScreen();
};
return self;
});
-var UFO = Container.expand(function () {
- var self = Container.call(this);
- var ufoBody = self.attachAsset('ufo', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- var alien = self.attachAsset('alien', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- alien.y = -5;
- // Add gentle floating animation to the UFO
- self.update = function () {
- self.y += Math.sin(LK.ticks * 0.05) * 0.5;
- ufoBody.rotation += 0.01;
- };
- return self;
-});
/****
* Initialize Game
****/
@@ -1102,9 +1084,9 @@
game.addChild(startScreen);
// Start spaceship animation
createSpaceship();
// Start UFO animation
- createUFO();
+ createUfo();
// Start background music for start screen
var musicVolume = storage.musicVolume === undefined ? 1.0 : storage.musicVolume;
if (musicVolume > 0) {
LK.playMusic('background', {
@@ -1286,9 +1268,9 @@
createSpaceship();
}
// Continue UFO animation during gameplay
if (!ufo || !ufo.parent) {
- createUFO();
+ createUfo();
}
}
function showOptionsMenu() {
gameState = 'options';
@@ -1332,32 +1314,44 @@
}, Math.random() * 5000 + 2000); // Wait 2-7 seconds before next spaceship
}
});
}
-function createUFO() {
+function createUfo() {
if (ufo) {
game.removeChild(ufo);
}
- ufo = new UFO();
- // Start from right side, random Y position in upper area
+ ufo = LK.getAsset('ufo', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Start from right side, random Y position
ufo.x = 2148;
- ufo.y = Math.random() * 800 + 300; // Random position between 300 and 1100
+ ufo.y = Math.random() * 1200 + 300; // Random position between 300 and 1500
ufo.alpha = 0.4;
game.addChild(ufo);
- // Animate UFO moving slowly across screen from right to left
+ // Animate UFO moving across screen from right to left
tween(ufo, {
- x: -200 // Move to left edge
+ x: -150 // Move to left edge
}, {
- duration: Math.random() * 15000 + 20000,
- // 20-35 seconds to cross screen (slower than spaceship)
+ 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() * 10000 + 8000); // Wait 8-18 seconds before next UFO
+ 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';
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