User prompt
selesaikan perbaikan sound generation failed
User prompt
repair sound generation failed
User prompt
fix sound generation failed
User prompt
add background asset
User prompt
musuh hanya bisa menembak satu peluru dalam sekali tampil
User prompt
buat image musuh bisa berbalik ke kiri saat di kiri. bisa berbalik kanan saat di kanan
User prompt
musuh muncul dari kanan dan kiri bergantian
User prompt
summon enemy
User prompt
seluruh gambar musuh bisa berbalik ke kanan atau kiri
User prompt
gambar armoredEnemy bisa balik ke kanan atau kiri
User prompt
buat image all enemy bisa berbalik ke kanan maupun kiri
User prompt
armoredEnemy bisa bergerak berbalik kanan dan kekiri ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
efek meledak musuh terpecah pecah ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
player image bisa berbalik ke kanan atau kiri
User prompt
musuh hanya dapat menembak 2 peluru
User prompt
musuh hanya dapat menembakkan 3 kali peluru
User prompt
player dapat meloncat saat swipe ke atas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
player dapat hancurkan peluruh musuh ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
perbaiki tembkkan musuh. buat horizontal ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
tambah musuh yang bisa menembakkan peluru setiap 1 detik ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ada efek musuh meledak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
musuh muncul acak kadang dari kanan kadang dari kiri
User prompt
can attack left and right ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
player dash and slash combination attack ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enemy act long jump ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
var assetName = type === 'armored' ? 'armoredEnemy' : type === 'shooting' ? 'shootingEnemy' : 'basicEnemy';
var enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1.0
});
self.type = type || 'basic';
self.speed = type === 'armored' ? -3 : type === 'shooting' ? -2 : -4;
self.maxHealth = type === 'shooting' ? 2 : 1;
self.health = self.maxHealth;
self.damage = type === 'armored' ? 30 : type === 'shooting' ? 25 : 20;
self.points = type === 'armored' ? 30 : type === 'shooting' ? 25 : 10;
// Direction tracking for all enemy types
self.direction = self.speed > 0 ? 1 : -1; // Track current direction for all enemies
self.lastDirection = self.direction; // Track last direction to detect changes
// Armored enemy movement properties
if (type === 'armored') {
self.baseSpeed = Math.abs(self.speed); // Store base speed value
self.direction = self.speed > 0 ? 1 : -1; // Track current direction
self.lastX = 0; // Track last position for direction changes
self.directionChangeTimer = 0;
self.directionChangeInterval = 120 + Math.random() * 120; // Random interval 2-4 seconds
}
// Shooting properties for shooting enemies
if (type === 'shooting') {
self.shootTimer = 0;
self.shootInterval = 60; // Shoot every 1 second (60 frames at 60fps)
self.bulletsShot = 0; // Track number of bullets fired
self.maxBullets = 1; // Maximum bullets this enemy can shoot - only one bullet per enemy
self.shoot = function () {
// Check if enemy has bullets remaining
if (self.bulletsShot >= self.maxBullets) {
return; // Don't shoot if limit reached
}
// Determine direction to shoot towards player
var direction = player.x > self.x ? 1 : -1;
var bullet = game.addChild(new EnemyBullet(direction));
bullet.x = self.x;
bullet.y = self.y - 40;
enemyBullets.push(bullet);
self.bulletsShot++; // Increment bullet count
};
}
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
LK.getSound('enemyHit').play();
if (self.health <= 0) {
// Create main explosion effect
var explosionEffect = game.addChild(LK.getAsset('slashEffect', {
anchorX: 0.5,
anchorY: 0.5
}));
explosionEffect.x = self.x;
explosionEffect.y = self.y - 40;
explosionEffect.tint = 0xff4500; // Orange explosion color
explosionEffect.alpha = 0.9;
explosionEffect.scaleX = 0.5;
explosionEffect.scaleY = 0.5;
// Animate main explosion effect
tween(explosionEffect, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
explosionEffect.destroy();
}
});
// Create fragmented explosion pieces
var fragmentCount = 6 + Math.floor(Math.random() * 4); // 6-9 fragments
for (var f = 0; f < fragmentCount; f++) {
var fragment = game.addChild(LK.getAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
}));
fragment.x = self.x;
fragment.y = self.y - 40;
fragment.tint = 0xff6600; // Darker orange for fragments
fragment.alpha = 0.8;
fragment.scaleX = 0.3 + Math.random() * 0.4; // Random size 0.3-0.7
fragment.scaleY = 0.3 + Math.random() * 0.4;
fragment.rotation = Math.random() * Math.PI * 2; // Random rotation
// Calculate random scatter direction
var angle = Math.PI * 2 / fragmentCount * f + (Math.random() - 0.5) * 0.8;
var velocity = 150 + Math.random() * 100; // Random velocity 150-250
var targetX = fragment.x + Math.cos(angle) * velocity;
var targetY = fragment.y + Math.sin(angle) * velocity;
// Animate fragment scatter with rotation and fade
tween(fragment, {
x: targetX,
y: targetY,
rotation: fragment.rotation + (Math.random() - 0.5) * Math.PI * 4,
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 600 + Math.random() * 400,
// Random duration 600-1000ms
easing: tween.easeOut,
onFinish: function onFinish() {
fragment.destroy();
}
});
}
// Award points
LK.setScore(LK.getScore() + self.points);
// Chance to drop power-up
if (Math.random() < 0.15) {
var powerUp = game.addChild(new PowerUp());
powerUp.x = self.x;
powerUp.y = self.y - 20;
powerUps.push(powerUp);
}
// Remove from enemies array
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
self.destroy();
}
};
// Initialize jumping properties
self.baseY = 0;
self.isJumping = false;
self.jumpTimer = 0;
self.jumpInterval = 150 + Math.random() * 90; // Random jump interval between 2.5-4 seconds for long jumps
self.startJump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.baseY = self.y;
var baseX = self.x;
var jumpDistance = 200 + Math.random() * 150; // Long horizontal jump 200-350 pixels
var jumpHeight = 120 + Math.random() * 80; // Higher jump 120-200 pixels
// Jump direction based on movement direction
var jumpDirectionX = self.speed > 0 ? jumpDistance : -jumpDistance;
// Long jump with arc motion - jump up and forward
tween(self, {
y: self.baseY - jumpHeight,
x: baseX + jumpDirectionX
}, {
duration: 800,
// Longer duration for long jump
easing: tween.easeOut,
onFinish: function onFinish() {
// Fall back down while continuing forward motion
tween(self, {
y: self.baseY
}, {
duration: 600,
easing: tween.bounceOut,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
}
};
self.update = function () {
// Handle armored enemy direction changes
if (self.type === 'armored') {
// Initialize lastX if not set
if (self.lastX === 0) self.lastX = self.x;
// Check for screen boundaries and change direction
if (self.x <= 100 && self.direction === -1 || self.x >= 1948 && self.direction === 1) {
self.direction *= -1; // Reverse direction
self.speed = self.baseSpeed * self.direction;
}
// Random direction changes
self.directionChangeTimer++;
if (self.directionChangeTimer >= self.directionChangeInterval) {
self.direction *= -1; // Reverse direction
self.speed = self.baseSpeed * self.direction;
self.directionChangeTimer = 0;
self.directionChangeInterval = 120 + Math.random() * 120; // Reset random interval
}
// Update lastX
self.lastX = self.x;
}
// Update direction based on speed for all enemy types (including armored)
self.direction = self.speed > 0 ? 1 : -1;
// Flip enemy image based on screen position for all enemy types
var targetScale;
if (self.x < 1024) {
// Left half of screen (2048/2 = 1024)
targetScale = -1; // Face left
} else {
// Right half of screen
targetScale = 1; // Face right
}
// Only animate if the scale needs to change
if (enemyGraphics.scaleX !== targetScale) {
tween(enemyGraphics, {
scaleX: targetScale
}, {
duration: 200,
easing: tween.easeOut
});
}
self.x += self.speed;
// Handle jumping
self.jumpTimer++;
if (self.jumpTimer >= self.jumpInterval && !self.isJumping) {
self.startJump();
self.jumpTimer = 0;
self.jumpInterval = 150 + Math.random() * 90; // Reset random interval for long jumps
}
// Handle shooting for shooting enemies
if (self.type === 'shooting') {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval && self.bulletsShot < self.maxBullets) {
self.shoot();
self.shootTimer = 0;
}
}
// Check collision with player
if (self.intersects(player) && !player.invulnerable) {
player.takeDamage(self.damage);
}
};
return self;
});
var EnemyBullet = Container.expand(function (direction) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 15;
self.direction = direction || 1; // 1 for right, -1 for left
self.update = function () {
self.x += self.speed * self.direction;
// Check collision with player
if (self.intersects(player) && !player.invulnerable) {
player.takeDamage(self.damage);
// Remove from enemyBullets array
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
self.destroy();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.slashDamage = 1;
self.slashRange = 150;
self.isSlashing = false;
self.slashCooldown = 0;
self.isDashing = false;
self.dashCooldown = 0;
self.dashDistance = 200;
self.dashDuration = 300;
self.invulnerable = false;
self.invulnerabilityTime = 0;
self.facingDirection = 1; // 1 for right, -1 for left
self.isJumping = false;
self.baseY = 0;
self.dashSlash = function () {
if (self.slashCooldown <= 0 && self.dashCooldown <= 0 && !self.isSlashing && !self.isDashing) {
self.isDashing = true;
self.isSlashing = true;
self.slashCooldown = 60; // 1 second cooldown
self.dashCooldown = 60;
var startX = self.x;
var dashTargetX = self.facingDirection > 0 ? Math.min(startX + self.dashDistance, 2048 - 40) : Math.max(startX - self.dashDistance, 40);
// Dash forward with tween
tween(self, {
x: dashTargetX
}, {
duration: self.dashDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isDashing = false;
}
});
// Create extended slash effect during dash
var slashEffect = game.addChild(LK.getAsset('slashEffect', {
anchorX: 0.5,
anchorY: 0.5
}));
slashEffect.x = self.x + 75 * self.facingDirection;
slashEffect.y = self.y - 60;
slashEffect.alpha = 0.9;
slashEffect.scaleX = 2.0 * self.facingDirection;
slashEffect.scaleY = 1.5;
// Follow player during dash
var slashFollowInterval = LK.setInterval(function () {
if (self.isDashing) {
slashEffect.x = self.x + 75 * self.facingDirection;
}
}, 16);
// Animate slash effect
tween(slashEffect, {
scaleX: 2.5,
scaleY: 2.0,
alpha: 0
}, {
duration: self.dashDuration,
onFinish: function onFinish() {
LK.clearInterval(slashFollowInterval);
slashEffect.destroy();
}
});
LK.getSound('slash').play();
// Extended damage check during dash
var damageCheckInterval = LK.setInterval(function () {
if (self.isDashing) {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
var enemyInFront = self.facingDirection > 0 ? enemy.x > self.x - 50 && enemy.x < self.x + 150 : enemy.x < self.x + 50 && enemy.x > self.x - 150;
if (distance < self.slashRange * 1.5 && enemyInFront) {
enemy.takeDamage(self.slashDamage * 2); // Double damage during dash
}
}
// Check for enemy bullet hits during dash
for (var j = enemyBullets.length - 1; j >= 0; j--) {
var bullet = enemyBullets[j];
var bulletDistance = Math.sqrt(Math.pow(bullet.x - self.x, 2) + Math.pow(bullet.y - self.y, 2));
var bulletInFront = self.facingDirection > 0 ? bullet.x > self.x - 50 && bullet.x < self.x + 150 : bullet.x < self.x + 50 && bullet.x > self.x - 150;
if (bulletDistance < self.slashRange * 1.5 && bulletInFront) {
// Destroy the bullet
bullet.destroy();
enemyBullets.splice(j, 1);
// Award small points for destroying bullets
LK.setScore(LK.getScore() + 5);
}
}
}
}, 30);
LK.setTimeout(function () {
LK.clearInterval(damageCheckInterval);
self.isSlashing = false;
}, self.dashDuration);
}
};
self.slash = function () {
if (self.slashCooldown <= 0 && !self.isSlashing && !self.isDashing) {
self.isSlashing = true;
self.slashCooldown = 20; // 1/3 second at 60fps
// Create slash effect
var slashEffect = game.addChild(LK.getAsset('slashEffect', {
anchorX: 0.5,
anchorY: 0.5
}));
slashEffect.x = self.x + 75 * self.facingDirection;
slashEffect.y = self.y - 60;
slashEffect.alpha = 0.8;
slashEffect.scaleX = self.facingDirection;
// Animate slash effect
tween(slashEffect, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
slashEffect.destroy();
}
});
LK.getSound('slash').play();
// Check for enemy hits
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
var enemyInRange = self.facingDirection > 0 ? enemy.x > self.x - 50 && enemy.x < self.x + self.slashRange : enemy.x < self.x + 50 && enemy.x > self.x - self.slashRange;
if (distance < self.slashRange && enemyInRange) {
enemy.takeDamage(self.slashDamage);
}
}
// Check for enemy bullet hits
for (var j = enemyBullets.length - 1; j >= 0; j--) {
var bullet = enemyBullets[j];
var bulletDistance = Math.sqrt(Math.pow(bullet.x - self.x, 2) + Math.pow(bullet.y - self.y, 2));
var bulletInRange = self.facingDirection > 0 ? bullet.x > self.x - 50 && bullet.x < self.x + self.slashRange : bullet.x < self.x + 50 && bullet.x > self.x - self.slashRange;
if (bulletDistance < self.slashRange && bulletInRange) {
// Destroy the bullet
bullet.destroy();
enemyBullets.splice(j, 1);
// Award small points for destroying bullets
LK.setScore(LK.getScore() + 5);
}
}
LK.setTimeout(function () {
self.isSlashing = false;
}, 200);
}
};
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.baseY = self.y;
var jumpHeight = 200; // Jump height in pixels
// Jump up with tween
tween(self, {
y: self.baseY - jumpHeight
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fall back down
tween(self, {
y: self.baseY
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
}
};
self.takeDamage = function (damage) {
if (!self.invulnerable) {
self.health -= damage;
self.invulnerable = true;
self.invulnerabilityTime = 120; // 2 seconds at 60fps
// Flash effect
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
}
};
self.update = function () {
// Update player image direction based on facing direction
playerGraphics.scaleX = self.facingDirection;
if (self.slashCooldown > 0) {
self.slashCooldown--;
}
if (self.dashCooldown > 0) {
self.dashCooldown--;
}
if (self.invulnerabilityTime > 0) {
self.invulnerabilityTime--;
if (self.invulnerabilityTime <= 0) {
self.invulnerable = false;
}
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -2;
self.bobOffset = 0;
self.update = function () {
self.x += self.speed;
self.bobOffset += 0.1;
self.y += Math.sin(self.bobOffset) * 0.5;
// Check collision with player
if (self.intersects(player)) {
self.collect();
}
};
self.collect = function () {
LK.getSound('powerUpSound').play();
// Random power-up effect
var powerType = Math.floor(Math.random() * 3);
switch (powerType) {
case 0:
// Increased damage
player.slashDamage += 1;
break;
case 1:
// Wider slash range
player.slashRange += 50;
break;
case 2:
// Temporary invincibility
player.invulnerable = true;
player.invulnerabilityTime = 300; // 5 seconds
break;
}
// Remove from powerUps array
var index = powerUps.indexOf(self);
if (index > -1) {
powerUps.splice(index, 1);
}
self.destroy();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var powerUps = [];
var enemyBullets = [];
var enemySpawnTimer = 0;
var enemySpawnRate = 180; // Start spawning every 3 seconds
var gameTime = 0;
var healthBar;
var healthBarBg;
// Create UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 120;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
// Create health bar background
healthBarBg = game.addChild(LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
}));
healthBarBg.x = 120;
healthBarBg.y = 120;
// Create health bar
healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0
}));
healthBar.x = 122;
healthBar.y = 122;
// Create health text
var healthTxt = new Text2('Health', {
size: 40,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 160;
game.addChild(healthTxt);
// Create background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
background.x = 0;
background.y = 0;
// Create player
player = game.addChild(new Player());
player.x = 300;
player.y = 2732 - 150; // Near bottom of screen
// Start background music
LK.playMusic('bgmusic');
// Touch controls for movement and slashing
var isDragging = false;
var lastTouchX = 0;
var lastTouchY = 0;
var swipeThreshold = 100; // Minimum distance for swipe detection
game.down = function (x, y, obj) {
isDragging = true;
lastTouchX = x;
lastTouchY = y;
// Set facing direction based on touch position relative to player
if (x < player.x) {
player.facingDirection = -1; // Face left
} else {
player.facingDirection = 1; // Face right
}
player.dashSlash();
};
game.move = function (x, y, obj) {
if (isDragging) {
var deltaX = x - lastTouchX;
player.x += deltaX * 0.5; // Smooth movement multiplier
// Keep player within screen bounds
if (player.x < 40) player.x = 40;
if (player.x > 2048 - 40) player.x = 2048 - 40;
lastTouchX = x;
}
};
game.up = function (x, y, obj) {
if (isDragging) {
var deltaY = lastTouchY - y; // Upward swipe has positive deltaY
var deltaX = Math.abs(x - lastTouchX);
// Check for upward swipe (vertical movement greater than horizontal and above threshold)
if (deltaY > swipeThreshold && deltaY > deltaX) {
player.jump();
}
}
isDragging = false;
};
// Spawn enemies
function spawnEnemy() {
var rand = Math.random();
var enemyType = rand < 0.5 ? 'basic' : rand < 0.8 ? 'armored' : 'shooting';
var enemy = game.addChild(new Enemy(enemyType));
// Randomly spawn from left or right
var spawnFromRight = Math.random() < 0.5;
if (spawnFromRight) {
enemy.x = 2048 + 100; // Start off-screen right
enemy.speed = enemy.type === 'armored' ? -3 : enemy.type === 'shooting' ? -2 : -4; // Move left
} else {
enemy.x = -100; // Start off-screen left
enemy.speed = enemy.type === 'armored' ? 3 : enemy.type === 'shooting' ? 2 : 4; // Move right
}
enemy.y = 2732 - 150 + Math.random() * 100 - 50; // Vary height slightly
enemies.push(enemy);
}
// Main game loop
game.update = function () {
gameTime++;
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
// Update health bar
var healthPercent = player.health / player.maxHealth;
healthBar.width = 200 * healthPercent;
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
spawnEnemy();
enemySpawnTimer = 0;
// Increase difficulty over time
if (enemySpawnRate > 60) {
// Minimum spawn rate
enemySpawnRate -= 0.5;
}
}
// Clean up off-screen enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.x < -100 || enemy.x > 2048 + 100) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Clean up off-screen power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.x < -100) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Clean up off-screen enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.x < -100 || bullet.x > 2048 + 100) {
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -574,9 +574,9 @@
player = game.addChild(new Player());
player.x = 300;
player.y = 2732 - 150; // Near bottom of screen
// Start background music
-LK.playMusic('1ninjapetir');
+LK.playMusic('bgmusic');
// Touch controls for movement and slashing
var isDragging = false;
var lastTouchX = 0;
var lastTouchY = 0;
efek slash kepala naga petir ke depan. In-Game asset. 2d. High contrast. No shadows
side scroller blue steel armored ninja aksi koreographi dua tangan memegang pedang ke depan In-Game asset. 2d. No shadows
side scroller image fat orc samurai front holding big axe. In-Game asset. 2d. High contrast. No shadows
side scroller kepala evil kelinci berapi. In-Game asset. 2d. High contrast. No shadows
realistic 2d anime style front field old samurai palace temple with pig evil ornament at midnight. In-Game asset. 2d. High contrast. No shadows