/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
playerHP: 20,
monstersFought: 0,
monstersSpared: 0,
currentArea: "ruins",
gameProgress: 0
});
/****
* Classes
****/
var ActionButton = Container.expand(function (type, text) {
var self = Container.call(this);
var assetId = type + 'Button';
var buttonGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.setPosition = function (x, y) {
self.x = x;
self.y = y;
self.text.x = 0;
self.text.y = 0;
};
self.down = function (x, y, obj) {
tween(buttonGraphics, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(buttonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
if (self.onClick) {
self.onClick();
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.damage = 2;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Check if out of bounds
if (self.x < battleArea.x || self.x > battleArea.x + battleArea.width || self.y < battleArea.y || self.y > battleArea.y + battleArea.height) {
self.shouldRemove = true;
}
};
self.setVelocity = function (speedX, speedY) {
self.speedX = speedX;
self.speedY = speedY;
};
return self;
});
var DialogBox = Container.expand(function () {
var self = Container.call(this);
var box = self.attachAsset('dialogBox', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2("", {
size: 48,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.setMessage = function (message) {
self.text.setText(message);
};
self.setPosition = function (x, y) {
self.x = x;
self.y = y;
self.text.x = 0;
self.text.y = 0;
};
self.show = function () {
self.visible = true;
};
self.hide = function () {
self.visible = false;
};
return self;
});
var Monster = Container.expand(function () {
var self = Container.call(this);
var monsterSprite = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.hp = 30;
self.maxHP = 30;
self.name = "Froggit";
self.mercy = 0;
self.mercyThreshold = 100;
self.spared = false;
self.defeated = false;
// Attacks available to this monster
self.attacks = ['basic', 'circle', 'random'];
self.setPosition = function (x, y) {
self.x = x;
self.y = y;
};
self.takeDamage = function (amount) {
self.hp = Math.max(0, self.hp - amount);
// Flash the sprite white
tween(monsterSprite, {
tint: 0xffffff
}, {
duration: 100,
onFinish: function onFinish() {
tween(monsterSprite, {
tint: 0xffffff
}, {
duration: 100,
onFinish: function onFinish() {
monsterSprite.tint = 0xffffff;
}
});
}
});
if (self.hp <= 0) {
self.defeated = true;
storage.monstersFought++;
monsterSprite.alpha = 0;
LK.getSound('hit').play();
}
};
self.increaseMercy = function (amount) {
self.mercy = Math.min(self.mercyThreshold, self.mercy + amount);
if (self.mercy >= self.mercyThreshold) {
self.spared = true;
storage.monstersSpared++;
tween(monsterSprite, {
alpha: 0
}, {
duration: 1000
});
LK.getSound('spare').play();
}
};
self.getRandomAttack = function () {
var index = Math.floor(Math.random() * self.attacks.length);
return self.attacks[index];
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.hp = storage.playerHP || 20;
self.maxHP = 20;
self.name = "You";
self.level = 1;
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.resetPosition = function () {
self.x = 2048 / 2;
self.y = 2732 / 2;
};
self.takeDamage = function (amount) {
self.hp = Math.max(0, self.hp - amount);
storage.playerHP = self.hp;
LK.getSound('damage').play();
// Flash the sprite red
tween(playerSprite, {
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerSprite, {
alpha: 1
}, {
duration: 100
});
}
});
if (self.hp <= 0) {
LK.showGameOver();
}
};
self.heal = function (amount) {
self.hp = Math.min(self.maxHP, self.hp + amount);
storage.playerHP = self.hp;
};
return self;
});
var Soul = Container.expand(function () {
var self = Container.call(this);
var heart = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
if (self.moving) {
// Move toward target position
self.x += (self.targetX - self.x) * 0.2;
self.y += (self.targetY - self.y) * 0.2;
}
};
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.moving = true;
};
self.stopMoving = function () {
self.moving = false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
game.setBackgroundColor(0x111111);
// Game state variables
var gameState = 'exploration'; // exploration, battle, dialog
var battlePhase = 'start'; // start, playerTurn, monsterTurn, end
var dialogQueue = [];
var bullets = [];
var attackTimer = 0;
var turnCounter = 0;
// Create our main gameplay objects
var player = new Player();
var currentMonster = null;
var soul = new Soul();
var dialogBox = new DialogBox();
var battleArea = null;
// Action buttons
var fightButton = new ActionButton('fight', 'FIGHT');
var actButton = new ActionButton('act', 'ACT');
var mercyButton = new ActionButton('mercy', 'MERCY');
// Set up dialog box
dialogBox.setPosition(2048 / 2, 2732 - 300);
dialogBox.hide();
game.addChild(dialogBox);
// Add UI elements
var hpText = new Text2("HP: " + player.hp + "/" + player.maxHP, {
size: 48,
fill: 0xFFFFFF
});
hpText.anchor.set(0, 0);
hpText.x = 50;
hpText.y = 50;
LK.gui.topLeft.addChild(hpText);
// Initialize player
player.resetPosition();
game.addChild(player);
// Set up button actions
fightButton.onClick = function () {
if (gameState === 'battle' && battlePhase === 'playerTurn') {
// Player chooses to attack
dialogBox.setMessage("You attack!");
battlePhase = 'playerAttack';
// Simple damage calculation
var damage = 5 + Math.floor(Math.random() * 3);
currentMonster.takeDamage(damage);
LK.setTimeout(function () {
if (currentMonster.defeated) {
endBattle(true);
} else {
startMonsterTurn();
}
}, 1000);
}
};
actButton.onClick = function () {
if (gameState === 'battle' && battlePhase === 'playerTurn') {
// Player chooses to interact
dialogBox.setMessage("* You try to talk to " + currentMonster.name);
battlePhase = 'playerAct';
// Increase mercy meter
currentMonster.increaseMercy(25);
LK.setTimeout(function () {
if (currentMonster.spared) {
endBattle(false);
} else {
startMonsterTurn();
}
}, 1500);
}
};
mercyButton.onClick = function () {
if (gameState === 'battle' && battlePhase === 'playerTurn') {
// Player chooses mercy
dialogBox.setMessage("* You spare " + currentMonster.name);
battlePhase = 'playerMercy';
// Increase mercy meter significantly
currentMonster.increaseMercy(50);
LK.setTimeout(function () {
if (currentMonster.spared) {
endBattle(false);
} else {
startMonsterTurn();
}
}, 1500);
}
};
// Helper functions
function startBattle() {
gameState = 'battle';
battlePhase = 'start';
// Create a new monster for this battle
currentMonster = new Monster();
currentMonster.setPosition(2048 / 2, 800);
game.addChild(currentMonster);
// Create battle area (where bullets and the soul interact)
battleArea = LK.getAsset('battleArea', {
anchorX: 0.5,
anchorY: 0.5
});
battleArea.x = 2048 / 2;
battleArea.y = 1600;
battleArea.width = 1000;
battleArea.height = 500;
game.addChild(battleArea);
// Initialize soul in battle area
soul.x = battleArea.x;
soul.y = battleArea.y + battleArea.height / 2;
game.addChild(soul);
// Add buttons
fightButton.setPosition(2048 / 4, 2200);
actButton.setPosition(2048 / 2, 2200);
mercyButton.setPosition(2048 * 3 / 4, 2200);
game.addChild(fightButton);
game.addChild(actButton);
game.addChild(mercyButton);
// Hide player during battle
player.visible = false;
// Show dialog to start
dialogBox.setMessage("* A " + currentMonster.name + " appears!");
dialogBox.show();
LK.setTimeout(function () {
startPlayerTurn();
}, 1500);
}
function startPlayerTurn() {
battlePhase = 'playerTurn';
dialogBox.setMessage("* What will you do?");
turnCounter++;
}
function startMonsterTurn() {
battlePhase = 'monsterTurn';
dialogBox.setMessage("* " + currentMonster.name + " prepares an attack!");
// Start a timer for this attack sequence
attackTimer = 0;
// Select attack pattern based on monster
currentAttack = currentMonster.getRandomAttack();
// Allow soul movement during monster turn
soul.moving = true;
}
function endBattle(won) {
battlePhase = 'end';
if (won) {
dialogBox.setMessage("* You defeated " + currentMonster.name + "!");
LK.setScore(LK.getScore() + 100);
} else {
dialogBox.setMessage("* You spared " + currentMonster.name + "!");
LK.setScore(LK.getScore() + 150);
}
// Clean up battle area
LK.setTimeout(function () {
// Remove all battle elements
if (battleArea) {
battleArea.destroy();
battleArea = null;
}
if (currentMonster) {
currentMonster.destroy();
currentMonster = null;
}
soul.destroy();
fightButton.destroy();
actButton.destroy();
mercyButton.destroy();
bullets.forEach(function (bullet) {
bullet.destroy();
});
bullets = [];
player.visible = true;
dialogBox.hide();
gameState = 'exploration';
// Check if game should be won
if (storage.monstersFought + storage.monstersSpared >= 5) {
LK.showYouWin();
}
}, 2000);
}
function createBullet(x, y, speedX, speedY) {
var bullet = new Bullet();
bullet.x = x;
bullet.y = y;
bullet.setVelocity(speedX, speedY);
bullets.push(bullet);
game.addChild(bullet);
return bullet;
}
function basicAttack() {
// Create bullets that move horizontally from left to right
if (attackTimer % 15 === 0 && attackTimer < 90) {
createBullet(battleArea.x - battleArea.width / 2, battleArea.y - battleArea.height / 3 + Math.random() * battleArea.height * 2 / 3, 5 + Math.random() * 3, 0);
}
}
function circleAttack() {
// Create bullets in a circular pattern
if (attackTimer % 10 === 0 && attackTimer < 100) {
var angle = attackTimer / 5;
var speed = 4;
createBullet(battleArea.x, battleArea.y, Math.cos(angle) * speed, Math.sin(angle) * speed);
createBullet(battleArea.x, battleArea.y, Math.cos(angle + Math.PI) * speed, Math.sin(angle + Math.PI) * speed);
}
}
function randomAttack() {
// Create bullets at random positions with random velocities
if (attackTimer % 20 === 0 && attackTimer < 100) {
for (var i = 0; i < 3; i++) {
var startX = battleArea.x - battleArea.width / 2 + Math.random() * battleArea.width;
var startY = battleArea.y - battleArea.height / 2;
createBullet(startX, startY, -2 + Math.random() * 4, 2 + Math.random() * 3);
}
}
}
// Game update loop
game.update = function () {
// Update HP text
hpText.setText("HP: " + player.hp + "/" + player.maxHP);
// Handle exploration state
if (gameState === 'exploration') {
// In a real game, we'd handle movement, exploration, etc. here
// For this demo, we'll just randomly trigger battles
if (LK.ticks % 180 === 0 && Math.random() < 0.3) {
startBattle();
}
}
// Handle battle state
if (gameState === 'battle') {
// Monster turn attack logic
if (battlePhase === 'monsterTurn') {
attackTimer++;
// Run current attack pattern
if (currentAttack === 'basic') {
basicAttack();
} else if (currentAttack === 'circle') {
circleAttack();
} else if (currentAttack === 'random') {
randomAttack();
}
// End turn after a certain time
if (attackTimer >= 120) {
battlePhase = 'playerTurn';
soul.moving = false;
dialogBox.setMessage("* What will you do?");
}
}
// Update all bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check collision with soul
if (soul.intersects(bullet)) {
player.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Remove bullets that are flagged for removal
if (bullet.shouldRemove) {
bullet.destroy();
bullets.splice(i, 1);
}
}
}
};
// Handle input events
var dragTarget = null;
game.down = function (x, y, obj) {
if (gameState === 'battle' && battlePhase === 'monsterTurn') {
// During monster turn, control the soul
soul.targetX = x;
soul.targetY = y;
}
};
game.move = function (x, y, obj) {
if (gameState === 'battle' && battlePhase === 'monsterTurn') {
// During monster turn, control the soul
soul.targetX = x;
soul.targetY = y;
} else if (gameState === 'exploration') {
// During exploration, move the player
player.x = x;
player.y = y;
}
};
game.up = function (x, y, obj) {
// Nothing special on release
};
// Start the game with a welcome message
dialogBox.setMessage("* Welcome to Monster Tales! Touch to move.");
dialogBox.show();
LK.setTimeout(function () {
dialogBox.hide();
}, 3000);
// Play background music
LK.playMusic('bgm'); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,539 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ playerHP: 20,
+ monstersFought: 0,
+ monstersSpared: 0,
+ currentArea: "ruins",
+ gameProgress: 0
+});
+
+/****
+* Classes
+****/
+var ActionButton = Container.expand(function (type, text) {
+ var self = Container.call(this);
+ var assetId = type + 'Button';
+ var buttonGraphics = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.text = new Text2(text, {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ self.text.anchor.set(0.5, 0.5);
+ self.addChild(self.text);
+ self.setPosition = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.text.x = 0;
+ self.text.y = 0;
+ };
+ self.down = function (x, y, obj) {
+ tween(buttonGraphics, {
+ scaleX: 0.9,
+ scaleY: 0.9
+ }, {
+ duration: 100
+ });
+ };
+ self.up = function (x, y, obj) {
+ tween(buttonGraphics, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 100
+ });
+ if (self.onClick) {
+ self.onClick();
+ }
+ };
+ return self;
+});
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speedX = 0;
+ self.speedY = 0;
+ self.damage = 2;
+ self.update = function () {
+ self.x += self.speedX;
+ self.y += self.speedY;
+ // Check if out of bounds
+ if (self.x < battleArea.x || self.x > battleArea.x + battleArea.width || self.y < battleArea.y || self.y > battleArea.y + battleArea.height) {
+ self.shouldRemove = true;
+ }
+ };
+ self.setVelocity = function (speedX, speedY) {
+ self.speedX = speedX;
+ self.speedY = speedY;
+ };
+ return self;
+});
+var DialogBox = Container.expand(function () {
+ var self = Container.call(this);
+ var box = self.attachAsset('dialogBox', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.text = new Text2("", {
+ size: 48,
+ fill: 0xFFFFFF
+ });
+ self.text.anchor.set(0.5, 0.5);
+ self.addChild(self.text);
+ self.setMessage = function (message) {
+ self.text.setText(message);
+ };
+ self.setPosition = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.text.x = 0;
+ self.text.y = 0;
+ };
+ self.show = function () {
+ self.visible = true;
+ };
+ self.hide = function () {
+ self.visible = false;
+ };
+ return self;
+});
+var Monster = Container.expand(function () {
+ var self = Container.call(this);
+ var monsterSprite = self.attachAsset('monster', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 1.5
+ });
+ self.hp = 30;
+ self.maxHP = 30;
+ self.name = "Froggit";
+ self.mercy = 0;
+ self.mercyThreshold = 100;
+ self.spared = false;
+ self.defeated = false;
+ // Attacks available to this monster
+ self.attacks = ['basic', 'circle', 'random'];
+ self.setPosition = function (x, y) {
+ self.x = x;
+ self.y = y;
+ };
+ self.takeDamage = function (amount) {
+ self.hp = Math.max(0, self.hp - amount);
+ // Flash the sprite white
+ tween(monsterSprite, {
+ tint: 0xffffff
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ tween(monsterSprite, {
+ tint: 0xffffff
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ monsterSprite.tint = 0xffffff;
+ }
+ });
+ }
+ });
+ if (self.hp <= 0) {
+ self.defeated = true;
+ storage.monstersFought++;
+ monsterSprite.alpha = 0;
+ LK.getSound('hit').play();
+ }
+ };
+ self.increaseMercy = function (amount) {
+ self.mercy = Math.min(self.mercyThreshold, self.mercy + amount);
+ if (self.mercy >= self.mercyThreshold) {
+ self.spared = true;
+ storage.monstersSpared++;
+ tween(monsterSprite, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ LK.getSound('spare').play();
+ }
+ };
+ self.getRandomAttack = function () {
+ var index = Math.floor(Math.random() * self.attacks.length);
+ return self.attacks[index];
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ self.hp = storage.playerHP || 20;
+ self.maxHP = 20;
+ self.name = "You";
+ self.level = 1;
+ var playerSprite = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.resetPosition = function () {
+ self.x = 2048 / 2;
+ self.y = 2732 / 2;
+ };
+ self.takeDamage = function (amount) {
+ self.hp = Math.max(0, self.hp - amount);
+ storage.playerHP = self.hp;
+ LK.getSound('damage').play();
+ // Flash the sprite red
+ tween(playerSprite, {
+ alpha: 0.5
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ tween(playerSprite, {
+ alpha: 1
+ }, {
+ duration: 100
+ });
+ }
+ });
+ if (self.hp <= 0) {
+ LK.showGameOver();
+ }
+ };
+ self.heal = function (amount) {
+ self.hp = Math.min(self.maxHP, self.hp + amount);
+ storage.playerHP = self.hp;
+ };
+ return self;
+});
+var Soul = Container.expand(function () {
+ var self = Container.call(this);
+ var heart = self.attachAsset('heart', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.targetX = 0;
+ self.targetY = 0;
+ self.update = function () {
+ if (self.moving) {
+ // Move toward target position
+ self.x += (self.targetX - self.x) * 0.2;
+ self.y += (self.targetY - self.y) * 0.2;
+ }
+ };
+ self.moveTo = function (x, y) {
+ self.targetX = x;
+ self.targetY = y;
+ self.moving = true;
+ };
+ self.stopMoving = function () {
+ self.moving = false;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+game.setBackgroundColor(0x111111);
+// Game state variables
+var gameState = 'exploration'; // exploration, battle, dialog
+var battlePhase = 'start'; // start, playerTurn, monsterTurn, end
+var dialogQueue = [];
+var bullets = [];
+var attackTimer = 0;
+var turnCounter = 0;
+// Create our main gameplay objects
+var player = new Player();
+var currentMonster = null;
+var soul = new Soul();
+var dialogBox = new DialogBox();
+var battleArea = null;
+// Action buttons
+var fightButton = new ActionButton('fight', 'FIGHT');
+var actButton = new ActionButton('act', 'ACT');
+var mercyButton = new ActionButton('mercy', 'MERCY');
+// Set up dialog box
+dialogBox.setPosition(2048 / 2, 2732 - 300);
+dialogBox.hide();
+game.addChild(dialogBox);
+// Add UI elements
+var hpText = new Text2("HP: " + player.hp + "/" + player.maxHP, {
+ size: 48,
+ fill: 0xFFFFFF
+});
+hpText.anchor.set(0, 0);
+hpText.x = 50;
+hpText.y = 50;
+LK.gui.topLeft.addChild(hpText);
+// Initialize player
+player.resetPosition();
+game.addChild(player);
+// Set up button actions
+fightButton.onClick = function () {
+ if (gameState === 'battle' && battlePhase === 'playerTurn') {
+ // Player chooses to attack
+ dialogBox.setMessage("You attack!");
+ battlePhase = 'playerAttack';
+ // Simple damage calculation
+ var damage = 5 + Math.floor(Math.random() * 3);
+ currentMonster.takeDamage(damage);
+ LK.setTimeout(function () {
+ if (currentMonster.defeated) {
+ endBattle(true);
+ } else {
+ startMonsterTurn();
+ }
+ }, 1000);
+ }
+};
+actButton.onClick = function () {
+ if (gameState === 'battle' && battlePhase === 'playerTurn') {
+ // Player chooses to interact
+ dialogBox.setMessage("* You try to talk to " + currentMonster.name);
+ battlePhase = 'playerAct';
+ // Increase mercy meter
+ currentMonster.increaseMercy(25);
+ LK.setTimeout(function () {
+ if (currentMonster.spared) {
+ endBattle(false);
+ } else {
+ startMonsterTurn();
+ }
+ }, 1500);
+ }
+};
+mercyButton.onClick = function () {
+ if (gameState === 'battle' && battlePhase === 'playerTurn') {
+ // Player chooses mercy
+ dialogBox.setMessage("* You spare " + currentMonster.name);
+ battlePhase = 'playerMercy';
+ // Increase mercy meter significantly
+ currentMonster.increaseMercy(50);
+ LK.setTimeout(function () {
+ if (currentMonster.spared) {
+ endBattle(false);
+ } else {
+ startMonsterTurn();
+ }
+ }, 1500);
+ }
+};
+// Helper functions
+function startBattle() {
+ gameState = 'battle';
+ battlePhase = 'start';
+ // Create a new monster for this battle
+ currentMonster = new Monster();
+ currentMonster.setPosition(2048 / 2, 800);
+ game.addChild(currentMonster);
+ // Create battle area (where bullets and the soul interact)
+ battleArea = LK.getAsset('battleArea', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ battleArea.x = 2048 / 2;
+ battleArea.y = 1600;
+ battleArea.width = 1000;
+ battleArea.height = 500;
+ game.addChild(battleArea);
+ // Initialize soul in battle area
+ soul.x = battleArea.x;
+ soul.y = battleArea.y + battleArea.height / 2;
+ game.addChild(soul);
+ // Add buttons
+ fightButton.setPosition(2048 / 4, 2200);
+ actButton.setPosition(2048 / 2, 2200);
+ mercyButton.setPosition(2048 * 3 / 4, 2200);
+ game.addChild(fightButton);
+ game.addChild(actButton);
+ game.addChild(mercyButton);
+ // Hide player during battle
+ player.visible = false;
+ // Show dialog to start
+ dialogBox.setMessage("* A " + currentMonster.name + " appears!");
+ dialogBox.show();
+ LK.setTimeout(function () {
+ startPlayerTurn();
+ }, 1500);
+}
+function startPlayerTurn() {
+ battlePhase = 'playerTurn';
+ dialogBox.setMessage("* What will you do?");
+ turnCounter++;
+}
+function startMonsterTurn() {
+ battlePhase = 'monsterTurn';
+ dialogBox.setMessage("* " + currentMonster.name + " prepares an attack!");
+ // Start a timer for this attack sequence
+ attackTimer = 0;
+ // Select attack pattern based on monster
+ currentAttack = currentMonster.getRandomAttack();
+ // Allow soul movement during monster turn
+ soul.moving = true;
+}
+function endBattle(won) {
+ battlePhase = 'end';
+ if (won) {
+ dialogBox.setMessage("* You defeated " + currentMonster.name + "!");
+ LK.setScore(LK.getScore() + 100);
+ } else {
+ dialogBox.setMessage("* You spared " + currentMonster.name + "!");
+ LK.setScore(LK.getScore() + 150);
+ }
+ // Clean up battle area
+ LK.setTimeout(function () {
+ // Remove all battle elements
+ if (battleArea) {
+ battleArea.destroy();
+ battleArea = null;
+ }
+ if (currentMonster) {
+ currentMonster.destroy();
+ currentMonster = null;
+ }
+ soul.destroy();
+ fightButton.destroy();
+ actButton.destroy();
+ mercyButton.destroy();
+ bullets.forEach(function (bullet) {
+ bullet.destroy();
+ });
+ bullets = [];
+ player.visible = true;
+ dialogBox.hide();
+ gameState = 'exploration';
+ // Check if game should be won
+ if (storage.monstersFought + storage.monstersSpared >= 5) {
+ LK.showYouWin();
+ }
+ }, 2000);
+}
+function createBullet(x, y, speedX, speedY) {
+ var bullet = new Bullet();
+ bullet.x = x;
+ bullet.y = y;
+ bullet.setVelocity(speedX, speedY);
+ bullets.push(bullet);
+ game.addChild(bullet);
+ return bullet;
+}
+function basicAttack() {
+ // Create bullets that move horizontally from left to right
+ if (attackTimer % 15 === 0 && attackTimer < 90) {
+ createBullet(battleArea.x - battleArea.width / 2, battleArea.y - battleArea.height / 3 + Math.random() * battleArea.height * 2 / 3, 5 + Math.random() * 3, 0);
+ }
+}
+function circleAttack() {
+ // Create bullets in a circular pattern
+ if (attackTimer % 10 === 0 && attackTimer < 100) {
+ var angle = attackTimer / 5;
+ var speed = 4;
+ createBullet(battleArea.x, battleArea.y, Math.cos(angle) * speed, Math.sin(angle) * speed);
+ createBullet(battleArea.x, battleArea.y, Math.cos(angle + Math.PI) * speed, Math.sin(angle + Math.PI) * speed);
+ }
+}
+function randomAttack() {
+ // Create bullets at random positions with random velocities
+ if (attackTimer % 20 === 0 && attackTimer < 100) {
+ for (var i = 0; i < 3; i++) {
+ var startX = battleArea.x - battleArea.width / 2 + Math.random() * battleArea.width;
+ var startY = battleArea.y - battleArea.height / 2;
+ createBullet(startX, startY, -2 + Math.random() * 4, 2 + Math.random() * 3);
+ }
+ }
+}
+// Game update loop
+game.update = function () {
+ // Update HP text
+ hpText.setText("HP: " + player.hp + "/" + player.maxHP);
+ // Handle exploration state
+ if (gameState === 'exploration') {
+ // In a real game, we'd handle movement, exploration, etc. here
+ // For this demo, we'll just randomly trigger battles
+ if (LK.ticks % 180 === 0 && Math.random() < 0.3) {
+ startBattle();
+ }
+ }
+ // Handle battle state
+ if (gameState === 'battle') {
+ // Monster turn attack logic
+ if (battlePhase === 'monsterTurn') {
+ attackTimer++;
+ // Run current attack pattern
+ if (currentAttack === 'basic') {
+ basicAttack();
+ } else if (currentAttack === 'circle') {
+ circleAttack();
+ } else if (currentAttack === 'random') {
+ randomAttack();
+ }
+ // End turn after a certain time
+ if (attackTimer >= 120) {
+ battlePhase = 'playerTurn';
+ soul.moving = false;
+ dialogBox.setMessage("* What will you do?");
+ }
+ }
+ // Update all bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
+ // Check collision with soul
+ if (soul.intersects(bullet)) {
+ player.takeDamage(bullet.damage);
+ bullet.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
+ // Remove bullets that are flagged for removal
+ if (bullet.shouldRemove) {
+ bullet.destroy();
+ bullets.splice(i, 1);
+ }
+ }
+ }
+};
+// Handle input events
+var dragTarget = null;
+game.down = function (x, y, obj) {
+ if (gameState === 'battle' && battlePhase === 'monsterTurn') {
+ // During monster turn, control the soul
+ soul.targetX = x;
+ soul.targetY = y;
+ }
+};
+game.move = function (x, y, obj) {
+ if (gameState === 'battle' && battlePhase === 'monsterTurn') {
+ // During monster turn, control the soul
+ soul.targetX = x;
+ soul.targetY = y;
+ } else if (gameState === 'exploration') {
+ // During exploration, move the player
+ player.x = x;
+ player.y = y;
+ }
+};
+game.up = function (x, y, obj) {
+ // Nothing special on release
+};
+// Start the game with a welcome message
+dialogBox.setMessage("* Welcome to Monster Tales! Touch to move.");
+dialogBox.show();
+LK.setTimeout(function () {
+ dialogBox.hide();
+}, 3000);
+// Play background music
+LK.playMusic('bgm');
\ No newline at end of file