Code edit (1 edits merged)
Please save this source code
User prompt
Monster Mayhem: Punch or Perish
Initial prompt
Make a game about monsters in the middle of the screen getting bigger and you have to punch them to death before they cover the screen. Make it very very very very very bloody. If they cover the screen add a jumpscare
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var BloodParticle = Container.expand(function () { var self = Container.call(this); var bloodGraphics = self.attachAsset('blood', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.2 + Math.random() * 0.6, scaleY: 0.2 + Math.random() * 0.6, alpha: 0.7 + Math.random() * 0.3 }); // Random velocity self.vx = (Math.random() - 0.5) * 40; self.vy = (Math.random() - 0.5) * 40; self.lifetime = 1000 + Math.random() * 2000; self.createdAt = Date.now(); self.update = function () { self.x += self.vx; self.y += self.vy; // Slow down self.vx *= 0.95; self.vy *= 0.95; // Fade out based on lifetime var age = Date.now() - self.createdAt; if (age > self.lifetime) { self.destroy(); var index = bloodParticles.indexOf(self); if (index !== -1) { bloodParticles.splice(index, 1); } } else if (age > self.lifetime * 0.7) { bloodGraphics.alpha = 1 - (age - self.lifetime * 0.7) / (self.lifetime * 0.3); } }; return self; }); var Monster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); self.health = 5; self.growthRate = 0.004; self.maxScale = 5; self.isDying = false; self.baseScale = 0.5; // Apply a random tint to make monsters look different var tints = [0x4A2B0F, 0x7E3500, 0x5D4037, 0x330000, 0x2D0C01]; monsterGraphics.tint = tints[Math.floor(Math.random() * tints.length)]; self.update = function () { if (self.isDying) { return; } // Grow the monster if (monsterGraphics.scale.x < self.maxScale) { monsterGraphics.scale.x += self.growthRate; monsterGraphics.scale.y += self.growthRate; } else { // Monster has grown too big - game over! gameOver(); } }; self.punch = function () { if (self.isDying) { return; } self.health--; // Temporarily shrink the monster when punched var currentScale = monsterGraphics.scale.x; tween(monsterGraphics.scale, { x: currentScale * 0.8, y: currentScale * 0.8 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { if (!self.isDying) { tween(monsterGraphics.scale, { x: currentScale, y: currentScale }, { duration: 300, easing: tween.easeOut }); } } }); // Flash red tween(monsterGraphics, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { if (!self.isDying) { tween(monsterGraphics, { tint: monsterGraphics.tint }, { duration: 200 }); } } }); // Add blood spray createBloodSpray(self.x, self.y, 8); // Play punch sound LK.getSound('punch').play(); // Check if monster is dead if (self.health <= 0) { self.die(); } }; self.die = function () { self.isDying = true; LK.getSound('monsterDeath').play(); // Create a big blood explosion createBloodSpray(self.x, self.y, 20); // Shrink and fade out tween(monsterGraphics.scale, { x: 0.1, y: 0.1 }, { duration: 500, easing: tween.easeIn }); tween(monsterGraphics, { alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); monstersKilled++; updateScore(); // Spawn next monster after delay if (monsterSpawnTimeout) { LK.clearTimeout(monsterSpawnTimeout); } monsterSpawnTimeout = LK.setTimeout(spawnMonster, 1000); } }); }; self.down = function (x, y, obj) { self.punch(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ /* Supported Types: 1. Shape: - Simple geometric figures with these properties: * width: (required) pixel width of the shape. * height: (required) pixel height of the shape. * color: (required) color of the shape. * shape: (required) type of shape. Valid options: 'box', 'ellipse'. 2. Image: - Imported images with these properties: * width: (required) pixel resolution width. * height: (required) pixel resolution height. * id: (required) identifier for the image. * flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip). * flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip). * orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values: - 0: No rotation. - 1: Rotate 90 degrees. - 2: Rotate 180 degrees. - 3: Rotate 270 degrees. Note: Width and height remain unchanged upon flipping. 3. Sound: - Sound effects with these properties: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. 4. Music: - In contract to sound effects, only one music can be played at a time - Music is using the same API to initilize just like sound. - Music loops by default - Music with these config options: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. * start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping * end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping */ // Game variables var monster = null; var bloodParticles = []; var monstersKilled = 0; var monsterSpawnTimeout = null; var difficultyLevel = 1; var isGameActive = true; var lastMonsterKillTime = 0; // UI elements var scoreTxt = new Text2('0', { size: 100, fill: 0xFF0000 }); var highScoreTxt = new Text2('Best: 0', { size: 60, fill: 0xFFFFFF }); var waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); function initializeGame() { // Set up background game.setBackgroundColor(0x110000); // Set up score display scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 50; LK.gui.top.addChild(scoreTxt); // Set up high score display highScoreTxt.anchor.set(0.5, 0); highScoreTxt.y = 150; LK.gui.top.addChild(highScoreTxt); updateHighScore(); // Set up wave display waveTxt.anchor.set(0.5, 0); waveTxt.y = 220; LK.gui.top.addChild(waveTxt); // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } }); // Spawn the first monster spawnMonster(); } function spawnMonster() { if (!isGameActive) { return; } // Create new monster monster = new Monster(); monster.x = 2048 / 2; monster.y = 2732 / 2; // Increase difficulty based on monsters killed if (monstersKilled > 0) { // Every 5 monsters, increase difficulty level if (monstersKilled % 5 === 0) { difficultyLevel++; waveTxt.setText('Wave: ' + difficultyLevel); LK.effects.flashScreen(0x330000, 500); } // Adjust monster properties based on difficulty monster.health = 5 + Math.min(10, difficultyLevel); monster.growthRate = 0.004 + difficultyLevel * 0.001; monster.baseScale = 0.5 + difficultyLevel * 0.05; // Update monster's initial appearance var monsterGraphics = monster.children[0]; monsterGraphics.scale.x = monster.baseScale; monsterGraphics.scale.y = monster.baseScale; } // Add monster to game game.addChild(monster); LK.getSound('monsterGrowl').play(); } function createBloodSpray(x, y, count) { for (var i = 0; i < count; i++) { var blood = new BloodParticle(); blood.x = x; blood.y = y; bloodParticles.push(blood); game.addChild(blood); } } function updateScore() { scoreTxt.setText(monstersKilled.toString()); // Check if high score needs updating if (monstersKilled > storage.highScore) { storage.highScore = monstersKilled; updateHighScore(); } lastMonsterKillTime = Date.now(); } function updateHighScore() { highScoreTxt.setText('Best: ' + storage.highScore); } function gameOver() { if (!isGameActive) { return; } isGameActive = false; // Play game over sound LK.getSound('gameOver').play(); // Fade music out LK.playMusic('bgMusic', { fade: { start: 0.3, end: 0, duration: 500 } }); // Flash screen red LK.effects.flashScreen(0xFF0000, 800); // Show game over screen LK.setTimeout(function () { LK.showGameOver(); }, 800); } // Initialize game on startup initializeGame(); // Event handling game.down = function (x, y, obj) { // This handles general taps on game area (not on specific monsters) // Not needed for now as monsters have their own down handler }; // Game update loop game.update = function () { // Update all blood particles for (var i = bloodParticles.length - 1; i >= 0; i--) { // BloodParticle.update() handles its own removal from the array if needed // We don't need to do anything here } // Check if we should increase difficulty over time // If a monster hasn't been killed in a while, make it grow faster if (monster && lastMonsterKillTime > 0) { var timeSinceLastKill = Date.now() - lastMonsterKillTime; if (timeSinceLastKill > 5000) { // Gradually increase growth rate if player is taking too long monster.growthRate *= 1.001; } } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,348 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var BloodParticle = Container.expand(function () {
+ var self = Container.call(this);
+ var bloodGraphics = self.attachAsset('blood', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.2 + Math.random() * 0.6,
+ scaleY: 0.2 + Math.random() * 0.6,
+ alpha: 0.7 + Math.random() * 0.3
+ });
+ // Random velocity
+ self.vx = (Math.random() - 0.5) * 40;
+ self.vy = (Math.random() - 0.5) * 40;
+ self.lifetime = 1000 + Math.random() * 2000;
+ self.createdAt = Date.now();
+ self.update = function () {
+ self.x += self.vx;
+ self.y += self.vy;
+ // Slow down
+ self.vx *= 0.95;
+ self.vy *= 0.95;
+ // Fade out based on lifetime
+ var age = Date.now() - self.createdAt;
+ if (age > self.lifetime) {
+ self.destroy();
+ var index = bloodParticles.indexOf(self);
+ if (index !== -1) {
+ bloodParticles.splice(index, 1);
+ }
+ } else if (age > self.lifetime * 0.7) {
+ bloodGraphics.alpha = 1 - (age - self.lifetime * 0.7) / (self.lifetime * 0.3);
+ }
+ };
+ return self;
+});
+var Monster = Container.expand(function () {
+ var self = Container.call(this);
+ var monsterGraphics = self.attachAsset('monster', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.5,
+ scaleY: 0.5
+ });
+ self.health = 5;
+ self.growthRate = 0.004;
+ self.maxScale = 5;
+ self.isDying = false;
+ self.baseScale = 0.5;
+ // Apply a random tint to make monsters look different
+ var tints = [0x4A2B0F, 0x7E3500, 0x5D4037, 0x330000, 0x2D0C01];
+ monsterGraphics.tint = tints[Math.floor(Math.random() * tints.length)];
+ self.update = function () {
+ if (self.isDying) {
+ return;
+ }
+ // Grow the monster
+ if (monsterGraphics.scale.x < self.maxScale) {
+ monsterGraphics.scale.x += self.growthRate;
+ monsterGraphics.scale.y += self.growthRate;
+ } else {
+ // Monster has grown too big - game over!
+ gameOver();
+ }
+ };
+ self.punch = function () {
+ if (self.isDying) {
+ return;
+ }
+ self.health--;
+ // Temporarily shrink the monster when punched
+ var currentScale = monsterGraphics.scale.x;
+ tween(monsterGraphics.scale, {
+ x: currentScale * 0.8,
+ y: currentScale * 0.8
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ if (!self.isDying) {
+ tween(monsterGraphics.scale, {
+ x: currentScale,
+ y: currentScale
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
+ }
+ });
+ // Flash red
+ tween(monsterGraphics, {
+ tint: 0xFF0000
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ if (!self.isDying) {
+ tween(monsterGraphics, {
+ tint: monsterGraphics.tint
+ }, {
+ duration: 200
+ });
+ }
+ }
+ });
+ // Add blood spray
+ createBloodSpray(self.x, self.y, 8);
+ // Play punch sound
+ LK.getSound('punch').play();
+ // Check if monster is dead
+ if (self.health <= 0) {
+ self.die();
+ }
+ };
+ self.die = function () {
+ self.isDying = true;
+ LK.getSound('monsterDeath').play();
+ // Create a big blood explosion
+ createBloodSpray(self.x, self.y, 20);
+ // Shrink and fade out
+ tween(monsterGraphics.scale, {
+ x: 0.1,
+ y: 0.1
+ }, {
+ duration: 500,
+ easing: tween.easeIn
+ });
+ tween(monsterGraphics, {
+ alpha: 0
+ }, {
+ duration: 500,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ self.destroy();
+ monstersKilled++;
+ updateScore();
+ // Spawn next monster after delay
+ if (monsterSpawnTimeout) {
+ LK.clearTimeout(monsterSpawnTimeout);
+ }
+ monsterSpawnTimeout = LK.setTimeout(spawnMonster, 1000);
+ }
+ });
+ };
+ self.down = function (x, y, obj) {
+ self.punch();
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+/*
+Supported Types:
+1. Shape:
+ - Simple geometric figures with these properties:
+ * width: (required) pixel width of the shape.
+ * height: (required) pixel height of the shape.
+ * color: (required) color of the shape.
+ * shape: (required) type of shape. Valid options: 'box', 'ellipse'.
+2. Image:
+ - Imported images with these properties:
+ * width: (required) pixel resolution width.
+ * height: (required) pixel resolution height.
+ * id: (required) identifier for the image.
+ * flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip).
+ * flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip).
+ * orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values:
+ - 0: No rotation.
+ - 1: Rotate 90 degrees.
+ - 2: Rotate 180 degrees.
+ - 3: Rotate 270 degrees.
+ Note: Width and height remain unchanged upon flipping.
+3. Sound:
+ - Sound effects with these properties:
+ * id: (required) identifier for the sound.
+ * volume: (optional) custom volume. Valid values are a float from 0 to 1.
+4. Music:
+- In contract to sound effects, only one music can be played at a time
+- Music is using the same API to initilize just like sound.
+- Music loops by default
+- Music with these config options:
+ * id: (required) identifier for the sound.
+ * volume: (optional) custom volume. Valid values are a float from 0 to 1.
+ * start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping
+ * end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping
+*/
+// Game variables
+var monster = null;
+var bloodParticles = [];
+var monstersKilled = 0;
+var monsterSpawnTimeout = null;
+var difficultyLevel = 1;
+var isGameActive = true;
+var lastMonsterKillTime = 0;
+// UI elements
+var scoreTxt = new Text2('0', {
+ size: 100,
+ fill: 0xFF0000
+});
+var highScoreTxt = new Text2('Best: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+var waveTxt = new Text2('Wave: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+function initializeGame() {
+ // Set up background
+ game.setBackgroundColor(0x110000);
+ // Set up score display
+ scoreTxt.anchor.set(0.5, 0);
+ scoreTxt.y = 50;
+ LK.gui.top.addChild(scoreTxt);
+ // Set up high score display
+ highScoreTxt.anchor.set(0.5, 0);
+ highScoreTxt.y = 150;
+ LK.gui.top.addChild(highScoreTxt);
+ updateHighScore();
+ // Set up wave display
+ waveTxt.anchor.set(0.5, 0);
+ waveTxt.y = 220;
+ LK.gui.top.addChild(waveTxt);
+ // Start background music
+ LK.playMusic('bgMusic', {
+ fade: {
+ start: 0,
+ end: 0.3,
+ duration: 1000
+ }
+ });
+ // Spawn the first monster
+ spawnMonster();
+}
+function spawnMonster() {
+ if (!isGameActive) {
+ return;
+ }
+ // Create new monster
+ monster = new Monster();
+ monster.x = 2048 / 2;
+ monster.y = 2732 / 2;
+ // Increase difficulty based on monsters killed
+ if (monstersKilled > 0) {
+ // Every 5 monsters, increase difficulty level
+ if (monstersKilled % 5 === 0) {
+ difficultyLevel++;
+ waveTxt.setText('Wave: ' + difficultyLevel);
+ LK.effects.flashScreen(0x330000, 500);
+ }
+ // Adjust monster properties based on difficulty
+ monster.health = 5 + Math.min(10, difficultyLevel);
+ monster.growthRate = 0.004 + difficultyLevel * 0.001;
+ monster.baseScale = 0.5 + difficultyLevel * 0.05;
+ // Update monster's initial appearance
+ var monsterGraphics = monster.children[0];
+ monsterGraphics.scale.x = monster.baseScale;
+ monsterGraphics.scale.y = monster.baseScale;
+ }
+ // Add monster to game
+ game.addChild(monster);
+ LK.getSound('monsterGrowl').play();
+}
+function createBloodSpray(x, y, count) {
+ for (var i = 0; i < count; i++) {
+ var blood = new BloodParticle();
+ blood.x = x;
+ blood.y = y;
+ bloodParticles.push(blood);
+ game.addChild(blood);
+ }
+}
+function updateScore() {
+ scoreTxt.setText(monstersKilled.toString());
+ // Check if high score needs updating
+ if (monstersKilled > storage.highScore) {
+ storage.highScore = monstersKilled;
+ updateHighScore();
+ }
+ lastMonsterKillTime = Date.now();
+}
+function updateHighScore() {
+ highScoreTxt.setText('Best: ' + storage.highScore);
+}
+function gameOver() {
+ if (!isGameActive) {
+ return;
+ }
+ isGameActive = false;
+ // Play game over sound
+ LK.getSound('gameOver').play();
+ // Fade music out
+ LK.playMusic('bgMusic', {
+ fade: {
+ start: 0.3,
+ end: 0,
+ duration: 500
+ }
+ });
+ // Flash screen red
+ LK.effects.flashScreen(0xFF0000, 800);
+ // Show game over screen
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 800);
+}
+// Initialize game on startup
+initializeGame();
+// Event handling
+game.down = function (x, y, obj) {
+ // This handles general taps on game area (not on specific monsters)
+ // Not needed for now as monsters have their own down handler
+};
+// Game update loop
+game.update = function () {
+ // Update all blood particles
+ for (var i = bloodParticles.length - 1; i >= 0; i--) {
+ // BloodParticle.update() handles its own removal from the array if needed
+ // We don't need to do anything here
+ }
+ // Check if we should increase difficulty over time
+ // If a monster hasn't been killed in a while, make it grow faster
+ if (monster && lastMonsterKillTime > 0) {
+ var timeSinceLastKill = Date.now() - lastMonsterKillTime;
+ if (timeSinceLastKill > 5000) {
+ // Gradually increase growth rate if player is taking too long
+ monster.growthRate *= 1.001;
+ }
+ }
+};
\ No newline at end of file