User prompt
Make a maze
User prompt
Make it like a maze, instead of it just shooting upwards, and like, all the monsters can just run at you at a random time, and you can't see them, until they come up, like, pretty close to you.
Code edit (1 edits merged)
Please save this source code
User prompt
Minecart Mayhem: Armed Run
Initial prompt
It's like my other game Minecart Escape, but basically you have guns and knives, and there's more than just the skeleton mob.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet var Bullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.width = bullet.width; self.height = bullet.height; self.speed = -36; // Upwards self.update = function () { self.y += self.speed; }; return self; }); // Enemy base class var Enemy = Container.expand(function () { var self = Container.call(this); self.type = 'enemy'; self.hp = 1; self.speed = 8; self.scoreValue = 1; self.update = function () {}; return self; }); // Skeleton enemy var Skeleton = Enemy.expand(function () { var self = Enemy.call(this); var skeleton = self.attachAsset('enemy_skeleton', { anchorX: 0.5, anchorY: 0.5 }); self.width = skeleton.width; self.height = skeleton.height; self.hp = 1; self.speed = 12 + Math.random() * 4; self.scoreValue = 2; self.update = function () { self.y += self.speed; }; return self; }); // Goblin enemy var Goblin = Enemy.expand(function () { var self = Enemy.call(this); var goblin = self.attachAsset('enemy_goblin', { anchorX: 0.5, anchorY: 0.5 }); self.width = goblin.width; self.height = goblin.height; self.hp = 2; self.speed = 10 + Math.random() * 4; self.scoreValue = 3; self.update = function () { self.y += self.speed; }; return self; }); // Bat enemy var Bat = Enemy.expand(function () { var self = Enemy.call(this); var bat = self.attachAsset('enemy_bat', { anchorX: 0.5, anchorY: 0.5 }); self.width = bat.width; self.height = bat.height; self.hp = 1; self.speed = 18 + Math.random() * 6; self.scoreValue = 2; self.update = function () { self.y += self.speed; self.x += Math.sin(LK.ticks / 12 + self._batWobble) * 8; }; self._batWobble = Math.random() * Math.PI * 2; return self; }); // Player Minecart var Minecart = Container.expand(function () { var self = Container.call(this); var cart = self.attachAsset('minecart', { anchorX: 0.5, anchorY: 0.5 }); self.width = cart.width; self.height = cart.height; self.weapon = 'gun'; // 'gun' or 'knife' self.weaponLevel = 1; // Upgrades increase this self.invincible = false; self.invincibleTimer = 0; self.attackCooldown = 0; self.knifeSwinging = false; self.knife = null; // Flash minecart when hit self.flash = function () { self.invincible = true; self.invincibleTimer = 60; // 1 second at 60fps tween(self, { alpha: 0.5 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 100 }); } }); }; // Switch weapon self.setWeapon = function (type) { self.weapon = type; }; // Upgrade weapon self.upgradeWeapon = function () { self.weaponLevel += 1; if (self.weaponLevel > 3) self.weaponLevel = 3; }; // Knife attack animation self.swingKnife = function () { if (self.knifeSwinging) return; self.knifeSwinging = true; if (!self.knife) { self.knife = self.attachAsset('knife', { anchorX: 0.1, anchorY: 0.5, x: self.width / 2 + 20, y: 0, rotation: 0 }); } self.knife.visible = true; self.knife.rotation = -0.7; tween(self.knife, { rotation: 0.7 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { self.knife.visible = false; self.knifeSwinging = false; self.knife.rotation = -0.7; } }); }; return self; }); // Obstacle (rock) var Obstacle = Container.expand(function () { var self = Container.call(this); var rock = self.attachAsset('obstacle_rock', { anchorX: 0.5, anchorY: 0.5 }); self.width = rock.width; self.height = rock.height; self.speed = 14 + Math.random() * 6; self.update = function () { self.y += self.speed; }; return self; }); // Upgrade (gun or knife) var Upgrade = Container.expand(function () { var self = Container.call(this); self.kind = Math.random() < 0.5 ? 'gun' : 'knife'; var assetId = self.kind === 'gun' ? 'upgrade_gun' : 'upgrade_knife'; var upg = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.width = upg.width; self.height = upg.height; self.speed = 10 + Math.random() * 4; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Upgrade: Knife // Upgrade: Gun // Obstacle: Rock // Enemy: Skeleton // Enemy: Goblin // Enemy: Bat // Player's bullet // Player's knife // Minecart (player) // Game constants var GAME_W = 2048; var GAME_H = 2732; var TRACK_LEFT = 300; var TRACK_RIGHT = GAME_W - 300; var PLAYER_Y = GAME_H - 350; // Game state var minecart = null; var bullets = []; var enemies = []; var obstacles = []; var upgrades = []; var dragNode = null; var lastTouchX = 0; var lastTouchY = 0; var scoreTxt = null; var lastScore = 0; var gameOver = false; var spawnTimer = 0; var obstacleTimer = 0; var upgradeTimer = 0; var difficulty = 1; var knifeHitEnemies = []; var lastKnifeSwingTick = -100; // Score display scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create player minecart = new Minecart(); game.addChild(minecart); minecart.x = GAME_W / 2; minecart.y = PLAYER_Y; // Touch controls: drag minecart horizontally game.down = function (x, y, obj) { if (gameOver) return; dragNode = minecart; lastTouchX = x; lastTouchY = y; }; game.up = function (x, y, obj) { dragNode = null; }; game.move = function (x, y, obj) { if (gameOver) return; if (dragNode === minecart) { // Only allow horizontal movement within track var nx = x; if (nx < TRACK_LEFT) nx = TRACK_LEFT; if (nx > TRACK_RIGHT) nx = TRACK_RIGHT; minecart.x = nx; } }; // Tap to attack (shoot or knife) game.tap = function (x, y, obj) { if (gameOver) return; if (minecart.weapon === 'gun') { if (minecart.attackCooldown <= 0) { fireBullet(); minecart.attackCooldown = 12 - minecart.weaponLevel * 2; // Faster with upgrades if (minecart.attackCooldown < 4) minecart.attackCooldown = 4; } } else if (minecart.weapon === 'knife') { if (LK.ticks - lastKnifeSwingTick > 18) { minecart.swingKnife(); lastKnifeSwingTick = LK.ticks; } } }; // Fire bullet(s) function fireBullet() { var spread = minecart.weaponLevel; for (var i = 0; i < spread; ++i) { var b = new Bullet(); b.x = minecart.x + (i - (spread - 1) / 2) * 40; b.y = minecart.y - minecart.height / 2 - 10; bullets.push(b); game.addChild(b); } } // Main update loop game.update = function () { if (gameOver) return; // Difficulty scaling if (LK.ticks % 300 === 0 && difficulty < 10) { difficulty += 1; } // Attack cooldown if (minecart.attackCooldown > 0) minecart.attackCooldown -= 1; // Invincibility timer if (minecart.invincible) { minecart.invincibleTimer -= 1; if (minecart.invincibleTimer <= 0) { minecart.invincible = false; } } // Bullets update for (var i = bullets.length - 1; i >= 0; --i) { var b = bullets[i]; b.update(); if (b.y < -50) { b.destroy(); bullets.splice(i, 1); continue; } // Bullet hits enemy for (var j = enemies.length - 1; j >= 0; --j) { var e = enemies[j]; if (b.intersects(e)) { e.hp -= 1; b.destroy(); bullets.splice(i, 1); if (e.hp <= 0) { addScore(e.scoreValue); e.destroy(); enemies.splice(j, 1); } break; } } } // Enemies update for (var i = enemies.length - 1; i >= 0; --i) { var e = enemies[i]; e.update(); if (e.y > GAME_H + 100) { e.destroy(); enemies.splice(i, 1); continue; } // Enemy hits minecart if (!minecart.invincible && e.intersects(minecart)) { minecart.flash(); LK.effects.flashScreen(0xff0000, 600); // End game LK.showGameOver(); gameOver = true; return; } // Enemy hit by knife if (minecart.weapon === 'knife' && minecart.knife && minecart.knife.visible && !knifeHitEnemies.includes(e)) { // Knife is in swing, check collision var knifeGlobal = minecart.toGlobal(minecart.knife.position); var knifeRect = new Rectangle(knifeGlobal.x - 30, knifeGlobal.y - 12, 60, 24); var enemyRect = new Rectangle(e.x - e.width / 2, e.y - e.height / 2, e.width, e.height); if (rectsIntersect(knifeRect, enemyRect)) { e.hp -= 1; knifeHitEnemies.push(e); if (e.hp <= 0) { addScore(e.scoreValue); e.destroy(); enemies.splice(i, 1); } } } } // Reset knife hit list if knife not swinging if (!(minecart.knife && minecart.knife.visible)) { knifeHitEnemies = []; } // Obstacles update for (var i = obstacles.length - 1; i >= 0; --i) { var o = obstacles[i]; o.update(); if (o.y > GAME_H + 100) { o.destroy(); obstacles.splice(i, 1); continue; } // Obstacle hits minecart if (!minecart.invincible && o.intersects(minecart)) { minecart.flash(); LK.effects.flashScreen(0xff0000, 600); LK.showGameOver(); gameOver = true; return; } } // Upgrades update for (var i = upgrades.length - 1; i >= 0; --i) { var u = upgrades[i]; u.update(); if (u.y > GAME_H + 100) { u.destroy(); upgrades.splice(i, 1); continue; } // Pickup if (u.intersects(minecart)) { if (u.kind === 'gun') { minecart.setWeapon('gun'); minecart.upgradeWeapon(); } else { minecart.setWeapon('knife'); minecart.upgradeWeapon(); } u.destroy(); upgrades.splice(i, 1); } } // Spawning enemies spawnTimer -= 1; if (spawnTimer <= 0) { spawnEnemy(); spawnTimer = Math.max(24, 60 - difficulty * 4 - Math.floor(Math.random() * 10)); } // Spawning obstacles obstacleTimer -= 1; if (obstacleTimer <= 0) { if (Math.random() < 0.5 + difficulty * 0.04) { spawnObstacle(); } obstacleTimer = 90 + Math.floor(Math.random() * 60) - difficulty * 4; if (obstacleTimer < 30) obstacleTimer = 30; } // Spawning upgrades upgradeTimer -= 1; if (upgradeTimer <= 0) { if (Math.random() < 0.18) { spawnUpgrade(); } upgradeTimer = 600 + Math.floor(Math.random() * 300); } // Update score display if (LK.getScore() !== lastScore) { scoreTxt.setText(LK.getScore()); lastScore = LK.getScore(); } }; // Spawn enemy function spawnEnemy() { var enemyType = Math.random(); var e = null; var x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160); if (enemyType < 0.33) { e = new Bat(); } else if (enemyType < 0.66) { e = new Goblin(); } else { e = new Skeleton(); } e.x = x; e.y = -80; enemies.push(e); game.addChild(e); } // Spawn obstacle function spawnObstacle() { var o = new Obstacle(); o.x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160); o.y = -60; obstacles.push(o); game.addChild(o); } // Spawn upgrade function spawnUpgrade() { var u = new Upgrade(); u.x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160); u.y = -60; upgrades.push(u); game.addChild(u); } // Add score function addScore(val) { LK.setScore(LK.getScore() + val); } // Rectangle intersection helper function rectsIntersect(r1, r2) { return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x || r2.y > r1.y + r1.height || r2.y + r2.height < r1.y); } // Touch to attack (simulate tap on mobile) game.down = function (origDown) { return function (x, y, obj) { if (origDown) origDown(x, y, obj); game.tap(x, y, obj); }; }(game.down); // Reset game state on game over LK.on('gameover', function () { gameOver = true; }); // Reset game state on new game LK.on('newgame', function () { gameOver = false; LK.setScore(0); scoreTxt.setText('0'); // Remove all objects for (var i = 0; i < bullets.length; ++i) bullets[i].destroy(); for (var i = 0; i < enemies.length; ++i) enemies[i].destroy(); for (var i = 0; i < obstacles.length; ++i) obstacles[i].destroy(); for (var i = 0; i < upgrades.length; ++i) upgrades[i].destroy(); bullets = []; enemies = []; obstacles = []; upgrades = []; minecart.x = GAME_W / 2; minecart.y = PLAYER_Y; minecart.weapon = 'gun'; minecart.weaponLevel = 1; minecart.invincible = false; minecart.invincibleTimer = 0; minecart.attackCooldown = 0; minecart.knifeSwinging = false; minecart.setWeapon('gun'); difficulty = 1; spawnTimer = 0; obstacleTimer = 0; upgradeTimer = 0; knifeHitEnemies = []; lastKnifeSwingTick = -100; }); // Initial state spawnTimer = 0; obstacleTimer = 60; upgradeTimer = 600; difficulty = 1; gameOver = false; LK.setScore(0); scoreTxt.setText('0');
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,532 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Bullet
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bullet = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = bullet.width;
+ self.height = bullet.height;
+ self.speed = -36; // Upwards
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Enemy base class
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = 'enemy';
+ self.hp = 1;
+ self.speed = 8;
+ self.scoreValue = 1;
+ self.update = function () {};
+ return self;
+});
+// Skeleton enemy
+var Skeleton = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ var skeleton = self.attachAsset('enemy_skeleton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = skeleton.width;
+ self.height = skeleton.height;
+ self.hp = 1;
+ self.speed = 12 + Math.random() * 4;
+ self.scoreValue = 2;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Goblin enemy
+var Goblin = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ var goblin = self.attachAsset('enemy_goblin', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = goblin.width;
+ self.height = goblin.height;
+ self.hp = 2;
+ self.speed = 10 + Math.random() * 4;
+ self.scoreValue = 3;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Bat enemy
+var Bat = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ var bat = self.attachAsset('enemy_bat', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = bat.width;
+ self.height = bat.height;
+ self.hp = 1;
+ self.speed = 18 + Math.random() * 6;
+ self.scoreValue = 2;
+ self.update = function () {
+ self.y += self.speed;
+ self.x += Math.sin(LK.ticks / 12 + self._batWobble) * 8;
+ };
+ self._batWobble = Math.random() * Math.PI * 2;
+ return self;
+});
+// Player Minecart
+var Minecart = Container.expand(function () {
+ var self = Container.call(this);
+ var cart = self.attachAsset('minecart', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = cart.width;
+ self.height = cart.height;
+ self.weapon = 'gun'; // 'gun' or 'knife'
+ self.weaponLevel = 1; // Upgrades increase this
+ self.invincible = false;
+ self.invincibleTimer = 0;
+ self.attackCooldown = 0;
+ self.knifeSwinging = false;
+ self.knife = null;
+ // Flash minecart when hit
+ self.flash = function () {
+ self.invincible = true;
+ self.invincibleTimer = 60; // 1 second at 60fps
+ tween(self, {
+ alpha: 0.5
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ alpha: 1
+ }, {
+ duration: 100
+ });
+ }
+ });
+ };
+ // Switch weapon
+ self.setWeapon = function (type) {
+ self.weapon = type;
+ };
+ // Upgrade weapon
+ self.upgradeWeapon = function () {
+ self.weaponLevel += 1;
+ if (self.weaponLevel > 3) self.weaponLevel = 3;
+ };
+ // Knife attack animation
+ self.swingKnife = function () {
+ if (self.knifeSwinging) return;
+ self.knifeSwinging = true;
+ if (!self.knife) {
+ self.knife = self.attachAsset('knife', {
+ anchorX: 0.1,
+ anchorY: 0.5,
+ x: self.width / 2 + 20,
+ y: 0,
+ rotation: 0
+ });
+ }
+ self.knife.visible = true;
+ self.knife.rotation = -0.7;
+ tween(self.knife, {
+ rotation: 0.7
+ }, {
+ duration: 180,
+ easing: tween.cubicOut,
+ onFinish: function onFinish() {
+ self.knife.visible = false;
+ self.knifeSwinging = false;
+ self.knife.rotation = -0.7;
+ }
+ });
+ };
+ return self;
+});
+// Obstacle (rock)
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var rock = self.attachAsset('obstacle_rock', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = rock.width;
+ self.height = rock.height;
+ self.speed = 14 + Math.random() * 6;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Upgrade (gun or knife)
+var Upgrade = Container.expand(function () {
+ var self = Container.call(this);
+ self.kind = Math.random() < 0.5 ? 'gun' : 'knife';
+ var assetId = self.kind === 'gun' ? 'upgrade_gun' : 'upgrade_knife';
+ var upg = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = upg.width;
+ self.height = upg.height;
+ self.speed = 10 + Math.random() * 4;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x181818
+});
+
+/****
+* Game Code
+****/
+// Upgrade: Knife
+// Upgrade: Gun
+// Obstacle: Rock
+// Enemy: Skeleton
+// Enemy: Goblin
+// Enemy: Bat
+// Player's bullet
+// Player's knife
+// Minecart (player)
+// Game constants
+var GAME_W = 2048;
+var GAME_H = 2732;
+var TRACK_LEFT = 300;
+var TRACK_RIGHT = GAME_W - 300;
+var PLAYER_Y = GAME_H - 350;
+// Game state
+var minecart = null;
+var bullets = [];
+var enemies = [];
+var obstacles = [];
+var upgrades = [];
+var dragNode = null;
+var lastTouchX = 0;
+var lastTouchY = 0;
+var scoreTxt = null;
+var lastScore = 0;
+var gameOver = false;
+var spawnTimer = 0;
+var obstacleTimer = 0;
+var upgradeTimer = 0;
+var difficulty = 1;
+var knifeHitEnemies = [];
+var lastKnifeSwingTick = -100;
+// Score display
+scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Create player
+minecart = new Minecart();
+game.addChild(minecart);
+minecart.x = GAME_W / 2;
+minecart.y = PLAYER_Y;
+// Touch controls: drag minecart horizontally
+game.down = function (x, y, obj) {
+ if (gameOver) return;
+ dragNode = minecart;
+ lastTouchX = x;
+ lastTouchY = y;
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+game.move = function (x, y, obj) {
+ if (gameOver) return;
+ if (dragNode === minecart) {
+ // Only allow horizontal movement within track
+ var nx = x;
+ if (nx < TRACK_LEFT) nx = TRACK_LEFT;
+ if (nx > TRACK_RIGHT) nx = TRACK_RIGHT;
+ minecart.x = nx;
+ }
+};
+// Tap to attack (shoot or knife)
+game.tap = function (x, y, obj) {
+ if (gameOver) return;
+ if (minecart.weapon === 'gun') {
+ if (minecart.attackCooldown <= 0) {
+ fireBullet();
+ minecart.attackCooldown = 12 - minecart.weaponLevel * 2; // Faster with upgrades
+ if (minecart.attackCooldown < 4) minecart.attackCooldown = 4;
+ }
+ } else if (minecart.weapon === 'knife') {
+ if (LK.ticks - lastKnifeSwingTick > 18) {
+ minecart.swingKnife();
+ lastKnifeSwingTick = LK.ticks;
+ }
+ }
+};
+// Fire bullet(s)
+function fireBullet() {
+ var spread = minecart.weaponLevel;
+ for (var i = 0; i < spread; ++i) {
+ var b = new Bullet();
+ b.x = minecart.x + (i - (spread - 1) / 2) * 40;
+ b.y = minecart.y - minecart.height / 2 - 10;
+ bullets.push(b);
+ game.addChild(b);
+ }
+}
+// Main update loop
+game.update = function () {
+ if (gameOver) return;
+ // Difficulty scaling
+ if (LK.ticks % 300 === 0 && difficulty < 10) {
+ difficulty += 1;
+ }
+ // Attack cooldown
+ if (minecart.attackCooldown > 0) minecart.attackCooldown -= 1;
+ // Invincibility timer
+ if (minecart.invincible) {
+ minecart.invincibleTimer -= 1;
+ if (minecart.invincibleTimer <= 0) {
+ minecart.invincible = false;
+ }
+ }
+ // Bullets update
+ for (var i = bullets.length - 1; i >= 0; --i) {
+ var b = bullets[i];
+ b.update();
+ if (b.y < -50) {
+ b.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
+ // Bullet hits enemy
+ for (var j = enemies.length - 1; j >= 0; --j) {
+ var e = enemies[j];
+ if (b.intersects(e)) {
+ e.hp -= 1;
+ b.destroy();
+ bullets.splice(i, 1);
+ if (e.hp <= 0) {
+ addScore(e.scoreValue);
+ e.destroy();
+ enemies.splice(j, 1);
+ }
+ break;
+ }
+ }
+ }
+ // Enemies update
+ for (var i = enemies.length - 1; i >= 0; --i) {
+ var e = enemies[i];
+ e.update();
+ if (e.y > GAME_H + 100) {
+ e.destroy();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Enemy hits minecart
+ if (!minecart.invincible && e.intersects(minecart)) {
+ minecart.flash();
+ LK.effects.flashScreen(0xff0000, 600);
+ // End game
+ LK.showGameOver();
+ gameOver = true;
+ return;
+ }
+ // Enemy hit by knife
+ if (minecart.weapon === 'knife' && minecart.knife && minecart.knife.visible && !knifeHitEnemies.includes(e)) {
+ // Knife is in swing, check collision
+ var knifeGlobal = minecart.toGlobal(minecart.knife.position);
+ var knifeRect = new Rectangle(knifeGlobal.x - 30, knifeGlobal.y - 12, 60, 24);
+ var enemyRect = new Rectangle(e.x - e.width / 2, e.y - e.height / 2, e.width, e.height);
+ if (rectsIntersect(knifeRect, enemyRect)) {
+ e.hp -= 1;
+ knifeHitEnemies.push(e);
+ if (e.hp <= 0) {
+ addScore(e.scoreValue);
+ e.destroy();
+ enemies.splice(i, 1);
+ }
+ }
+ }
+ }
+ // Reset knife hit list if knife not swinging
+ if (!(minecart.knife && minecart.knife.visible)) {
+ knifeHitEnemies = [];
+ }
+ // Obstacles update
+ for (var i = obstacles.length - 1; i >= 0; --i) {
+ var o = obstacles[i];
+ o.update();
+ if (o.y > GAME_H + 100) {
+ o.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ // Obstacle hits minecart
+ if (!minecart.invincible && o.intersects(minecart)) {
+ minecart.flash();
+ LK.effects.flashScreen(0xff0000, 600);
+ LK.showGameOver();
+ gameOver = true;
+ return;
+ }
+ }
+ // Upgrades update
+ for (var i = upgrades.length - 1; i >= 0; --i) {
+ var u = upgrades[i];
+ u.update();
+ if (u.y > GAME_H + 100) {
+ u.destroy();
+ upgrades.splice(i, 1);
+ continue;
+ }
+ // Pickup
+ if (u.intersects(minecart)) {
+ if (u.kind === 'gun') {
+ minecart.setWeapon('gun');
+ minecart.upgradeWeapon();
+ } else {
+ minecart.setWeapon('knife');
+ minecart.upgradeWeapon();
+ }
+ u.destroy();
+ upgrades.splice(i, 1);
+ }
+ }
+ // Spawning enemies
+ spawnTimer -= 1;
+ if (spawnTimer <= 0) {
+ spawnEnemy();
+ spawnTimer = Math.max(24, 60 - difficulty * 4 - Math.floor(Math.random() * 10));
+ }
+ // Spawning obstacles
+ obstacleTimer -= 1;
+ if (obstacleTimer <= 0) {
+ if (Math.random() < 0.5 + difficulty * 0.04) {
+ spawnObstacle();
+ }
+ obstacleTimer = 90 + Math.floor(Math.random() * 60) - difficulty * 4;
+ if (obstacleTimer < 30) obstacleTimer = 30;
+ }
+ // Spawning upgrades
+ upgradeTimer -= 1;
+ if (upgradeTimer <= 0) {
+ if (Math.random() < 0.18) {
+ spawnUpgrade();
+ }
+ upgradeTimer = 600 + Math.floor(Math.random() * 300);
+ }
+ // Update score display
+ if (LK.getScore() !== lastScore) {
+ scoreTxt.setText(LK.getScore());
+ lastScore = LK.getScore();
+ }
+};
+// Spawn enemy
+function spawnEnemy() {
+ var enemyType = Math.random();
+ var e = null;
+ var x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160);
+ if (enemyType < 0.33) {
+ e = new Bat();
+ } else if (enemyType < 0.66) {
+ e = new Goblin();
+ } else {
+ e = new Skeleton();
+ }
+ e.x = x;
+ e.y = -80;
+ enemies.push(e);
+ game.addChild(e);
+}
+// Spawn obstacle
+function spawnObstacle() {
+ var o = new Obstacle();
+ o.x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160);
+ o.y = -60;
+ obstacles.push(o);
+ game.addChild(o);
+}
+// Spawn upgrade
+function spawnUpgrade() {
+ var u = new Upgrade();
+ u.x = TRACK_LEFT + 80 + Math.random() * (TRACK_RIGHT - TRACK_LEFT - 160);
+ u.y = -60;
+ upgrades.push(u);
+ game.addChild(u);
+}
+// Add score
+function addScore(val) {
+ LK.setScore(LK.getScore() + val);
+}
+// Rectangle intersection helper
+function rectsIntersect(r1, r2) {
+ return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x || r2.y > r1.y + r1.height || r2.y + r2.height < r1.y);
+}
+// Touch to attack (simulate tap on mobile)
+game.down = function (origDown) {
+ return function (x, y, obj) {
+ if (origDown) origDown(x, y, obj);
+ game.tap(x, y, obj);
+ };
+}(game.down);
+// Reset game state on game over
+LK.on('gameover', function () {
+ gameOver = true;
+});
+// Reset game state on new game
+LK.on('newgame', function () {
+ gameOver = false;
+ LK.setScore(0);
+ scoreTxt.setText('0');
+ // Remove all objects
+ for (var i = 0; i < bullets.length; ++i) bullets[i].destroy();
+ for (var i = 0; i < enemies.length; ++i) enemies[i].destroy();
+ for (var i = 0; i < obstacles.length; ++i) obstacles[i].destroy();
+ for (var i = 0; i < upgrades.length; ++i) upgrades[i].destroy();
+ bullets = [];
+ enemies = [];
+ obstacles = [];
+ upgrades = [];
+ minecart.x = GAME_W / 2;
+ minecart.y = PLAYER_Y;
+ minecart.weapon = 'gun';
+ minecart.weaponLevel = 1;
+ minecart.invincible = false;
+ minecart.invincibleTimer = 0;
+ minecart.attackCooldown = 0;
+ minecart.knifeSwinging = false;
+ minecart.setWeapon('gun');
+ difficulty = 1;
+ spawnTimer = 0;
+ obstacleTimer = 0;
+ upgradeTimer = 0;
+ knifeHitEnemies = [];
+ lastKnifeSwingTick = -100;
+});
+// Initial state
+spawnTimer = 0;
+obstacleTimer = 60;
+upgradeTimer = 600;
+difficulty = 1;
+gameOver = false;
+LK.setScore(0);
+scoreTxt.setText('0');
\ No newline at end of file
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Minecart Mayhem: Armed Run" and with the description "Survive a wild minecart ride by battling multiple enemy types with guns and knives, dodging obstacles, and collecting upgrades for a high-score chase.". No text on banner!
A skeleton with 3 legs and a creepy face and red eyes. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A silver bullet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a maze . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Man with bag on head and red eyes. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A man with a bag over his head and red eyes. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Knife. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Rock. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Zombie. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A knife with purple and golden around it. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Man with bag on head with cross on it. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Skeleton player model. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat