User prompt
Okçu ya oyuncu kesme uygulandığında gelen oku okçu ya %100 geri döner ve okçu ya hasar verir
User prompt
SnakeEnemy toplam canı 30 olsun ve 3y görüntüsünü kullan
User prompt
Ağaçtan sonra yılanı ekle ve aynı anda üç atış yapsın
User prompt
Oyuncu ağacı yene bilmesi için ona 10 saniye boyunca kesme, vurma, büyü saldırılarının hiçbirinin kullanmaması gerekiyor ağaçtan sonra oyuncunun maksimum kalbi 10 olur
User prompt
Ağaçın canı azalmaz maksimum canını arttırabilir hasar aldığında
User prompt
Oyuncu ağaca verdiği hasarı ağaç kendi maksimum kalbini arttırır
User prompt
Ağaç hasar almaz bunun yerine alması gereken hasarı maksimum canını arttırır
User prompt
Büyücünün normal de attığı büyülerin sıklığını biraz azalt
User prompt
Büyücünün attığı büyüleri biraz azalt
User prompt
Ağaç görüntüsünü yaptım eğitici ile ağacı ayır
User prompt
Okçudan sonra ağaç gelir ve ağacın maksimum canı 2 dir ama hasar yemek yerine tüm saldırılar ona maksimum kalp sayısını arttırır eğer ağaca 6 saniye boyunca bir şey yapmazsak oyuncunun maksimum kalbini 10 yapar ağaç hareket etmez saldırmaz . Oyuncunun maksimum kalbini arttırdıktan sonra kaybolur
User prompt
Oyuncunun kalbini bir arttır
User prompt
Okçu büyücüden sonra sadece bir kez gelsin tekrarlan masın
User prompt
Müzik oynarken duyulsun ve müzik bittiğinde döngü halinde devam etsin
User prompt
Oyuncunun maksimum canını 7 ayarla
User prompt
Düşmanlar biraz daha yavaş saldırsın
User prompt
Oyunda düğmeler yerine kesme için kaydırma vurma için tıklama büyü için ise basılı tutarak kullanılır
User prompt
Kesme, kesme, büyü gizli komboyu gizli kombo 2 olarak yap düşmanlarun 10 kalbini birden hasar versin
User prompt
Eski konvoyu kaldırmadan yeni konvoyu yap dedim
User prompt
Kesme , kesme, büyü gizli gücünü silmeden yeni bir gizli güç yap ve kesme, vurma,büyü yaptığında sadece okçuya etki eden ve okçunu öldüren bir gizli güç yap
User prompt
Oyuncu sırasıyla kesme, vurma büyü yaptığında sadece okçuya etki eden özel bir yeni gizli güç atar ve okçu ölür
User prompt
Büyücünün attığı büyülerin yeni bir görüntü yap okçuyla karışmasın
User prompt
Okçunu hasar alabilirsiniz sağla
User prompt
Kesme yazısının vurma yazısının ve büyü yazısını oyunda görünmeyecek hale getir
User prompt
Kesme vurma ve büyü yazılarını sil
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// ArcherArrow: can be reflected by hero, damages archer if reflected
var ArcherArrow = Container.expand(function () {
var self = Container.call(this);
var gfx = self.attachAsset('mage_proj', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 14;
self.dx = 0;
self.dy = 0;
self.active = true;
self.owner = null; // ArcherEnemyV2 instance
self.isReflected = false;
self.update = function () {
if (!self.active) return;
self.x += self.dx;
self.y += self.dy;
// Off screen
if (self.x < -60 || self.x > 2048 + 60 || self.y < -60 || self.y > 2732 + 60) {
self.active = false;
self.destroy();
}
// If not reflected, check collision with hero
if (!self.isReflected && self.active && hero && hero.hearts > 0) {
var dx = self.x - hero.x;
var dy = self.y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < hero.radius + 20) {
// If player is attacking (slash), reflect arrow
if (isHeroSlashing()) {
// Reflect arrow back to archer
if (self.owner) {
var archer = self.owner;
var adx = archer.x - self.x;
var ady = archer.y - self.y;
var adist = Math.sqrt(adx * adx + ady * ady);
self.dx = adx / adist * self.speed * 1.2;
self.dy = ady / adist * self.speed * 1.2;
self.isReflected = true;
// Tint to yellow to show reflection
self.children[0].tint = 0xf7e12c;
}
} else {
// Hit hero
self.active = false;
self.destroy();
hero.takeDamage(1);
}
}
}
// If reflected, check collision with archer
if (self.isReflected && self.active && self.owner && self.owner.hearts > 0) {
var dx2 = self.x - self.owner.x;
var dy2 = self.y - self.owner.y;
var dist2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
if (dist2 < 100) {
// Damage archer
self.active = false;
self.destroy();
self.owner.takeDamage('slash', 1, true);
}
}
};
return self;
});
// Helper: isHeroSlashing
var BashAttack = Container.expand(function () {
var self = Container.call(this);
var gfx = self.attachAsset('atk_bash', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'bash';
self.speed = 32;
self.target = null;
self.active = true;
self.update = function () {
if (!self.active) return;
if (self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.x = self.target.x;
self.y = self.target.y;
self.active = false;
} else {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
}
};
return self;
});
// Enemy base class
var EnemyBase = Container.expand(function () {
var self = Container.call(this);
self.maxHearts = 1;
self.hearts = 1;
self.invuln = 0;
self.name = '';
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
self.hearts -= amount;
if (self.hearts < 0) self.hearts = 0;
self.invuln = 10;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
return true;
};
self.heal = function (amount) {
self.hearts += amount;
if (self.hearts > self.maxHearts) self.hearts = self.maxHearts;
updateEnemyHearts();
LK.getSound('heal').play();
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
};
return self;
});
// TreeEnemy: appears after Archer, does not attack, increases its own max hearts on hit, if not attacked for 10s increases hero's max hearts to 10 and disappears
var TreeEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('Tree', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Ağaç';
self.maxHearts = 2;
self.hearts = 2;
self.increaseAmount = 1; // Each hit increases tree's own max hearts by 1
self.lastAttackTime = Date.now();
self.hasDisappeared = false;
self._hitCount = 0;
// Override takeDamage: instead of damage, increase tree's own max hearts
self.takeDamage = function (type, amount) {
if (self.hasDisappeared) return false;
// On any attack, increase tree's max hearts by 1 (up to 10). Hearts do not decrease.
if (self.maxHearts < 10) {
self.maxHearts += self.increaseAmount;
self.hearts = self.maxHearts;
updateEnemyHearts();
LK.getSound('heal').play();
showInfo('Ağaç: Kendi maksimum kalbini artırdı! (' + self.maxHearts + ')', 1200);
}
self.lastAttackTime = Date.now();
updateEnemyHearts();
// Tree never disappears from being hit, only from timeout
return true;
};
self.update = function () {
// Tree does not move or attack
// If 10 seconds pass without being hit, set hero max hearts to 10 and disappear
if (!self.hasDisappeared && Date.now() - self.lastAttackTime > 10000) {
if (hero && hero.maxHearts < 10) {
hero.maxHearts = 10;
hero.hearts = 10;
updateHeroHearts();
showInfo('Ağaç: Maksimum kalbin 10 oldu!', 1800);
LK.getSound('heal').play();
}
self.hasDisappeared = true;
LK.setTimeout(function () {
nextEnemy();
}, 900);
}
};
return self;
});
// Trainer enemy: disappears after being hit by all 3 attack types
var TrainerEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('enemy_trainer', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Eğitici';
self.maxHearts = 3;
self.hearts = 3;
self.hitTypes = {
slash: false,
bash: false,
magic: false
};
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
if (!self.hitTypes[type]) {
self.hitTypes[type] = true;
self.hearts--;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts <= 0) {
// All types hit
nextEnemy();
}
self.invuln = 10;
return true;
}
return false;
};
return self;
});
// SnakeEnemy: appears after Tree, attacks with 3 projectiles at once
var SnakeEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('3y', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Yılan';
self.maxHearts = 30;
self.hearts = 30;
self.attackCooldown = 0;
self.moveDir = 1;
self.moveTimer = 0;
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
self.hearts -= amount;
LK.effects.flashObject(self, 0x00ff00, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts <= 0) {
nextEnemy();
}
self.invuln = 10;
return true;
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
// Move left/right
self.moveTimer++;
if (self.moveTimer % 40 === 0) self.moveDir *= -1;
self.x += self.moveDir * 5;
// Limit movement to arena bounds
if (self.x < 200) {
self.x = 200;
self.moveDir = 1;
}
if (self.x > 1848) {
self.x = 1848;
self.moveDir = -1;
}
// Attack every 60 frames
if (self.attackCooldown > 0) {
self.attackCooldown--;
} else {
if (hero && hero.hearts > 0) {
// Fire 3 projectiles: one straight, two angled
for (var i = 0; i < 3; i++) {
var proj = new MageProjectile();
proj.x = self.x;
proj.y = self.y;
var angleOffset = (i - 1) * (Math.PI / 10); // -1, 0, 1 -> -0.314, 0, 0.314 radians
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var baseAngle = Math.atan2(dy, dx);
var angle = baseAngle + angleOffset;
var dist = Math.sqrt(dx * dx + dy * dy);
proj.dx = Math.cos(angle) * proj.speed;
proj.dy = Math.sin(angle) * proj.speed;
mageProjectiles.push(proj);
game.addChild(proj);
}
self.attackCooldown = 60;
}
}
};
return self;
});
// Mage: 25 hearts, every 10s fires 10 magic projectiles, heals to full at 1hp
var MageEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('enemy_mage', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Büyücü';
self.maxHearts = 25;
self.hearts = 25;
self.magicTimer = 0;
self.healed = false;
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
self.hearts -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts === 1 && !self.healed) {
// Heal to full
self.healed = true;
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
self.heal(self.maxHearts - 1);
}
if (self.hearts <= 0) {
nextEnemy();
}
self.invuln = 10;
return true;
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
self.magicTimer++;
if (self.magicTimer % 600 === 0) {
// Fire 40 projectiles in a circle
for (var i = 0; i < 40; i++) {
var angle = 2 * Math.PI / 40 * i;
var px = self.x + Math.cos(angle) * 100;
var py = self.y + Math.sin(angle) * 100;
spawnMageProjectile(self.x, self.y, px, py);
}
} else if (self.magicTimer % 120 === 0) {
// Fire a single projectile at the hero (reduced frequency)
if (hero && hero.hearts > 0) {
spawnMageProjectile(self.x, self.y, hero.x, hero.y);
}
}
};
return self;
});
// Knight: 36 hearts, takes extra from magic, attacks with slash and bash
var KnightEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('enemy_knight', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Şövalye';
self.maxHearts = 36;
self.hearts = 36;
self.attackCooldown = 0;
self.moveDir = 1;
self.moveTimer = 0;
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
var dmg = amount;
if (type === 'magic') dmg = amount + 2;
self.hearts -= dmg;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts <= 0) {
nextEnemy();
}
self.invuln = 10;
return true;
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
// Move left/right
self.moveTimer++;
if (self.moveTimer % 50 === 0) self.moveDir *= -1;
self.x += self.moveDir * 3;
// Attack every 70 frames
if (self.attackCooldown > 0) self.attackCooldown--;else {
// Alternate between slash and bash
if (Math.abs(self.x - hero.x) < 300) {
if (self.moveTimer % 2 === 0) {
spawnEnemyAttack('slash', self.x, self.y, hero.x, hero.y);
} else {
spawnEnemyAttack('bash', self.x, self.y, hero.x, hero.y);
}
self.attackCooldown = 70;
}
}
};
return self;
});
// Goblin: 20 hearts, only takes damage from slash and magic, attacks with bash
var GoblinEnemy = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('enemy_goblin', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Goblin';
self.maxHearts = 20;
self.hearts = 20;
self.attackCooldown = 0;
self.moveDir = 1;
self.moveTimer = 0;
self.takeDamage = function (type, amount) {
if (self.invuln > 0) return false;
if (type === 'slash' || type === 'magic') {
self.hearts -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts <= 0) {
nextEnemy();
}
self.invuln = 10;
return true;
}
return false;
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
// Move left/right slowly
self.moveTimer++;
if (self.moveTimer % 60 === 0) self.moveDir *= -1;
self.x += self.moveDir * 2;
// Attack every 90 frames
if (self.attackCooldown > 0) self.attackCooldown--;else {
if (Math.abs(self.x - hero.x) < 200) {
// Bash attack
spawnEnemyAttack('bash', self.x, self.y, hero.x, hero.y);
self.attackCooldown = 90;
}
}
};
return self;
});
// ArcherEnemyV2: 10 hearts, only takes damage from reflected arrows, fires arrows with variable speed
var ArcherEnemyV2 = EnemyBase.expand(function () {
var self = EnemyBase.call(this);
var gfx = self.attachAsset('Archeryenemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Okçu';
self.maxHearts = 10;
self.hearts = 10;
self.attackCooldown = 0;
self.moveDir = 1;
self.moveTimer = 0;
self.arrowSpeed = 12 + Math.floor(Math.random() * 7); // 12-18
self.arrowCooldownBase = 70 + Math.floor(Math.random() * 30); // 70-99
self.takeDamage = function (type, amount, fromArrow) {
// Takes 2 damage from all attacks, but only reflected arrows can actually hit
if (self.invuln > 0) return false;
if (fromArrow === true) {
self.hearts -= 2; // Always 2 damage from reflected arrow
LK.effects.flashObject(self, 0x00cfff, 200);
LK.getSound('enemyHit').play();
updateEnemyHearts();
if (self.hearts < 0) self.hearts = 0;
if (self.hearts <= 0) {
nextEnemy();
}
self.invuln = 10;
return true;
}
return false;
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
// Move left/right, but sometimes speed up or slow down while escaping
self.moveTimer++;
// Randomly change speed every 60 frames (1 second)
if (self.moveTimer % 60 === 0) {
// 50% chance to change speed
if (Math.random() < 0.5) {
self.moveSpeed = 3 + Math.floor(Math.random() * 6); // 3-8 px per frame
}
}
if (typeof self.moveSpeed !== "number") self.moveSpeed = 4;
if (self.moveTimer % 70 === 0) self.moveDir *= -1;
self.x += self.moveDir * self.moveSpeed;
// Limit archer movement to within arena bounds (minX = 200, maxX = 1848)
if (self.x < 200) {
self.x = 200;
self.moveDir = 1;
}
if (self.x > 1848) {
self.x = 1848;
self.moveDir = -1;
}
// Attack every arrowCooldownBase frames
if (self.attackCooldown > 0) self.attackCooldown--;else {
if (hero && hero.hearts > 0 && Math.abs(self.x - hero.x) < 900) {
// Fire an arrow
var proj = new ArcherArrow();
proj.x = self.x;
proj.y = self.y;
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
proj.dx = dx / dist * self.arrowSpeed;
proj.dy = dy / dist * self.arrowSpeed;
proj.owner = self;
proj.isReflected = false;
proj.speed = self.arrowSpeed;
// Tint to look like an arrow (blue)
proj.children[0].tint = 0x00cfff;
archerArrows.push(proj);
game.addChild(proj);
// Randomize next arrow speed/cooldown
self.arrowSpeed = 12 + Math.floor(Math.random() * 7);
self.arrowCooldownBase = 70 + Math.floor(Math.random() * 30);
self.attackCooldown = self.arrowCooldownBase;
}
}
};
return self;
});
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGfx = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = heroGfx.width / 2;
self.maxHearts = 7;
self.hearts = self.maxHearts;
self.invuln = 0; // frames of invulnerability after hit
self.takeDamage = function (amount) {
if (self.invuln > 0) return;
self.hearts -= amount;
if (self.hearts < 0) self.hearts = 0;
self.invuln = 30;
LK.effects.flashObject(self, 0xff0000, 300);
LK.getSound('hit').play();
updateHeroHearts();
if (self.hearts <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
};
self.heal = function (amount) {
self.hearts += amount;
if (self.hearts > self.maxHearts) self.hearts = self.maxHearts;
updateHeroHearts();
LK.getSound('heal').play();
};
self.update = function () {
if (self.invuln > 0) self.invuln--;
};
return self;
});
// Enemy magic projectile (for Mage)
var MageProjectile = Container.expand(function () {
var self = Container.call(this);
var gfx = self.attachAsset('mage_proj2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 14;
self.dx = 0;
self.dy = 0;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.dx;
self.y += self.dy;
// Off screen
if (self.x < -60 || self.x > 2048 + 60 || self.y < -60 || self.y > 2732 + 60) {
self.active = false;
self.destroy();
}
// Hit hero
if (self.active && hero && hero.hearts > 0) {
var dx = self.x - hero.x;
var dy = self.y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < hero.radius + 20) {
self.active = false;
self.destroy();
hero.takeDamage(1);
}
}
};
return self;
});
var MagicAttack = Container.expand(function () {
var self = Container.call(this);
var gfx = self.attachAsset('atk_magic', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'magic';
self.speed = 36;
self.target = null;
self.active = true;
self.update = function () {
if (!self.active) return;
if (self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.x = self.target.x;
self.y = self.target.y;
self.active = false;
} else {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
}
};
return self;
});
// Attack classes
var SlashAttack = Container.expand(function () {
var self = Container.call(this);
var gfx = self.attachAsset('atk_slash', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'slash';
self.speed = 40;
self.target = null;
self.active = true;
self.update = function () {
if (!self.active) return;
if (self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.x = self.target.x;
self.y = self.target.y;
self.active = false;
} else {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xc2b280 // Kurak toprak rengi (dry earth color)
});
/****
* Game Code
****/
// --- Use static background image asset for arena ---
function setArenaBackground() {
// Remove previous background if exists
if (game._arenaBg) {
game._arenaBg.destroy();
game._arenaBg = null;
}
// Create and add the static background image
var bg = LK.getAsset('Arkaplan', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732
});
bg.x = 0;
bg.y = 0;
bg.scaleX = 2048 / bg.width;
bg.scaleY = 2732 / bg.height;
game.addChildAt(bg, 0);
game._arenaBg = bg;
}
// Set background on start
setArenaBackground();
// Global variables
// Hero
// Attack types
// Enemies
// Enemy hearts
// Magic projectile
// Sounds (placeholders)
function isHeroSlashing() {
// If a SlashAttack is active and close to hero, treat as slashing
for (var i = 0; i < attacks.length; i++) {
var atk = attacks[i];
if (atk.type === 'slash' && atk.active) {
var dx = atk.x - hero.x;
var dy = atk.y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) return true;
}
}
return false;
}
var hero = null;
// Increase hero's current hearts by 1 at game start (if not already at max)
LK.setTimeout(function () {
if (hero && hero.hearts < hero.maxHearts) {
hero.hearts += 1;
updateHeroHearts();
}
}, 1000);
var heroHearts = [];
var enemy = null;
var enemyHearts = [];
var attacks = [];
var enemyAttacks = [];
var mageProjectiles = [];
var archerArrows = [];
var currentEnemyIndex = 0;
var enemies = [];
var canAttack = true;
var attackCooldown = 0;
var attackType = null;
var dragNode = null;
var attackButtons = {};
var infoText = null;
var enemyNameText = null;
// Track last 3 player attack types for secret combo
var playerAttackSequence = [];
// Enemy sequence
function setupEnemies() {
enemies = [TrainerEnemy, GoblinEnemy, KnightEnemy, MageEnemy, ArcherEnemyV2, TreeEnemy, SnakeEnemy];
currentEnemyIndex = 0;
}
// UI: Hero hearts
function updateHeroHearts() {
for (var i = 0; i < heroHearts.length; i++) {
heroHearts[i].visible = i < hero.hearts;
}
}
// UI: Enemy hearts
function updateEnemyHearts() {
for (var i = 0; i < enemyHearts.length; i++) {
enemyHearts[i].visible = i < enemy.hearts;
}
}
// UI: Enemy name
function updateEnemyName() {
if (!enemyNameText) return;
enemyNameText.setText(enemy ? enemy.name : '');
}
// UI: Info text
function showInfo(msg, duration) {
if (!infoText) return;
infoText.setText(msg);
infoText.visible = true;
if (duration) {
LK.setTimeout(function () {
infoText.visible = false;
}, duration);
}
}
// Spawn player attack
function spawnAttack(type) {
if (!enemy || !canAttack) return;
// Track attack sequence for secret combo
playerAttackSequence.push(type);
if (playerAttackSequence.length > 3) playerAttackSequence.shift();
// Check for secret combo 2: slash, slash, magic (in order)
if (playerAttackSequence.length === 3 && playerAttackSequence[0] === 'slash' && playerAttackSequence[1] === 'slash' && playerAttackSequence[2] === 'magic') {
// Deal 10 damage to all enemies (if present)
if (enemy && enemy.hearts > 0) {
showInfo('Gizli Kombo 2! Düşmana 10 hasar verdin!', 1800);
LK.effects.flashObject(enemy, 0xff00ff, 800);
enemy.takeDamage('magic', 10);
updateEnemyHearts();
// Clear sequence so it can't be spammed
playerAttackSequence = [];
canAttack = false;
attackCooldown = 20;
return;
}
}
// Check for old secret combo: slash, bash, magic (in order)
if (playerAttackSequence.length === 3 && playerAttackSequence[0] === 'slash' && playerAttackSequence[1] === 'bash' && playerAttackSequence[2] === 'magic') {
// Only affect archer enemy
if (enemy && enemy.name === 'Okçu' && enemy.hearts > 0) {
showInfo('Gizli güç! Okçuyu yok ettin!', 1800);
LK.effects.flashObject(enemy, 0x000000, 800);
// Instantly kill archer
enemy.hearts = 0;
updateEnemyHearts();
LK.setTimeout(function () {
nextEnemy();
}, 900);
// Clear sequence so it can't be spammed
playerAttackSequence = [];
canAttack = false;
attackCooldown = 20;
return;
}
}
// Check for new secret combo: bash, magic, slash (in order)
if (playerAttackSequence.length === 3 && playerAttackSequence[0] === 'bash' && playerAttackSequence[1] === 'magic' && playerAttackSequence[2] === 'slash') {
// Only affect archer enemy
if (enemy && enemy.name === 'Okçu' && enemy.hearts > 0) {
showInfo('Yeni gizli güç! Okçuyu yok ettin!', 1800);
LK.effects.flashObject(enemy, 0x000000, 800);
// Instantly kill archer
enemy.hearts = 0;
updateEnemyHearts();
LK.setTimeout(function () {
nextEnemy();
}, 900);
// Clear sequence so it can't be spammed
playerAttackSequence = [];
canAttack = false;
attackCooldown = 20;
return;
}
}
var atk;
if (type === 'slash') atk = new SlashAttack();else if (type === 'bash') atk = new BashAttack();else if (type === 'magic') atk = new MagicAttack();else return;
atk.x = hero.x;
atk.y = hero.y;
atk.target = {
x: enemy.x,
y: enemy.y
};
attacks.push(atk);
game.addChild(atk);
canAttack = false;
attackCooldown = 20;
}
// Spawn enemy attack
function spawnEnemyAttack(type, sx, sy, tx, ty) {
var atk;
if (type === 'slash') atk = new SlashAttack();else if (type === 'bash') atk = new BashAttack();else if (type === 'magic') atk = new MagicAttack();else return;
atk.x = sx;
atk.y = sy;
atk.target = {
x: tx,
y: ty
};
atk.active = true;
enemyAttacks.push(atk);
game.addChild(atk);
}
// Mage projectile
function spawnMageProjectile(sx, sy, tx, ty) {
var proj = new MageProjectile();
proj.x = sx;
proj.y = sy;
var dx = tx - sx;
var dy = ty - sy;
var dist = Math.sqrt(dx * dx + dy * dy);
proj.dx = dx / dist * proj.speed;
proj.dy = dy / dist * proj.speed;
mageProjectiles.push(proj);
game.addChild(proj);
}
// Next enemy
function nextEnemy() {
// Remove old enemy
if (enemy) {
enemy.destroy();
enemy = null;
}
for (var i = 0; i < enemyHearts.length; i++) {
enemyHearts[i].destroy();
}
enemyHearts = [];
currentEnemyIndex++;
if (currentEnemyIndex >= enemies.length) {
LK.showYouWin();
return;
}
// Refill hero hearts to max after each enemy
if (hero) {
hero.hearts = hero.maxHearts;
updateHeroHearts();
}
// Wait 2 seconds before spawning next enemy
LK.setTimeout(function () {
// Spawn new enemy
var EnemyClass = enemies[currentEnemyIndex];
enemy = new EnemyClass();
enemy.x = 2048 / 2;
enemy.y = 700;
game.addChild(enemy);
// Enemy hearts
for (var i = 0; i < enemy.maxHearts; i++) {
var h = LK.getAsset('enemyHeart', {
anchorX: 0.5,
anchorY: 0.5
});
h.x = 2048 / 2 - enemy.maxHearts * 30 / 2 + i * 30;
h.y = 500;
enemyHearts.push(h);
game.addChild(h);
}
updateEnemyHearts();
updateEnemyName();
// Info
if (enemy.name === 'Eğitici') {
showInfo('Her saldırı türünü dene: Kesme, Vurma, Büyü!', 3000);
} else if (enemy.name === 'Goblin') {
showInfo('Goblin sadece Kesme ve Büyü saldırılarından hasar alır!', 3500);
} else if (enemy.name === 'Şövalye') {
showInfo('Şövalye, Büyü saldırısından fazladan hasar alır!', 3500);
} else if (enemy.name === 'Büyücü') {
showInfo('Büyücü, her 10 saniyede 10 büyü fırlatır ve canı 1’e düştüğünde iyileşir!', 4000);
} else if (enemy.name === 'Okçu') {
showInfo('Okçunun oklarını Kesme saldırısı ile geri yolla! Sadece geri dönen oklar hasar verir.', 4000);
} else if (enemy.name === 'Ağaç') {
showInfo('Ağaç: Saldırılar ona zarar vermez, her saldırı maksimum kalbini artırır! 6 saniye dokunmazsan maksimum kalbin 10 olur ve kaybolur.', 5000);
// Hide enemy hearts for tree
for (var i = 0; i < enemyHearts.length; i++) {
enemyHearts[i].visible = false;
}
} else if (enemy.name === 'Yılan') {
showInfo('Yılan: Her saldırıda aynı anda 3 büyü fırlatır!', 4000);
}
}, 2000);
}
// Start game
function startGame() {
setupEnemies();
// Hero
hero = new Hero();
hero.x = 2048 / 2;
hero.y = 2000;
game.addChild(hero);
// Hero hearts
for (var i = 0; i < hero.maxHearts; i++) {
var h = LK.getAsset('heroHeart', {
anchorX: 0.5,
anchorY: 0.5
});
h.x = 2048 / 2 - hero.maxHearts * 40 / 2 + i * 40;
h.y = 2732 - 120;
heroHearts.push(h);
game.addChild(h);
}
updateHeroHearts();
// Enemy
currentEnemyIndex = -1;
nextEnemy();
// Enemy name
enemyNameText = new Text2('', {
size: 90,
fill: '#fff'
});
enemyNameText.anchor.set(0.5, 0);
enemyNameText.x = 2048 / 2;
enemyNameText.y = 120;
LK.gui.top.addChild(enemyNameText);
updateEnemyName();
// Info text
infoText = new Text2('', {
size: 60,
fill: '#fff'
});
infoText.anchor.set(0.5, 0);
infoText.x = 2048 / 2;
infoText.y = 250;
LK.gui.top.addChild(infoText);
infoText.visible = false;
// Gesture-based controls: swipe for slash, tap for bash, hold for magic
// Touch gesture state
var gestureStart = null;
var gestureStartTime = 0;
var gestureActive = false;
var holdTimeout = null;
var holdTriggered = false;
// Helper: distance between two points
function dist2(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
// Minimum swipe distance for slash (in px)
var SWIPE_MIN_DIST = 120;
// Maximum tap distance for bash (in px)
var TAP_MAX_DIST = 40;
// Hold time for magic (in ms)
var HOLD_TIME = 400;
// Touch/Mouse down
game.down = function (x, y, obj) {
gestureStart = {
x: x,
y: y
};
gestureStartTime = Date.now();
gestureActive = true;
holdTriggered = false;
// Set up hold detection for magic
if (holdTimeout) LK.clearTimeout(holdTimeout);
holdTimeout = LK.setTimeout(function () {
if (gestureActive && !holdTriggered) {
holdTriggered = true;
spawnAttack('magic');
gestureActive = false;
}
}, HOLD_TIME);
};
// Touch/Mouse move
game.move = function (x, y, obj) {
if (!gestureActive || !gestureStart) return;
var d = dist2(gestureStart.x, gestureStart.y, x, y);
// If swipe detected and not already triggered
if (d > SWIPE_MIN_DIST && !holdTriggered) {
// Only trigger once per gesture
holdTriggered = true;
spawnAttack('slash');
gestureActive = false;
if (holdTimeout) LK.clearTimeout(holdTimeout);
}
};
// Touch/Mouse up
game.up = function (x, y, obj) {
if (!gestureActive || !gestureStart) return;
var d = dist2(gestureStart.x, gestureStart.y, x, y);
var elapsed = Date.now() - gestureStartTime;
if (!holdTriggered) {
if (d < TAP_MAX_DIST && elapsed < HOLD_TIME) {
// Tap detected
spawnAttack('bash');
}
// Cancel hold timeout if not triggered
if (holdTimeout) LK.clearTimeout(holdTimeout);
}
gestureActive = false;
holdTriggered = false;
gestureStart = null;
gestureStartTime = 0;
holdTimeout = null;
};
}
// Game move handler (for future drag, not used now)
game.move = function (x, y, obj) {
// No drag
};
// Game update
var regenTimer = 0; // Heart regen timer
game.update = function () {
// Hero update
if (hero) hero.update();
// Heart regeneration logic
if (hero && hero.hearts < hero.maxHearts) {
regenTimer++;
if (regenTimer >= 60) {
// 60 frames = 1 second at 60fps
hero.heal(1);
regenTimer = 0;
}
} else {
regenTimer = 0;
}
// Enemy update
if (enemy) {
enemy.update();
}
// Player attacks
for (var i = attacks.length - 1; i >= 0; i--) {
var atk = attacks[i];
atk.update();
if (!atk.active) {
// Check hit
if (enemy && atk.target && Math.abs(atk.x - enemy.x) < 100 && Math.abs(atk.y - enemy.y) < 100) {
// Damage logic
var dmg = 1;
if (enemy.name === 'Şövalye' && atk.type === 'magic') dmg = 3;
var hit = enemy.takeDamage(atk.type, dmg);
if (hit) {
// Already flashed in enemy.takeDamage, do not flash again here
}
}
atk.destroy();
attacks.splice(i, 1);
}
}
// Enemy attacks
for (var i = enemyAttacks.length - 1; i >= 0; i--) {
var atk = enemyAttacks[i];
atk.update();
if (!atk.active) {
// Check hit
if (hero && atk.target && Math.abs(atk.x - hero.x) < 100 && Math.abs(atk.y - hero.y) < 100) {
hero.takeDamage(1);
}
atk.destroy();
enemyAttacks.splice(i, 1);
}
}
// Mage projectiles
for (var i = mageProjectiles.length - 1; i >= 0; i--) {
var proj = mageProjectiles[i];
proj.update();
if (!proj.active) {
mageProjectiles.splice(i, 1);
}
}
// Archer arrows
for (var i = archerArrows.length - 1; i >= 0; i--) {
var arr = archerArrows[i];
arr.update();
if (!arr.active) {
archerArrows.splice(i, 1);
}
}
// Attack cooldown
if (!canAttack) {
attackCooldown--;
if (attackCooldown <= 0) canAttack = true;
}
};
// Start game
startGame();
;
// Play background music in a loop
LK.playMusic('Ses1', {
loop: true
}); ===================================================================
--- original.js
+++ change.js
@@ -219,10 +219,10 @@
anchorX: 0.5,
anchorY: 0.5
});
self.name = 'Yılan';
- self.maxHearts = 12;
- self.hearts = 12;
+ self.maxHearts = 30;
+ self.hearts = 30;
self.attackCooldown = 0;
self.moveDir = 1;
self.moveTimer = 0;
self.takeDamage = function (type, amount) {
Karekter insan. In-Game asset. 2d. High contrast. No shadows
Büyük barbar vahşi pis bir goblin yeşil solgun derili. In-Game asset. 2d. High contrast. No shadows
Kara şövalye iskelet atının üzerinde elinde parlak bir kılıç tutuyor. In-Game asset. 2d. High contrast. No shadows
Mor perelinli bir büyücü yüzünde bir pagan maskesi var. In-Game asset. 2d. High contrast. No shadows
Basit pixel artla yapılmış siyah bir kalp. In-Game asset. 2d. High contrast. No shadows
Kırmızı
Yumruk işareti. In-Game asset. 2d. High contrast. No shadows
Mor ateş. In-Game asset. 2d. High contrast. No shadows
Arrow. In-Game asset. 2d. High contrast. No shadows
Daha yuvarlak ve kırmızı hale yaklaştır
Kılıç vurma efekti. In-Game asset. 2d. High contrast. No shadows
Biraz ayrıntılı olsun
Daha ayrıntılı olsun kıyafeti elf okçu olsun ve kör olduğu için gözlerini bağlanmış olsun
Yüzü olan bir ağaç altın elmalar var. In-Game asset. 2d. High contrast. No shadows
3 başı olan koyu renkli pullu bir yılan. In-Game asset. 2d. High contrast. No shadows