/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // EnglishWordBox: static target var EnglishWordBox = Container.expand(function () { var self = Container.call(this); // Attach box var box = self.attachAsset('englishBox', { anchorX: 0.5, anchorY: 0.5 }); // Attach text self.textObj = new Text2('', { size: 80, fill: 0xFFFFFF }); self.textObj.anchor.set(0.5, 0.5); self.addChild(self.textObj); // Store word self.word = ''; self.matchId = ''; // Set word and match id self.setWord = function (word, matchId) { self.word = word; self.matchId = matchId; self.textObj.setText(word); }; return self; }); // TurkishWordBox: draggable Turkish word var TurkishWordBox = Container.expand(function () { var self = Container.call(this); // Attach box var box = self.attachAsset('turkishBox', { anchorX: 0.5, anchorY: 0.5 }); // Attach text self.textObj = new Text2('', { size: 80, fill: 0xFFFFFF }); self.textObj.anchor.set(0.5, 0.5); self.addChild(self.textObj); // Store word self.word = ''; self.matchId = ''; // Drag state self.isDragging = false; // Set word and match id self.setWord = function (word, matchId) { self.word = word; self.matchId = matchId; self.textObj.setText(word); }; // For drag offset self.dragOffsetX = 0; self.dragOffsetY = 0; // Down event: start drag self.down = function (x, y, obj) { self.isDragging = true; // Offset from center self.dragOffsetX = self.x - x; self.dragOffsetY = self.y - y; dragNode = self; }; // Up event: handled in game.up return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf7f7f7 }); /**** * Game Code ****/ // Wrong match flash // Correct match flash // English word box // Turkish word box // --- Word Data --- var wordPairs = [{ tr: "Merhaba", en: "Hello" }, { tr: "Günaydın", en: "Good morning" }, { tr: "Teşekkürler", en: "Thank you" }, { tr: "Evet", en: "Yes" }, { tr: "Hayır", en: "No" }, { tr: "Lütfen", en: "Please" }, { tr: "Güle güle", en: "Goodbye" }, { tr: "Nasılsın?", en: "How are you?" }, { tr: "İyi", en: "Good" }, { tr: "Kötü", en: "Bad" }, { tr: "Tamam", en: "Okay" }, { tr: "Affedersiniz", en: "Excuse me" }, { tr: "Hoş geldiniz", en: "Welcome" }, { tr: "Hoşça kal", en: "Bye" }, { tr: "Benim adım...", en: "My name is..." }, { tr: "Ne?", en: "What?" }, { tr: "Kim?", en: "Who?" }, { tr: "Nerede?", en: "Where?" }, { tr: "Ne zaman?", en: "When?" }, { tr: "Neden?", en: "Why?" }]; // --- Game State --- var currentRound = 0; var score = 0; var timeLeft = 15; // seconds per round, will decrease var roundTimer = null; var timerText = null; var scoreText = null; var dragNode = null; var turkishBoxes = []; var englishBoxes = []; var matchCount = 0; var roundActive = false; var lastFlash = null; // --- UI Setup --- // Score display scoreText = new Text2('Score: 0', { size: 90, fill: 0x222222 }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Timer display timerText = new Text2('15', { size: 90, fill: 0xD83318 }); timerText.anchor.set(1, 0); LK.gui.topRight.addChild(timerText); // --- Game Functions --- function shuffleArray(arr) { // Fisher-Yates shuffle for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; } function startRound() { // Clean up previous round for (var i = 0; i < turkishBoxes.length; i++) { turkishBoxes[i].destroy(); } for (var i = 0; i < englishBoxes.length; i++) { englishBoxes[i].destroy(); } turkishBoxes = []; englishBoxes = []; matchCount = 0; dragNode = null; roundActive = true; // Increase difficulty: more pairs, less time var numPairs = 2 + Math.floor(currentRound / 2); if (numPairs > 6) { numPairs = 6; } timeLeft = 15 - currentRound * 1; if (timeLeft < 6) { timeLeft = 6; } // Pick random pairs var pairs = []; var used = []; while (pairs.length < numPairs && used.length < wordPairs.length) { var idx = Math.floor(Math.random() * wordPairs.length); if (used.indexOf(idx) === -1) { pairs.push({ tr: wordPairs[idx].tr, en: wordPairs[idx].en, id: 'pair' + idx }); used.push(idx); } } // Shuffle Turkish and English sides separately var turkishList = []; var englishList = []; for (var i = 0; i < pairs.length; i++) { turkishList.push({ word: pairs[i].tr, id: pairs[i].id }); englishList.push({ word: pairs[i].en, id: pairs[i].id }); } shuffleArray(turkishList); shuffleArray(englishList); // Layout Turkish boxes (draggable) on left var spacingY = 220; var startY = (2732 - (turkishList.length * spacingY - (spacingY - 180))) / 2; for (var i = 0; i < turkishList.length; i++) { var box = new TurkishWordBox(); box.setWord(turkishList[i].word, turkishList[i].id); box.x = 400; box.y = startY + i * spacingY; // Store initial position for snap-back box.initialX = box.x; box.initialY = box.y; turkishBoxes.push(box); game.addChild(box); } // Layout English boxes (targets) on right for (var i = 0; i < englishList.length; i++) { var box = new EnglishWordBox(); box.setWord(englishList[i].word, englishList[i].id); box.x = 2048 - 400; box.y = startY + i * spacingY; englishBoxes.push(box); game.addChild(box); } // Start timer timerText.setText(timeLeft); if (roundTimer) { LK.clearInterval(roundTimer); } roundTimer = LK.setInterval(function () { if (!roundActive) { return; } timeLeft -= 1; timerText.setText(timeLeft); if (timeLeft <= 0) { endRound(false); } }, 1000); } function endRound(success) { roundActive = false; if (roundTimer) { LK.clearInterval(roundTimer); roundTimer = null; } // Flash feedback if (success) { LK.effects.flashScreen(0x83de44, 600); } else { LK.effects.flashScreen(0xff0000, 900); } // Next round or game over LK.setTimeout(function () { if (success) { currentRound += 1; if (currentRound >= 10) { LK.showYouWin(); } else { startRound(); } } else { LK.showGameOver(); } }, 900); } function checkMatch(turkishBox, englishBox) { if (!roundActive) { return; } if (turkishBox.matchId === englishBox.matchId) { // Correct score += 1; LK.setScore(score); scoreText.setText('Score: ' + score); // Animate to target tween(turkishBox, { x: englishBox.x, y: englishBox.y }, { duration: 250, easing: tween.easeIn, onFinish: function onFinish() { turkishBox.destroy(); englishBox.destroy(); } }); // Remove from arrays for (var i = 0; i < turkishBoxes.length; i++) { if (turkishBoxes[i] === turkishBox) { turkishBoxes.splice(i, 1); break; } } for (var i = 0; i < englishBoxes.length; i++) { if (englishBoxes[i] === englishBox) { englishBoxes.splice(i, 1); break; } } matchCount += 1; LK.effects.flashObject(turkishBox, 0x83de44, 400); // Only pass if all Turkish and English boxes are matched (arrays are empty) if (turkishBoxes.length === 0 && englishBoxes.length === 0) { endRound(true); } } else { // Wrong score -= 1; if (score < 0) score = 0; LK.setScore(score); scoreText.setText('Score: ' + score); LK.effects.flashObject(turkishBox, 0xff0000, 400); // Snap back tween(turkishBox, { x: typeof turkishBox.initialX !== "undefined" ? turkishBox.initialX : 400, y: typeof turkishBox.initialY !== "undefined" ? turkishBox.initialY : turkishBox.y }, { duration: 200, easing: tween.easeOut }); } } // --- Drag and Drop Logic --- function handleMove(x, y, obj) { if (!roundActive) { return; } if (dragNode && dragNode.isDragging) { // Move Turkish box to where player touches (centered) dragNode.x = x; dragNode.y = y; } } game.move = handleMove; game.down = function (x, y, obj) { if (!roundActive) { return; } // Check if a Turkish box is pressed for (var i = 0; i < turkishBoxes.length; i++) { var box = turkishBoxes[i]; // Check bounds var bx = box.x - box.width / 2; var by = box.y - box.height / 2; if (x >= bx && x <= bx + box.width && y >= by && y <= by + box.height) { // Start drag box.down(x, y, obj); break; } } }; game.up = function (x, y, obj) { if (!roundActive) { return; } if (dragNode && dragNode.isDragging) { // Check if over any English box var dropped = false; for (var i = 0; i < englishBoxes.length; i++) { var target = englishBoxes[i]; if (dragNode.intersects(target)) { checkMatch(dragNode, target); dropped = true; break; } } if (!dropped) { // Check for nesting with other Turkish boxes var nested = false; for (var i = 0; i < turkishBoxes.length; i++) { var other = turkishBoxes[i]; if (other !== dragNode && dragNode.intersects(other)) { nested = true; break; } } if (nested) { // Find a free Y position (not overlapping others) var spacingY = 220; var startY = (2732 - (turkishBoxes.length * spacingY - (spacingY - 180))) / 2; var found = false; for (var tryI = 0; tryI < 20 && !found; tryI++) { var tryY = startY + Math.floor(Math.random() * turkishBoxes.length) * spacingY; var overlap = false; for (var j = 0; j < turkishBoxes.length; j++) { var otherBox = turkishBoxes[j]; if (otherBox !== dragNode) { var dy = Math.abs(otherBox.y - tryY); if (dy < 180) { // box height overlap = true; break; } } } if (!overlap) { found = true; tween(dragNode, { x: 400, y: tryY }, { duration: 200, easing: tween.easeOut }); } } if (!found) { // fallback: snap to default tween(dragNode, { x: 400 }, { duration: 200, easing: tween.easeOut }); } } else { // Snap back tween(dragNode, { x: typeof dragNode.initialX !== "undefined" ? dragNode.initialX : 400, y: typeof dragNode.initialY !== "undefined" ? dragNode.initialY : dragNode.y }, { duration: 200, easing: tween.easeOut }); } } dragNode.isDragging = false; dragNode = null; } }; // --- Game Update --- game.update = function () { // No per-frame logic needed for now }; // --- Start Game --- currentRound = 0; score = 0; LK.setScore(0); scoreText.setText('Score: 0'); startRound();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// EnglishWordBox: static target
var EnglishWordBox = Container.expand(function () {
var self = Container.call(this);
// Attach box
var box = self.attachAsset('englishBox', {
anchorX: 0.5,
anchorY: 0.5
});
// Attach text
self.textObj = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
self.textObj.anchor.set(0.5, 0.5);
self.addChild(self.textObj);
// Store word
self.word = '';
self.matchId = '';
// Set word and match id
self.setWord = function (word, matchId) {
self.word = word;
self.matchId = matchId;
self.textObj.setText(word);
};
return self;
});
// TurkishWordBox: draggable Turkish word
var TurkishWordBox = Container.expand(function () {
var self = Container.call(this);
// Attach box
var box = self.attachAsset('turkishBox', {
anchorX: 0.5,
anchorY: 0.5
});
// Attach text
self.textObj = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
self.textObj.anchor.set(0.5, 0.5);
self.addChild(self.textObj);
// Store word
self.word = '';
self.matchId = '';
// Drag state
self.isDragging = false;
// Set word and match id
self.setWord = function (word, matchId) {
self.word = word;
self.matchId = matchId;
self.textObj.setText(word);
};
// For drag offset
self.dragOffsetX = 0;
self.dragOffsetY = 0;
// Down event: start drag
self.down = function (x, y, obj) {
self.isDragging = true;
// Offset from center
self.dragOffsetX = self.x - x;
self.dragOffsetY = self.y - y;
dragNode = self;
};
// Up event: handled in game.up
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf7f7f7
});
/****
* Game Code
****/
// Wrong match flash
// Correct match flash
// English word box
// Turkish word box
// --- Word Data ---
var wordPairs = [{
tr: "Merhaba",
en: "Hello"
}, {
tr: "Günaydın",
en: "Good morning"
}, {
tr: "Teşekkürler",
en: "Thank you"
}, {
tr: "Evet",
en: "Yes"
}, {
tr: "Hayır",
en: "No"
}, {
tr: "Lütfen",
en: "Please"
}, {
tr: "Güle güle",
en: "Goodbye"
}, {
tr: "Nasılsın?",
en: "How are you?"
}, {
tr: "İyi",
en: "Good"
}, {
tr: "Kötü",
en: "Bad"
}, {
tr: "Tamam",
en: "Okay"
}, {
tr: "Affedersiniz",
en: "Excuse me"
}, {
tr: "Hoş geldiniz",
en: "Welcome"
}, {
tr: "Hoşça kal",
en: "Bye"
}, {
tr: "Benim adım...",
en: "My name is..."
}, {
tr: "Ne?",
en: "What?"
}, {
tr: "Kim?",
en: "Who?"
}, {
tr: "Nerede?",
en: "Where?"
}, {
tr: "Ne zaman?",
en: "When?"
}, {
tr: "Neden?",
en: "Why?"
}];
// --- Game State ---
var currentRound = 0;
var score = 0;
var timeLeft = 15; // seconds per round, will decrease
var roundTimer = null;
var timerText = null;
var scoreText = null;
var dragNode = null;
var turkishBoxes = [];
var englishBoxes = [];
var matchCount = 0;
var roundActive = false;
var lastFlash = null;
// --- UI Setup ---
// Score display
scoreText = new Text2('Score: 0', {
size: 90,
fill: 0x222222
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Timer display
timerText = new Text2('15', {
size: 90,
fill: 0xD83318
});
timerText.anchor.set(1, 0);
LK.gui.topRight.addChild(timerText);
// --- Game Functions ---
function shuffleArray(arr) {
// Fisher-Yates shuffle
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return arr;
}
function startRound() {
// Clean up previous round
for (var i = 0; i < turkishBoxes.length; i++) {
turkishBoxes[i].destroy();
}
for (var i = 0; i < englishBoxes.length; i++) {
englishBoxes[i].destroy();
}
turkishBoxes = [];
englishBoxes = [];
matchCount = 0;
dragNode = null;
roundActive = true;
// Increase difficulty: more pairs, less time
var numPairs = 2 + Math.floor(currentRound / 2);
if (numPairs > 6) {
numPairs = 6;
}
timeLeft = 15 - currentRound * 1;
if (timeLeft < 6) {
timeLeft = 6;
}
// Pick random pairs
var pairs = [];
var used = [];
while (pairs.length < numPairs && used.length < wordPairs.length) {
var idx = Math.floor(Math.random() * wordPairs.length);
if (used.indexOf(idx) === -1) {
pairs.push({
tr: wordPairs[idx].tr,
en: wordPairs[idx].en,
id: 'pair' + idx
});
used.push(idx);
}
}
// Shuffle Turkish and English sides separately
var turkishList = [];
var englishList = [];
for (var i = 0; i < pairs.length; i++) {
turkishList.push({
word: pairs[i].tr,
id: pairs[i].id
});
englishList.push({
word: pairs[i].en,
id: pairs[i].id
});
}
shuffleArray(turkishList);
shuffleArray(englishList);
// Layout Turkish boxes (draggable) on left
var spacingY = 220;
var startY = (2732 - (turkishList.length * spacingY - (spacingY - 180))) / 2;
for (var i = 0; i < turkishList.length; i++) {
var box = new TurkishWordBox();
box.setWord(turkishList[i].word, turkishList[i].id);
box.x = 400;
box.y = startY + i * spacingY;
// Store initial position for snap-back
box.initialX = box.x;
box.initialY = box.y;
turkishBoxes.push(box);
game.addChild(box);
}
// Layout English boxes (targets) on right
for (var i = 0; i < englishList.length; i++) {
var box = new EnglishWordBox();
box.setWord(englishList[i].word, englishList[i].id);
box.x = 2048 - 400;
box.y = startY + i * spacingY;
englishBoxes.push(box);
game.addChild(box);
}
// Start timer
timerText.setText(timeLeft);
if (roundTimer) {
LK.clearInterval(roundTimer);
}
roundTimer = LK.setInterval(function () {
if (!roundActive) {
return;
}
timeLeft -= 1;
timerText.setText(timeLeft);
if (timeLeft <= 0) {
endRound(false);
}
}, 1000);
}
function endRound(success) {
roundActive = false;
if (roundTimer) {
LK.clearInterval(roundTimer);
roundTimer = null;
}
// Flash feedback
if (success) {
LK.effects.flashScreen(0x83de44, 600);
} else {
LK.effects.flashScreen(0xff0000, 900);
}
// Next round or game over
LK.setTimeout(function () {
if (success) {
currentRound += 1;
if (currentRound >= 10) {
LK.showYouWin();
} else {
startRound();
}
} else {
LK.showGameOver();
}
}, 900);
}
function checkMatch(turkishBox, englishBox) {
if (!roundActive) {
return;
}
if (turkishBox.matchId === englishBox.matchId) {
// Correct
score += 1;
LK.setScore(score);
scoreText.setText('Score: ' + score);
// Animate to target
tween(turkishBox, {
x: englishBox.x,
y: englishBox.y
}, {
duration: 250,
easing: tween.easeIn,
onFinish: function onFinish() {
turkishBox.destroy();
englishBox.destroy();
}
});
// Remove from arrays
for (var i = 0; i < turkishBoxes.length; i++) {
if (turkishBoxes[i] === turkishBox) {
turkishBoxes.splice(i, 1);
break;
}
}
for (var i = 0; i < englishBoxes.length; i++) {
if (englishBoxes[i] === englishBox) {
englishBoxes.splice(i, 1);
break;
}
}
matchCount += 1;
LK.effects.flashObject(turkishBox, 0x83de44, 400);
// Only pass if all Turkish and English boxes are matched (arrays are empty)
if (turkishBoxes.length === 0 && englishBoxes.length === 0) {
endRound(true);
}
} else {
// Wrong
score -= 1;
if (score < 0) score = 0;
LK.setScore(score);
scoreText.setText('Score: ' + score);
LK.effects.flashObject(turkishBox, 0xff0000, 400);
// Snap back
tween(turkishBox, {
x: typeof turkishBox.initialX !== "undefined" ? turkishBox.initialX : 400,
y: typeof turkishBox.initialY !== "undefined" ? turkishBox.initialY : turkishBox.y
}, {
duration: 200,
easing: tween.easeOut
});
}
}
// --- Drag and Drop Logic ---
function handleMove(x, y, obj) {
if (!roundActive) {
return;
}
if (dragNode && dragNode.isDragging) {
// Move Turkish box to where player touches (centered)
dragNode.x = x;
dragNode.y = y;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!roundActive) {
return;
}
// Check if a Turkish box is pressed
for (var i = 0; i < turkishBoxes.length; i++) {
var box = turkishBoxes[i];
// Check bounds
var bx = box.x - box.width / 2;
var by = box.y - box.height / 2;
if (x >= bx && x <= bx + box.width && y >= by && y <= by + box.height) {
// Start drag
box.down(x, y, obj);
break;
}
}
};
game.up = function (x, y, obj) {
if (!roundActive) {
return;
}
if (dragNode && dragNode.isDragging) {
// Check if over any English box
var dropped = false;
for (var i = 0; i < englishBoxes.length; i++) {
var target = englishBoxes[i];
if (dragNode.intersects(target)) {
checkMatch(dragNode, target);
dropped = true;
break;
}
}
if (!dropped) {
// Check for nesting with other Turkish boxes
var nested = false;
for (var i = 0; i < turkishBoxes.length; i++) {
var other = turkishBoxes[i];
if (other !== dragNode && dragNode.intersects(other)) {
nested = true;
break;
}
}
if (nested) {
// Find a free Y position (not overlapping others)
var spacingY = 220;
var startY = (2732 - (turkishBoxes.length * spacingY - (spacingY - 180))) / 2;
var found = false;
for (var tryI = 0; tryI < 20 && !found; tryI++) {
var tryY = startY + Math.floor(Math.random() * turkishBoxes.length) * spacingY;
var overlap = false;
for (var j = 0; j < turkishBoxes.length; j++) {
var otherBox = turkishBoxes[j];
if (otherBox !== dragNode) {
var dy = Math.abs(otherBox.y - tryY);
if (dy < 180) {
// box height
overlap = true;
break;
}
}
}
if (!overlap) {
found = true;
tween(dragNode, {
x: 400,
y: tryY
}, {
duration: 200,
easing: tween.easeOut
});
}
}
if (!found) {
// fallback: snap to default
tween(dragNode, {
x: 400
}, {
duration: 200,
easing: tween.easeOut
});
}
} else {
// Snap back
tween(dragNode, {
x: typeof dragNode.initialX !== "undefined" ? dragNode.initialX : 400,
y: typeof dragNode.initialY !== "undefined" ? dragNode.initialY : dragNode.y
}, {
duration: 200,
easing: tween.easeOut
});
}
}
dragNode.isDragging = false;
dragNode = null;
}
};
// --- Game Update ---
game.update = function () {
// No per-frame logic needed for now
};
// --- Start Game ---
currentRound = 0;
score = 0;
LK.setScore(0);
scoreText.setText('Score: 0');
startRound();