User prompt
sonic ölünce oyun bitsin
User prompt
sonic ölünce yok olsun
User prompt
silah sonice zarar versin
User prompt
mario ölünce yok olsun ve mario öldükden sonra sonic bize saldırsın
User prompt
dracon ölürse yok olsun
User prompt
sonicede can barı ekle ve bu 3 karakterde ölmeden oyun bitmesin
User prompt
dragonu ödürsek bile sonic yok olmasın ve marioya saldırmasın
User prompt
eyer dragonun ve marioyu öldürdüdükten sonra puanımız 700 olmasa kaybederiz
User prompt
sonic altını oyun başına sadece 3 tane spam olur
User prompt
eyer 30 saniye içinde 3 sonic altını toplamasak bize saldırır
User prompt
sonic altını oluştur
User prompt
sonic için sonic altını toplamalıyız
User prompt
eyer sonice 50 saniye içinde 3 altın toplamasak bize saldırır
User prompt
mario ölürse yok olur
User prompt
marioya silahla saldıra biliriz
User prompt
sonic dragonu öldürürdükden sonra yok olur
User prompt
eyer mario ve dragonu öldürdükten sonra 500 puanı geçemezsek luigi yok olur
User prompt
drogon ölünce kazanmak için marioyu öldürmemiz gerek
User prompt
dragon ölünce yok olsun
User prompt
drogon ölmeli ve ölüdüyünde mario bize saldırsın
User prompt
luigi bize dragonu yemek için bi silah versin
User prompt
dragonun can barı olsun
User prompt
marioya can barı ekle
User prompt
marionun spagathhetisini alınga bize saldırsın
User prompt
SHONİG DE OLSUN VE MARİO İLE KAVGA ETSİN
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Achievement = Container.expand(function (id, title, description, icon) {
var self = Container.call(this);
self.id = id;
self.title = title;
self.description = description;
self.icon = icon;
self.unlocked = false;
self.displayTime = 0;
// Create achievement notification display
var bg = LK.getAsset('achievement_bg', {
width: 600,
height: 120,
color: 0x2C3E50,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(bg);
var titleText = new Text2(title, {
size: 40,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0);
titleText.x = 0;
titleText.y = -30;
self.addChild(titleText);
var descText = new Text2(description, {
size: 30,
fill: 0xFFFFFF
});
descText.anchor.set(0.5, 1);
descText.x = 0;
descText.y = 30;
self.addChild(descText);
self.unlock = function () {
if (!self.unlocked) {
self.unlocked = true;
self.show();
// Save to storage
storage['achievement_' + self.id] = true;
}
};
self.show = function () {
self.x = 1024;
self.y = 200;
self.alpha = 0;
self.scaleX = 0.5;
self.scaleY = 0.5;
self.displayTime = 180; // 3 seconds
// Animate in
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500
});
};
self.update = function () {
if (self.displayTime > 0) {
self.displayTime--;
if (self.displayTime <= 0) {
// Animate out
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500
});
}
}
};
return self;
});
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.baseSpeed = 1.5;
self.currentSpeed = self.baseSpeed;
self.fireTimer = 0;
self.fireInterval = 120; // 2 seconds initially
self.health = 150;
self.maxHealth = 150;
// Create health bar
var dragonHealthBarBg = self.attachAsset('dragon_health_bar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
dragonHealthBarBg.y = -180;
var dragonHealthBarFill = self.attachAsset('dragon_health_bar_fill', {
anchorX: 0,
anchorY: 0.5
});
dragonHealthBarFill.x = -60;
dragonHealthBarFill.y = -180;
self.update = function () {
// Follow player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.currentSpeed;
self.y += dy / distance * self.currentSpeed;
}
// Fire breathing timer
self.fireTimer++;
if (self.fireTimer >= self.fireInterval) {
self.breatheFire();
self.fireTimer = 0;
}
// Adjust difficulty based on score
var difficulty = Math.floor(score / 10);
self.currentSpeed = self.baseSpeed + difficulty * 0.5;
self.fireInterval = Math.max(60, 120 - difficulty * 10);
// Update health bar
var healthPercent = self.health / self.maxHealth;
dragonHealthBarFill.width = 120 * healthPercent;
if (healthPercent > 0.6) {
dragonHealthBarFill.tint = 0xFF0000; // Red
} else if (healthPercent > 0.3) {
dragonHealthBarFill.tint = 0xFF4444; // Light Red
} else {
dragonHealthBarFill.tint = 0xFF8888; // Very Light Red
}
};
self.breatheFire = function () {
var fireball = new Fireball();
fireball.x = self.x;
fireball.y = self.y;
// Aim towards player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
fireball.directionX = dx / distance;
fireball.directionY = dy / distance;
fireballs.push(fireball);
game.addChild(fireball);
LK.getSound('fire').play();
};
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
// Dragon is defeated
LK.effects.flashObject(self, 0x000000, 1000);
self.baseSpeed = 0;
self.currentSpeed = 0;
self.fireInterval = 999999; // Stop firing
}
};
return self;
});
var Fireball = Container.expand(function () {
var self = Container.call(this);
var fireballGraphics = self.attachAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.directionX = 0;
self.directionY = 0;
self.lifetime = 300; // 5 seconds
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
fireballGraphics.rotation += 0.2;
fireballGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.3 + 0.7;
self.lifetime--;
if (self.lifetime <= 0) {
self.shouldDestroy = true;
}
// Check bounds
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.shouldDestroy = true;
}
};
return self;
});
var Gem = Container.expand(function () {
var self = Container.call(this);
var gemGraphics = self.attachAsset('gem', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 25;
self.floatOffset = Math.random() * Math.PI * 2;
self.update = function () {
gemGraphics.y = Math.sin(LK.ticks * 0.15 + self.floatOffset) * 3;
gemGraphics.rotation += 0.05;
gemGraphics.scaleX = Math.sin(LK.ticks * 0.1 + self.floatOffset) * 0.2 + 1;
gemGraphics.scaleY = Math.sin(LK.ticks * 0.1 + self.floatOffset) * 0.2 + 1;
};
return self;
});
var Luigi = Container.expand(function () {
var self = Container.call(this);
var luigiGraphics = self.attachAsset('luigi', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.jumpTimer = 0;
self.jumpInterval = 120; // 2 seconds
self.isJumping = false;
self.jumpHeight = 0;
self.maxJumpHeight = 100;
self.jumpSpeed = 8;
self.direction = 1; // 1 for right, -1 for left
self.update = function () {
// Move horizontally
self.x += self.speed * self.direction;
// Bounce off screen edges
if (self.x <= 100 || self.x >= 1948) {
self.direction *= -1;
luigiGraphics.scaleX = self.direction;
}
// Jump behavior
self.jumpTimer++;
if (self.jumpTimer >= self.jumpInterval && !self.isJumping) {
self.isJumping = true;
self.jumpHeight = 0;
self.jumpTimer = 0;
}
if (self.isJumping) {
self.jumpHeight += self.jumpSpeed;
if (self.jumpHeight >= self.maxJumpHeight) {
self.jumpSpeed = -8;
}
if (self.jumpHeight <= 0 && self.jumpSpeed < 0) {
self.jumpHeight = 0;
self.jumpSpeed = 8;
self.isJumping = false;
}
luigiGraphics.y = -self.jumpHeight;
}
// Check if player is close and doesn't have weapon
if (!playerWeapon) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 100) {
// Give weapon to player
playerWeapon = new Weapon();
playerWeapon.x = player.x;
playerWeapon.y = player.y - 50;
game.addChild(playerWeapon);
LK.effects.flashObject(self, 0x00FF00, 500);
updateScore(100); // Bonus for getting weapon
}
}
// Animate Luigi
luigiGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.1;
};
return self;
});
var Mario = Container.expand(function () {
var self = Container.call(this);
var marioGraphics = self.attachAsset('mario', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.targetSpaghetti = null;
self.searchTimer = 0;
self.searchInterval = 60; // 1 second
self.isAngry = false;
self.angerTimer = 0;
self.angerDuration = 300; // 5 seconds of anger
self.attackSpeed = 6;
self.health = 100;
self.maxHealth = 100;
// Create health bar
var healthBarBg = self.attachAsset('health_bar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
healthBarBg.y = -120;
var healthBarFill = self.attachAsset('health_bar_fill', {
anchorX: 0,
anchorY: 0.5
});
healthBarFill.x = -40;
healthBarFill.y = -120;
self.update = function () {
// Search for nearest spaghetti
self.searchTimer++;
if (self.searchTimer >= self.searchInterval) {
self.findNearestSpaghetti();
self.searchTimer = 0;
}
// Handle anger state
if (self.isAngry) {
self.angerTimer--;
if (self.angerTimer <= 0) {
self.isAngry = false;
marioGraphics.tint = 0xFFFFFF; // Return to normal color
} else {
// Attack player when angry
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.attackSpeed;
self.y += dy / distance * self.attackSpeed;
// Face the direction of movement
marioGraphics.scaleX = dx > 0 ? 1 : -1;
}
}
} else {
// Move towards target spaghetti
if (self.targetSpaghetti && spaghettis.indexOf(self.targetSpaghetti) !== -1) {
var dx = self.targetSpaghetti.x - self.x;
var dy = self.targetSpaghetti.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Face the direction of movement
marioGraphics.scaleX = dx > 0 ? 1 : -1;
}
} else {
// Random movement when no spaghetti found
self.x += (Math.random() - 0.5) * 2;
self.y += (Math.random() - 0.5) * 2;
}
}
// Keep Mario in bounds
self.x = Math.max(100, Math.min(1948, self.x));
self.y = Math.max(100, Math.min(2632, self.y));
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBarFill.width = 80 * healthPercent;
if (healthPercent > 0.6) {
healthBarFill.tint = 0x00FF00; // Green
} else if (healthPercent > 0.3) {
healthBarFill.tint = 0xFFFF00; // Yellow
} else {
healthBarFill.tint = 0xFF0000; // Red
}
// Animate Mario
marioGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.05;
};
self.findNearestSpaghetti = function () {
var nearestDistance = Infinity;
var nearestSpaghetti = null;
for (var i = 0; i < spaghettis.length; i++) {
var spaghetti = spaghettis[i];
var dx = spaghetti.x - self.x;
var dy = spaghetti.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestSpaghetti = spaghetti;
}
}
self.targetSpaghetti = nearestSpaghetti;
};
self.becomeAngry = function () {
self.isAngry = true;
self.angerTimer = self.angerDuration;
marioGraphics.tint = 0xFF0000; // Turn red when angry
LK.effects.flashObject(self, 0xFF0000, 500);
};
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
// Mario is defeated
LK.effects.flashObject(self, 0x000000, 1000);
self.speed = 0;
self.attackSpeed = 0;
self.shouldDestroy = true; // Mark for removal
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.invulnerable = false;
self.invulnerabilityTime = 0;
self.speedBoost = false;
self.speedBoostTime = 0;
self.update = function () {
if (self.invulnerabilityTime > 0) {
self.invulnerabilityTime--;
playerGraphics.alpha = Math.sin(LK.ticks * 0.3) * 0.5 + 0.5;
if (self.invulnerabilityTime <= 0) {
self.invulnerable = false;
playerGraphics.alpha = 1;
}
}
if (self.speedBoostTime > 0) {
self.speedBoostTime--;
if (self.speedBoostTime <= 0) {
self.speedBoost = false;
playerGraphics.tint = 0xFFFFFF;
}
}
};
self.activateInvulnerability = function () {
self.invulnerable = true;
self.invulnerabilityTime = 120; // 2 seconds at 60fps
};
self.activateSpeedBoost = function () {
self.speedBoost = true;
self.speedBoostTime = 300; // 5 seconds at 60fps
playerGraphics.tint = 0x00FFFF;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = Math.random() < 0.5 ? 'speed' : 'invulnerable';
self.floatOffset = Math.random() * Math.PI * 2;
if (self.type === 'invulnerable') {
powerupGraphics.tint = 0xFFD700;
}
self.update = function () {
powerupGraphics.y = Math.sin(LK.ticks * 0.2 + self.floatOffset) * 8;
powerupGraphics.rotation += 0.1;
powerupGraphics.alpha = Math.sin(LK.ticks * 0.3) * 0.3 + 0.7;
};
return self;
});
var Sonic = Container.expand(function () {
var self = Container.call(this);
var sonicGraphics = self.attachAsset('sonic', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.targetMario = null;
self.searchTimer = 0;
self.searchInterval = 30; // 0.5 seconds
self.attackTimer = 0;
self.attackInterval = 120; // 2 seconds
self.spindashTimer = 0;
self.isSpinning = false;
self.direction = 1;
self.goldTimer = 50 * 60; // 50 seconds at 60fps
self.goldCollected = 0;
self.goldTarget = 3;
self.isAttackingPlayer = false;
self.targetPlayer = null;
self.update = function () {
// Update gold collection timer
self.goldTimer--;
if (self.goldTimer <= 0 && self.goldCollected < self.goldTarget) {
self.isAttackingPlayer = true;
self.targetPlayer = player;
sonicGraphics.tint = 0xFF0000; // Turn red when attacking player
}
// Behavior based on current state
if (self.isAttackingPlayer && self.targetPlayer) {
// Attack player mode
var dx = self.targetPlayer.x - self.x;
var dy = self.targetPlayer.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * (self.speed * 1.5); // Faster when attacking player
self.y += dy / distance * (self.speed * 1.5);
sonicGraphics.scaleX = dx > 0 ? 1 : -1;
self.direction = dx > 0 ? 1 : -1;
}
} else if (self.goldCollected < self.goldTarget) {
// Gold collection mode - search for gems (gold)
self.searchTimer++;
if (self.searchTimer >= self.searchInterval) {
self.findNearestGem();
self.searchTimer = 0;
}
// Move towards nearest gem
if (self.targetGem && gems.indexOf(self.targetGem) !== -1) {
var dx = self.targetGem.x - self.x;
var dy = self.targetGem.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
sonicGraphics.scaleX = dx > 0 ? 1 : -1;
self.direction = dx > 0 ? 1 : -1;
}
} else {
// Search pattern movement
self.x += Math.sin(LK.ticks * 0.02) * 3;
self.y += Math.cos(LK.ticks * 0.015) * 2;
}
} else {
// Normal Mario combat mode (after collecting enough gold)
self.searchTimer++;
if (self.searchTimer >= self.searchInterval) {
self.findMario();
self.searchTimer = 0;
}
// Move towards Mario for combat
if (self.targetMario && marios.indexOf(self.targetMario) !== -1) {
var dx = self.targetMario.x - self.x;
var dy = self.targetMario.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 80) {
// Move towards Mario
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
sonicGraphics.scaleX = dx > 0 ? 1 : -1;
self.direction = dx > 0 ? 1 : -1;
} else {
// Close enough to attack - start spindash
self.attackTimer++;
if (self.attackTimer >= self.attackInterval && !self.isSpinning) {
self.startSpindash();
self.attackTimer = 0;
}
}
} else {
// Search pattern movement
self.x += Math.sin(LK.ticks * 0.02) * 3;
self.y += Math.cos(LK.ticks * 0.015) * 2;
}
}
// Handle spindash attack
if (self.isSpinning) {
self.spindashTimer++;
sonicGraphics.rotation += 0.5;
sonicGraphics.scaleX = Math.sin(LK.ticks * 0.3) * 0.2 + 0.8;
sonicGraphics.scaleY = Math.sin(LK.ticks * 0.3) * 0.2 + 0.8;
if (self.spindashTimer >= 60) {
self.isSpinning = false;
self.spindashTimer = 0;
sonicGraphics.rotation = 0;
sonicGraphics.scaleX = self.direction;
sonicGraphics.scaleY = 1;
}
}
// Keep Sonic in bounds
self.x = Math.max(100, Math.min(1948, self.x));
self.y = Math.max(100, Math.min(2632, self.y));
// Idle animation when not spinning
if (!self.isSpinning) {
sonicGraphics.y = Math.sin(LK.ticks * 0.15) * 2;
}
};
self.findMario = function () {
var nearestDistance = Infinity;
var nearestMario = null;
for (var i = 0; i < marios.length; i++) {
var mario = marios[i];
var dx = mario.x - self.x;
var dy = mario.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestMario = mario;
}
}
self.targetMario = nearestMario;
};
self.findNearestGem = function () {
var nearestDistance = Infinity;
var nearestGem = null;
for (var i = 0; i < gems.length; i++) {
var gem = gems[i];
var dx = gem.x - self.x;
var dy = gem.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestGem = gem;
}
}
self.targetGem = nearestGem;
};
self.startSpindash = function () {
self.isSpinning = true;
self.spindashTimer = 0;
// Flash blue to indicate attack
LK.effects.flashObject(self, 0x0066FF, 200);
};
return self;
});
var Spaghetti = Container.expand(function () {
var self = Container.call(this);
var spaghettiGraphics = self.attachAsset('spaghetti', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 15;
self.floatOffset = Math.random() * Math.PI * 2;
self.update = function () {
spaghettiGraphics.y = Math.sin(LK.ticks * 0.12 + self.floatOffset) * 4;
spaghettiGraphics.rotation += 0.03;
spaghettiGraphics.scaleX = Math.sin(LK.ticks * 0.08 + self.floatOffset) * 0.1 + 1;
spaghettiGraphics.scaleY = Math.sin(LK.ticks * 0.08 + self.floatOffset) * 0.1 + 1;
};
return self;
});
var Treasure = Container.expand(function () {
var self = Container.call(this);
var treasureGraphics = self.attachAsset('treasure', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 10;
self.floatOffset = Math.random() * Math.PI * 2;
self.update = function () {
treasureGraphics.y = Math.sin(LK.ticks * 0.1 + self.floatOffset) * 5;
treasureGraphics.rotation += 0.02;
};
return self;
});
var Weapon = Container.expand(function () {
var self = Container.call(this);
var weaponGraphics = self.attachAsset('weapon', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 25;
self.cooldown = 0;
self.maxCooldown = 30; // 0.5 seconds
self.range = 150;
self.isActive = false;
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
}
// Rotate weapon around player
weaponGraphics.rotation += 0.2;
// Pulse effect when ready to use
if (self.cooldown <= 0) {
weaponGraphics.alpha = Math.sin(LK.ticks * 0.3) * 0.3 + 0.7;
weaponGraphics.scaleX = Math.sin(LK.ticks * 0.2) * 0.2 + 1;
weaponGraphics.scaleY = Math.sin(LK.ticks * 0.2) * 0.2 + 1;
} else {
weaponGraphics.alpha = 0.5;
weaponGraphics.scaleX = 0.8;
weaponGraphics.scaleY = 0.8;
}
};
self.attack = function (target) {
if (self.cooldown <= 0) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range) {
target.takeDamage(self.damage);
self.cooldown = self.maxCooldown;
LK.effects.flashObject(self, 0xFFFFFF, 300);
LK.getSound('weapon_hit').play();
return true;
}
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
game.setBackgroundColor(0xDEB887);
// Game variables
var score = 0;
var health = 250;
var maxHealth = 250;
var gameTimer = 80 * 60; // 1 minute 20 seconds (80 seconds) at 60fps
var treasures = [];
var gems = [];
var powerups = [];
var fireballs = [];
var luigis = [];
var marios = [];
var spaghettis = [];
var sonics = [];
var treasureSpawnTimer = 0;
var gemSpawnTimer = 0;
var powerupSpawnTimer = 0;
var luigiSpawnTimer = 0;
var spaghettiSpawnTimer = 0;
var playerWeapon = null;
// Achievement system
var achievements = [];
var activeAchievements = [];
var achievementStats = {
treasuresCollected: 0,
gemsCollected: 0,
powerupsCollected: 0,
dragonHits: 0,
fireballsAvoided: 0,
survivalTime: 0,
maxScore: 0
};
// Initialize achievements
function initializeAchievements() {
achievements = [new Achievement('first_treasure', 'First Treasure!', 'Collect your first treasure', '💰'), new Achievement('treasure_hunter', 'Treasure Hunter', 'Collect 10 treasures', '🏆'), new Achievement('gem_collector', 'Gem Collector', 'Collect 5 gems', '💎'), new Achievement('survivor', 'Survivor', 'Survive for 30 seconds', '⏰'), new Achievement('speed_demon', 'Speed Demon', 'Use 3 speed power-ups', '⚡'), new Achievement('invincible', 'Invincible', 'Use 3 invulnerability power-ups', '🛡️'), new Achievement('score_master', 'Score Master', 'Reach 200 points', '🎯'), new Achievement('dragon_dancer', 'Dragon Dancer', 'Get hit by dragon 5 times and survive', '🐉'), new Achievement('high_scorer', 'High Scorer', 'Reach 300 points', '🌟'), new Achievement('ultimate_survivor', 'Ultimate Survivor', 'Survive for 60 seconds', '👑')];
// Load unlocked achievements from storage
for (var i = 0; i < achievements.length; i++) {
var achievement = achievements[i];
if (storage['achievement_' + achievement.id]) {
achievement.unlocked = true;
}
}
}
function checkAchievements() {
for (var i = 0; i < achievements.length; i++) {
var achievement = achievements[i];
if (!achievement.unlocked) {
var shouldUnlock = false;
switch (achievement.id) {
case 'first_treasure':
shouldUnlock = achievementStats.treasuresCollected >= 1;
break;
case 'treasure_hunter':
shouldUnlock = achievementStats.treasuresCollected >= 10;
break;
case 'gem_collector':
shouldUnlock = achievementStats.gemsCollected >= 5;
break;
case 'survivor':
shouldUnlock = achievementStats.survivalTime >= 30 * 60;
break;
case 'speed_demon':
shouldUnlock = achievementStats.powerupsCollected >= 3;
break;
case 'invincible':
shouldUnlock = achievementStats.powerupsCollected >= 3;
break;
case 'score_master':
shouldUnlock = score >= 200;
break;
case 'dragon_dancer':
shouldUnlock = achievementStats.dragonHits >= 5;
break;
case 'high_scorer':
shouldUnlock = score >= 300;
break;
case 'ultimate_survivor':
shouldUnlock = achievementStats.survivalTime >= 60 * 60;
break;
}
if (shouldUnlock) {
achievement.unlock();
activeAchievements.push(achievement);
game.addChild(achievement);
}
}
}
}
// Initialize achievements
initializeAchievements();
// Create player
var player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Create dragon
var dragon = game.addChild(new Dragon());
dragon.x = 200;
dragon.y = 200;
// Create Luigi monster
var luigi = game.addChild(new Luigi());
luigi.x = 1500;
luigi.y = 1000;
luigis.push(luigi);
// Create Mario character
var mario = game.addChild(new Mario());
mario.x = 300;
mario.y = 800;
marios.push(mario);
// Create Sonic character
var sonic = game.addChild(new Sonic());
sonic.x = 1700;
sonic.y = 600;
sonics.push(sonic);
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 250/250', {
size: 60,
fill: 0x00FF00
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 20;
LK.gui.addChild(healthTxt);
var timerTxt = new Text2('Time: 1:20', {
size: 70,
fill: 0xFFFFFF
});
timerTxt.anchor.set(1, 0);
timerTxt.x = 2048 - 20;
timerTxt.y = 20;
LK.gui.addChild(timerTxt);
var instructionTxt = new Text2('Tap to move! Get close to Luigi for weapon to defeat dragon!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionTxt);
// Game logic functions
function spawnTreasure() {
var treasure = new Treasure();
treasure.x = Math.random() * 1800 + 124;
treasure.y = Math.random() * 2400 + 166;
treasures.push(treasure);
game.addChild(treasure);
}
function spawnGem() {
var gem = new Gem();
gem.x = Math.random() * 1800 + 124;
gem.y = Math.random() * 2400 + 166;
gems.push(gem);
game.addChild(gem);
}
function spawnPowerUp() {
var powerup = new PowerUp();
powerup.x = Math.random() * 1800 + 124;
powerup.y = Math.random() * 2400 + 166;
powerups.push(powerup);
game.addChild(powerup);
}
function spawnSpaghetti() {
var spaghetti = new Spaghetti();
spaghetti.x = Math.random() * 1800 + 124;
spaghetti.y = Math.random() * 2400 + 166;
spaghettis.push(spaghetti);
game.addChild(spaghetti);
}
function updateScore(points) {
score += points;
scoreTxt.setText('Score: ' + score);
LK.setScore(score);
}
function updateHealth(damage) {
health = Math.max(0, health - damage);
healthTxt.setText('Health: ' + health + '/' + maxHealth);
// Change color based on health percentage
var healthPercent = health / maxHealth;
if (healthPercent > 0.6) {
healthTxt.fill = 0x00FF00; // Green
} else if (healthPercent > 0.3) {
healthTxt.fill = 0xFFFF00; // Yellow
} else {
healthTxt.fill = 0xFF0000; // Red
}
if (health <= 0) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
}
function updateTimer() {
gameTimer = Math.max(0, gameTimer - 1);
var totalSeconds = Math.floor(gameTimer / 60);
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
var timeText = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
timerTxt.setText('Time: ' + timeText);
// Change color based on remaining time
if (gameTimer <= 10 * 60) {
// Last 10 seconds
timerTxt.fill = 0xFF0000; // Red
} else if (gameTimer <= 30 * 60) {
// Last 30 seconds
timerTxt.fill = 0xFFFF00; // Yellow
} else {
timerTxt.fill = 0xFFFFFF; // White
}
if (gameTimer <= 0) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
}
// Touch controls
var targetX = player.x;
var targetY = player.y;
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
// Attack dragon with weapon if player has one
if (playerWeapon) {
playerWeapon.attack(dragon);
// Also attack any Mario in range
for (var i = 0; i < marios.length; i++) {
var mario = marios[i];
if (mario.health > 0) {
playerWeapon.attack(mario);
}
}
}
};
game.move = function (x, y, obj) {
targetX = x;
targetY = y;
};
// Game update loop
game.update = function () {
// Update timer
updateTimer();
// Move player towards target
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var speed = player.speedBoost ? player.speed * 1.5 : player.speed;
player.x += dx / distance * speed;
player.y += dy / distance * speed;
}
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Update weapon position if player has one
if (playerWeapon) {
playerWeapon.x = player.x;
playerWeapon.y = player.y - 50;
// Auto-attack dragon when in range
var dx = dragon.x - playerWeapon.x;
var dy = dragon.y - playerWeapon.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= playerWeapon.range) {
playerWeapon.attack(dragon);
}
// Auto-attack Mario when in range
for (var i = 0; i < marios.length; i++) {
var mario = marios[i];
if (mario.health > 0) {
var dx = mario.x - playerWeapon.x;
var dy = mario.y - playerWeapon.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= playerWeapon.range) {
playerWeapon.attack(mario);
}
}
}
}
// Spawn treasures
treasureSpawnTimer++;
if (treasureSpawnTimer >= 90) {
// Every 1.5 seconds
spawnTreasure();
treasureSpawnTimer = 0;
}
// Spawn gems
gemSpawnTimer++;
if (gemSpawnTimer >= 180) {
// Every 3 seconds
spawnGem();
gemSpawnTimer = 0;
}
// Spawn power-ups
powerupSpawnTimer++;
if (powerupSpawnTimer >= 600) {
// Every 10 seconds
spawnPowerUp();
powerupSpawnTimer = 0;
}
// Spawn spaghetti
spaghettiSpawnTimer++;
if (spaghettiSpawnTimer >= 120) {
// Every 2 seconds
spawnSpaghetti();
spaghettiSpawnTimer = 0;
}
// Check treasure collection
for (var i = treasures.length - 1; i >= 0; i--) {
var treasure = treasures[i];
if (player.intersects(treasure)) {
updateScore(treasure.points);
achievementStats.treasuresCollected++;
LK.effects.flashObject(treasure, 0xFFFFFF, 300);
treasure.destroy();
treasures.splice(i, 1);
LK.getSound('collect').play();
}
}
// Check gem collection
for (var i = gems.length - 1; i >= 0; i--) {
var gem = gems[i];
if (player.intersects(gem)) {
updateScore(gem.points);
achievementStats.gemsCollected++;
LK.effects.flashObject(gem, 0xFFFFFF, 300);
gem.destroy();
gems.splice(i, 1);
LK.getSound('collect').play();
}
}
// Check power-up collection
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (player.intersects(powerup)) {
if (powerup.type === 'speed') {
player.activateSpeedBoost();
} else if (powerup.type === 'invulnerable') {
player.activateInvulnerability();
}
achievementStats.powerupsCollected++;
LK.effects.flashObject(powerup, 0xFFFFFF, 300);
powerup.destroy();
powerups.splice(i, 1);
LK.getSound('powerup').play();
}
}
// Check Mario spaghetti collection
for (var i = marios.length - 1; i >= 0; i--) {
var mario = marios[i];
for (var j = spaghettis.length - 1; j >= 0; j--) {
var spaghetti = spaghettis[j];
if (mario.intersects(spaghetti)) {
updateScore(spaghetti.points);
LK.effects.flashObject(spaghetti, 0xFFD700, 300);
spaghetti.destroy();
spaghettis.splice(j, 1);
LK.getSound('collect').play();
break;
}
}
}
// Check player spaghetti collection
for (var i = spaghettis.length - 1; i >= 0; i--) {
var spaghetti = spaghettis[i];
if (player.intersects(spaghetti)) {
updateScore(spaghetti.points);
LK.effects.flashObject(spaghetti, 0xFFD700, 300);
// Make all Marios angry when player steals spaghetti
for (var j = 0; j < marios.length; j++) {
var mario = marios[j];
if (!mario.isAngry) {
mario.becomeAngry();
}
}
spaghetti.destroy();
spaghettis.splice(i, 1);
LK.getSound('collect').play();
}
}
// Check if dragon is dead
if (dragon.health <= 0 && !dragon.isDead) {
dragon.isDead = true;
// Make all Marios angry when dragon dies
for (var j = 0; j < marios.length; j++) {
var mario = marios[j];
if (!mario.isAngry) {
mario.becomeAngry();
}
}
// Remove all Sonics from the game when dragon dies
for (var k = sonics.length - 1; k >= 0; k--) {
var sonic = sonics[k];
LK.effects.flashObject(sonic, 0x0066FF, 1000); // Blue flash before disappearing
sonic.destroy();
sonics.splice(k, 1);
}
LK.effects.flashScreen(0x00FF00, 1000); // Green flash for dragon death
updateScore(200); // Bonus points for killing dragon
// Remove dragon from game
dragon.destroy();
}
// Remove dead Marios from game
for (var i = marios.length - 1; i >= 0; i--) {
var mario = marios[i];
if (mario.shouldDestroy) {
mario.destroy();
marios.splice(i, 1);
}
}
// Check if Mario is dead (win condition after dragon is defeated)
if (dragon.isDead) {
var allMariosDead = true;
for (var j = 0; j < marios.length; j++) {
var mario = marios[j];
if (mario.health > 0) {
allMariosDead = false;
break;
}
}
if (allMariosDead) {
// Check if score is below 500 - Luigi disappears
if (score < 500) {
// Remove all Luigis from the game
for (var k = luigis.length - 1; k >= 0; k--) {
var luigi = luigis[k];
LK.effects.flashObject(luigi, 0xFF0000, 1000); // Red flash before disappearing
luigi.destroy();
luigis.splice(k, 1);
}
LK.effects.flashScreen(0xFF0000, 1000); // Red flash for Luigi disappearance
// Show game over since Luigi is gone
LK.showGameOver();
} else {
LK.effects.flashScreen(0x00FF00, 1000); // Green flash for victory
LK.showYouWin();
}
}
}
// Check dragon collision
if (!player.invulnerable && player.intersects(dragon)) {
if (!player.lastDragonHit) {
updateHealth(50);
achievementStats.dragonHits++;
player.activateInvulnerability();
LK.effects.flashScreen(0xFF0000, 500);
player.lastDragonHit = true;
}
} else {
player.lastDragonHit = false;
}
// Check fireball collisions
for (var i = fireballs.length - 1; i >= 0; i--) {
var fireball = fireballs[i];
if (fireball.shouldDestroy) {
fireball.destroy();
fireballs.splice(i, 1);
continue;
}
if (!player.invulnerable && player.intersects(fireball)) {
if (!fireball.hasHit) {
updateHealth(25);
player.activateInvulnerability();
LK.effects.flashScreen(0xFF0000, 300);
fireball.hasHit = true;
fireball.shouldDestroy = true;
}
}
}
// Check Luigi collisions
for (var i = luigis.length - 1; i >= 0; i--) {
var luigi = luigis[i];
if (!player.invulnerable && player.intersects(luigi)) {
if (!luigi.lastHit) {
updateHealth(30);
player.activateInvulnerability();
LK.effects.flashScreen(0x00FF00, 400);
luigi.lastHit = true;
}
} else {
luigi.lastHit = false;
}
}
// Check angry Mario attacking player
for (var i = marios.length - 1; i >= 0; i--) {
var mario = marios[i];
if (mario.isAngry && !player.invulnerable && player.intersects(mario)) {
if (!mario.lastPlayerHit) {
updateHealth(40);
player.activateInvulnerability();
LK.effects.flashScreen(0xFF0000, 400);
mario.lastPlayerHit = true;
}
} else {
mario.lastPlayerHit = false;
}
}
// Check Sonic gem collection
for (var i = sonics.length - 1; i >= 0; i--) {
var sonic = sonics[i];
// Check if Sonic collects gems
for (var j = gems.length - 1; j >= 0; j--) {
var gem = gems[j];
if (sonic.intersects(gem)) {
sonic.goldCollected++;
LK.effects.flashObject(gem, 0x0066FF, 300);
gem.destroy();
gems.splice(j, 1);
LK.getSound('collect').play();
break;
}
}
}
// Check Sonic attacking player
for (var i = sonics.length - 1; i >= 0; i--) {
var sonic = sonics[i];
if (sonic.isAttackingPlayer && !player.invulnerable && player.intersects(sonic)) {
if (!sonic.lastPlayerHit) {
updateHealth(35);
player.activateInvulnerability();
LK.effects.flashScreen(0x0066FF, 400);
sonic.lastPlayerHit = true;
}
} else {
sonic.lastPlayerHit = false;
}
}
// Check Sonic vs Mario combat
for (var i = sonics.length - 1; i >= 0; i--) {
var sonic = sonics[i];
for (var j = marios.length - 1; j >= 0; j--) {
var mario = marios[j];
if (sonic.intersects(mario)) {
if (!sonic.lastMarioHit && sonic.isSpinning) {
// Sonic hits Mario during spindash
mario.takeDamage(20);
LK.effects.flashObject(mario, 0xFF0000, 500);
LK.effects.flashObject(sonic, 0x0066FF, 300);
updateScore(50); // Bonus points for combat
sonic.lastMarioHit = true;
} else if (!mario.lastSonicHit && !sonic.isSpinning) {
// Mario hits Sonic when not spinning
LK.effects.flashObject(sonic, 0xFF0000, 500);
LK.effects.flashObject(mario, 0x00FF00, 300);
updateScore(30); // Bonus points for combat
mario.lastSonicHit = true;
}
} else {
sonic.lastMarioHit = false;
mario.lastSonicHit = false;
}
}
}
// Spawn additional Luigis based on score
luigiSpawnTimer++;
if (luigiSpawnTimer >= 1800 && score >= 100) {
// Every 30 seconds after score 100
var newLuigi = new Luigi();
newLuigi.x = Math.random() * 1800 + 124;
newLuigi.y = Math.random() * 2000 + 500;
luigis.push(newLuigi);
game.addChild(newLuigi);
luigiSpawnTimer = 0;
}
// Update achievement stats
achievementStats.survivalTime++;
if (score > achievementStats.maxScore) {
achievementStats.maxScore = score;
}
// Check for new achievements
checkAchievements();
// Update active achievement displays
for (var i = activeAchievements.length - 1; i >= 0; i--) {
var achievement = activeAchievements[i];
if (achievement.displayTime <= 0 && achievement.alpha <= 0) {
achievement.destroy();
activeAchievements.splice(i, 1);
}
}
// Win condition
if (score >= 500) {
LK.showYouWin();
}
};
// Start background music
LK.playMusic('desert');
// Initial treasures
for (var i = 0; i < 3; i++) {
spawnTreasure();
}
// Initial spaghetti
for (var i = 0; i < 2; i++) {
spawnSpaghetti();
}
; ===================================================================
--- original.js
+++ change.js
@@ -458,38 +458,87 @@
self.attackInterval = 120; // 2 seconds
self.spindashTimer = 0;
self.isSpinning = false;
self.direction = 1;
+ self.goldTimer = 50 * 60; // 50 seconds at 60fps
+ self.goldCollected = 0;
+ self.goldTarget = 3;
+ self.isAttackingPlayer = false;
+ self.targetPlayer = null;
self.update = function () {
- // Search for Mario
- self.searchTimer++;
- if (self.searchTimer >= self.searchInterval) {
- self.findMario();
- self.searchTimer = 0;
+ // Update gold collection timer
+ self.goldTimer--;
+ if (self.goldTimer <= 0 && self.goldCollected < self.goldTarget) {
+ self.isAttackingPlayer = true;
+ self.targetPlayer = player;
+ sonicGraphics.tint = 0xFF0000; // Turn red when attacking player
}
- // Move towards Mario for combat
- if (self.targetMario && marios.indexOf(self.targetMario) !== -1) {
- var dx = self.targetMario.x - self.x;
- var dy = self.targetMario.y - self.y;
+ // Behavior based on current state
+ if (self.isAttackingPlayer && self.targetPlayer) {
+ // Attack player mode
+ var dx = self.targetPlayer.x - self.x;
+ var dy = self.targetPlayer.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance > 80) {
- // Move towards Mario
- self.x += dx / distance * self.speed;
- self.y += dy / distance * self.speed;
+ if (distance > 5) {
+ self.x += dx / distance * (self.speed * 1.5); // Faster when attacking player
+ self.y += dy / distance * (self.speed * 1.5);
sonicGraphics.scaleX = dx > 0 ? 1 : -1;
self.direction = dx > 0 ? 1 : -1;
- } else {
- // Close enough to attack - start spindash
- self.attackTimer++;
- if (self.attackTimer >= self.attackInterval && !self.isSpinning) {
- self.startSpindash();
- self.attackTimer = 0;
+ }
+ } else if (self.goldCollected < self.goldTarget) {
+ // Gold collection mode - search for gems (gold)
+ self.searchTimer++;
+ if (self.searchTimer >= self.searchInterval) {
+ self.findNearestGem();
+ self.searchTimer = 0;
+ }
+ // Move towards nearest gem
+ if (self.targetGem && gems.indexOf(self.targetGem) !== -1) {
+ var dx = self.targetGem.x - self.x;
+ var dy = self.targetGem.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 5) {
+ self.x += dx / distance * self.speed;
+ self.y += dy / distance * self.speed;
+ sonicGraphics.scaleX = dx > 0 ? 1 : -1;
+ self.direction = dx > 0 ? 1 : -1;
}
+ } else {
+ // Search pattern movement
+ self.x += Math.sin(LK.ticks * 0.02) * 3;
+ self.y += Math.cos(LK.ticks * 0.015) * 2;
}
} else {
- // Search pattern movement
- self.x += Math.sin(LK.ticks * 0.02) * 3;
- self.y += Math.cos(LK.ticks * 0.015) * 2;
+ // Normal Mario combat mode (after collecting enough gold)
+ self.searchTimer++;
+ if (self.searchTimer >= self.searchInterval) {
+ self.findMario();
+ self.searchTimer = 0;
+ }
+ // Move towards Mario for combat
+ if (self.targetMario && marios.indexOf(self.targetMario) !== -1) {
+ var dx = self.targetMario.x - self.x;
+ var dy = self.targetMario.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 80) {
+ // Move towards Mario
+ self.x += dx / distance * self.speed;
+ self.y += dy / distance * self.speed;
+ sonicGraphics.scaleX = dx > 0 ? 1 : -1;
+ self.direction = dx > 0 ? 1 : -1;
+ } else {
+ // Close enough to attack - start spindash
+ self.attackTimer++;
+ if (self.attackTimer >= self.attackInterval && !self.isSpinning) {
+ self.startSpindash();
+ self.attackTimer = 0;
+ }
+ }
+ } else {
+ // Search pattern movement
+ self.x += Math.sin(LK.ticks * 0.02) * 3;
+ self.y += Math.cos(LK.ticks * 0.015) * 2;
+ }
}
// Handle spindash attack
if (self.isSpinning) {
self.spindashTimer++;
@@ -526,8 +575,23 @@
}
}
self.targetMario = nearestMario;
};
+ self.findNearestGem = function () {
+ var nearestDistance = Infinity;
+ var nearestGem = null;
+ for (var i = 0; i < gems.length; i++) {
+ var gem = gems[i];
+ var dx = gem.x - self.x;
+ var dy = gem.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < nearestDistance) {
+ nearestDistance = distance;
+ nearestGem = gem;
+ }
+ }
+ self.targetGem = nearestGem;
+ };
self.startSpindash = function () {
self.isSpinning = true;
self.spindashTimer = 0;
// Flash blue to indicate attack
@@ -1115,8 +1179,38 @@
} else {
mario.lastPlayerHit = false;
}
}
+ // Check Sonic gem collection
+ for (var i = sonics.length - 1; i >= 0; i--) {
+ var sonic = sonics[i];
+ // Check if Sonic collects gems
+ for (var j = gems.length - 1; j >= 0; j--) {
+ var gem = gems[j];
+ if (sonic.intersects(gem)) {
+ sonic.goldCollected++;
+ LK.effects.flashObject(gem, 0x0066FF, 300);
+ gem.destroy();
+ gems.splice(j, 1);
+ LK.getSound('collect').play();
+ break;
+ }
+ }
+ }
+ // Check Sonic attacking player
+ for (var i = sonics.length - 1; i >= 0; i--) {
+ var sonic = sonics[i];
+ if (sonic.isAttackingPlayer && !player.invulnerable && player.intersects(sonic)) {
+ if (!sonic.lastPlayerHit) {
+ updateHealth(35);
+ player.activateInvulnerability();
+ LK.effects.flashScreen(0x0066FF, 400);
+ sonic.lastPlayerHit = true;
+ }
+ } else {
+ sonic.lastPlayerHit = false;
+ }
+ }
// Check Sonic vs Mario combat
for (var i = sonics.length - 1; i >= 0; i--) {
var sonic = sonics[i];
for (var j = marios.length - 1; j >= 0; j--) {
CREATE THIS IMAGE. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
MAKE THIS PICTURE LIKE A FIREBALL. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
DESIGN THIS PICTURE AS AN ENERGY DRINK. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
LUİGİ KARAKTERİNİ OLUŞTUR. In-Game asset. 2d. High contrast. No shadows
KORKAK BİR ADAM. In-Game asset. 2d. High contrast. No shadows
BÜYÜK BİR EJDER. In-Game asset. 2d. High contrast. No shadows
MARİO. In-Game asset. 2d. High contrast. No shadows
SPAGHETTİ. In-Game asset. 2d. High contrast. No shadows
sonic. In-Game asset. 2d. High contrast. No shadows
silah. In-Game asset. 2d. High contrast. No shadows
sonic altını. In-Game asset. 2d. High contrast. No shadows