/****
* 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.