User prompt
когда заходишь на Learning Mode то там где показывается "кана" и как он читается то там баг, они друг на друга положились, исправь это. сделай выбор языка интерфейса Английский и Русский
User prompt
интерфейс всё ещё немного староватый измени интерфейс. сделай звук на правильном ответе и звук в неправильном ответе
User prompt
улучши интерфейс игры сделай современным и красивым и понятным и добавь ещё варианты и комбинации в катакану и в хирагану
Code edit (1 edits merged)
Please save this source code
User prompt
Japanese Character Master
Initial prompt
Создай игру для тренировки японского, например тесты на хирагану и на катакану. тесты на хирагану отдельный тест на катакану отдельный. ещё когда заходишь в программу можно было немного выучить хирагану и катакану
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AnswerButton = Container.expand(function (text, isCorrect, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 40,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.isCorrect = isCorrect;
self.callback = callback;
self.isPressed = false;
self.down = function (x, y, obj) {
if (!self.isPressed) {
self.isPressed = true;
tween(buttonGraphics, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
if (self.callback) {
self.callback(self.isCorrect);
}
}
};
return self;
});
var CharacterDisplay = Container.expand(function (character, romanization) {
var self = Container.call(this);
var cardGraphics = self.attachAsset('characterCard', {
anchorX: 0.5,
anchorY: 0.5
});
var charText = new Text2(character, {
size: 120,
fill: 0x000000
});
charText.anchor.set(0.5, 0.3);
self.addChild(charText);
var romText = new Text2(romanization, {
size: 50,
fill: 0x666666
});
romText.anchor.set(0.5, 0.7);
self.addChild(romText);
return self;
});
var MenuButton = Container.expand(function (text, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 50,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.callback = callback;
self.down = function (x, y, obj) {
tween(buttonGraphics, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
if (self.callback) {
self.callback();
}
};
self.up = function (x, y, obj) {
tween(buttonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// Game data
var hiraganaChars = [{
"char": 'あ',
rom: 'a'
}, {
"char": 'い',
rom: 'i'
}, {
"char": 'う',
rom: 'u'
}, {
"char": 'え',
rom: 'e'
}, {
"char": 'お',
rom: 'o'
}, {
"char": 'か',
rom: 'ka'
}, {
"char": 'き',
rom: 'ki'
}, {
"char": 'く',
rom: 'ku'
}, {
"char": 'け',
rom: 'ke'
}, {
"char": 'こ',
rom: 'ko'
}, {
"char": 'さ',
rom: 'sa'
}, {
"char": 'し',
rom: 'shi'
}, {
"char": 'す',
rom: 'su'
}, {
"char": 'せ',
rom: 'se'
}, {
"char": 'そ',
rom: 'so'
}, {
"char": 'た',
rom: 'ta'
}, {
"char": 'ち',
rom: 'chi'
}, {
"char": 'つ',
rom: 'tsu'
}, {
"char": 'て',
rom: 'te'
}, {
"char": 'と',
rom: 'to'
}, {
"char": 'な',
rom: 'na'
}, {
"char": 'に',
rom: 'ni'
}, {
"char": 'ぬ',
rom: 'nu'
}, {
"char": 'ね',
rom: 'ne'
}, {
"char": 'の',
rom: 'no'
}, {
"char": 'は',
rom: 'ha'
}, {
"char": 'ひ',
rom: 'hi'
}, {
"char": 'ふ',
rom: 'fu'
}, {
"char": 'へ',
rom: 'he'
}, {
"char": 'ほ',
rom: 'ho'
}, {
"char": 'ま',
rom: 'ma'
}, {
"char": 'み',
rom: 'mi'
}, {
"char": 'む',
rom: 'mu'
}, {
"char": 'め',
rom: 'me'
}, {
"char": 'も',
rom: 'mo'
}, {
"char": 'や',
rom: 'ya'
}, {
"char": 'ゆ',
rom: 'yu'
}, {
"char": 'よ',
rom: 'yo'
}, {
"char": 'ら',
rom: 'ra'
}, {
"char": 'り',
rom: 'ri'
}, {
"char": 'る',
rom: 'ru'
}, {
"char": 'れ',
rom: 're'
}, {
"char": 'ろ',
rom: 'ro'
}, {
"char": 'わ',
rom: 'wa'
}, {
"char": 'を',
rom: 'wo'
}, {
"char": 'ん',
rom: 'n'
}];
var katakanaChars = [{
"char": 'ア',
rom: 'a'
}, {
"char": 'イ',
rom: 'i'
}, {
"char": 'ウ',
rom: 'u'
}, {
"char": 'エ',
rom: 'e'
}, {
"char": 'オ',
rom: 'o'
}, {
"char": 'カ',
rom: 'ka'
}, {
"char": 'キ',
rom: 'ki'
}, {
"char": 'ク',
rom: 'ku'
}, {
"char": 'ケ',
rom: 'ke'
}, {
"char": 'コ',
rom: 'ko'
}, {
"char": 'サ',
rom: 'sa'
}, {
"char": 'シ',
rom: 'shi'
}, {
"char": 'ス',
rom: 'su'
}, {
"char": 'セ',
rom: 'se'
}, {
"char": 'ソ',
rom: 'so'
}, {
"char": 'タ',
rom: 'ta'
}, {
"char": 'チ',
rom: 'chi'
}, {
"char": 'ツ',
rom: 'tsu'
}, {
"char": 'テ',
rom: 'te'
}, {
"char": 'ト',
rom: 'to'
}, {
"char": 'ナ',
rom: 'na'
}, {
"char": 'ニ',
rom: 'ni'
}, {
"char": 'ヌ',
rom: 'nu'
}, {
"char": 'ネ',
rom: 'ne'
}, {
"char": 'ノ',
rom: 'no'
}, {
"char": 'ハ',
rom: 'ha'
}, {
"char": 'ヒ',
rom: 'hi'
}, {
"char": 'フ',
rom: 'fu'
}, {
"char": 'ヘ',
rom: 'he'
}, {
"char": 'ホ',
rom: 'ho'
}, {
"char": 'マ',
rom: 'ma'
}, {
"char": 'ミ',
rom: 'mi'
}, {
"char": 'ム',
rom: 'mu'
}, {
"char": 'メ',
rom: 'me'
}, {
"char": 'モ',
rom: 'mo'
}, {
"char": 'ヤ',
rom: 'ya'
}, {
"char": 'ユ',
rom: 'yu'
}, {
"char": 'ヨ',
rom: 'yo'
}, {
"char": 'ラ',
rom: 'ra'
}, {
"char": 'リ',
rom: 'ri'
}, {
"char": 'ル',
rom: 'ru'
}, {
"char": 'レ',
rom: 're'
}, {
"char": 'ロ',
rom: 'ro'
}, {
"char": 'ワ',
rom: 'wa'
}, {
"char": 'ヲ',
rom: 'wo'
}, {
"char": 'ン',
rom: 'n'
}];
// Game state
var gameState = 'menu'; // 'menu', 'learn', 'hiraganaTest', 'katakanaTest'
var currentMode = null;
var currentCharIndex = 0;
var currentQuestion = null;
var answerButtons = [];
var score = 0;
var streak = 0;
var questionsAnswered = 0;
// Load saved progress
var savedScore = storage.bestScore || 0;
var savedStreak = storage.bestStreak || 0;
// UI Elements
var backgroundPanel = game.addChild(LK.getAsset('backgroundPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
var titleText = new Text2('Japanese Character Master', {
size: 80,
fill: 0x333333
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
var scoreText = new Text2('Best Score: ' + savedScore, {
size: 40,
fill: 0x666666
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
scoreText.y = 50;
var currentScoreText = new Text2('Score: 0', {
size: 50,
fill: 0x333333
});
currentScoreText.anchor.set(0.5, 0);
currentScoreText.x = 1024;
currentScoreText.y = 200;
game.addChild(currentScoreText);
currentScoreText.visible = false;
var streakText = new Text2('Streak: 0', {
size: 40,
fill: 0x4A90E2
});
streakText.anchor.set(0.5, 0);
streakText.x = 1024;
streakText.y = 260;
game.addChild(streakText);
streakText.visible = false;
// Menu buttons
var learnButton = game.addChild(new MenuButton('Learn Mode', function () {
startLearnMode();
}));
learnButton.x = 1024;
learnButton.y = 700;
var hiraganaButton = game.addChild(new MenuButton('Hiragana Test', function () {
startHiraganaTest();
}));
hiraganaButton.x = 1024;
hiraganaButton.y = 850;
var katakanaButton = game.addChild(new MenuButton('Katakana Test', function () {
startKatakanaTest();
}));
katakanaButton.x = 1024;
katakanaButton.y = 1000;
var backButton = game.addChild(new MenuButton('Back to Menu', function () {
returnToMenu();
}));
backButton.x = 1024;
backButton.y = 2200;
backButton.visible = false;
var nextButton = game.addChild(new MenuButton('Next Character', function () {
showNextCharacter();
}));
nextButton.x = 1024;
nextButton.y = 1800;
nextButton.visible = false;
var prevButton = game.addChild(new MenuButton('Previous Character', function () {
showPrevCharacter();
}));
prevButton.x = 1024;
prevButton.y = 1950;
prevButton.visible = false;
// Character display for learn mode
var characterDisplay = null;
// Question character display for tests
var questionCharText = new Text2('', {
size: 150,
fill: 0x000000
});
questionCharText.anchor.set(0.5, 0.5);
questionCharText.x = 1024;
questionCharText.y = 600;
game.addChild(questionCharText);
questionCharText.visible = false;
function hideMenuElements() {
titleText.visible = false;
learnButton.visible = false;
hiraganaButton.visible = false;
katakanaButton.visible = false;
}
function showMenuElements() {
titleText.visible = true;
learnButton.visible = true;
hiraganaButton.visible = true;
katakanaButton.visible = true;
backButton.visible = false;
nextButton.visible = false;
prevButton.visible = false;
currentScoreText.visible = false;
streakText.visible = false;
questionCharText.visible = false;
if (characterDisplay) {
characterDisplay.visible = false;
}
for (var i = 0; i < answerButtons.length; i++) {
answerButtons[i].visible = false;
}
}
function startLearnMode() {
gameState = 'learn';
currentMode = hiraganaChars;
currentCharIndex = 0;
hideMenuElements();
backButton.visible = true;
nextButton.visible = true;
prevButton.visible = true;
showCurrentCharacter();
}
function startHiraganaTest() {
gameState = 'hiraganaTest';
currentMode = hiraganaChars;
score = 0;
streak = 0;
questionsAnswered = 0;
hideMenuElements();
backButton.visible = true;
currentScoreText.visible = true;
streakText.visible = true;
questionCharText.visible = true;
updateScoreDisplay();
generateQuestion();
}
function startKatakanaTest() {
gameState = 'katakanaTest';
currentMode = katakanaChars;
score = 0;
streak = 0;
questionsAnswered = 0;
hideMenuElements();
backButton.visible = true;
currentScoreText.visible = true;
streakText.visible = true;
questionCharText.visible = true;
updateScoreDisplay();
generateQuestion();
}
function returnToMenu() {
gameState = 'menu';
showMenuElements();
}
function showCurrentCharacter() {
if (characterDisplay) {
game.removeChild(characterDisplay);
}
var _char = currentMode[currentCharIndex];
characterDisplay = game.addChild(new CharacterDisplay(_char["char"], _char.rom));
characterDisplay.x = 1024;
characterDisplay.y = 1000;
}
function showNextCharacter() {
currentCharIndex = (currentCharIndex + 1) % currentMode.length;
showCurrentCharacter();
}
function showPrevCharacter() {
currentCharIndex = (currentCharIndex - 1 + currentMode.length) % currentMode.length;
showCurrentCharacter();
}
function generateQuestion() {
// Clear previous answer buttons
for (var i = 0; i < answerButtons.length; i++) {
game.removeChild(answerButtons[i]);
}
answerButtons = [];
// Pick random character
var randomIndex = Math.floor(Math.random() * currentMode.length);
currentQuestion = currentMode[randomIndex];
questionCharText.setText(currentQuestion["char"]);
// Generate wrong answers
var wrongAnswers = [];
while (wrongAnswers.length < 3) {
var wrongIndex = Math.floor(Math.random() * currentMode.length);
var wrongAnswer = currentMode[wrongIndex].rom;
if (wrongAnswer !== currentQuestion.rom && wrongAnswers.indexOf(wrongAnswer) === -1) {
wrongAnswers.push(wrongAnswer);
}
}
// Create answer options
var allAnswers = [currentQuestion.rom].concat(wrongAnswers);
// Shuffle answers
for (var i = allAnswers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allAnswers[i];
allAnswers[i] = allAnswers[j];
allAnswers[j] = temp;
}
// Create answer buttons
var buttonPositions = [{
x: 512,
y: 1000
}, {
x: 1536,
y: 1000
}, {
x: 512,
y: 1150
}, {
x: 1536,
y: 1150
}];
for (var i = 0; i < 4; i++) {
var isCorrect = allAnswers[i] === currentQuestion.rom;
var button = game.addChild(new AnswerButton(allAnswers[i], isCorrect, onAnswerSelected));
button.x = buttonPositions[i].x;
button.y = buttonPositions[i].y;
answerButtons.push(button);
}
}
function onAnswerSelected(isCorrect) {
questionsAnswered++;
if (isCorrect) {
score++;
streak++;
LK.getSound('correct').play();
// Show correct feedback
var feedback = game.addChild(LK.getAsset('correctFeedback', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
alpha: 0
}));
tween(feedback, {
alpha: 1
}, {
duration: 200,
onFinish: function onFinish() {
tween(feedback, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
game.removeChild(feedback);
}
});
}
});
} else {
streak = 0;
LK.getSound('incorrect').play();
// Show incorrect feedback
var feedback = game.addChild(LK.getAsset('incorrectFeedback', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
alpha: 0
}));
tween(feedback, {
alpha: 1
}, {
duration: 200,
onFinish: function onFinish() {
tween(feedback, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
game.removeChild(feedback);
}
});
}
});
}
updateScoreDisplay();
// Save best scores
if (score > savedScore) {
savedScore = score;
storage.bestScore = savedScore;
scoreText.setText('Best Score: ' + savedScore);
}
if (streak > savedStreak) {
savedStreak = streak;
storage.bestStreak = savedStreak;
}
// Generate next question after delay
LK.setTimeout(function () {
generateQuestion();
}, 800);
}
function updateScoreDisplay() {
currentScoreText.setText('Score: ' + score);
streakText.setText('Streak: ' + streak);
}
// Game update loop
game.update = function () {
// Game loop logic if needed
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,695 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var AnswerButton = Container.expand(function (text, isCorrect, callback) {
+ var self = Container.call(this);
+ var buttonGraphics = self.attachAsset('answerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var buttonText = new Text2(text, {
+ size: 40,
+ fill: 0x000000
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ self.addChild(buttonText);
+ self.isCorrect = isCorrect;
+ self.callback = callback;
+ self.isPressed = false;
+ self.down = function (x, y, obj) {
+ if (!self.isPressed) {
+ self.isPressed = true;
+ tween(buttonGraphics, {
+ scaleX: 0.9,
+ scaleY: 0.9
+ }, {
+ duration: 100
+ });
+ if (self.callback) {
+ self.callback(self.isCorrect);
+ }
+ }
+ };
+ return self;
+});
+var CharacterDisplay = Container.expand(function (character, romanization) {
+ var self = Container.call(this);
+ var cardGraphics = self.attachAsset('characterCard', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var charText = new Text2(character, {
+ size: 120,
+ fill: 0x000000
+ });
+ charText.anchor.set(0.5, 0.3);
+ self.addChild(charText);
+ var romText = new Text2(romanization, {
+ size: 50,
+ fill: 0x666666
+ });
+ romText.anchor.set(0.5, 0.7);
+ self.addChild(romText);
+ return self;
+});
+var MenuButton = Container.expand(function (text, callback) {
+ var self = Container.call(this);
+ var buttonGraphics = self.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var buttonText = new Text2(text, {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ self.addChild(buttonText);
+ self.callback = callback;
+ self.down = function (x, y, obj) {
+ tween(buttonGraphics, {
+ scaleX: 0.95,
+ scaleY: 0.95
+ }, {
+ duration: 100
+ });
+ if (self.callback) {
+ self.callback();
+ }
+ };
+ self.up = function (x, y, obj) {
+ tween(buttonGraphics, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 100
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xffffff
+});
+
+/****
+* Game Code
+****/
+// Game data
+var hiraganaChars = [{
+ "char": 'あ',
+ rom: 'a'
+}, {
+ "char": 'い',
+ rom: 'i'
+}, {
+ "char": 'う',
+ rom: 'u'
+}, {
+ "char": 'え',
+ rom: 'e'
+}, {
+ "char": 'お',
+ rom: 'o'
+}, {
+ "char": 'か',
+ rom: 'ka'
+}, {
+ "char": 'き',
+ rom: 'ki'
+}, {
+ "char": 'く',
+ rom: 'ku'
+}, {
+ "char": 'け',
+ rom: 'ke'
+}, {
+ "char": 'こ',
+ rom: 'ko'
+}, {
+ "char": 'さ',
+ rom: 'sa'
+}, {
+ "char": 'し',
+ rom: 'shi'
+}, {
+ "char": 'す',
+ rom: 'su'
+}, {
+ "char": 'せ',
+ rom: 'se'
+}, {
+ "char": 'そ',
+ rom: 'so'
+}, {
+ "char": 'た',
+ rom: 'ta'
+}, {
+ "char": 'ち',
+ rom: 'chi'
+}, {
+ "char": 'つ',
+ rom: 'tsu'
+}, {
+ "char": 'て',
+ rom: 'te'
+}, {
+ "char": 'と',
+ rom: 'to'
+}, {
+ "char": 'な',
+ rom: 'na'
+}, {
+ "char": 'に',
+ rom: 'ni'
+}, {
+ "char": 'ぬ',
+ rom: 'nu'
+}, {
+ "char": 'ね',
+ rom: 'ne'
+}, {
+ "char": 'の',
+ rom: 'no'
+}, {
+ "char": 'は',
+ rom: 'ha'
+}, {
+ "char": 'ひ',
+ rom: 'hi'
+}, {
+ "char": 'ふ',
+ rom: 'fu'
+}, {
+ "char": 'へ',
+ rom: 'he'
+}, {
+ "char": 'ほ',
+ rom: 'ho'
+}, {
+ "char": 'ま',
+ rom: 'ma'
+}, {
+ "char": 'み',
+ rom: 'mi'
+}, {
+ "char": 'む',
+ rom: 'mu'
+}, {
+ "char": 'め',
+ rom: 'me'
+}, {
+ "char": 'も',
+ rom: 'mo'
+}, {
+ "char": 'や',
+ rom: 'ya'
+}, {
+ "char": 'ゆ',
+ rom: 'yu'
+}, {
+ "char": 'よ',
+ rom: 'yo'
+}, {
+ "char": 'ら',
+ rom: 'ra'
+}, {
+ "char": 'り',
+ rom: 'ri'
+}, {
+ "char": 'る',
+ rom: 'ru'
+}, {
+ "char": 'れ',
+ rom: 're'
+}, {
+ "char": 'ろ',
+ rom: 'ro'
+}, {
+ "char": 'わ',
+ rom: 'wa'
+}, {
+ "char": 'を',
+ rom: 'wo'
+}, {
+ "char": 'ん',
+ rom: 'n'
+}];
+var katakanaChars = [{
+ "char": 'ア',
+ rom: 'a'
+}, {
+ "char": 'イ',
+ rom: 'i'
+}, {
+ "char": 'ウ',
+ rom: 'u'
+}, {
+ "char": 'エ',
+ rom: 'e'
+}, {
+ "char": 'オ',
+ rom: 'o'
+}, {
+ "char": 'カ',
+ rom: 'ka'
+}, {
+ "char": 'キ',
+ rom: 'ki'
+}, {
+ "char": 'ク',
+ rom: 'ku'
+}, {
+ "char": 'ケ',
+ rom: 'ke'
+}, {
+ "char": 'コ',
+ rom: 'ko'
+}, {
+ "char": 'サ',
+ rom: 'sa'
+}, {
+ "char": 'シ',
+ rom: 'shi'
+}, {
+ "char": 'ス',
+ rom: 'su'
+}, {
+ "char": 'セ',
+ rom: 'se'
+}, {
+ "char": 'ソ',
+ rom: 'so'
+}, {
+ "char": 'タ',
+ rom: 'ta'
+}, {
+ "char": 'チ',
+ rom: 'chi'
+}, {
+ "char": 'ツ',
+ rom: 'tsu'
+}, {
+ "char": 'テ',
+ rom: 'te'
+}, {
+ "char": 'ト',
+ rom: 'to'
+}, {
+ "char": 'ナ',
+ rom: 'na'
+}, {
+ "char": 'ニ',
+ rom: 'ni'
+}, {
+ "char": 'ヌ',
+ rom: 'nu'
+}, {
+ "char": 'ネ',
+ rom: 'ne'
+}, {
+ "char": 'ノ',
+ rom: 'no'
+}, {
+ "char": 'ハ',
+ rom: 'ha'
+}, {
+ "char": 'ヒ',
+ rom: 'hi'
+}, {
+ "char": 'フ',
+ rom: 'fu'
+}, {
+ "char": 'ヘ',
+ rom: 'he'
+}, {
+ "char": 'ホ',
+ rom: 'ho'
+}, {
+ "char": 'マ',
+ rom: 'ma'
+}, {
+ "char": 'ミ',
+ rom: 'mi'
+}, {
+ "char": 'ム',
+ rom: 'mu'
+}, {
+ "char": 'メ',
+ rom: 'me'
+}, {
+ "char": 'モ',
+ rom: 'mo'
+}, {
+ "char": 'ヤ',
+ rom: 'ya'
+}, {
+ "char": 'ユ',
+ rom: 'yu'
+}, {
+ "char": 'ヨ',
+ rom: 'yo'
+}, {
+ "char": 'ラ',
+ rom: 'ra'
+}, {
+ "char": 'リ',
+ rom: 'ri'
+}, {
+ "char": 'ル',
+ rom: 'ru'
+}, {
+ "char": 'レ',
+ rom: 're'
+}, {
+ "char": 'ロ',
+ rom: 'ro'
+}, {
+ "char": 'ワ',
+ rom: 'wa'
+}, {
+ "char": 'ヲ',
+ rom: 'wo'
+}, {
+ "char": 'ン',
+ rom: 'n'
+}];
+// Game state
+var gameState = 'menu'; // 'menu', 'learn', 'hiraganaTest', 'katakanaTest'
+var currentMode = null;
+var currentCharIndex = 0;
+var currentQuestion = null;
+var answerButtons = [];
+var score = 0;
+var streak = 0;
+var questionsAnswered = 0;
+// Load saved progress
+var savedScore = storage.bestScore || 0;
+var savedStreak = storage.bestStreak || 0;
+// UI Elements
+var backgroundPanel = game.addChild(LK.getAsset('backgroundPanel', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366
+}));
+var titleText = new Text2('Japanese Character Master', {
+ size: 80,
+ fill: 0x333333
+});
+titleText.anchor.set(0.5, 0.5);
+titleText.x = 1024;
+titleText.y = 400;
+game.addChild(titleText);
+var scoreText = new Text2('Best Score: ' + savedScore, {
+ size: 40,
+ fill: 0x666666
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+scoreText.y = 50;
+var currentScoreText = new Text2('Score: 0', {
+ size: 50,
+ fill: 0x333333
+});
+currentScoreText.anchor.set(0.5, 0);
+currentScoreText.x = 1024;
+currentScoreText.y = 200;
+game.addChild(currentScoreText);
+currentScoreText.visible = false;
+var streakText = new Text2('Streak: 0', {
+ size: 40,
+ fill: 0x4A90E2
+});
+streakText.anchor.set(0.5, 0);
+streakText.x = 1024;
+streakText.y = 260;
+game.addChild(streakText);
+streakText.visible = false;
+// Menu buttons
+var learnButton = game.addChild(new MenuButton('Learn Mode', function () {
+ startLearnMode();
+}));
+learnButton.x = 1024;
+learnButton.y = 700;
+var hiraganaButton = game.addChild(new MenuButton('Hiragana Test', function () {
+ startHiraganaTest();
+}));
+hiraganaButton.x = 1024;
+hiraganaButton.y = 850;
+var katakanaButton = game.addChild(new MenuButton('Katakana Test', function () {
+ startKatakanaTest();
+}));
+katakanaButton.x = 1024;
+katakanaButton.y = 1000;
+var backButton = game.addChild(new MenuButton('Back to Menu', function () {
+ returnToMenu();
+}));
+backButton.x = 1024;
+backButton.y = 2200;
+backButton.visible = false;
+var nextButton = game.addChild(new MenuButton('Next Character', function () {
+ showNextCharacter();
+}));
+nextButton.x = 1024;
+nextButton.y = 1800;
+nextButton.visible = false;
+var prevButton = game.addChild(new MenuButton('Previous Character', function () {
+ showPrevCharacter();
+}));
+prevButton.x = 1024;
+prevButton.y = 1950;
+prevButton.visible = false;
+// Character display for learn mode
+var characterDisplay = null;
+// Question character display for tests
+var questionCharText = new Text2('', {
+ size: 150,
+ fill: 0x000000
+});
+questionCharText.anchor.set(0.5, 0.5);
+questionCharText.x = 1024;
+questionCharText.y = 600;
+game.addChild(questionCharText);
+questionCharText.visible = false;
+function hideMenuElements() {
+ titleText.visible = false;
+ learnButton.visible = false;
+ hiraganaButton.visible = false;
+ katakanaButton.visible = false;
+}
+function showMenuElements() {
+ titleText.visible = true;
+ learnButton.visible = true;
+ hiraganaButton.visible = true;
+ katakanaButton.visible = true;
+ backButton.visible = false;
+ nextButton.visible = false;
+ prevButton.visible = false;
+ currentScoreText.visible = false;
+ streakText.visible = false;
+ questionCharText.visible = false;
+ if (characterDisplay) {
+ characterDisplay.visible = false;
+ }
+ for (var i = 0; i < answerButtons.length; i++) {
+ answerButtons[i].visible = false;
+ }
+}
+function startLearnMode() {
+ gameState = 'learn';
+ currentMode = hiraganaChars;
+ currentCharIndex = 0;
+ hideMenuElements();
+ backButton.visible = true;
+ nextButton.visible = true;
+ prevButton.visible = true;
+ showCurrentCharacter();
+}
+function startHiraganaTest() {
+ gameState = 'hiraganaTest';
+ currentMode = hiraganaChars;
+ score = 0;
+ streak = 0;
+ questionsAnswered = 0;
+ hideMenuElements();
+ backButton.visible = true;
+ currentScoreText.visible = true;
+ streakText.visible = true;
+ questionCharText.visible = true;
+ updateScoreDisplay();
+ generateQuestion();
+}
+function startKatakanaTest() {
+ gameState = 'katakanaTest';
+ currentMode = katakanaChars;
+ score = 0;
+ streak = 0;
+ questionsAnswered = 0;
+ hideMenuElements();
+ backButton.visible = true;
+ currentScoreText.visible = true;
+ streakText.visible = true;
+ questionCharText.visible = true;
+ updateScoreDisplay();
+ generateQuestion();
+}
+function returnToMenu() {
+ gameState = 'menu';
+ showMenuElements();
+}
+function showCurrentCharacter() {
+ if (characterDisplay) {
+ game.removeChild(characterDisplay);
+ }
+ var _char = currentMode[currentCharIndex];
+ characterDisplay = game.addChild(new CharacterDisplay(_char["char"], _char.rom));
+ characterDisplay.x = 1024;
+ characterDisplay.y = 1000;
+}
+function showNextCharacter() {
+ currentCharIndex = (currentCharIndex + 1) % currentMode.length;
+ showCurrentCharacter();
+}
+function showPrevCharacter() {
+ currentCharIndex = (currentCharIndex - 1 + currentMode.length) % currentMode.length;
+ showCurrentCharacter();
+}
+function generateQuestion() {
+ // Clear previous answer buttons
+ for (var i = 0; i < answerButtons.length; i++) {
+ game.removeChild(answerButtons[i]);
+ }
+ answerButtons = [];
+ // Pick random character
+ var randomIndex = Math.floor(Math.random() * currentMode.length);
+ currentQuestion = currentMode[randomIndex];
+ questionCharText.setText(currentQuestion["char"]);
+ // Generate wrong answers
+ var wrongAnswers = [];
+ while (wrongAnswers.length < 3) {
+ var wrongIndex = Math.floor(Math.random() * currentMode.length);
+ var wrongAnswer = currentMode[wrongIndex].rom;
+ if (wrongAnswer !== currentQuestion.rom && wrongAnswers.indexOf(wrongAnswer) === -1) {
+ wrongAnswers.push(wrongAnswer);
+ }
+ }
+ // Create answer options
+ var allAnswers = [currentQuestion.rom].concat(wrongAnswers);
+ // Shuffle answers
+ for (var i = allAnswers.length - 1; i > 0; i--) {
+ var j = Math.floor(Math.random() * (i + 1));
+ var temp = allAnswers[i];
+ allAnswers[i] = allAnswers[j];
+ allAnswers[j] = temp;
+ }
+ // Create answer buttons
+ var buttonPositions = [{
+ x: 512,
+ y: 1000
+ }, {
+ x: 1536,
+ y: 1000
+ }, {
+ x: 512,
+ y: 1150
+ }, {
+ x: 1536,
+ y: 1150
+ }];
+ for (var i = 0; i < 4; i++) {
+ var isCorrect = allAnswers[i] === currentQuestion.rom;
+ var button = game.addChild(new AnswerButton(allAnswers[i], isCorrect, onAnswerSelected));
+ button.x = buttonPositions[i].x;
+ button.y = buttonPositions[i].y;
+ answerButtons.push(button);
+ }
+}
+function onAnswerSelected(isCorrect) {
+ questionsAnswered++;
+ if (isCorrect) {
+ score++;
+ streak++;
+ LK.getSound('correct').play();
+ // Show correct feedback
+ var feedback = game.addChild(LK.getAsset('correctFeedback', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 800,
+ alpha: 0
+ }));
+ tween(feedback, {
+ alpha: 1
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ tween(feedback, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ game.removeChild(feedback);
+ }
+ });
+ }
+ });
+ } else {
+ streak = 0;
+ LK.getSound('incorrect').play();
+ // Show incorrect feedback
+ var feedback = game.addChild(LK.getAsset('incorrectFeedback', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 800,
+ alpha: 0
+ }));
+ tween(feedback, {
+ alpha: 1
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ tween(feedback, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ game.removeChild(feedback);
+ }
+ });
+ }
+ });
+ }
+ updateScoreDisplay();
+ // Save best scores
+ if (score > savedScore) {
+ savedScore = score;
+ storage.bestScore = savedScore;
+ scoreText.setText('Best Score: ' + savedScore);
+ }
+ if (streak > savedStreak) {
+ savedStreak = streak;
+ storage.bestStreak = savedStreak;
+ }
+ // Generate next question after delay
+ LK.setTimeout(function () {
+ generateQuestion();
+ }, 800);
+}
+function updateScoreDisplay() {
+ currentScoreText.setText('Score: ' + score);
+ streakText.setText('Streak: ' + streak);
+}
+// Game update loop
+game.update = function () {
+ // Game loop logic if needed
+};
\ No newline at end of file