User prompt
shoptaki buy yazılarını sil
User prompt
- Genişlik (width): `winW = 1500` - Yükseklik (height): `winH = 2000` olarak ayarla ve shop yazısını sil
User prompt
- Yükseklik (height): `winH = 1800` olarak ayarla
User prompt
butonların backgorundunu kaldır.
User prompt
shop backgroundunu shop assetiyle değiştir
User prompt
Buton stillerini upgrade ekranının aynısı yap
User prompt
submachine gun ismini SMG yap semiauto gun ismini SAG yap
User prompt
shop kısmına 5 farklı silah ekleyeceğiz bunlar. submachine gun, shotgun, shuriken, minigun, semiauto gun olacak bunları alt alta bir buton halinde ekle aynı upgrade ekranı gibi olsun ve her birinin assetini kullan
User prompt
upgrade ekranı gibi bir shop ekranı da oluşturmak istiyorum. upgrade butonu gibi altına bir buton daha koyarak adına shop diyelim ve tıkladığımda bir ekran açılsın
User prompt
coinText.x = coinIcon.x + 100; coinText.y = coinIcon.y - 50; olarak bütün ekranlarda uygula
User prompt
bu koşulu bekleme ekranında da uygula
User prompt
bu durumu bütün oyun için uygula
User prompt
coinText.x = coinIcon.x + 250; coinText.y = coinIcon.y - 250; olarak güncelle
User prompt
coin miktarı coin assetinin 50 piksel sağına 50 piksel üzerine taşı
User prompt
coin miktarı coin assetinin 50 piksel soluna 25 piksel üzerine taşı
User prompt
coin miktarını 50 piksel sağa 25 piksel yukarı taşı
User prompt
coin miktarı coin assetinin sağında yer alsın
User prompt
oyun başlangıç ekranında coin assetini score yazısının altına taşı
User prompt
score artık kullanılmasın score tamamen kaldıralım
User prompt
Please fix the bug: 'ReferenceError: scoreText is not defined' in or related to this line: 'scoreText.setText("Score: " + score);' Line Number: 1347
User prompt
Oyun ekranında coin asseti ve coin miktarı score yazısının orda yer alsın ve score yazısını tamamen kaldıralım
User prompt
upgrade ekranında power yerine DAMAGE yazsın
User prompt
health artışı için coin miktarlarını şöyle düzenle toplamda 3 defa can artışı yapılabilsin. 25 coin ile başlasın 50 coin ve 75 coin son olsun. ateş hızı için 50 coinle başlasın 75 coin ve 100 coin olsun. damage için ise 60 coinle başlasın 120 ve 180 coin olsun
User prompt
upgrade ekranında speed ve damage olan upgradelerin ya yazı düzenini HEALTH | 1 coin asset olarak ayarla her upgrade 1 coin olarak başlasın ve 5-10 olarak devam etsin. speed için upgrade yapıldığında her upgrade için 150 ms ateş hızında artış sağla. damage için ise her upgrade için fireball damagesi 1 artırılsın. yani seviye 2 düşmanlar bir upgrade sonra tek mermide ölebilsin.
User prompt
upgrade ekranında back butonundaki coin assetini kaldır
/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Coin class: represents coins dropped by enemies when destroyed
var Coin = Container.expand(function () {
var self = Container.call(this);
// Create a gold coin visual (using a yellow circle)
var coinSprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Coin movement properties
self.vx = 0;
self.vy = 0;
self.gravity = 0;
self.collected = false;
// Track last position for event triggers
self.lastX = 0;
self.lastY = 0;
self.lastWasIntersecting = false;
self.update = function () {
// No gravity or bounce logic needed
// Remove coin if it leaves the screen horizontally
if (self.x < -50 || self.x > 2048 + 50) {
self.destroy();
}
// Pulsate slightly for visual effect
var t = LK.ticks || Date.now();
var scale = 1 + 0.1 * Math.sin(t * 0.1);
if (self.children && self.children.length > 0) {
self.children[0].scale.x = scale;
self.children[0].scale.y = scale;
}
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Enemy class: represents an enemy that moves toward the wizard
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Attach a unique enemy asset (pixel blue monster)
var enemySprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Enemy speed and direction
self.vx = 0;
self.vy = 0;
// Track last position for event triggers
self.lastX = 0;
self.lastY = 0;
self.health = 1; // Enemy1: 1 hit to kill
self.type = 1;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Pulsate scale for movement effect
var t = LK.ticks || Date.now(); // fallback for safety
var scale = 1 + 0.15 * Math.sin((t + self.x + self.y) * 0.05);
if (self.children && self.children.length > 0) {
self.children[0].scale.x = scale;
self.children[0].scale.y = scale;
}
// Remove enemy if it leaves the screen
if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) {
self.destroy();
}
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Enemy2: needs 2 fireballs to die
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.lastX = 0;
self.lastY = 0;
self.health = 2;
self.type = 2;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
var t = LK.ticks || Date.now();
var scale = 1 + 0.18 * Math.sin((t + self.x + self.y) * 0.06);
if (self.children && self.children.length > 0) {
self.children[0].scale.x = scale;
self.children[0].scale.y = scale;
}
if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) {
self.destroy();
}
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Enemy3: needs 3 fireballs to die
var Enemy3 = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.lastX = 0;
self.lastY = 0;
self.health = 3;
self.type = 3;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
var t = LK.ticks || Date.now();
var scale = 1 + 0.22 * Math.sin((t + self.x + self.y) * 0.07);
if (self.children && self.children.length > 0) {
self.children[0].scale.x = scale;
self.children[0].scale.y = scale;
}
if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) {
self.destroy();
}
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Explosion class: shows a quick explosion effect at (x, y)
var Explosion = Container.expand(function () {
var self = Container.call(this);
var sprite = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
// Initial scale and alpha
sprite.scale.x = 0.5;
sprite.scale.y = 0.5;
sprite.alpha = 1;
// Animate explosion: grow and fade out
var duration = 18; // frames (~0.3s)
var frame = 0;
self.update = function () {
frame++;
// Grow and fade
var progress = frame / duration;
sprite.scale.x = 0.5 + 1.2 * progress;
sprite.scale.y = 0.5 + 1.2 * progress;
sprite.alpha = 1 - progress;
if (frame >= duration) {
self.destroy();
}
};
return self;
});
// Fireball class: represents a fireball shot by the wizard
var Fireball = Container.expand(function () {
var self = Container.call(this);
// Attach fireball asset (pixel fireball)
var fireballSprite = self.attachAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5
});
// Fireball speed and direction
self.vx = 0;
self.vy = 0;
// Track last position for event triggers
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Remove fireball if it leaves the screen
if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) {
self.destroy();
}
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Wizard class: represents the player character
var Wizard = Container.expand(function () {
var self = Container.call(this);
// Attach wizard asset (blue hat, pixel style)
var wizardSprite = self.attachAsset('wizard', {
anchorX: 0.5,
anchorY: 0.5
});
// Track last position for event triggers
self.lastX = 0;
self.lastY = 0;
// Update method (called every tick)
self.update = function () {
// No movement logic here; wizard is moved by mouse/touch
self.lastX = self.x;
self.lastY = self.y;
// Always keep health bar above wizard in case of movement
if (self.children && self.children.length > 0 && typeof healthBarBg !== "undefined" && typeof healthBar !== "undefined") {
healthBarBg.y = -self.children[0].height / 2 - 18 - 50;
healthBar.x = 0;
healthBarBg.x = 0;
healthBar.y = healthBarBg.y;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Explosion asset for enemy death effect
;
// Add background image to the game scene
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(background);
// --- Game Code for Pixel Wizard: Blue Hat Adventure ---
// Create wizard instance and add to game
var wizard = new Wizard();
game.addChild(wizard);
// Center wizard on screen at start
wizard.x = 2048 / 2;
wizard.y = 2732 / 2;
// --- START & UPGRADE BUTTON UI LOGIC ---
var gameStarted = false;
// UI container for start and upgrade buttons
var startUiContainer = new Container();
// Create start button asset (simple box with text)
var startButtonWidth = 420;
var startButtonHeight = 140;
var startButton = new Container();
var startButtonBg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
width: startButtonWidth,
height: startButtonHeight
});
startButtonBg.alpha = 0.92;
startButton.addChild(startButtonBg);
var startButtonText = new Text2("START GAME", {
size: 220,
fill: "#fff"
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.x = 0;
startButtonText.y = -120;
startButton.addChild(startButtonText);
// Create upgrade button below start button
var upgradeButtonWidth = 420;
var upgradeButtonHeight = 110;
var upgradeButton = new Container();
var upgradeButtonBg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
width: upgradeButtonWidth,
height: upgradeButtonHeight
});
upgradeButtonBg.alpha = 0.92;
upgradeButton.addChild(upgradeButtonBg);
var upgradeButtonText = new Text2("UPGRADE", {
size: 110,
// Half of START GAME (220)
fill: "#fff"
});
upgradeButtonText.anchor.set(0.5, 0.5);
upgradeButtonText.x = 0;
upgradeButtonText.y = 0;
upgradeButton.addChild(upgradeButtonText);
// Position start and upgrade buttons in the UI container
startButton.x = 0;
startButton.y = -400; //{36} // Moved much higher
upgradeButton.x = 0;
upgradeButton.y = startButton.y + startButtonHeight / 2 + 55 + upgradeButtonHeight / 2; //{38} // Increased spacing by 15px
// Add both buttons to the UI container
startUiContainer.addChild(startButton);
startUiContainer.addChild(upgradeButton);
// Position the UI container: horizontally centered, vertically centered
startUiContainer.x = 2048 / 2;
startUiContainer.y = 2732 / 2;
// Add to game
game.addChild(startUiContainer);
// Block input until start is pressed
function blockGameInput() {
game.move = function () {};
game.down = function () {};
game.up = function () {};
isFiring = false;
if (fireInterval) {
LK.clearInterval(fireInterval);
fireInterval = null;
}
}
blockGameInput();
// --- UPGRADE WINDOW LOGIC ---
var upgradeWindow = null;
function showUpgradeWindow() {
if (upgradeWindow && !upgradeWindow.destroyed) return;
upgradeWindow = new Container();
// Window background (main)
var winW = 1200 + 500 - 250,
// Decrease width by 250px
winH = 1100 + 500 + 500; // Increase height by 500px again, width unchanged
var winBg = LK.getAsset('upgradescreen', {
anchorX: 0.5,
anchorY: 0.5,
width: winW,
height: winH
});
winBg.alpha = 0.97;
upgradeWindow.addChild(winBg);
// Title removed: no upgrade window title text
// Button helper with icon
function makeUpgradeBtn(label, y, color, iconAsset, iconColor) {
var btn = new Container();
// Removed background for speed, power, health buttons
// Icon asset (left side of button)
var icon = null;
if (iconAsset) {
// If this is the health asset, increase its size by 50px
if (iconAsset === 'health') {
icon = LK.getAsset(iconAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: -360,
// 100px more to the left
y: 0,
width: 150,
height: 150
});
} else {
icon = LK.getAsset(iconAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: -360,
// 100px more to the left
y: 0,
scaleX: 1.2,
scaleY: 1.2
});
}
// Remove any filter/overlay in front of the icon (if any exist)
if (icon.filters && icon.filters.length > 0) {
icon.filters = [];
}
btn.addChild(icon);
}
var btnText = new Text2(label, {
size: 100,
fill: "#fff"
});
btnText.anchor.set(0.5, 0.5);
btnText.x = 60;
btnText.y = 0;
btn.addChild(btnText);
btn.x = 0;
btn.y = y;
return btn;
}
// Hız, Hüç, Health, Geri buttons with icons and unique colors
var btnSpacing = 280; // Increased by 50 from 230 to 280
var btns = [];
// Use fast, power, background assets for each upgrade (background as health icon)
var btnLabels = [{
label: "SPEED",
iconAsset: 'fast'
}, {
label: "DAMAGE",
iconAsset: 'power'
}, {
label: "HEALTH",
iconAsset: 'health'
}];
for (var i = 0; i < btnLabels.length; i++) {
var btn = makeUpgradeBtn(btnLabels[i].label, -120 + i * btnSpacing, btnLabels[i].color, btnLabels[i].iconAsset, btnLabels[i].iconColor);
upgradeWindow.addChild(btn);
btns.push(btn);
}
// --- SPEED UPGRADE LOGIC ---
if (typeof speedUpgradeBtnText === "undefined") speedUpgradeBtnText = null;
if (typeof speedUpgradeLevel === "undefined") speedUpgradeLevel = 0;
if (typeof speedUpgradeCost === "undefined") speedUpgradeCost = 50;
btns[0].down = function () {
if (coinCount >= speedUpgradeCost && speedUpgradeLevel < 3) {
coinCount -= speedUpgradeCost;
coinText.setText("" + coinCount);
speedUpgradeLevel += 1;
// Set next cost based on upgrade level
if (speedUpgradeLevel === 1) {
speedUpgradeCost = 75;
} else if (speedUpgradeLevel === 2) {
speedUpgradeCost = 100;
} else if (speedUpgradeLevel >= 3) {
speedUpgradeCost = "-";
}
// Update fire interval for faster shooting (decrease interval by 150ms per upgrade)
tapFireCooldown = Math.max(100, 850 - speedUpgradeLevel * 150);
// Update button label to show new cost or disable if maxed
if (speedUpgradeBtnText) {
if (btns[0].coinIcon && btns[0].coinIcon.parent) {
btns[0].coinIcon.parent.removeChild(btns[0].coinIcon);
btns[0].coinIcon = null;
}
if (speedUpgradeLevel < 3) {
speedUpgradeBtnText.setText("SPEED | " + speedUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = speedUpgradeBtnText.x + speedUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = speedUpgradeBtnText.y;
btns[0].addChild(coinAsset);
btns[0].coinIcon = coinAsset;
} else {
speedUpgradeBtnText.setText("SPEED | MAX");
}
}
LK.effects.flashObject(btns[0], 0x2ecc40, 400);
} else if (speedUpgradeLevel >= 3) {
LK.effects.flashObject(btns[0], 0x888888, 400);
} else {
LK.effects.flashObject(coinText, 0xe74c3c, 600);
}
};
// Always set speedUpgradeBtnText to the SPEED button label when opening the window
speedUpgradeBtnText = btns[0].children[1];
if (speedUpgradeBtnText) {
if (btns[0].coinIcon && btns[0].coinIcon.parent) {
btns[0].coinIcon.parent.removeChild(btns[0].coinIcon);
btns[0].coinIcon = null;
}
if (speedUpgradeLevel < 3) {
speedUpgradeBtnText.setText("SPEED | " + speedUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = speedUpgradeBtnText.x + speedUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = speedUpgradeBtnText.y;
btns[0].addChild(coinAsset);
btns[0].coinIcon = coinAsset;
} else {
speedUpgradeBtnText.setText("SPEED | MAX");
}
}
// --- DAMAGE/POWER UPGRADE LOGIC ---
if (typeof damageUpgradeBtnText === "undefined") damageUpgradeBtnText = null;
if (typeof damageUpgradeLevel === "undefined") damageUpgradeLevel = 0;
if (typeof damageUpgradeCost === "undefined") damageUpgradeCost = 60;
btns[1].down = function () {
if (coinCount >= damageUpgradeCost && damageUpgradeLevel < 3) {
coinCount -= damageUpgradeCost;
coinText.setText("" + coinCount);
damageUpgradeLevel += 1;
fireballDamage = 1 + damageUpgradeLevel;
// Set next cost based on upgrade level
if (damageUpgradeLevel === 1) {
damageUpgradeCost = 120;
} else if (damageUpgradeLevel === 2) {
damageUpgradeCost = 180;
} else if (damageUpgradeLevel >= 3) {
damageUpgradeCost = "-";
}
// Update button label to show new cost or disable if maxed
if (damageUpgradeBtnText) {
if (btns[1].coinIcon && btns[1].coinIcon.parent) {
btns[1].coinIcon.parent.removeChild(btns[1].coinIcon);
btns[1].coinIcon = null;
}
if (damageUpgradeLevel < 3) {
damageUpgradeBtnText.setText("DAMAGE | " + damageUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = damageUpgradeBtnText.x + damageUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = damageUpgradeBtnText.y;
btns[1].addChild(coinAsset);
btns[1].coinIcon = coinAsset;
} else {
damageUpgradeBtnText.setText("DAMAGE | MAX");
}
}
LK.effects.flashObject(btns[1], 0x2ecc40, 400);
} else if (damageUpgradeLevel >= 3) {
LK.effects.flashObject(btns[1], 0x888888, 400);
} else {
LK.effects.flashObject(coinText, 0xe74c3c, 600);
}
};
// Always set damageUpgradeBtnText to the POWER button label when opening the window
damageUpgradeBtnText = btns[1].children[1];
if (damageUpgradeBtnText) {
if (btns[1].coinIcon && btns[1].coinIcon.parent) {
btns[1].coinIcon.parent.removeChild(btns[1].coinIcon);
btns[1].coinIcon = null;
}
if (damageUpgradeLevel < 3) {
damageUpgradeBtnText.setText("DAMAGE | " + damageUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = damageUpgradeBtnText.x + damageUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = damageUpgradeBtnText.y;
btns[1].addChild(coinAsset);
btns[1].coinIcon = coinAsset;
} else {
damageUpgradeBtnText.setText("DAMAGE | MAX");
}
}
// HEALTH upgrade logic: cost increases after each purchase, +2 max health, +2 current health, max 3 upgrades: 25, 50, 75 coin
if (typeof healthUpgradeCost === "undefined") {
healthUpgradeCost = 25;
}
if (typeof healthUpgradeBtnText === "undefined") {
healthUpgradeBtnText = null;
}
if (typeof healthUpgradeLevel === "undefined") {
healthUpgradeLevel = 0;
}
btns[2].down = function () {
if (coinCount >= healthUpgradeCost && healthUpgradeLevel < 3) {
coinCount -= healthUpgradeCost;
coinText.setText("" + coinCount);
maxWizardHealth += 2;
wizardHealth += 2;
updateHealthBar();
LK.effects.flashObject(healthBar, 0x2ecc40, 600);
healthUpgradeLevel += 1;
// Set next cost based on upgrade level
if (healthUpgradeLevel === 1) {
healthUpgradeCost = 50;
} else if (healthUpgradeLevel === 2) {
healthUpgradeCost = 75;
} else if (healthUpgradeLevel >= 3) {
healthUpgradeCost = "-";
}
// Update button label to show new cost or disable if maxed
if (healthUpgradeBtnText) {
if (btns[2].coinIcon && btns[2].coinIcon.parent) {
btns[2].coinIcon.parent.removeChild(btns[2].coinIcon);
btns[2].coinIcon = null;
}
if (healthUpgradeLevel < 3) {
healthUpgradeBtnText.setText("HEALTH | " + healthUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = healthUpgradeBtnText.x + healthUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = healthUpgradeBtnText.y;
btns[2].addChild(coinAsset);
btns[2].coinIcon = coinAsset;
} else {
healthUpgradeBtnText.setText("HEALTH | MAX");
}
}
} else if (healthUpgradeLevel >= 3) {
// Already maxed, do nothing or feedback
LK.effects.flashObject(btns[2], 0x888888, 400);
} else {
LK.effects.flashObject(coinText, 0xe74c3c, 600);
}
};
// Always set healthUpgradeBtnText to the HEALTH button label when opening the window
healthUpgradeBtnText = btns[2].children[1];
if (healthUpgradeBtnText) {
// Remove any previous coin icon if present
if (btns[2].coinIcon && btns[2].coinIcon.parent) {
btns[2].coinIcon.parent.removeChild(btns[2].coinIcon);
btns[2].coinIcon = null;
}
// Set text to "HEALTH | <cost>" or "HEALTH | MAX"
if (healthUpgradeLevel < 3) {
healthUpgradeBtnText.setText("HEALTH | " + healthUpgradeCost);
var coinAsset = LK.getAsset('coin', {
anchorX: 0.0,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
coinAsset.x = healthUpgradeBtnText.x + healthUpgradeBtnText.width / 2 + coinAsset.width * 0.6;
coinAsset.y = healthUpgradeBtnText.y;
btns[2].addChild(coinAsset);
btns[2].coinIcon = coinAsset;
} else {
healthUpgradeBtnText.setText("HEALTH | MAX");
}
}
// BACK button without coin asset
// Place it 500 units further from HEALTH (btnSpacing = 280, so HEALTH is at -120 + 2*280 = 440, BACK at 440+500=940)
var geriBtn = makeUpgradeBtn("BACK", 940, undefined, null, undefined);
upgradeWindow.addChild(geriBtn);
// BACK closes window
geriBtn.down = function () {
if (upgradeWindow && !upgradeWindow.destroyed) {
upgradeWindow.destroy();
upgradeWindow = null;
}
};
// Center window
upgradeWindow.x = 2048 / 2;
upgradeWindow.y = 2732 / 2;
game.addChild(upgradeWindow);
}
// Upgrade button interaction
upgradeButton.down = function (x, y, obj) {
if (upgradeWindow && !upgradeWindow.destroyed) return;
showUpgradeWindow();
};
// Start button interaction
startButton.down = function (x, y, obj) {
if (gameStarted) return;
gameStarted = true;
// Remove start UI container (removes both start and upgrade buttons)
if (startUiContainer && !startUiContainer.destroyed) {
startUiContainer.destroy();
}
// --- RESET GAME STATE ---
// Remove all enemies, fireballs, coins from game and arrays
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] && !enemies[i].destroyed) enemies[i].destroy();
enemies.splice(i, 1);
}
for (var i = fireballs.length - 1; i >= 0; i--) {
if (fireballs[i] && !fireballs[i].destroyed) fireballs[i].destroy();
fireballs.splice(i, 1);
}
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i] && !coins[i].destroyed) coins[i].destroy();
coins.splice(i, 1);
}
// Reset score and coin count
score = 0;
// coinCount is NOT reset here, so coins are preserved when starting a new game
scoreText.setText("Score: 0");
coinText.setText("" + coinCount);
// Center wizard
wizard.x = 2048 / 2;
wizard.y = 2732 / 2;
if (wizard.children && wizard.children.length > 0) {
wizard.children[0].rotation = Math.PI; // face left
}
// Reposition health bar above wizard after centering
if (wizard.children && wizard.children.length > 0) {
healthBarBg.y = -wizard.children[0].height / 2 - 18 - 50;
healthBar.x = 0;
healthBarBg.x = 0;
healthBar.y = healthBarBg.y;
}
// Reset health
wizardHealth = maxWizardHealth;
updateHealthBar();
// Enable game input
game.move = originalGameMove;
game.down = originalGameDown;
game.up = originalGameUp;
};
// Save original handlers for restoration
var originalGameMove = function originalGameMove(x, y, obj) {
// Wizard is fixed; do nothing
// Calculate angle from wizard to pointer/touch and rotate wizard sprite
var dx = x - wizard.x;
var dy = y - wizard.y;
var angle = Math.atan2(dy, dx);
// Wizard's default asset faces left, so add Math.PI to rotate to correct direction
if (wizard.children && wizard.children.length > 0) {
wizard.children[0].rotation = angle + Math.PI;
}
// If firing, update direction for continuous fire
if (isFiring) {
lastFireX = x;
lastFireY = y;
}
};
var originalGameDown = function originalGameDown(x, y, obj) {
var now = Date.now();
if (now - lastTapFireTime < tapFireCooldown) {
// Too soon, ignore this tap for firing
return;
}
lastTapFireTime = now;
isFiring = true;
lastFireX = x;
lastFireY = y;
shootFireballAt(x, y);
if (fireInterval) LK.clearInterval(fireInterval);
fireInterval = LK.setInterval(function () {
if (isFiring) {
shootFireballAt(lastFireX, lastFireY);
}
}, tapFireCooldown); // fire every tapFireCooldown ms when holding down
};
var originalGameUp = function originalGameUp(x, y, obj) {
isFiring = false;
if (fireInterval) {
LK.clearInterval(fireInterval);
fireInterval = null;
}
};
// Array to hold all fireballs
var fireballs = [];
// Helper: get direction vector from wizard to (x, y)
function getDirection(fromX, fromY, toX, toY, speed) {
var dx = toX - fromX;
var dy = toY - fromY;
var len = Math.sqrt(dx * dx + dy * dy);
if (len === 0) return {
vx: 0,
vy: 0
};
return {
vx: dx / len * speed,
vy: dy / len * speed
};
}
// Dragging wizard with mouse/touch (disabled)
var dragging = false;
// Move handler: wizard does not move
game.move = function (x, y, obj) {
// Wizard is fixed; do nothing
// Calculate angle from wizard to pointer/touch and rotate wizard sprite
var dx = x - wizard.x;
var dy = y - wizard.y;
var angle = Math.atan2(dy, dx);
// Wizard's default asset faces left, so add Math.PI to rotate to correct direction
if (wizard.children && wizard.children.length > 0) {
wizard.children[0].rotation = angle + Math.PI;
}
// If firing, update direction for continuous fire
if (isFiring) {
lastFireX = x;
lastFireY = y;
}
};
// Track if fire is being held
var isFiring = false;
var fireInterval = null;
var lastFireX = 0;
var lastFireY = 0;
// Cooldown for tap-to-fire (now 850ms)
var lastTapFireTime = 0;
var tapFireCooldown = 850;
// Helper to shoot a fireball toward (x, y)
function shootFireballAt(x, y) {
var fireball = new Fireball();
fireball.x = wizard.x;
fireball.y = wizard.y;
var dir = getDirection(wizard.x, wizard.y, x, y, 8);
fireball.vx = dir.vx;
fireball.vy = dir.vy;
var angle = Math.atan2(dir.vy, dir.vx);
if (fireball.children && fireball.children.length > 0) {
fireball.children[0].rotation = angle;
}
if (wizard.children && wizard.children.length > 0) {
wizard.children[0].rotation = Math.atan2(y - wizard.y, x - wizard.x) + Math.PI;
}
fireballs.push(fireball);
game.addChild(fireball);
LK.getSound('fire').play();
}
// Down handler: start firing repeatedly only if gameStarted
game.down = function (x, y, obj) {
if (!gameStarted) return;
var now = Date.now();
if (now - lastTapFireTime < tapFireCooldown) {
// Too soon, ignore this tap for firing
return;
}
lastTapFireTime = now;
isFiring = true;
lastFireX = x;
lastFireY = y;
shootFireballAt(x, y);
if (fireInterval) LK.clearInterval(fireInterval);
fireInterval = LK.setInterval(function () {
if (isFiring) {
shootFireballAt(lastFireX, lastFireY);
}
}, tapFireCooldown); // fire every tapFireCooldown ms when holding down
};
// Up handler: stop firing only if gameStarted
game.up = function (x, y, obj) {
if (!gameStarted) return;
isFiring = false;
if (fireInterval) {
LK.clearInterval(fireInterval);
fireInterval = null;
}
};
// Array to hold all enemies
var enemies = [];
// Import storage plugin for persistent coin saving
// Array to hold all coins
var coins = [];
// Wizard health system
var wizardHealth = 5;
var maxWizardHealth = 5;
// Health upgrade cost system
var healthUpgradeCost = 25;
var healthUpgradeBtnText = null;
var healthUpgradeLevel = 0;
// Speed upgrade cost/level system
var speedUpgradeCost = 50;
var speedUpgradeLevel = 0;
// Damage upgrade cost/level system
var damageUpgradeCost = 60;
var damageUpgradeLevel = 0;
// Fireball damage (default 1, increases with damage upgrades)
var fireballDamage = 1;
// Health bar UI (smaller, positioned just above wizard)
var healthBarWidth = 180;
var healthBarHeight = 18;
var healthBarYOffset = 90; // vertical offset above wizard (not used now)
var healthBarBg = LK.getAsset('background', {
anchorX: 0.5,
// center horizontally
anchorY: 1,
// bottom edge
width: healthBarWidth,
height: healthBarHeight
});
var healthBar = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 1,
width: healthBarWidth,
height: healthBarHeight
});
// Add health bar as children of wizard so it follows wizard position
wizard.addChild(healthBarBg);
wizard.addChild(healthBar);
// Position health bar just above wizard sprite
healthBarBg.x = 0;
healthBarBg.y = wizard.children[0] ? -wizard.children[0].height / 2 - 18 : -healthBarHeight - 10;
healthBar.x = 0;
healthBar.y = healthBarBg.y;
// Health bar update function
function updateHealthBar() {
var percent = Math.max(0, wizardHealth) / maxWizardHealth;
healthBar.width = healthBarBg.width * percent;
// Color changes as health drops
if (percent > 0.6) {
healthBar.tint = 0x2ecc40; // green
} else if (percent > 0.3) {
healthBar.tint = 0xffc107; // yellow
} else {
healthBar.tint = 0xe74c3c; // red
}
}
updateHealthBar();
// Score variable
var score = 0;
// Persistent total coins (stacked across games)
var totalCoins = storage.totalCoins || 0;
// Score text
var scoreText = new Text2("Score: 0", {
size: 100,
fill: "#fff"
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// After scoreText and wizard are positioned, update startUiContainer position
if (typeof startUiContainer !== "undefined" && startUiContainer && typeof wizard !== "undefined" && wizard) {
// Place UI container between score and wizard, but not overlapping either
startUiContainer.x = 2048 / 2;
startUiContainer.y = wizard.y - 180;
}
// Coin icon and coin count text
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var coinCount = 0;
var coinText = new Text2("0", {
size: 90,
fill: 0xFFD700
});
coinText.anchor.set(0.5, 0);
// Add coin icon and text to the GUI, but position them below the score text
LK.gui.top.addChild(coinIcon);
LK.gui.top.addChild(coinText);
// Position coin icon and text below the score text in the start screen
coinIcon.x = scoreText.x;
coinIcon.y = scoreText.y + scoreText.height + coinIcon.height * 0.6;
coinText.x = coinIcon.x + coinIcon.width * 0.7;
coinText.y = coinIcon.y;
// Helper: spawn an enemy at a random edge, moving toward wizard
function spawnEnemy() {
// Determine which enemy types are available based on score
var availableTypes = [1];
if (score >= 10) availableTypes.push(2);
if (score >= 20) availableTypes.push(3);
// Randomly pick an available type
var typeIdx = Math.floor(Math.random() * availableTypes.length);
var enemyType = availableTypes[typeIdx];
var enemy;
if (enemyType === 1) {
enemy = new Enemy();
} else if (enemyType === 2) {
enemy = new Enemy2();
} else {
enemy = new Enemy3();
}
// Randomly pick an edge: 0=top, 1=bottom, 2=left, 3=right
var edge = Math.floor(Math.random() * 4);
var ex, ey;
if (edge === 0) {
// top
ex = Math.random() * 2048;
ey = -50;
} else if (edge === 1) {
// bottom
ex = Math.random() * 2048;
ey = 2732 + 50;
} else if (edge === 2) {
// left
ex = -50;
ey = Math.random() * 2732;
} else {
// right
ex = 2048 + 50;
ey = Math.random() * 2732;
}
enemy.x = ex;
enemy.y = ey;
// Move toward wizard
var dir = getDirection(ex, ey, wizard.x, wizard.y, 2.5 + Math.random() * 1.5); // randomize speed a bit
enemy.vx = dir.vx;
enemy.vy = dir.vy;
enemies.push(enemy);
game.addChild(enemy);
}
// Enemy spawn timer
var enemySpawnTimer = LK.setInterval(function () {
spawnEnemy();
}, 1200);
// Game update: update wizard, fireballs, enemies, handle collisions, and scoring
game.update = function () {
// If game not started, only update startButton and wizard visuals
if (!gameStarted) {
if (wizard.update) wizard.update();
// Animate start button (pulse effect)
if (typeof startButton !== "undefined" && startButton && startButton.children && startButton.children.length > 0) {
var t = LK.ticks || Date.now();
var scale = 1 + 0.06 * Math.sin(t * 0.12);
startButton.scale.x = scale;
startButton.scale.y = scale;
}
return;
}
// Update wizard
if (wizard.update) wizard.update();
// Update fireballs and remove destroyed ones
for (var i = fireballs.length - 1; i >= 0; i--) {
var fb = fireballs[i];
if (fb.update) fb.update();
if (fb.destroyed) {
fireballs.splice(i, 1);
}
}
// Update coins and remove destroyed ones
for (var c = coins.length - 1; c >= 0; c--) {
var coin = coins[c];
// Move coin directly toward wizard
var dx = wizard.x - coin.x;
var dy = wizard.y - coin.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var speed = 22; // Fast enough to feel instant, but visible
if (dist > 1) {
coin.x += dx / dist * Math.min(speed, dist);
coin.y += dy / dist * Math.min(speed, dist);
} else {
coin.x = wizard.x;
coin.y = wizard.y;
}
// Check collision with wizard (collect coin)
if (coin.lastWasIntersecting === undefined) coin.lastWasIntersecting = false;
var coinIntersecting = coin.intersects(wizard);
if (!coin.lastWasIntersecting && coinIntersecting) {
// Do not add to score when collecting coin
coinCount += 1;
coinText.setText("" + coinCount);
// Create gain effect (use gain asset instead of explosion)
var gainEffect = LK.getAsset('gain', {
anchorX: 0.5,
anchorY: 0.5,
x: coin.x,
y: coin.y,
scaleX: 1,
scaleY: 1,
alpha: 1
});
game.addChild(gainEffect);
// Animate gain effect: scale up and fade out, then destroy
(function (effect) {
var frames = 24;
var frame = 0;
effect.update = function () {
frame++;
effect.scale.x = 1 + 0.5 * (frame / frames);
effect.scale.y = 1 + 0.5 * (frame / frames);
effect.alpha = 1 - frame / frames;
if (frame >= frames) {
effect.destroy();
}
};
})(gainEffect);
// Create +N asset effect at wizard position
var plusAmount = 1;
if (coin.hasOwnProperty('amount')) {
plusAmount = coin.amount;
}
var plusText = new Text2("+" + plusAmount, {
size: 90,
fill: 0xFFD700
});
plusText.anchor.set(0.5, 0.5);
plusText.x = wizard.x;
plusText.y = wizard.y;
game.addChild(plusText);
// Animate +N asset: move up and fade out, then destroy
(function (txt) {
var startY = txt.y;
var frames = 36;
var frame = 0;
txt.alpha = 1;
txt.update = function () {
frame++;
txt.y = startY - frame * 2.2;
txt.alpha = 1 - frame / frames;
if (frame >= frames) {
txt.destroy();
}
};
})(plusText);
// Remove coin
coin.destroy();
coins.splice(c, 1);
continue;
}
coin.lastWasIntersecting = coinIntersecting;
}
// Position coin icon and text below the score text (centered)
if (scoreText.parent && coinIcon.parent && coinText.parent) {
// Place coin icon below the score text, centered
coinIcon.x = scoreText.x;
coinIcon.y = scoreText.y + scoreText.height + coinIcon.height * 0.6;
// Place coinText 50px to the right and 50px above the coin icon
coinText.x = coinIcon.x + 50;
coinText.y = coinIcon.y - 50;
}
// Update enemies and remove destroyed ones
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (enemy.update) enemy.update();
if (enemy.destroyed) {
enemies.splice(j, 1);
continue;
}
// Check collision with wizard (health system)
if (enemy.lastWasIntersecting === undefined) enemy.lastWasIntersecting = false;
var nowIntersecting = enemy.intersects(wizard);
if (!enemy.lastWasIntersecting && nowIntersecting) {
// Only decrease health if not already at 0
if (wizardHealth > 0) {
wizardHealth -= 1;
// Flash wizard red
if (wizard.children && wizard.children.length > 0) {
LK.effects.flashObject(wizard.children[0], 0xff0000, 400);
}
// Update health bar
updateHealthBar();
// Remove enemy after hit
enemy.destroy();
enemies.splice(j, 1);
// If health reaches 0, trigger game over
if (wizardHealth <= 0) {
totalCoins += coinCount;
storage.totalCoins = totalCoins;
LK.effects.flashScreen(0xff0000, 1000);
// Instead of game over, reset to start screen
gameStarted = false;
// Recreate start UI if needed
if (!startUiContainer || startUiContainer.destroyed) {
startUiContainer = new Container();
startButton = new Container();
startButtonBg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
width: startButtonWidth,
height: startButtonHeight,
color: 0x1e90ff
});
startButtonBg.alpha = 0.92;
startButton.addChild(startButtonBg);
startButtonText = new Text2("START GAME", {
size: 220,
fill: "#fff"
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.x = 0;
startButtonText.y = -120;
startButton.addChild(startButtonText);
upgradeButton = new Container();
upgradeButtonBg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
width: upgradeButtonWidth,
height: upgradeButtonHeight,
color: 0x2ecc71
});
upgradeButtonBg.alpha = 0.92;
upgradeButton.addChild(upgradeButtonBg);
upgradeButtonText = new Text2("UPGRADE", {
size: 110,
// Half of recreated START GAME (220)
fill: "#fff"
});
upgradeButtonText.anchor.set(0.5, 0.5);
upgradeButtonText.x = 0;
upgradeButtonText.y = 0;
upgradeButton.addChild(upgradeButtonText);
startButton.x = 0;
startButton.y = -400;
upgradeButton.x = 0;
upgradeButton.y = startButton.y + startButtonHeight / 2 + 55 + upgradeButtonHeight / 2;
startUiContainer.addChild(startButton);
startUiContainer.addChild(upgradeButton);
startUiContainer.x = 2048 / 2;
startUiContainer.y = 2732 / 2;
game.addChild(startUiContainer);
// Re-attach handlers
upgradeButton.down = function (x, y, obj) {
if (upgradeWindow && !upgradeWindow.destroyed) return;
showUpgradeWindow();
};
startButton.down = function (x, y, obj) {
var now = Date.now();
if (now - lastTapFireTime < tapFireCooldown) {
// Too soon, ignore this tap for firing
return;
}
lastTapFireTime = now;
if (gameStarted) return;
gameStarted = true;
if (startUiContainer && !startUiContainer.destroyed) {
startUiContainer.destroy();
}
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] && !enemies[i].destroyed) enemies[i].destroy();
enemies.splice(i, 1);
}
for (var i = fireballs.length - 1; i >= 0; i--) {
if (fireballs[i] && !fireballs[i].destroyed) fireballs[i].destroy();
fireballs.splice(i, 1);
}
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i] && !coins[i].destroyed) coins[i].destroy();
coins.splice(i, 1);
}
score = 0;
// coinCount is NOT reset here, so coins are preserved when starting a new game
scoreText.setText("Score: 0");
coinText.setText("" + coinCount);
wizard.x = 2048 / 2;
wizard.y = 2732 / 2;
if (wizard.children && wizard.children.length > 0) {
wizard.children[0].rotation = Math.PI;
}
if (wizard.children && wizard.children.length > 0) {
healthBarBg.y = -wizard.children[0].height / 2 - 18 - 50;
healthBar.x = 0;
healthBarBg.x = 0;
healthBar.y = healthBarBg.y;
}
wizardHealth = maxWizardHealth;
updateHealthBar();
game.move = originalGameMove;
game.down = originalGameDown;
game.up = originalGameUp;
};
} else {
// If UI exists, just re-add it
if (startUiContainer.parent !== game) {
game.addChild(startUiContainer);
}
}
// Block input until start is pressed
blockGameInput();
return;
}
}
}
enemy.lastWasIntersecting = nowIntersecting;
// Check collision with fireballs
for (var k = fireballs.length - 1; k >= 0; k--) {
var fb = fireballs[k];
if (enemy['fb' + k + '_lastIntersecting'] === undefined) enemy['fb' + k + '_lastIntersecting'] = false;
var fbIntersect = enemy.intersects(fb);
// Only allow collision if fireball is inside the visible screen
var fireballOnScreen = fb.x >= 0 && fb.x <= 2048 && fb.y >= 0 && fb.y <= 2732;
if (!enemy['fb' + k + '_lastIntersecting'] && fbIntersect && fireballOnScreen) {
// Decrease enemy health by fireballDamage (default 1, upgrades increase)
enemy.health -= fireballDamage;
// Destroy fireball
fb.destroy();
fireballs.splice(k, 1);
// If enemy health reaches 0, destroy enemy and increase score
if (enemy.health <= 0) {
// Spawn explosion at enemy position
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Determine coin count and plus text based on enemy type
var coinAmount = 1;
if (enemy.type === 2) coinAmount = 2;
if (enemy.type === 3) coinAmount = 3;
// Drop the correct number of coins
for (var cc = 0; cc < coinAmount; cc++) {
var coin = new Coin();
coin.x = enemy.x;
coin.y = enemy.y;
coin.vx = 0;
coin.vy = 0;
coin.gravity = 0;
// For multi-coin drops, only the first coin will show +N at wizard
if (cc === 0) {
coin.amount = coinAmount;
}
coins.push(coin);
game.addChild(coin);
}
// Play dead sound
LK.getSound('dead').play();
enemy.destroy();
enemies.splice(j, 1);
score += 1;
scoreText.setText("Score: " + score);
// (Removed: +N effect at enemy death. Now shown at wizard when coin is collected)
break;
}
}
enemy['fb' + k + '_lastIntersecting'] = fbIntersect;
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -918,10 +918,10 @@
LK.gui.top.addChild(coinText);
// Position coin icon and text below the score text in the start screen
coinIcon.x = scoreText.x;
coinIcon.y = scoreText.y + scoreText.height + coinIcon.height * 0.6;
-coinText.x = coinIcon.x - 50;
-coinText.y = coinIcon.y - 25;
+coinText.x = coinIcon.x + coinIcon.width * 0.7;
+coinText.y = coinIcon.y;
// Helper: spawn an enemy at a random edge, moving toward wizard
function spawnEnemy() {
// Determine which enemy types are available based on score
var availableTypes = [1];
@@ -1081,11 +1081,11 @@
if (scoreText.parent && coinIcon.parent && coinText.parent) {
// Place coin icon below the score text, centered
coinIcon.x = scoreText.x;
coinIcon.y = scoreText.y + scoreText.height + coinIcon.height * 0.6;
- // Place coinText 50px to the left and 25px above the coin icon
- coinText.x = coinIcon.x - 50;
- coinText.y = coinIcon.y - 25;
+ // Place coinText 50px to the right and 50px above the coin icon
+ coinText.x = coinIcon.x + 50;
+ coinText.y = coinIcon.y - 50;
}
// Update enemies and remove destroyed ones
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
get an enemy in the form of slime. In-Game asset. 2d. High contrast. No shadows
get an enemy in the form of slime. In-Game asset. 2d. High contrast. No shadows
Let there be a mini machine gun and let this gun be pixel shaped. In-Game asset. 2d. High contrast. No shadows
a bullet but yellow and pixel. In-Game asset. 2d. High contrast. No shadows
slime explosion. In-Game asset. 2d. High contrast. No shadows
Change eyes like red
+ gain coin effect. In-Game asset. 2d. High contrast. No shadows
Fast bullet upgrade. In-Game asset. 2d. High contrast. No shadows
Upgrade power bullet. In-Game asset. 2d. High contrast. No shadows
Health + icon pixels. In-Game asset. 2d. High contrast. No shadows
Handgun pixel its look left. In-Game asset. 2d. High contrast. No shadows
işaretli alanı siyaha boya
pixel shuriken but 8 edges. In-Game asset. 2d. High contrast. No shadows
shotgun pixel and look left side. In-Game asset. 2d. High contrast. No shadows
submachine gun look left. In-Game asset. 2d. High contrast. No shadows
mp5 gun pixel. In-Game asset. 2d. High contrast. No shadows
Minigun bullet pixel. In-Game asset. 2d. High contrast. No shadows
Eliptic neon laser bullet. In-Game asset. 2d. High contrast. No shadows. Pixel
slime but have metalic helmet. In-Game asset. 2d. High contrast. No shadows
a slime boss enemy very strict. In-Game asset. 2d. High contrast. No shadows
create mirror view a bit smaller
add a dragon baby on top of gun
a goblin slime which have backpack fully coins. In-Game asset. 2d. High contrast. No shadows
Disappear smoke pixel. In-Game asset. 2d. High contrast. No shadows
Coin pile pixel. In-Game asset. 2d. High contrast. No shadows
fire left to right pixel. In-Game asset. 2d. High contrast. No shadows
Slime enemy healer. In-Game asset. 2d. High contrast. No shadows
Healt restore pixel. In-Game asset. 2d. High contrast. No shadows
Ammo +1 upgrade. In-Game asset. 2d. High contrast. No shadows
Type SLOW bottom of the amblem
Fire ball pixel
boss slime but like fire and dangereous. In-Game asset. 2d. High contrast. No shadows
Add body of this slime