/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var GridCell = Container.expand(function (letter, row, col) { var self = Container.call(this); self.letter = letter; self.row = row; self.col = col; self.isSelected = false; self.isFound = false; var cellBG = self.attachAsset('gridCell', { anchorX: 0.5, anchorY: 0.5 }); var letterText = new Text2(letter, { size: 80, fill: 0x333333, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); letterText.anchor.set(0.5, 0.5); self.addChild(letterText); self.setSelected = function (selected) { self.isSelected = selected; if (self.isFound) return; self.removeChild(cellBG); if (selected) { cellBG = self.attachAsset('gridCellSelected', { anchorX: 0.5, anchorY: 0.5 }); } else { cellBG = self.attachAsset('gridCell', { anchorX: 0.5, anchorY: 0.5 }); } self.addChildAt(cellBG, 0); }; self.setFound = function () { self.isFound = true; self.removeChild(cellBG); cellBG = self.attachAsset('gridCellFound', { anchorX: 0.5, anchorY: 0.5 }); self.addChildAt(cellBG, 0); }; return self; }); var TargetWord = Container.expand(function (frenchWord, englishWord, turkishWord, level) { var self = Container.call(this); self.frenchWord = frenchWord; self.englishWord = englishWord; self.turkishWord = turkishWord; self.level = level; self.isFound = false; var bg = self.attachAsset('targetWordBG', { anchorX: 0.5, anchorY: 0.5 }); var frenchText = new Text2(frenchWord + ' (' + level + ')', { size: 65, fill: 0x000000, font: "Arial" }); frenchText.anchor.set(0.5, 0.5); frenchText.y = -100; self.addChild(frenchText); var englishText = new Text2(englishWord, { size: 65, fill: 0x000000, font: "Arial" }); englishText.anchor.set(0.5, 0.5); englishText.y = -20; self.addChild(englishText); var turkishText = new Text2(turkishWord, { size: 65, fill: 0x000000, font: "Arial" }); turkishText.anchor.set(0.5, 0.5); turkishText.y = 60; self.addChild(turkishText); self.markFound = function () { self.isFound = true; frenchText.tint = 0x4CAF50; bg.tint = 0xC8E6C9; tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut }); tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff }); /**** * Game Code ****/ // French vocabulary database with CEFR levels var vocabularyDatabase = [ // A1 Level { french: "CHAT", english: "Cat", turkish: "Kedi", level: "A1" }, { french: "CHIEN", english: "Dog", turkish: "Köpek", level: "A1" }, { french: "MAISON", english: "House", turkish: "Ev", level: "A1" }, { french: "EAU", english: "Water", turkish: "Su", level: "A1" }, { french: "PAIN", english: "Bread", turkish: "Ekmek", level: "A1" }, { french: "LAIT", english: "Milk", turkish: "Süt", level: "A1" }, { french: "ROUGE", english: "Red", turkish: "Kırmızı", level: "A1" }, { french: "BLEU", english: "Blue", turkish: "Mavi", level: "A1" }, { french: "VERT", english: "Green", turkish: "Yeşil", level: "A1" }, { french: "NOIR", english: "Black", turkish: "Siyah", level: "A1" }, // A2 Level { french: "VOITURE", english: "Car", turkish: "Araba", level: "A2" }, { french: "TRAVAIL", english: "Work", turkish: "İş", level: "A2" }, { french: "ECOLE", english: "School", turkish: "Okul", level: "A2" }, { french: "FAMILLE", english: "Family", turkish: "Aile", level: "A2" }, { french: "TEMPS", english: "Time", turkish: "Zaman", level: "A2" }, { french: "ARGENT", english: "Money", turkish: "Para", level: "A2" }, { french: "VOYAGE", english: "Travel", turkish: "Seyahat", level: "A2" }, { french: "MUSIQUE", english: "Music", turkish: "Müzik", level: "A2" }, { french: "LIVRE", english: "Book", turkish: "Kitap", level: "A2" }, { french: "FILM", english: "Movie", turkish: "Film", level: "A2" }, // B1 Level { french: "BONHEUR", english: "Happiness", turkish: "Mutluluk", level: "B1" }, { french: "CULTURE", english: "Culture", turkish: "Kültür", level: "B1" }, { french: "SOCIETE", english: "Society", turkish: "Toplum", level: "B1" }, { french: "NATURE", english: "Nature", turkish: "Doğa", level: "B1" }, { french: "SCIENCE", english: "Science", turkish: "Bilim", level: "B1" }, { french: "HISTOIRE", english: "History", turkish: "Tarih", level: "B1" }, { french: "OPINION", english: "Opinion", turkish: "Görüş", level: "B1" }, { french: "ENERGIE", english: "Energy", turkish: "Enerji", level: "B1" }, { french: "PROJECT", english: "Project", turkish: "Proje", level: "B1" }, { french: "RESULTAT", english: "Result", turkish: "Sonuç", level: "B1" }, // B2 Level { french: "CONSCIENCE", english: "Conscience", turkish: "Vicdan", level: "B2" }, { french: "PHILOSOPHIE", english: "Philosophy", turkish: "Felsefe", level: "B2" }, { french: "TECHNOLOGIE", english: "Technology", turkish: "Teknoloji", level: "B2" }, { french: "ECONOMIE", english: "Economy", turkish: "Ekonomi", level: "B2" }, { french: "POLITIQUE", english: "Politics", turkish: "Politika", level: "B2" }, { french: "ENVIRONNEMENT", english: "Environment", turkish: "Çevre", level: "B2" }, { french: "DEMOCRATIE", english: "Democracy", turkish: "Demokrasi", level: "B2" }, { french: "INNOVATION", english: "Innovation", turkish: "İnovasyon", level: "B2" }, { french: "GLOBALISATION", english: "Globalization", turkish: "Küreselleşme", level: "B2" }, { french: "COMMUNICATION", english: "Communication", turkish: "İletişim", level: "B2" }, // C1 Level { french: "EPISTEMOLOGIE", english: "Epistemology", turkish: "Epistemoloji", level: "C1" }, { french: "METAPHYSIQUE", english: "Metaphysics", turkish: "Metafizik", level: "C1" }, { french: "PHENOMENOLOGIE", english: "Phenomenology", turkish: "Fenomenoloji", level: "C1" }, { french: "HERMENEUTIQUE", english: "Hermeneutics", turkish: "Hermenötik", level: "C1" }, { french: "DIALECTIQUE", english: "Dialectics", turkish: "Diyalektik", level: "C1" }, { french: "EPISODIQUE", english: "Episodic", turkish: "Epizodik", level: "C1" }, { french: "PARADIGME", english: "Paradigm", turkish: "Paradigma", level: "C1" }, { french: "ONTOLOGIE", english: "Ontology", turkish: "Ontoloji", level: "C1" }, { french: "SYNTHETIQUE", english: "Synthetic", turkish: "Sentetik", level: "C1" }, { french: "EMPIRIQUE", english: "Empirical", turkish: "Ampirik", level: "C1" }]; // Game variables var gridSize = 10; var cellSize = 160; var grid = []; var gridCells = []; var targetWords = []; var currentTargetWords = []; var selectedCells = []; var isDragging = false; var currentSection = 1; var wordsFoundInSection = 0; // Score text var scoreTxt = new Text2('Section: 1', { size: 80, fill: 0x333333 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 100; // Create grid container var gridContainer = new Container(); game.addChild(gridContainer); // Create target words container var targetWordsContainer = new Container(); game.addChild(targetWordsContainer); // Initialize grid function initializeGrid() { // Clear existing grid for (var i = 0; i < gridCells.length; i++) { for (var j = 0; j < gridCells[i].length; j++) { gridContainer.removeChild(gridCells[i][j]); } } grid = []; gridCells = []; // Create empty grid for (var row = 0; row < gridSize; row++) { grid[row] = []; gridCells[row] = []; for (var col = 0; col < gridSize; col++) { grid[row][col] = ''; } } // Place target words in grid for (var w = 0; w < currentTargetWords.length; w++) { placeWordInGrid(currentTargetWords[w].french); } // Fill remaining cells with random letters var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; for (var row = 0; row < gridSize; row++) { for (var col = 0; col < gridSize; col++) { if (grid[row][col] === '') { grid[row][col] = letters[Math.floor(Math.random() * letters.length)]; } } } // Create visual grid cells var startX = 1024 - gridSize * cellSize / 2 + cellSize / 2; var startY = 400; for (var row = 0; row < gridSize; row++) { for (var col = 0; col < gridSize; col++) { var cell = new GridCell(grid[row][col], row, col); cell.x = startX + col * cellSize; cell.y = startY + row * cellSize; gridCells[row][col] = cell; gridContainer.addChild(cell); } } } function placeWordInGrid(word) { var placed = false; var attempts = 0; while (!placed && attempts < 100) { var direction = Math.floor(Math.random() * 4); // 0: horizontal, 1: vertical, 2: diagonal down-right, 3: diagonal down-left var row, col; if (direction === 0) { // horizontal row = Math.floor(Math.random() * gridSize); col = Math.floor(Math.random() * (gridSize - word.length + 1)); var canPlace = true; for (var i = 0; i < word.length; i++) { if (col + i >= gridSize || grid[row][col + i] !== '' && grid[row][col + i] !== word[i]) { canPlace = false; break; } } if (canPlace) { for (var i = 0; i < word.length; i++) { if (col + i < gridSize) { grid[row][col + i] = word[i]; } } placed = true; } } else if (direction === 1) { // vertical row = Math.floor(Math.random() * (gridSize - word.length + 1)); col = Math.floor(Math.random() * gridSize); var canPlace = true; for (var i = 0; i < word.length; i++) { if (row + i >= gridSize || grid[row + i] && grid[row + i][col] !== '' && grid[row + i][col] !== word[i]) { canPlace = false; break; } } if (canPlace) { for (var i = 0; i < word.length; i++) { if (row + i < gridSize) { grid[row + i][col] = word[i]; } } placed = true; } } attempts++; } } function selectTargetWords() { currentTargetWords = []; var availableWords = vocabularyDatabase.slice(); for (var i = 0; i < 3; i++) { var randomIndex = Math.floor(Math.random() * availableWords.length); currentTargetWords.push(availableWords[randomIndex]); availableWords.splice(randomIndex, 1); } } function createTargetWordsDisplay() { // Clear existing target words while (targetWordsContainer.children.length > 0) { targetWordsContainer.removeChild(targetWordsContainer.children[0]); } targetWords = []; var startX = 1024 - 3 * 650 / 2 + 325; var yPos = 2500; for (var i = 0; i < currentTargetWords.length; i++) { var targetWord = new TargetWord(currentTargetWords[i].french, currentTargetWords[i].english, currentTargetWords[i].turkish, currentTargetWords[i].level); targetWord.x = startX + i * 650; targetWord.y = yPos; targetWords.push(targetWord); targetWordsContainer.addChild(targetWord); } } function getSelectedWord() { var word = ''; for (var i = 0; i < selectedCells.length; i++) { word += selectedCells[i].letter; } return word; } function checkForWord() { var selectedWord = getSelectedWord(); for (var i = 0; i < currentTargetWords.length; i++) { if (currentTargetWords[i].french === selectedWord && !targetWords[i].isFound) { // Word found! targetWords[i].markFound(); // Mark cells as found for (var j = 0; j < selectedCells.length; j++) { selectedCells[j].setFound(); } LK.getSound('wordFound').play(); wordsFoundInSection++; if (wordsFoundInSection >= 3) { // Section complete LK.setTimeout(function () { LK.getSound('sectionComplete').play(); startNewSection(); }, 500); } break; } } } function startNewSection() { currentSection++; wordsFoundInSection = 0; scoreTxt.setText('Section: ' + currentSection); selectTargetWords(); createTargetWordsDisplay(); initializeGrid(); } function clearSelection() { for (var i = 0; i < selectedCells.length; i++) { selectedCells[i].setSelected(false); } selectedCells = []; } function getCellAt(x, y) { // Calculate grid position based on start position and cell size var startX = 1024 - gridSize * cellSize / 2; var startY = 400; // Calculate which grid cell was touched directly from game coordinates var col = Math.floor((x - startX) / cellSize); var row = Math.floor((y - startY) / cellSize); // Check bounds and return cell if valid if (row >= 0 && row < gridSize && col >= 0 && col < gridSize) { return gridCells[row][col]; } return null; } function isValidSelection(lastCell, newCell) { if (!lastCell) return true; var rowDiff = Math.abs(lastCell.row - newCell.row); var colDiff = Math.abs(lastCell.col - newCell.col); // Allow horizontal, vertical, and diagonal connections return rowDiff <= 1 && colDiff <= 1 && (rowDiff > 0 || colDiff > 0); } // Game events game.down = function (x, y, obj) { var cell = getCellAt(x, y); if (cell && !cell.isFound) { isDragging = true; clearSelection(); selectedCells.push(cell); cell.setSelected(true); } }; game.move = function (x, y, obj) { if (!isDragging) return; var cell = getCellAt(x, y); if (cell && !cell.isFound) { var lastCell = selectedCells.length > 0 ? selectedCells[selectedCells.length - 1] : null; if (cell !== lastCell && isValidSelection(lastCell, cell)) { // Check if cell is already in selection var cellIndex = -1; for (var i = 0; i < selectedCells.length; i++) { if (selectedCells[i] === cell) { cellIndex = i; break; } } if (cellIndex >= 0) { // Remove cells after this one (backtracking) for (var i = selectedCells.length - 1; i > cellIndex; i--) { selectedCells[i].setSelected(false); selectedCells.splice(i, 1); } } else { // Add new cell to selection selectedCells.push(cell); cell.setSelected(true); } } } }; game.up = function (x, y, obj) { if (isDragging) { isDragging = false; if (selectedCells.length > 0) { checkForWord(); } clearSelection(); } }; // Initialize game selectTargetWords(); createTargetWordsDisplay(); initializeGrid();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GridCell = Container.expand(function (letter, row, col) {
var self = Container.call(this);
self.letter = letter;
self.row = row;
self.col = col;
self.isSelected = false;
self.isFound = false;
var cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2(letter, {
size: 80,
fill: 0x333333,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
self.setSelected = function (selected) {
self.isSelected = selected;
if (self.isFound) return;
self.removeChild(cellBG);
if (selected) {
cellBG = self.attachAsset('gridCellSelected', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.addChildAt(cellBG, 0);
};
self.setFound = function () {
self.isFound = true;
self.removeChild(cellBG);
cellBG = self.attachAsset('gridCellFound', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChildAt(cellBG, 0);
};
return self;
});
var TargetWord = Container.expand(function (frenchWord, englishWord, turkishWord, level) {
var self = Container.call(this);
self.frenchWord = frenchWord;
self.englishWord = englishWord;
self.turkishWord = turkishWord;
self.level = level;
self.isFound = false;
var bg = self.attachAsset('targetWordBG', {
anchorX: 0.5,
anchorY: 0.5
});
var frenchText = new Text2(frenchWord + ' (' + level + ')', {
size: 65,
fill: 0x000000,
font: "Arial"
});
frenchText.anchor.set(0.5, 0.5);
frenchText.y = -100;
self.addChild(frenchText);
var englishText = new Text2(englishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
englishText.anchor.set(0.5, 0.5);
englishText.y = -20;
self.addChild(englishText);
var turkishText = new Text2(turkishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
turkishText.anchor.set(0.5, 0.5);
turkishText.y = 60;
self.addChild(turkishText);
self.markFound = function () {
self.isFound = true;
frenchText.tint = 0x4CAF50;
bg.tint = 0xC8E6C9;
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// French vocabulary database with CEFR levels
var vocabularyDatabase = [
// A1 Level
{
french: "CHAT",
english: "Cat",
turkish: "Kedi",
level: "A1"
}, {
french: "CHIEN",
english: "Dog",
turkish: "Köpek",
level: "A1"
}, {
french: "MAISON",
english: "House",
turkish: "Ev",
level: "A1"
}, {
french: "EAU",
english: "Water",
turkish: "Su",
level: "A1"
}, {
french: "PAIN",
english: "Bread",
turkish: "Ekmek",
level: "A1"
}, {
french: "LAIT",
english: "Milk",
turkish: "Süt",
level: "A1"
}, {
french: "ROUGE",
english: "Red",
turkish: "Kırmızı",
level: "A1"
}, {
french: "BLEU",
english: "Blue",
turkish: "Mavi",
level: "A1"
}, {
french: "VERT",
english: "Green",
turkish: "Yeşil",
level: "A1"
}, {
french: "NOIR",
english: "Black",
turkish: "Siyah",
level: "A1"
},
// A2 Level
{
french: "VOITURE",
english: "Car",
turkish: "Araba",
level: "A2"
}, {
french: "TRAVAIL",
english: "Work",
turkish: "İş",
level: "A2"
}, {
french: "ECOLE",
english: "School",
turkish: "Okul",
level: "A2"
}, {
french: "FAMILLE",
english: "Family",
turkish: "Aile",
level: "A2"
}, {
french: "TEMPS",
english: "Time",
turkish: "Zaman",
level: "A2"
}, {
french: "ARGENT",
english: "Money",
turkish: "Para",
level: "A2"
}, {
french: "VOYAGE",
english: "Travel",
turkish: "Seyahat",
level: "A2"
}, {
french: "MUSIQUE",
english: "Music",
turkish: "Müzik",
level: "A2"
}, {
french: "LIVRE",
english: "Book",
turkish: "Kitap",
level: "A2"
}, {
french: "FILM",
english: "Movie",
turkish: "Film",
level: "A2"
},
// B1 Level
{
french: "BONHEUR",
english: "Happiness",
turkish: "Mutluluk",
level: "B1"
}, {
french: "CULTURE",
english: "Culture",
turkish: "Kültür",
level: "B1"
}, {
french: "SOCIETE",
english: "Society",
turkish: "Toplum",
level: "B1"
}, {
french: "NATURE",
english: "Nature",
turkish: "Doğa",
level: "B1"
}, {
french: "SCIENCE",
english: "Science",
turkish: "Bilim",
level: "B1"
}, {
french: "HISTOIRE",
english: "History",
turkish: "Tarih",
level: "B1"
}, {
french: "OPINION",
english: "Opinion",
turkish: "Görüş",
level: "B1"
}, {
french: "ENERGIE",
english: "Energy",
turkish: "Enerji",
level: "B1"
}, {
french: "PROJECT",
english: "Project",
turkish: "Proje",
level: "B1"
}, {
french: "RESULTAT",
english: "Result",
turkish: "Sonuç",
level: "B1"
},
// B2 Level
{
french: "CONSCIENCE",
english: "Conscience",
turkish: "Vicdan",
level: "B2"
}, {
french: "PHILOSOPHIE",
english: "Philosophy",
turkish: "Felsefe",
level: "B2"
}, {
french: "TECHNOLOGIE",
english: "Technology",
turkish: "Teknoloji",
level: "B2"
}, {
french: "ECONOMIE",
english: "Economy",
turkish: "Ekonomi",
level: "B2"
}, {
french: "POLITIQUE",
english: "Politics",
turkish: "Politika",
level: "B2"
}, {
french: "ENVIRONNEMENT",
english: "Environment",
turkish: "Çevre",
level: "B2"
}, {
french: "DEMOCRATIE",
english: "Democracy",
turkish: "Demokrasi",
level: "B2"
}, {
french: "INNOVATION",
english: "Innovation",
turkish: "İnovasyon",
level: "B2"
}, {
french: "GLOBALISATION",
english: "Globalization",
turkish: "Küreselleşme",
level: "B2"
}, {
french: "COMMUNICATION",
english: "Communication",
turkish: "İletişim",
level: "B2"
},
// C1 Level
{
french: "EPISTEMOLOGIE",
english: "Epistemology",
turkish: "Epistemoloji",
level: "C1"
}, {
french: "METAPHYSIQUE",
english: "Metaphysics",
turkish: "Metafizik",
level: "C1"
}, {
french: "PHENOMENOLOGIE",
english: "Phenomenology",
turkish: "Fenomenoloji",
level: "C1"
}, {
french: "HERMENEUTIQUE",
english: "Hermeneutics",
turkish: "Hermenötik",
level: "C1"
}, {
french: "DIALECTIQUE",
english: "Dialectics",
turkish: "Diyalektik",
level: "C1"
}, {
french: "EPISODIQUE",
english: "Episodic",
turkish: "Epizodik",
level: "C1"
}, {
french: "PARADIGME",
english: "Paradigm",
turkish: "Paradigma",
level: "C1"
}, {
french: "ONTOLOGIE",
english: "Ontology",
turkish: "Ontoloji",
level: "C1"
}, {
french: "SYNTHETIQUE",
english: "Synthetic",
turkish: "Sentetik",
level: "C1"
}, {
french: "EMPIRIQUE",
english: "Empirical",
turkish: "Ampirik",
level: "C1"
}];
// Game variables
var gridSize = 10;
var cellSize = 160;
var grid = [];
var gridCells = [];
var targetWords = [];
var currentTargetWords = [];
var selectedCells = [];
var isDragging = false;
var currentSection = 1;
var wordsFoundInSection = 0;
// Score text
var scoreTxt = new Text2('Section: 1', {
size: 80,
fill: 0x333333
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Create grid container
var gridContainer = new Container();
game.addChild(gridContainer);
// Create target words container
var targetWordsContainer = new Container();
game.addChild(targetWordsContainer);
// Initialize grid
function initializeGrid() {
// Clear existing grid
for (var i = 0; i < gridCells.length; i++) {
for (var j = 0; j < gridCells[i].length; j++) {
gridContainer.removeChild(gridCells[i][j]);
}
}
grid = [];
gridCells = [];
// Create empty grid
for (var row = 0; row < gridSize; row++) {
grid[row] = [];
gridCells[row] = [];
for (var col = 0; col < gridSize; col++) {
grid[row][col] = '';
}
}
// Place target words in grid
for (var w = 0; w < currentTargetWords.length; w++) {
placeWordInGrid(currentTargetWords[w].french);
}
// Fill remaining cells with random letters
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
if (grid[row][col] === '') {
grid[row][col] = letters[Math.floor(Math.random() * letters.length)];
}
}
}
// Create visual grid cells
var startX = 1024 - gridSize * cellSize / 2 + cellSize / 2;
var startY = 400;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var cell = new GridCell(grid[row][col], row, col);
cell.x = startX + col * cellSize;
cell.y = startY + row * cellSize;
gridCells[row][col] = cell;
gridContainer.addChild(cell);
}
}
}
function placeWordInGrid(word) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 100) {
var direction = Math.floor(Math.random() * 4); // 0: horizontal, 1: vertical, 2: diagonal down-right, 3: diagonal down-left
var row, col;
if (direction === 0) {
// horizontal
row = Math.floor(Math.random() * gridSize);
col = Math.floor(Math.random() * (gridSize - word.length + 1));
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (col + i >= gridSize || grid[row][col + i] !== '' && grid[row][col + i] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (col + i < gridSize) {
grid[row][col + i] = word[i];
}
}
placed = true;
}
} else if (direction === 1) {
// vertical
row = Math.floor(Math.random() * (gridSize - word.length + 1));
col = Math.floor(Math.random() * gridSize);
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (row + i >= gridSize || grid[row + i] && grid[row + i][col] !== '' && grid[row + i][col] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (row + i < gridSize) {
grid[row + i][col] = word[i];
}
}
placed = true;
}
}
attempts++;
}
}
function selectTargetWords() {
currentTargetWords = [];
var availableWords = vocabularyDatabase.slice();
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * availableWords.length);
currentTargetWords.push(availableWords[randomIndex]);
availableWords.splice(randomIndex, 1);
}
}
function createTargetWordsDisplay() {
// Clear existing target words
while (targetWordsContainer.children.length > 0) {
targetWordsContainer.removeChild(targetWordsContainer.children[0]);
}
targetWords = [];
var startX = 1024 - 3 * 650 / 2 + 325;
var yPos = 2500;
for (var i = 0; i < currentTargetWords.length; i++) {
var targetWord = new TargetWord(currentTargetWords[i].french, currentTargetWords[i].english, currentTargetWords[i].turkish, currentTargetWords[i].level);
targetWord.x = startX + i * 650;
targetWord.y = yPos;
targetWords.push(targetWord);
targetWordsContainer.addChild(targetWord);
}
}
function getSelectedWord() {
var word = '';
for (var i = 0; i < selectedCells.length; i++) {
word += selectedCells[i].letter;
}
return word;
}
function checkForWord() {
var selectedWord = getSelectedWord();
for (var i = 0; i < currentTargetWords.length; i++) {
if (currentTargetWords[i].french === selectedWord && !targetWords[i].isFound) {
// Word found!
targetWords[i].markFound();
// Mark cells as found
for (var j = 0; j < selectedCells.length; j++) {
selectedCells[j].setFound();
}
LK.getSound('wordFound').play();
wordsFoundInSection++;
if (wordsFoundInSection >= 3) {
// Section complete
LK.setTimeout(function () {
LK.getSound('sectionComplete').play();
startNewSection();
}, 500);
}
break;
}
}
}
function startNewSection() {
currentSection++;
wordsFoundInSection = 0;
scoreTxt.setText('Section: ' + currentSection);
selectTargetWords();
createTargetWordsDisplay();
initializeGrid();
}
function clearSelection() {
for (var i = 0; i < selectedCells.length; i++) {
selectedCells[i].setSelected(false);
}
selectedCells = [];
}
function getCellAt(x, y) {
// Calculate grid position based on start position and cell size
var startX = 1024 - gridSize * cellSize / 2;
var startY = 400;
// Calculate which grid cell was touched directly from game coordinates
var col = Math.floor((x - startX) / cellSize);
var row = Math.floor((y - startY) / cellSize);
// Check bounds and return cell if valid
if (row >= 0 && row < gridSize && col >= 0 && col < gridSize) {
return gridCells[row][col];
}
return null;
}
function isValidSelection(lastCell, newCell) {
if (!lastCell) return true;
var rowDiff = Math.abs(lastCell.row - newCell.row);
var colDiff = Math.abs(lastCell.col - newCell.col);
// Allow horizontal, vertical, and diagonal connections
return rowDiff <= 1 && colDiff <= 1 && (rowDiff > 0 || colDiff > 0);
}
// Game events
game.down = function (x, y, obj) {
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
isDragging = true;
clearSelection();
selectedCells.push(cell);
cell.setSelected(true);
}
};
game.move = function (x, y, obj) {
if (!isDragging) return;
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
var lastCell = selectedCells.length > 0 ? selectedCells[selectedCells.length - 1] : null;
if (cell !== lastCell && isValidSelection(lastCell, cell)) {
// Check if cell is already in selection
var cellIndex = -1;
for (var i = 0; i < selectedCells.length; i++) {
if (selectedCells[i] === cell) {
cellIndex = i;
break;
}
}
if (cellIndex >= 0) {
// Remove cells after this one (backtracking)
for (var i = selectedCells.length - 1; i > cellIndex; i--) {
selectedCells[i].setSelected(false);
selectedCells.splice(i, 1);
}
} else {
// Add new cell to selection
selectedCells.push(cell);
cell.setSelected(true);
}
}
}
};
game.up = function (x, y, obj) {
if (isDragging) {
isDragging = false;
if (selectedCells.length > 0) {
checkForWord();
}
clearSelection();
}
};
// Initialize game
selectTargetWords();
createTargetWordsDisplay();
initializeGrid();