User prompt
increase the cooldown of regular attack to 1.2 secx
User prompt
make a health potion and spawn it randomly
User prompt
make a cooldown for 1 sec to reagular attacks
User prompt
every attack deals less damage
User prompt
Please fix the bug: 'MainMenu is not defined' in or related to this line: 'var mainMenu = new MainMenu();' Line Number: 33
User prompt
Please fix the bug: 'MainMenu is not defined' in or related to this line: 'var mainMenu = new MainMenu();' Line Number: 33
User prompt
make a main menu for the game
User prompt
reduce it to 1.2 secs
User prompt
make the immobility time 1.5 secs
User prompt
if a fighter is hit with a speacial attack he cant move for 1 second
User prompt
Place the counter above the special attack button that shows how much time is left until the next special attack.
User prompt
make buttons bigger
User prompt
ıncrease the cooldown to 6 secs
User prompt
make a cooldown for 3 seconds for the speccial attack
User prompt
significantly reduce the range of regular attacks
User prompt
reduce the range of regular attacks
User prompt
make the knockback of special attack a lot more
User prompt
remove the number healthbars
User prompt
make the knockback a little stronger
User prompt
add a knockback when a fighter is hit
User prompt
move it down more
User prompt
again
User prompt
move the ground txture down
User prompt
make a throwable class
User prompt
make the player cant hold the jump button
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Arena class: handles the ground and background var Arena = Container.expand(function () { var self = Container.call(this); // Attach background asset self.bg = self.attachAsset('arena_bg', { anchorX: 0.5, anchorY: 1.0, x: 2048 / 2, y: 2732 }); // Ground Y for fighters self.groundY = 2100; return self; }); // Attack class: represents a punch/kick or special move var Attack = Container.expand(function (isSpecial) { var self = Container.call(this); self.isSpecial = isSpecial === true; self.owner = null; self.damage = self.isSpecial ? 22 : 4; self.lifetime = self.isSpecial ? 30 : 12; self.frame = 0; // Attach asset self.sprite = self.attachAsset(self.isSpecial ? 'special_attack' : 'attack', { anchorX: 0.5, anchorY: 0.5 }); // Explosion effect: scale up and fade in, then shrink to normal self.sprite.scaleX = self.sprite.scaleY = 0.2; self.sprite.alpha = 0.2; // Explosion effect: scale up and fade in, then shrink to normal using tween plugin tween(self.sprite, { scaleX: 1.2, scaleY: 1.2, alpha: 1 }, { duration: 700, onFinish: function onFinish() { tween(self.sprite, { scaleX: 1, scaleY: 1 }, { duration: 700 }); } }); // Set owner after creation self.setOwner = function (owner) { self.owner = owner; }; // Update per frame self.update = function () { self.frame++; if (self.frame > self.lifetime) { self.destroy(); } }; return self; }); var Fighter = Container.expand(function () { var self = Container.call(this); // Immobility state for special attack hit self.immobile = false; self.immobileTimer = 0; // Regular attack cooldown variables self.attackCooldown = 0; // frames left until next attack allowed self.attackCooldownDuration = 72; // 1.2 seconds at 60fps // Jump cooldown variables self.jumpCooldown = 0; // frames left until next jump allowed self.jumpCooldownDuration = 18; // 0.3s at 60fps // Attach fighter asset (placeholder box, can be replaced with unique fighter art) self.sprite = self.attachAsset('fighter', { anchorX: 0.5, anchorY: 1.0 }); // Fighter properties self.maxHealth = 100; self.health = 100; self.isFacingRight = true; self.isJumping = false; self.isAttacking = false; self.isSpecialReady = true; self.specialCooldown = 360; // 6 seconds at 60fps self.specialTimer = 0; self.moveSpeed = 18; self.jumpPower = -38; self.gravity = 3.2; self.velY = 0; self.groundY = 2100; // Default ground Y, will be set by Arena // Health bar self.healthBar = new Container(); // Add outline behind healthbar background self.healthBarOutline = self.healthBar.addChild(LK.getAsset('healthbar_bg', { anchorX: 0, anchorY: 0.5, width: 308, // 4px border on each side (300+8) height: 58, // 4px border on each side (50+8) color: 0xffffff // white outline })); self.healthBarBg = self.healthBar.addChild(LK.getAsset('healthbar_bg', { anchorX: 0, anchorY: 0.5 })); self.healthBarFg = self.healthBar.addChild(LK.getAsset('healthbar_fg', { anchorX: 0, anchorY: 0.5 })); self.healthBar.y = -220; self.addChild(self.healthBar); // Update health bar self.updateHealthBar = function () { var ratio = Math.max(0, self.health / self.maxHealth); self.healthBarFg.width = 300 * ratio; }; // Take damage self.takeDamage = function (amount, knockbackDir, knockbackStrength) { // If jumping, do not take damage if (self.isJumping) return; self.health = Math.max(0, self.health - amount); self.updateHealthBar(); // If hit by a special attack, become immobile for 1.2 seconds (72 frames) if (amount >= 35) { self.immobile = true; self.immobileTimer = 72; } // Knockback: Only if not jumping and knockbackDir is provided if (typeof knockbackDir !== "undefined" && typeof knockbackStrength !== "undefined") { // Apply knockback as a velocity on X if (!self.knockbackVelX) self.knockbackVelX = 0; self.knockbackVelX = knockbackStrength * (knockbackDir > 0 ? 1 : -1); self.knockbackFrames = 12; // frames of knockback } }; // Attack self.attack = function () { if (self.isAttacking) return; if (self.attackCooldown > 0) return; self.isAttacking = true; self.attackCooldown = self.attackCooldownDuration; var atk = new Attack(false); // Significantly reduced range for regular attacks atk.x = self.x + (self.isFacingRight ? 30 : -30); atk.y = self.y - 180; atk.setOwner(self); self.parent.addChild(atk); attacks.push(atk); LK.setTimeout(function () { self.isAttacking = false; }, 300); }; // Special move self.special = function () { if (!self.isSpecialReady) return; self.isSpecialReady = false; self.specialTimer = self.specialCooldown; var atk = new Attack(true); atk.x = self.x + (self.isFacingRight ? 180 : -180); atk.y = self.y - 180; atk.setOwner(self); self.parent.addChild(atk); attacks.push(atk); }; // Jump self.jump = function () { if (self.isJumping) return; if (self.jumpCooldown > 0) return; self.isJumping = true; self.velY = self.jumpPower; self.jumpCooldown = self.jumpCooldownDuration; }; // Update per frame self.update = function () { // Immobility timer if (self.immobile) { self.immobileTimer--; if (self.immobileTimer <= 0) { self.immobile = false; self.immobileTimer = 0; } } // Special cooldown if (!self.isSpecialReady) { self.specialTimer--; if (self.specialTimer <= 0) { self.isSpecialReady = true; } } // Regular attack cooldown if (self.attackCooldown > 0) { self.attackCooldown--; } // Jump cooldown if (self.jumpCooldown > 0) { self.jumpCooldown--; } // Jump physics if (self.isJumping) { self.y += self.velY; self.velY += self.gravity; if (self.y >= self.groundY) { self.y = self.groundY; self.isJumping = false; self.velY = 0; } } // Knockback physics (applies even if not jumping) if (self.knockbackFrames && self.knockbackFrames > 0) { // Clamp to arena bounds var minX = 120, maxX = 2048 - 120; self.x += self.knockbackVelX || 0; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; // Dampen knockback self.knockbackVelX *= 0.7; self.knockbackFrames--; if (self.knockbackFrames <= 0) { self.knockbackVelX = 0; } } }; // Flip sprite self.setFacing = function (right) { self.isFacingRight = right; self.sprite.scaleX = right ? 1 : -1; }; // Initialize health bar self.updateHealthBar(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Arena setup --- //Note game dimensions are 2048x2732 //Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property. var arena = new Arena(); arena.x = 0; arena.y = 0; game.addChild(arena); // --- Fixed ground platform (visual) --- var groundHeight = 60; var groundTileWidth = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }).width; var groundY = arena.groundY - 100; // Move ground even further down by reducing the offset (was -300) var groundTiles = []; var numGroundTiles = Math.ceil(2048 / groundTileWidth); // Only enough to fill the screen for (var i = 0; i < numGroundTiles; i++) { var groundTile = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: i * groundTileWidth, y: groundY }); game.addChild(groundTile); groundTiles.push(groundTile); } // No infinite scrolling, ground is fixed and does not move // --- Fighters --- var fighter1 = new Fighter(); fighter1.lastJumpPressed = false; var fighter2 = new Fighter(); // Place fighters on opposite sides fighter1.x = 600; fighter1.y = arena.groundY; fighter1.setFacing(true); fighter2.x = 2048 - 600; fighter2.y = arena.groundY; fighter2.setFacing(false); game.addChild(fighter1); game.addChild(fighter2); // --- Health bar GUI --- // Removed number healthbars (Text2 healthBar1 and healthBar2) // Move the box healthbars (fighter healthBar containers) to a more visible, symmetric place below the timer at the top center // Remove from fighter containers and add to GUI, position symmetrically below timer fighter1.removeChild(fighter1.healthBar); fighter2.removeChild(fighter2.healthBar); // Place both healthbars below the timer, offset horizontally from center fighter1.healthBar.x = -550; fighter1.healthBar.y = 170; fighter2.healthBar.x = 250; fighter2.healthBar.y = 170; LK.gui.top.addChild(fighter1.healthBar); LK.gui.top.addChild(fighter2.healthBar); // --- Round and timer --- var round = 1; var maxRounds = 3; var wins1 = 0; var wins2 = 0; var roundTime = 60 * 30; // 30 seconds at 60fps var roundTimer = roundTime; var timerText = new Text2('30', { size: 80, fill: "#fff" }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); // --- Touch controls (mobile-friendly) --- var leftPressed = false, rightPressed = false, atkPressed = false, jumpPressed = false, spcPressed = false; // Special attack cooldown overlay for button var spcCooldownOverlay = LK.getAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 180, color: 0x000000 }); spcCooldownOverlay.alpha = 0.5; spcCooldownOverlay.visible = false; spcCooldownOverlay.x = 2048 - 350; spcCooldownOverlay.y = 2450; game.addChild(spcCooldownOverlay); var spcCooldownText = new Text2('3', { size: 90, fill: "#fff" }); spcCooldownText.anchor.set(0.5, 0.5); spcCooldownText.x = 2048 - 350; spcCooldownText.y = 2450; spcCooldownText.visible = false; game.addChild(spcCooldownText); // Special attack cooldown counter above the special attack button var spcCooldownCounter = new Text2('', { size: 60, fill: "#fff" }); spcCooldownCounter.anchor.set(0.5, 1.0); // Place above the special button (btnSpc) spcCooldownCounter.x = 2048 - 350; spcCooldownCounter.y = 2450 - 120; spcCooldownCounter.visible = false; game.addChild(spcCooldownCounter); // Control buttons (simple rectangles for now) var btnLeft = LK.getAsset('btn_left', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 2600, scaleX: 1.8, scaleY: 1.8 }); var btnRight = LK.getAsset('btn_right', { anchorX: 0.5, anchorY: 0.5, x: 500, y: 2600, scaleX: 1.8, scaleY: 1.8 }); var btnAtk = LK.getAsset('btn_atk', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 500, y: 2600, scaleX: 1.8, scaleY: 1.8 }); var btnJump = LK.getAsset('btn_jump', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 200, y: 2600, scaleX: 1.8, scaleY: 1.8 }); var btnSpc = LK.getAsset('btn_spc', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 350, y: 2450, scaleX: 1.8, scaleY: 1.8 }); game.addChild(btnLeft); game.addChild(btnRight); game.addChild(btnAtk); game.addChild(btnJump); game.addChild(btnSpc); // Button event helpers btnLeft.down = function () { leftPressed = true; }; btnLeft.up = function () { leftPressed = false; }; btnRight.down = function () { rightPressed = true; }; btnRight.up = function () { rightPressed = false; }; btnAtk.down = function () { atkPressed = true; }; btnAtk.up = function () { atkPressed = false; }; btnJump.down = function () { jumpPressed = true; }; btnJump.up = function () { jumpPressed = false; }; btnSpc.down = function () { spcPressed = true; }; btnSpc.up = function () { spcPressed = false; }; // --- Attacks array --- var attacks = []; // --- Game update loop --- game.update = function () { // --- Timer --- if (roundTimer > 0) { roundTimer--; timerText.setText(Math.ceil(roundTimer / 60)); } // --- Ground is fixed, no update needed --- // --- Player 1 controls (left side) --- if (!fighter1.immobile) { if (leftPressed) { fighter1.x = Math.max(120, fighter1.x - fighter1.moveSpeed); fighter1.setFacing(false); } if (rightPressed) { fighter1.x = Math.min(2048 - 120, fighter1.x + fighter1.moveSpeed); fighter1.setFacing(true); } // Only trigger jump on the frame the button is pressed (rising edge) if (jumpPressed && !fighter1.lastJumpPressed) { fighter1.jump(); } if (atkPressed) { fighter1.attack(); } if (spcPressed) { if (fighter1.isSpecialReady) { fighter1.special(); } } } fighter1.lastJumpPressed = jumpPressed; // --- Special attack cooldown overlay update --- if (!fighter1.isSpecialReady) { spcCooldownOverlay.visible = true; spcCooldownText.visible = true; var secondsLeft = Math.ceil(fighter1.specialTimer / 60); spcCooldownText.setText(secondsLeft); // Show and update the counter above the special button spcCooldownCounter.visible = true; spcCooldownCounter.setText(secondsLeft + "s"); } else { spcCooldownOverlay.visible = false; spcCooldownText.visible = false; spcCooldownCounter.visible = false; } // --- AI for fighter2 (simple: move toward player, attack if close) --- if (!fighter2.immobile) { var dx = fighter1.x - fighter2.x; if (Math.abs(dx) > 180) { if (dx < 0) { fighter2.x -= fighter2.moveSpeed * 0.7; fighter2.setFacing(false); } else { fighter2.x += fighter2.moveSpeed * 0.7; fighter2.setFacing(true); } } else if (!fighter2.isAttacking && Math.random() < 0.04) { fighter2.attack(); } if (!fighter2.isJumping && Math.random() < 0.01) { fighter2.jump(); } if (fighter2.isSpecialReady && Math.random() < 0.008) { fighter2.special(); } } // --- Update fighters --- fighter1.update(); fighter2.update(); // --- Update attacks --- for (var i = attacks.length - 1; i >= 0; i--) { var atk = attacks[i]; atk.update(); // Remove if destroyed if (atk.destroyed) { attacks.splice(i, 1); continue; } // Set owner if not set if (!atk.owner) { atk.setOwner(atk.isSpecial ? atk.x < 2048 / 2 ? fighter1 : fighter2 : fighter1); } // Check collision var target = atk.owner === fighter1 ? fighter2 : fighter1; if (atk.intersects(target) && !atk.hit) { // Knockback direction: +1 if attacker is facing right, -1 if left var knockbackDir = atk.owner && atk.owner.isFacingRight ? 1 : -1; // Knockback strength: special attacks knock back a LOT more (much stronger effect) var knockbackStrength = atk.isSpecial ? 120 : 32; target.takeDamage(atk.damage, knockbackDir, knockbackStrength); atk.hit = true; atk.destroy(); // Flash on hit LK.effects.flashObject(target, 0xff0000, 200); // Show a visible attack effect at the hit location, rotated to match the attack direction var hitEffect = LK.getAsset(atk.isSpecial ? 'special_attack' : 'attack', { anchorX: 0.5, anchorY: 0.5, x: target.x, y: target.y - 200 }); // Rotate the effect to match the direction the attacker is facing if (atk.owner && atk.owner.isFacingRight === false) { hitEffect.rotation = Math.PI; // Face left } else { hitEffect.rotation = 0; // Face right (default) } game.addChild(hitEffect); // Animate the effect: scale up and fade out, then destroy hitEffect.scaleX = hitEffect.scaleY = 1.2; hitEffect.alpha = 1; tween(hitEffect, { scaleX: 2.0, scaleY: 2.0, alpha: 0 }, { duration: 350, onFinish: function onFinish() { if (hitEffect && hitEffect.destroy) hitEffect.destroy(); } }); } } // --- Health bar updates --- // Removed number healthbars update // --- Win/lose/round logic --- var roundOver = false; var winner = null; if (fighter1.health <= 0) { wins2++; roundOver = true; winner = 2; } else if (fighter2.health <= 0) { wins1++; roundOver = true; winner = 1; } else if (roundTimer <= 0) { if (fighter1.health > fighter2.health) { wins1++; winner = 1; } else if (fighter2.health > fighter1.health) { wins2++; winner = 2; } else { // Draw, no one gets a win } roundOver = true; } if (roundOver) { if (wins1 >= 2) { LK.showYouWin(); return; } else if (wins2 >= 2) { LK.showGameOver(); return; } // Next round round++; roundTimer = roundTime; fighter1.health = fighter1.maxHealth; fighter2.health = fighter2.maxHealth; fighter1.updateHealthBar(); fighter2.updateHealthBar(); fighter1.x = 600; fighter2.x = 2048 - 600; fighter1.setFacing(true); fighter2.setFacing(false); // Remove all attacks for (var j = attacks.length - 1; j >= 0; j--) { if (attacks[j].destroy) attacks[j].destroy(); } attacks = []; } };
===================================================================
--- original.js
+++ change.js
@@ -71,9 +71,9 @@
self.immobile = false;
self.immobileTimer = 0;
// Regular attack cooldown variables
self.attackCooldown = 0; // frames left until next attack allowed
- self.attackCooldownDuration = 60; // 1 second at 60fps
+ self.attackCooldownDuration = 72; // 1.2 seconds at 60fps
// Jump cooldown variables
self.jumpCooldown = 0; // frames left until next jump allowed
self.jumpCooldownDuration = 18; // 0.3s at 60fps
// Attach fighter asset (placeholder box, can be replaced with unique fighter art)
@@ -248,11 +248,11 @@
/****
* Game Code
****/
-//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
-//Note game dimensions are 2048x2732
// --- Arena setup ---
+//Note game dimensions are 2048x2732
+//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
var arena = new Arena();
arena.x = 0;
arena.y = 0;
game.addChild(arena);