/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Adventurer = Container.expand(function () { var self = Container.call(this); var adventurerGraphics = self.attachAsset('adventurer', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = self.maxHealth; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xFF0000, 500); }; self.castSpell = function () { var bolt = game.addChild(new MagicBolt()); bolt.x = self.x; bolt.y = self.y - 30; bolt.damage = 15; magicBolts.push(bolt); LK.getSound('magicCast').play(); LK.effects.flashObject(self, 0xFFD700, 300); }; return self; }); var MagicBolt = Container.expand(function () { var self = Container.call(this); var boltGraphics = self.attachAsset('magicBolt', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.damage = 10; self.update = function () { self.y -= self.speed; }; return self; }); var MonsterAttack = Container.expand(function () { var self = Container.call(this); var attackGraphics = self.attachAsset('monsterAttack', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.damage = 35; self.update = function () { // Use calculated velocity if available, otherwise default downward movement if (self.velocityX !== undefined && self.velocityY !== undefined) { self.x += self.velocityX; self.y += self.velocityY; } else { self.y += self.speed; } self.rotation += 0.2; }; return self; }); var RockMonster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('rockMonster', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 500; self.health = self.maxHealth; self.attackTimer = 0; self.attackCooldown = 200; self.moveDirection = 1; self.moveSpeed = 2; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showYouWin(); } LK.getSound('monsterHit').play(); }; self.attack = function () { var attack = game.addChild(new MonsterAttack()); attack.x = self.x; attack.y = self.y + 120; // Calculate direction towards adventurer var dx = adventurer.x - self.x; var dy = adventurer.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Normalize direction and set velocity if (distance > 0) { attack.velocityX = dx / distance * attack.speed; attack.velocityY = dy / distance * attack.speed; } else { attack.velocityX = 0; attack.velocityY = attack.speed; } monsterAttacks.push(attack); }; self.update = function () { // Move side to side with boundary safety self.x += self.moveDirection * self.moveSpeed; if (self.x <= 200) { self.x = 200; self.moveDirection = 1; } else if (self.x >= 1848) { self.x = 1848; self.moveDirection = -1; } // Attack timer with better safety check self.attackTimer++; if (self.attackTimer >= self.attackCooldown) { self.attack(); self.attackTimer = 0; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C3E50 }); /**** * Game Code ****/ var background = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); var adventurer = game.addChild(new Adventurer()); adventurer.x = 1024; adventurer.y = 2200; var rockMonster = game.addChild(new RockMonster()); rockMonster.x = 1024; rockMonster.y = 400; var magicBolts = []; var monsterAttacks = []; var dragNode = null; var shootCooldown = 0; var autoShootTimer = 0; var autoShootInterval = 60; // 1 second at 60 FPS var enemyAutoShootTimer = 0; var enemyAutoShootInterval = 60; // 1 second at 60 FPS for enemy var lastMoveX = 0; var lastMoveY = 0; // Health bars var adventurerHealthBar = new Text2('Health: 100', { size: 60, fill: 0x00FF00 }); adventurerHealthBar.anchor.set(0, 0); LK.gui.bottomLeft.addChild(adventurerHealthBar); var monsterHealthBar = new Text2('Monster: 500', { size: 60, fill: 0xFF0000 }); monsterHealthBar.anchor.set(0.5, 0); LK.gui.top.addChild(monsterHealthBar); function handleMove(x, y, obj) { // Calculate movement delta for scroll control var deltaX = x - lastMoveX; var deltaY = y - lastMoveY; // Move adventurer based on touch/mouse movement if (dragNode) { var moveSpeed = 1.5; var newX = adventurer.x + deltaX * moveSpeed; var newY = adventurer.y + deltaY * moveSpeed; adventurer.x = Math.max(40, Math.min(2008, newX)); adventurer.y = Math.max(1500, Math.min(2680, newY)); } lastMoveX = x; lastMoveY = y; } // Start background music LK.playMusic('1epicpertarunganpagi'); game.move = handleMove; game.down = function (x, y, obj) { // Start drag control for movement dragNode = adventurer; lastMoveX = x; lastMoveY = y; }; game.up = function (x, y, obj) { // Stop drag control dragNode = null; }; game.update = function () { // Update magic bolts with safety checks for (var i = magicBolts.length - 1; i >= 0; i--) { var bolt = magicBolts[i]; // Safety check for destroyed objects if (!bolt || !bolt.parent) { magicBolts.splice(i, 1); continue; } // Initialize collision tracking if (bolt.hasHitMonster === undefined) { bolt.hasHitMonster = false; } if (bolt.y < -50) { bolt.destroy(); magicBolts.splice(i, 1); continue; } if (!bolt.hasHitMonster && rockMonster && rockMonster.parent && bolt.intersects(rockMonster)) { bolt.hasHitMonster = true; rockMonster.takeDamage(bolt.damage); bolt.destroy(); magicBolts.splice(i, 1); } } // Update monster attacks with safety checks for (var j = monsterAttacks.length - 1; j >= 0; j--) { var attack = monsterAttacks[j]; // Safety check for destroyed objects if (!attack || !attack.parent) { monsterAttacks.splice(j, 1); continue; } // Initialize collision tracking if (attack.hasHitAdventurer === undefined) { attack.hasHitAdventurer = false; } if (attack.y > 2800) { attack.destroy(); monsterAttacks.splice(j, 1); continue; } if (!attack.hasHitAdventurer && adventurer && adventurer.parent && attack.intersects(adventurer)) { attack.hasHitAdventurer = true; adventurer.takeDamage(attack.damage); LK.getSound('playerHit').play(); attack.destroy(); monsterAttacks.splice(j, 1); } } // Update shoot cooldown if (shootCooldown > 0) { shootCooldown--; } // Auto shoot timer - player shoots automatically every 1 second autoShootTimer++; if (autoShootTimer >= autoShootInterval) { adventurer.castSpell(); autoShootTimer = 0; } // Enemy auto shoot timer - enemy shoots automatically every 1 second enemyAutoShootTimer++; if (enemyAutoShootTimer >= enemyAutoShootInterval && rockMonster && rockMonster.parent) { rockMonster.attack(); enemyAutoShootTimer = 0; } // Update health displays with safety checks if (adventurerHealthBar && adventurer) { adventurerHealthBar.setText('Health: ' + adventurer.health); } if (monsterHealthBar && rockMonster) { monsterHealthBar.setText('Monster: ' + rockMonster.health); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Adventurer = Container.expand(function () {
var self = Container.call(this);
var adventurerGraphics = self.attachAsset('adventurer', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.effects.flashObject(self, 0xFF0000, 500);
};
self.castSpell = function () {
var bolt = game.addChild(new MagicBolt());
bolt.x = self.x;
bolt.y = self.y - 30;
bolt.damage = 15;
magicBolts.push(bolt);
LK.getSound('magicCast').play();
LK.effects.flashObject(self, 0xFFD700, 300);
};
return self;
});
var MagicBolt = Container.expand(function () {
var self = Container.call(this);
var boltGraphics = self.attachAsset('magicBolt', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.damage = 10;
self.update = function () {
self.y -= self.speed;
};
return self;
});
var MonsterAttack = Container.expand(function () {
var self = Container.call(this);
var attackGraphics = self.attachAsset('monsterAttack', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 35;
self.update = function () {
// Use calculated velocity if available, otherwise default downward movement
if (self.velocityX !== undefined && self.velocityY !== undefined) {
self.x += self.velocityX;
self.y += self.velocityY;
} else {
self.y += self.speed;
}
self.rotation += 0.2;
};
return self;
});
var RockMonster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('rockMonster', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 500;
self.health = self.maxHealth;
self.attackTimer = 0;
self.attackCooldown = 200;
self.moveDirection = 1;
self.moveSpeed = 2;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showYouWin();
}
LK.getSound('monsterHit').play();
};
self.attack = function () {
var attack = game.addChild(new MonsterAttack());
attack.x = self.x;
attack.y = self.y + 120;
// Calculate direction towards adventurer
var dx = adventurer.x - self.x;
var dy = adventurer.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize direction and set velocity
if (distance > 0) {
attack.velocityX = dx / distance * attack.speed;
attack.velocityY = dy / distance * attack.speed;
} else {
attack.velocityX = 0;
attack.velocityY = attack.speed;
}
monsterAttacks.push(attack);
};
self.update = function () {
// Move side to side with boundary safety
self.x += self.moveDirection * self.moveSpeed;
if (self.x <= 200) {
self.x = 200;
self.moveDirection = 1;
} else if (self.x >= 1848) {
self.x = 1848;
self.moveDirection = -1;
}
// Attack timer with better safety check
self.attackTimer++;
if (self.attackTimer >= self.attackCooldown) {
self.attack();
self.attackTimer = 0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var adventurer = game.addChild(new Adventurer());
adventurer.x = 1024;
adventurer.y = 2200;
var rockMonster = game.addChild(new RockMonster());
rockMonster.x = 1024;
rockMonster.y = 400;
var magicBolts = [];
var monsterAttacks = [];
var dragNode = null;
var shootCooldown = 0;
var autoShootTimer = 0;
var autoShootInterval = 60; // 1 second at 60 FPS
var enemyAutoShootTimer = 0;
var enemyAutoShootInterval = 60; // 1 second at 60 FPS for enemy
var lastMoveX = 0;
var lastMoveY = 0;
// Health bars
var adventurerHealthBar = new Text2('Health: 100', {
size: 60,
fill: 0x00FF00
});
adventurerHealthBar.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(adventurerHealthBar);
var monsterHealthBar = new Text2('Monster: 500', {
size: 60,
fill: 0xFF0000
});
monsterHealthBar.anchor.set(0.5, 0);
LK.gui.top.addChild(monsterHealthBar);
function handleMove(x, y, obj) {
// Calculate movement delta for scroll control
var deltaX = x - lastMoveX;
var deltaY = y - lastMoveY;
// Move adventurer based on touch/mouse movement
if (dragNode) {
var moveSpeed = 1.5;
var newX = adventurer.x + deltaX * moveSpeed;
var newY = adventurer.y + deltaY * moveSpeed;
adventurer.x = Math.max(40, Math.min(2008, newX));
adventurer.y = Math.max(1500, Math.min(2680, newY));
}
lastMoveX = x;
lastMoveY = y;
}
// Start background music
LK.playMusic('1epicpertarunganpagi');
game.move = handleMove;
game.down = function (x, y, obj) {
// Start drag control for movement
dragNode = adventurer;
lastMoveX = x;
lastMoveY = y;
};
game.up = function (x, y, obj) {
// Stop drag control
dragNode = null;
};
game.update = function () {
// Update magic bolts with safety checks
for (var i = magicBolts.length - 1; i >= 0; i--) {
var bolt = magicBolts[i];
// Safety check for destroyed objects
if (!bolt || !bolt.parent) {
magicBolts.splice(i, 1);
continue;
}
// Initialize collision tracking
if (bolt.hasHitMonster === undefined) {
bolt.hasHitMonster = false;
}
if (bolt.y < -50) {
bolt.destroy();
magicBolts.splice(i, 1);
continue;
}
if (!bolt.hasHitMonster && rockMonster && rockMonster.parent && bolt.intersects(rockMonster)) {
bolt.hasHitMonster = true;
rockMonster.takeDamage(bolt.damage);
bolt.destroy();
magicBolts.splice(i, 1);
}
}
// Update monster attacks with safety checks
for (var j = monsterAttacks.length - 1; j >= 0; j--) {
var attack = monsterAttacks[j];
// Safety check for destroyed objects
if (!attack || !attack.parent) {
monsterAttacks.splice(j, 1);
continue;
}
// Initialize collision tracking
if (attack.hasHitAdventurer === undefined) {
attack.hasHitAdventurer = false;
}
if (attack.y > 2800) {
attack.destroy();
monsterAttacks.splice(j, 1);
continue;
}
if (!attack.hasHitAdventurer && adventurer && adventurer.parent && attack.intersects(adventurer)) {
attack.hasHitAdventurer = true;
adventurer.takeDamage(attack.damage);
LK.getSound('playerHit').play();
attack.destroy();
monsterAttacks.splice(j, 1);
}
}
// Update shoot cooldown
if (shootCooldown > 0) {
shootCooldown--;
}
// Auto shoot timer - player shoots automatically every 1 second
autoShootTimer++;
if (autoShootTimer >= autoShootInterval) {
adventurer.castSpell();
autoShootTimer = 0;
}
// Enemy auto shoot timer - enemy shoots automatically every 1 second
enemyAutoShootTimer++;
if (enemyAutoShootTimer >= enemyAutoShootInterval && rockMonster && rockMonster.parent) {
rockMonster.attack();
enemyAutoShootTimer = 0;
}
// Update health displays with safety checks
if (adventurerHealthBar && adventurer) {
adventurerHealthBar.setText('Health: ' + adventurer.health);
}
if (monsterHealthBar && rockMonster) {
monsterHealthBar.setText('Monster: ' + rockMonster.health);
}
};
16 bit image litle girl ride flyng broom stick. In-Game asset. 2d.
16 bit image evil black gray cloud monster. In-Game asset. 2d.
16 bit image black dark lighting orb ball In-Game asset. 2d.
16 bit image langit biru cerah, daerah hutan luas, di kejauhan ada pedesaaan sederhana. suasana pagi hari langit biru. In-Game asset. 2d.