User prompt
Ne kadar mayın varsa o kadar bayrak koyma hakkı olsun ekranın üst kısmındada bayrak koyma sınırı olsu
User prompt
Bayrak koyulmuyo
User prompt
Ekranın herangi bi yerinde bayrak butonu olsun oyuncu mayın olan yerin üstüne koyabilsin
User prompt
Harita küçük olsun
Code edit (1 edits merged)
Please save this source code
User prompt
Mayın Tarlası 45x30
Initial prompt
Bana mayın tarlası yap 45×30 olsun
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Cell class: represents a single cell in the minesweeper grid
var Cell = Container.expand(function () {
var self = Container.call(this);
// Cell state
self.isMine = false;
self.isRevealed = false;
self.isFlagged = false;
self.adjacentMines = 0;
self.gridX = 0;
self.gridY = 0;
// Visuals
// Cell background (hidden/revealed)
self.bg = self.attachAsset('cellBg', {
anchorX: 0.5,
anchorY: 0.5
});
// Flag icon (hidden by default)
self.flagIcon = self.attachAsset('cellFlag', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Mine icon (hidden by default)
self.mineIcon = self.attachAsset('cellMine', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Number text (hidden by default)
self.numberText = new Text2('', {
size: 32,
fill: 0x1A1A1A
});
self.numberText.anchor.set(0.5, 0.5);
self.numberText.alpha = 0;
self.addChild(self.numberText);
// Reveal this cell
self.reveal = function () {
if (self.isRevealed || self.isFlagged) return;
self.isRevealed = true;
// Show mine or number
if (self.isMine) {
self.mineIcon.alpha = 1;
self.bg.tint = 0xffaaaa;
} else {
self.bg.tint = 0xe0e0e0;
if (self.adjacentMines > 0) {
self.numberText.setText(self.adjacentMines + '');
self.numberText.alpha = 1;
}
}
};
// Hide (reset) this cell
self.hide = function () {
self.isRevealed = false;
self.isFlagged = false;
self.bg.tint = 0xcccccc;
self.flagIcon.alpha = 0;
self.mineIcon.alpha = 0;
self.numberText.alpha = 0;
};
// Set flagged state
self.setFlagged = function (flagged) {
if (self.isRevealed) return;
// Only allow flagging if not already flagged and flag limit not reached
if (flagged && !self.isFlagged) {
if (flagCount >= MINE_COUNT) return; // Do not allow more flags than mines
self.isFlagged = true;
self.flagIcon.alpha = 1;
if (typeof game.updateFlagCount === "function") game.updateFlagCount();
} else if (!flagged && self.isFlagged) {
self.isFlagged = false;
self.flagIcon.alpha = 0;
if (typeof game.updateFlagCount === "function") game.updateFlagCount();
}
};
// Event: tap/click (reveal)
self.down = function (x, y, obj) {
if (game.isGameOver || game.isWin) return;
if (flagMode) {
// Only allow flagging if not revealed
if (!self.isRevealed) {
// Only allow flagging if not exceeding flag limit
if (!self.isFlagged && flagCount >= MINE_COUNT) {
// Optionally: flash or shake to indicate no more flags
return;
}
self.setFlagged(!self.isFlagged);
// game.updateFlagCount(); // Already called in setFlagged
}
return;
}
if (self.isFlagged) return;
if (!self.isRevealed) {
game.revealCell(self.gridX, self.gridY);
}
};
// Event: long press (flag)
self.up = function (x, y, obj) {
// No-op, handled in game
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xeeeeee
});
/****
* Game Code
****/
// --- Game constants ---
var COLS = 12;
var ROWS = 8;
var CELL_SIZE = 120; // px, will be scaled to fit
var MINE_COUNT = 18; // Küçük harita için uygun mayın sayısı
// --- Game variables ---
var grid = [];
var cellNodes = [];
var isFirstClick = true;
var isGameOver = false;
var isWin = false;
var flagCount = 0;
var revealedCount = 0;
var flagMode = false; // If true, taps flag/unflag instead of reveal
// --- Asset initialization ---
// --- Layout calculation ---
var boardWidth = COLS * CELL_SIZE;
var boardHeight = ROWS * CELL_SIZE;
var boardOffsetX = Math.floor((2048 - boardWidth) / 2);
var boardOffsetY = Math.floor((2732 - boardHeight) / 2);
// --- GUI elements ---
var flagTxt = new Text2('Bayrak: 0/' + MINE_COUNT, {
size: 60,
fill: 0x333333
});
flagTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(flagTxt);
// Floating flag button (bottom right, not in top left!)
// Use the flag asset for visual consistency
var flagBtn = LK.getAsset('cellFlag', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 180,
y: 2732 - 180,
scaleX: 1.2,
scaleY: 1.2
});
flagBtn.interactive = true;
flagBtn.buttonMode = true;
game.addChild(flagBtn);
// Visual feedback for flag mode
function updateFlagBtnVisual() {
flagBtn.alpha = flagMode ? 1 : 0.7;
flagBtn.tint = flagMode ? 0xff3333 : 0xffffff;
}
updateFlagBtnVisual();
// Touch handler for flag button
flagBtn.down = function (x, y, obj) {
flagMode = !flagMode;
updateFlagBtnVisual();
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// Optional: also allow toggling with the old modeTxt for accessibility
var modeTxt = new Text2('Aç', {
size: 48,
fill: 0x666666
});
modeTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(modeTxt);
modeTxt.y = 80;
modeTxt.x = 2048 / 2;
modeTxt.down = function (x, y, obj) {
flagMode = !flagMode;
updateFlagBtnVisual();
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// --- Board container ---
var board = new Container();
game.addChild(board);
board.x = boardOffsetX;
board.y = boardOffsetY;
// --- Helper functions ---
// Returns true if (x, y) is inside the grid
function inBounds(x, y) {
return x >= 0 && x < COLS && y >= 0 && y < ROWS;
}
// Place mines randomly, avoiding (safeX, safeY) and its neighbors
function placeMines(safeX, safeY) {
var placed = 0;
while (placed < MINE_COUNT) {
var x = Math.floor(Math.random() * COLS);
var y = Math.floor(Math.random() * ROWS);
// Don't place on safe cell or its neighbors
if (Math.abs(x - safeX) <= 1 && Math.abs(y - safeY) <= 1) continue;
if (!grid[y][x].isMine) {
grid[y][x].isMine = true;
placed++;
}
}
}
// Calculate adjacent mine counts for all cells
function calcAdjacents() {
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var count = 0;
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
if (dx === 0 && dy === 0) continue;
var nx = x + dx,
ny = y + dy;
if (inBounds(nx, ny) && grid[ny][nx].isMine) count++;
}
}
grid[y][x].adjacentMines = count;
}
}
}
// Reveal cell at (x, y). If first click, place mines after click.
game.revealCell = function (x, y) {
if (isGameOver || isWin) return;
var cell = grid[y][x];
if (cell.isRevealed || cell.isFlagged) return;
if (isFirstClick) {
placeMines(x, y);
calcAdjacents();
isFirstClick = false;
}
cell.reveal();
revealedCount++;
if (cell.isMine) {
// Game over
isGameOver = true;
revealAllMines();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// If no adjacent mines, reveal neighbors recursively
if (cell.adjacentMines === 0) {
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
if (dx === 0 && dy === 0) continue;
var nx = x + dx,
ny = y + dy;
if (inBounds(nx, ny)) {
var neighbor = grid[ny][nx];
if (!neighbor.isRevealed && !neighbor.isMine && !neighbor.isFlagged) {
game.revealCell(nx, ny);
}
}
}
}
}
checkWin();
};
// Reveal all mines (on game over)
function revealAllMines() {
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var cell = grid[y][x];
if (cell.isMine) {
cell.mineIcon.alpha = 1;
cell.bg.tint = 0xffaaaa;
}
}
}
}
// Check win condition
function checkWin() {
// Win if all non-mine cells are revealed
var totalSafe = COLS * ROWS - MINE_COUNT;
if (revealedCount === totalSafe) {
isWin = true;
LK.effects.flashScreen(0x44ff44, 1000);
LK.showYouWin();
}
}
// Update flag count display
game.updateFlagCount = function () {
flagCount = 0;
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
if (grid[y][x].isFlagged) flagCount++;
}
}
flagTxt.setText('Bayrak: ' + flagCount + '/' + MINE_COUNT);
};
// --- Board setup ---
// Create grid and cell nodes
for (var y = 0; y < ROWS; y++) {
grid[y] = [];
cellNodes[y] = [];
for (var x = 0; x < COLS; x++) {
var cell = new Cell();
cell.gridX = x;
cell.gridY = y;
cell.x = x * CELL_SIZE + CELL_SIZE / 2;
cell.y = y * CELL_SIZE + CELL_SIZE / 2;
board.addChild(cell);
grid[y][x] = cell;
cellNodes[y][x] = cell;
}
}
// --- Touch/flag mode toggle ---
// Toggle flag mode on modeTxt tap
modeTxt.down = function (x, y, obj) {
flagMode = !flagMode;
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// --- Game event handlers ---
// Prevent drag/scroll on board
board.move = function (x, y, obj) {};
// --- Reset function (called by LK on game restart) ---
game.reset = function () {
isFirstClick = true;
isGameOver = false;
isWin = false;
flagCount = 0;
revealedCount = 0;
flagMode = false;
if (typeof updateFlagBtnVisual === "function") updateFlagBtnVisual();
modeTxt.setText('Aç');
modeTxt.fill = "#666666";
flagTxt.setText('Bayrak: 0/' + MINE_COUNT);
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var cell = grid[y][x];
cell.isMine = false;
cell.isRevealed = false;
cell.isFlagged = false;
cell.adjacentMines = 0;
cell.hide();
}
}
};
// --- Game update loop (not used, but required) ---
game.update = function () {};
// --- End of file --- /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Cell class: represents a single cell in the minesweeper grid
var Cell = Container.expand(function () {
var self = Container.call(this);
// Cell state
self.isMine = false;
self.isRevealed = false;
self.isFlagged = false;
self.adjacentMines = 0;
self.gridX = 0;
self.gridY = 0;
// Visuals
// Cell background (hidden/revealed)
self.bg = self.attachAsset('cellBg', {
anchorX: 0.5,
anchorY: 0.5
});
// Flag icon (hidden by default)
self.flagIcon = self.attachAsset('cellFlag', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Mine icon (hidden by default)
self.mineIcon = self.attachAsset('cellMine', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Number text (hidden by default)
self.numberText = new Text2('', {
size: 32,
fill: 0x1A1A1A
});
self.numberText.anchor.set(0.5, 0.5);
self.numberText.alpha = 0;
self.addChild(self.numberText);
// Reveal this cell
self.reveal = function () {
if (self.isRevealed || self.isFlagged) return;
self.isRevealed = true;
// Show mine or number
if (self.isMine) {
self.mineIcon.alpha = 1;
self.bg.tint = 0xffaaaa;
} else {
self.bg.tint = 0xe0e0e0;
if (self.adjacentMines > 0) {
self.numberText.setText(self.adjacentMines + '');
self.numberText.alpha = 1;
}
}
};
// Hide (reset) this cell
self.hide = function () {
self.isRevealed = false;
self.isFlagged = false;
self.bg.tint = 0xcccccc;
self.flagIcon.alpha = 0;
self.mineIcon.alpha = 0;
self.numberText.alpha = 0;
};
// Set flagged state
self.setFlagged = function (flagged) {
if (self.isRevealed) return;
// Only allow flagging if not already flagged and flag limit not reached
if (flagged && !self.isFlagged) {
if (flagCount >= MINE_COUNT) return; // Do not allow more flags than mines
self.isFlagged = true;
self.flagIcon.alpha = 1;
if (typeof game.updateFlagCount === "function") game.updateFlagCount();
} else if (!flagged && self.isFlagged) {
self.isFlagged = false;
self.flagIcon.alpha = 0;
if (typeof game.updateFlagCount === "function") game.updateFlagCount();
}
};
// Event: tap/click (reveal)
self.down = function (x, y, obj) {
if (game.isGameOver || game.isWin) return;
if (flagMode) {
// Only allow flagging if not revealed
if (!self.isRevealed) {
// Only allow flagging if not exceeding flag limit
if (!self.isFlagged && flagCount >= MINE_COUNT) {
// Optionally: flash or shake to indicate no more flags
return;
}
self.setFlagged(!self.isFlagged);
// game.updateFlagCount(); // Already called in setFlagged
}
return;
}
if (self.isFlagged) return;
if (!self.isRevealed) {
game.revealCell(self.gridX, self.gridY);
}
};
// Event: long press (flag)
self.up = function (x, y, obj) {
// No-op, handled in game
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xeeeeee
});
/****
* Game Code
****/
// --- Game constants ---
var COLS = 12;
var ROWS = 8;
var CELL_SIZE = 120; // px, will be scaled to fit
var MINE_COUNT = 18; // Küçük harita için uygun mayın sayısı
// --- Game variables ---
var grid = [];
var cellNodes = [];
var isFirstClick = true;
var isGameOver = false;
var isWin = false;
var flagCount = 0;
var revealedCount = 0;
var flagMode = false; // If true, taps flag/unflag instead of reveal
// --- Asset initialization ---
// --- Layout calculation ---
var boardWidth = COLS * CELL_SIZE;
var boardHeight = ROWS * CELL_SIZE;
var boardOffsetX = Math.floor((2048 - boardWidth) / 2);
var boardOffsetY = Math.floor((2732 - boardHeight) / 2);
// --- GUI elements ---
var flagTxt = new Text2('Bayrak: 0/' + MINE_COUNT, {
size: 60,
fill: 0x333333
});
flagTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(flagTxt);
// Floating flag button (bottom right, not in top left!)
// Use the flag asset for visual consistency
var flagBtn = LK.getAsset('cellFlag', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 180,
y: 2732 - 180,
scaleX: 1.2,
scaleY: 1.2
});
flagBtn.interactive = true;
flagBtn.buttonMode = true;
game.addChild(flagBtn);
// Visual feedback for flag mode
function updateFlagBtnVisual() {
flagBtn.alpha = flagMode ? 1 : 0.7;
flagBtn.tint = flagMode ? 0xff3333 : 0xffffff;
}
updateFlagBtnVisual();
// Touch handler for flag button
flagBtn.down = function (x, y, obj) {
flagMode = !flagMode;
updateFlagBtnVisual();
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// Optional: also allow toggling with the old modeTxt for accessibility
var modeTxt = new Text2('Aç', {
size: 48,
fill: 0x666666
});
modeTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(modeTxt);
modeTxt.y = 80;
modeTxt.x = 2048 / 2;
modeTxt.down = function (x, y, obj) {
flagMode = !flagMode;
updateFlagBtnVisual();
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// --- Board container ---
var board = new Container();
game.addChild(board);
board.x = boardOffsetX;
board.y = boardOffsetY;
// --- Helper functions ---
// Returns true if (x, y) is inside the grid
function inBounds(x, y) {
return x >= 0 && x < COLS && y >= 0 && y < ROWS;
}
// Place mines randomly, avoiding (safeX, safeY) and its neighbors
function placeMines(safeX, safeY) {
var placed = 0;
while (placed < MINE_COUNT) {
var x = Math.floor(Math.random() * COLS);
var y = Math.floor(Math.random() * ROWS);
// Don't place on safe cell or its neighbors
if (Math.abs(x - safeX) <= 1 && Math.abs(y - safeY) <= 1) continue;
if (!grid[y][x].isMine) {
grid[y][x].isMine = true;
placed++;
}
}
}
// Calculate adjacent mine counts for all cells
function calcAdjacents() {
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var count = 0;
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
if (dx === 0 && dy === 0) continue;
var nx = x + dx,
ny = y + dy;
if (inBounds(nx, ny) && grid[ny][nx].isMine) count++;
}
}
grid[y][x].adjacentMines = count;
}
}
}
// Reveal cell at (x, y). If first click, place mines after click.
game.revealCell = function (x, y) {
if (isGameOver || isWin) return;
var cell = grid[y][x];
if (cell.isRevealed || cell.isFlagged) return;
if (isFirstClick) {
placeMines(x, y);
calcAdjacents();
isFirstClick = false;
}
cell.reveal();
revealedCount++;
if (cell.isMine) {
// Game over
isGameOver = true;
revealAllMines();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// If no adjacent mines, reveal neighbors recursively
if (cell.adjacentMines === 0) {
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
if (dx === 0 && dy === 0) continue;
var nx = x + dx,
ny = y + dy;
if (inBounds(nx, ny)) {
var neighbor = grid[ny][nx];
if (!neighbor.isRevealed && !neighbor.isMine && !neighbor.isFlagged) {
game.revealCell(nx, ny);
}
}
}
}
}
checkWin();
};
// Reveal all mines (on game over)
function revealAllMines() {
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var cell = grid[y][x];
if (cell.isMine) {
cell.mineIcon.alpha = 1;
cell.bg.tint = 0xffaaaa;
}
}
}
}
// Check win condition
function checkWin() {
// Win if all non-mine cells are revealed
var totalSafe = COLS * ROWS - MINE_COUNT;
if (revealedCount === totalSafe) {
isWin = true;
LK.effects.flashScreen(0x44ff44, 1000);
LK.showYouWin();
}
}
// Update flag count display
game.updateFlagCount = function () {
flagCount = 0;
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
if (grid[y][x].isFlagged) flagCount++;
}
}
flagTxt.setText('Bayrak: ' + flagCount + '/' + MINE_COUNT);
};
// --- Board setup ---
// Create grid and cell nodes
for (var y = 0; y < ROWS; y++) {
grid[y] = [];
cellNodes[y] = [];
for (var x = 0; x < COLS; x++) {
var cell = new Cell();
cell.gridX = x;
cell.gridY = y;
cell.x = x * CELL_SIZE + CELL_SIZE / 2;
cell.y = y * CELL_SIZE + CELL_SIZE / 2;
board.addChild(cell);
grid[y][x] = cell;
cellNodes[y][x] = cell;
}
}
// --- Touch/flag mode toggle ---
// Toggle flag mode on modeTxt tap
modeTxt.down = function (x, y, obj) {
flagMode = !flagMode;
modeTxt.setText(flagMode ? 'Bayrak' : 'Aç');
modeTxt.fill = flagMode ? "#ff3333" : "#666666";
};
// --- Game event handlers ---
// Prevent drag/scroll on board
board.move = function (x, y, obj) {};
// --- Reset function (called by LK on game restart) ---
game.reset = function () {
isFirstClick = true;
isGameOver = false;
isWin = false;
flagCount = 0;
revealedCount = 0;
flagMode = false;
if (typeof updateFlagBtnVisual === "function") updateFlagBtnVisual();
modeTxt.setText('Aç');
modeTxt.fill = "#666666";
flagTxt.setText('Bayrak: 0/' + MINE_COUNT);
for (var y = 0; y < ROWS; y++) {
for (var x = 0; x < COLS; x++) {
var cell = grid[y][x];
cell.isMine = false;
cell.isRevealed = false;
cell.isFlagged = false;
cell.adjacentMines = 0;
cell.hide();
}
}
};
// --- Game update loop (not used, but required) ---
game.update = function () {};
// --- End of file ---