/**** * Classes ****/ /****************************************************************************************** */ /************************************* ATHLETE CLASS ************************************** */ /****************************************************************************************** */ var Athlete = Container.expand(function (isPlayer) { var self = Container.call(this); self.isPlayer = isPlayer; self.isPunching = false; // Indicates if the athlete is currently punching self.isGuarding = false; // Indicates if the athlete is currently punching self.isFighting = false; self.isHit = false; self.isTouched = false; self.energy = 100; self.guardLevel = 100; self.health = 100; self.retreat = false; self.basePunchEnergy = 2; // Punch cost in energy self.baseGuardLevelDecrease = 5; self.currentPunchEnergy = 2; // Punch cost in energy self.punchCount = 0; // Initialize punch count self.lastPunchTime = 0; // Timestamp of the last punch self.lastHitTime = 0; // Timestamp of the last hit self.immunityDelayMs = 300; // Timestamp of the last hit self.isTargetOther = true; self.hasReachedTarget = true; self.lastTargetReachTime = 0; self.baseStayTimeMs = 3000; self.targetStayTimeMs = 3000; self.body = new Container(); game.addChild(self.body); var punchDistance = 60; // Define punch distance for punching animation var attackDistance = 375; self.targetX = self.targetX || 1024; // Default target X self.targetY = self.targetY || 1366; // Default target Y self.shadow = self.body.attachAsset('body', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.10, scaleY: 1.15, tint: 0x000000, alpha: 0.15 }); // Left Arm self.leftForearm = self.body.attachAsset('forearm', { anchorX: 0.5, anchorY: 0.5, x: -110, y: -125, width: 80, rotation: -Math.PI * 0.2 }); self.leftForearmShadow = self.leftForearm.attachAsset('forearm', { anchorX: 0.5, anchorY: 0.5, x: -0, y: -0, width: 80, rotation: 0, scaleX: 1.25, scaleY: 1.25, tint: 0x000000, alpha: 0.15 }); self.leftHand = self.body.attachAsset('hand', { anchorX: 0.5, anchorY: 0.5, x: -100, y: -250, width: 90, height: 180, rotation: -Math.PI * 0.05, tint: isPlayer ? 0xFFFFFF : 0x33CCFF }); self.leftHandShadow = self.leftHand.attachAsset('hand', { anchorX: 0.5, anchorY: 0.5, x: -0, y: -0, width: 90, height: 180, rotation: 0, scaleX: 1.15, scaleY: 1.15, tint: 0x000000, alpha: 0.15 }); self.leftArm = self.body.attachAsset('arm', { anchorX: 0.5, anchorY: 0, x: -120, y: -120 }); self.leftArmShadow = self.leftArm.attachAsset('arm', { anchorX: 0.5, anchorY: 0, x: -0, y: -0, scaleX: 1.25, scaleY: 1.15, tint: 0x000000, alpha: 0.15 }); // Right Arm self.rightForearm = self.body.attachAsset('forearm', { anchorX: 0.5, anchorY: 0.5, x: 110, y: -125, scaleX: -1, width: 80, rotation: Math.PI * 0.2 }); self.rightForearmShadow = self.rightForearm.attachAsset('forearm', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -0, width: 80, rotation: 0, scaleX: 1.25, scaleY: 1.25, tint: 0x000000, alpha: 0.15 }); self.rightHand = self.body.attachAsset('hand', { anchorX: 0.5, anchorY: 0.5, x: 100, y: -250, scaleX: -1, width: 90, height: 180, rotation: Math.PI * 0.05, tint: isPlayer ? 0xFFFFFF : 0x33CCFF }); self.rightHandShadow = self.rightHand.attachAsset('hand', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -0, width: 90, height: 180, rotation: 0, scaleX: 1.15, scaleY: 1.15, tint: 0x000000, alpha: 0.15 }); self.rightArm = self.body.attachAsset('arm', { anchorX: 0.5, anchorY: 0, x: 120, y: -120, scaleX: -1 }); self.rightArmShadow = self.rightArm.attachAsset('arm', { anchorX: 0.5, anchorY: 0, x: 0, y: -0, scaleX: 1.25, scaleY: 1.15, tint: 0x000000, alpha: 0.15 }); self.torso = self.body.attachAsset('body', { anchorX: 0.5, anchorY: 0.5 }); self.head = self.body.attachAsset(isPlayer ? 'head' : 'head2', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -40 }); // Player movement speed self.speed = 5; // Punch function to handle punching action self.punch = function (isLeft) { if (Date.now() - self.lastHitTime < self.immunityDelayMs) { return false; } if (!self.isPlayer) { log("AI PUNCH : isLeft=" + isLeft); } if (self.isPunching || self.isGuarding || !self.isPlayer && self.retreat) { return; } if (self.energy <= 0) { return; } // Calculate time difference since last punch var currentTime = Date.now(); var timeDiff = currentTime - self.lastPunchTime; // If punches are within 1 second, increase punch count, else reset if (timeDiff <= 1000) { self.punchCount++; } else { self.punchCount = 1; self.currentPunchEnergy = self.basePunchEnergy; } // Update last punch time self.lastPunchTime = currentTime; // Adjust currentPunchEnergy based on punchCount self.currentPunchEnergy = self.basePunchEnergy * self.punchCount; self.energy = Math.max(0, self.energy - self.currentPunchEnergy); if (!self.isPlayer && self.energy <= 0) { log("AI NO MORE ENERGY !!!"); } //log("self.punchCount => " + self.punchCount, "self.currentPunchEnergy => " + self.currentPunchEnergy); if (self.isPlayer) { playerEnergyBar.updateEnergy(self.energy); } var arm = isLeft ? self.leftArm : self.rightArm; var forearm = isLeft ? self.leftForearm : self.rightForearm; var hand = isLeft ? self.leftHand : self.rightHand; // Refactored punch animation logic using deltas method self.isPunching = true; self.setPosture(idlePosture); var deltas = { arm: { height: punchDistance, x: 15 * (isLeft ? 1 : -1), y: -punchDistance }, forearm: { height: punchDistance, x: 22 * (isLeft ? 1 : -1), y: -punchDistance * 1.5, rotation: isLeft ? 0.6 : -0.6 }, hand: { x: 80 * (isLeft ? 1 : -1), y: -punchDistance * 1.5, rotation: isLeft ? 0.4 : -0.4 }, head: { x: isLeft ? 15 : -15, width: -0.05, height: 0.05, rotation: isLeft ? 0.1 : -0.1 } }; // Apply deltas for punch animation (function (arm, forearm, hand, head) { LK.setTimeout(function () { if (!self.isPlayer) { log("AI PUNCH : applyDeltas..."); } applyDeltas(arm, deltas.arm); applyDeltas(forearm, deltas.forearm); applyDeltas(hand, deltas.hand); applyDeltas(head, deltas.head); }, 10); })(arm, forearm, hand, self.head); (function (arm, forearm, hand, head) { LK.setTimeout(function () { if (!self.isPlayer) { log("AI PUNCH : applyDeltas Reverse..."); } applyDeltas(arm, reverseDeltas(deltas.arm)); applyDeltas(forearm, reverseDeltas(deltas.forearm)); applyDeltas(hand, reverseDeltas(deltas.hand)); applyDeltas(head, reverseDeltas(deltas.head)); self.isPunching = false; }, 200); })(arm, forearm, hand, self.head); function applyDeltas(element, deltas) { for (var key in deltas) { element[key] += deltas[key]; } } function reverseDeltas(deltas) { var reversed = {}; for (var key in deltas) { reversed[key] = -deltas[key]; } return reversed; } }; // Guard function to handle guarding action self.guard = function (setGuard) { if (!self.isPlayer) { log("AI GUARD : setGuard=" + setGuard); } if (!self.isGuarding && !setGuard || self.isGuarding && setGuard) { return; } if (setGuard && self.guardLevel <= 0) { self.setPosture(idlePosture); self.isGuarding = false; return; } if (setGuard && !self.isGuarding) { self.setPosture(idlePosture); self.head.height *= 0.95; } self.isGuarding = setGuard; // Simplified adjustments for guarding using symmetrical elements var adjustPosition = function adjustPosition(elementPair, deltaX, deltaY, deltaW, deltaH, deltaR, setGuard) { elementPair.forEach(function (element, index) { var directionH = (index === 0 ? 1 : -1) * (setGuard ? 1 : -1); var directionV = setGuard ? 1 : -1; element.x += deltaX * directionH; element.y += deltaY * directionV; // Add vertical adjustment element.rotation += deltaR * directionH; element.width += deltaW * directionV; // Add width adjustment element.height += deltaH * directionV; // Add height adjustment }); }; // Pair elements for symmetrical adjustments var elementPairs = [[self.leftHand, self.rightHand], [self.leftForearm, self.rightForearm], [self.leftArm, self.rightArm]]; // Adjustments for Hands, Forearms and Arms var adjustments = [{ deltaX: 65, deltaY: 90, deltaW: 15, deltaH: 15, deltaR: 0.35 }, { deltaX: 30, deltaY: 60, deltaW: 0, deltaH: 0, deltaR: 0.2 }, { deltaX: 50, deltaY: 10, deltaW: 0, deltaH: 0, deltaR: 0.4 }]; adjustments.forEach(function (adj, index) { if (!self.isPlayer) { log("AI GUARD : adjustPositions..."); } return adjustPosition(elementPairs[index], adj.deltaX, adj.deltaY, adj.deltaW, adj.deltaH, adj.deltaR, setGuard); }); if (!setGuard) { self.setPosture(idlePosture); } }; self.handleHitImpact = function (attacker) { if (Date.now() - self.lastHitTime < self.immunityDelayMs) { return false; } self.lastHitTime = Date.now(); var damage = attacker.punchCount * (self.isGuarding ? 0.01 : 0.5); if (!self.isPlayer) { log("AI Received damage=" + damage); } self.health = Math.max(0, self.health - damage); (self.isPlayer ? playerHealthBar : opponentHealthBar).updateHealth(self.health); if (self.health <= 0) { isPlaying = false; var isVictory = self.isPlayer ? false : true; // Show victory or defeat picture before game over var pictureToShow = isVictory ? 'victoryPicture' : 'defeatPicture'; var victoryOrDefeatPicture = LK.getAsset(pictureToShow, { anchorX: 0.5, anchorY: 0.5, x: game.width / 2, y: game.height / 2 }); game.addChild(victoryOrDefeatPicture); var resultText = new Text2(isVictory ? "VICTORY!" : " DEFEAT!", { size: 200, fill: "#ffffff", weight: 1000, dropShadow: true }); resultText.anchor.set(0.5, -1.75); // Center the text horizontally LK.gui.top.addChild(resultText); // Add the text to the top-center of the screen LK.setTimeout(function () { LK.showGameOver(); }, 2000); // Show the picture and text for 2 seconds before game over } return true; }; // Update player position based on input self.update = function () { if (isPlaying) { self.mainMove(); } if (LK.ticks % 60 == 0) { log("===================== TICK ====================="); if (self.isGuarding) { //log("self.isGuarding : self.guardLevel=" + self.guardLevel); self.guardLevel = Math.max(0, self.guardLevel - self.baseGuardLevelDecrease); if (self.guardLevel <= 0) { if (!self.isPlayer) { log("AI NO MORE GUARD !!!"); } self.guard(false); } self.energy = Math.min(100, self.energy + 4); } else { self.guardLevel = Math.min(100, self.guardLevel + (self.isPunching ? self.punchCount : 2)); } self.energy = Math.min(100, self.energy + 3); if (self.isPlayer) { playerEnergyBar.updateEnergy(self.energy); playerGuardBar.updateEnergy(self.guardLevel); } // AI Guard Handling if (!self.isPlayer) { if (self.retreat && !self.isGuarding && self.guardLevel > 0) { self.guard(true); } } } // Player is idle self.miniMove(); // Update body position and rotation self.body.x = self.x; self.body.y = self.y; // Calculate angle to face the opponent var target = self.isPlayer ? opponent : player; // Determine target based on whether self is Player or Opponent var angleToOpponent = Math.atan2(target.y - self.y, target.x - self.x) + Math.PI * 0.5; self.body.rotation = angleToOpponent; }; self.thinkAboutTarget = function () { log((self.isPlayer ? "PLAYER" : "AI") + " Search target..." + self.hasReachedTarget); self.hasReachedTarget = false; var other = self.isPlayer ? opponent : player; // If Guard level < 25% or Energy < 25% retreat to closest ring corner if (self.energy < 15) { self.retreat = true; self.isTargetOther = false; if (!self.isPlayer) { log("AI RETREAT !!! self.energy=" + self.energy); } else { log("PLAYER RETREAT !!! self.energy=" + self.energy); } if (Math.random() < 0.5) { if (other.x > 1024) { self.targetX = ring.leftCorner; } else { self.targetX = ring.rightCorner; } //self.targetY = other.y > 1044 || other.targetY == ring.bottomCorner ? ring.topCorner : ring.bottomCorner; self.targetY = self.y < 1044 ? ring.topCorner : ring.bottomCorner; } else { if (other.y > 1044) { self.targetY = ring.topCorner; } else { self.targetY = ring.bottomCorner; } //self.targetX = other.x < 1024 || other.targetX == ring.leftCorner ? ring.rightCorner : ring.leftCorner; self.targetX = self.x > 1024 ? ring.rightCorner : ring.leftCorner; } } else { if (self.isPlayer) { log("PLAYER ATTACK !!! self.energy=" + self.energy); } self.retreat = false; self.isTargetOther = true; self.targetX = other.x; self.targetY = other.y; } }; self.mainMove = function () { var stayDelay = Date.now() - self.lastTargetReachTime; if (self.hasReachedTarget && stayDelay > self.targetStayTimeMs) { // Randomize next target stay time self.targetStayTimeMs = self.baseStayTimeMs + Math.random() * 1000; self.thinkAboutTarget(); } // Check if athlete has reached the target if (self.isTargetOther) { // Update target if it's the other player var other = self.isPlayer ? opponent : player; self.targetX = other.x; self.targetY = other.y; } var distanceToTarget = Math.sqrt(Math.pow(self.targetX - self.x, 2) + Math.pow(self.targetY - self.y, 2)); if (self.isPlayer) { log("PLAYER DISTANCE TO " + (self.retreat ? "RETREAT" : "FIGHT") + " " + self.targetX + "," + self.targetY + " = " + distanceToTarget); } if (self.retreat) { // Going to a corner if (distanceToTarget > 20) { // Progressively move to the target // Calculate acceleration factor based on distance to target var accelerationFactor = Math.min(1, distanceToTarget / 500); var decelerationDistance = 200; // Distance from target to start decelerating var speedModifier = distanceToTarget < decelerationDistance ? distanceToTarget / decelerationDistance : accelerationFactor; var adjustedSpeed = self.speed * speedModifier; var moveX = (self.targetX - self.x) / distanceToTarget * adjustedSpeed; var moveY = (self.targetY - self.y) / distanceToTarget * adjustedSpeed; self.x += moveX; self.y += moveY; if (self.isPlayer) { log("PLAYER STILL FAR of Retreat" + self.lastTargetReachTime + " / Moved " + moveX + "," + moveY); } } else { if (!self.hasReachedTarget) { self.hasReachedTarget = true; self.lastTargetReachTime = Date.now(); } if (self.isPlayer) { log("PLAYER REACHED corner at " + self.lastTargetReachTime); } } } else { // Going to fight if (distanceToTarget < attackDistance) { self.isInAttackRange = true; if (!self.hasReachedTarget) { self.hasReachedTarget = true; self.lastTargetReachTime = Date.now(); } if (self.isPlayer) { log("PLAYER REACHED fight at " + self.lastTargetReachTime); } if (!self.isPlayer) { self.guard(false); self.aiFight(); } } else { // Progressively move to the target var moveX = (self.targetX - self.x) / distanceToTarget * self.speed; var moveY = (self.targetY - self.y) / distanceToTarget * self.speed; self.x += moveX; self.y += moveY; if (self.isPlayer) { log((self.isPlayer ? "PLAYER" : "AI") + " STILL FAR of Fight" + self.lastTargetReachTime); } } } }; self.aiFight = function () { if (self.retreat) { return; } if (LK.ticks % 2 == 0 && !self.isFighting) { self.punch(Math.random() < 0.5); // Punch during 4-5sec LK.setTimeout(function () { self.isFighting = true; // Stop durring 2-4 sec LK.setTimeout(function () { self.isFighting = false; }, 2000 - 1000 * Math.random()); }, 5000 - 1000 * Math.random()); } }; self.miniMove = function () { if (self.isPunching || self.isGuarding || self.isHit) { return; } // Mini head movement with added randomness self.head.y = -40 + Math.sin(LK.ticks / 10 + Math.random() * 0.2) * 2; // Mini arm and forearm movement with added randomness self.leftArm.rotation += Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; self.leftForearm.rotation += Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; // Add forearm movement self.leftHand.x += Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.5; // Add hand movement self.leftHand.rotation += Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; // Add hand movement self.rightArm.rotation -= Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; self.rightForearm.rotation -= Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; // Add forearm movement self.rightHand.x -= Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.5; // Add hand movement self.rightHand.rotation -= Math.sin(LK.ticks / 15 + Math.random() * 0.2) * 0.005; // Add hand movement }; self.setPosture = function (targetPosture) { if (targetPosture == null) { return; } if (!self.isPlayer) { log("AI setPosture: " + targetPosture.name); } // Torso self.torso.x = targetPosture.torso.x; self.torso.y = targetPosture.torso.y; self.torso.width = targetPosture.torso.w; self.torso.height = targetPosture.torso.h; self.torso.rotation = targetPosture.torso.r; // Head self.head.x = targetPosture.head.x; self.head.y = targetPosture.head.y; self.head.width = targetPosture.head.w; self.head.height = targetPosture.head.h; self.head.rotation = targetPosture.head.r; // Left Arm self.leftArm.x = targetPosture.leftArm.x; self.leftArm.y = targetPosture.leftArm.y; self.leftArm.width = targetPosture.leftArm.w; self.leftArm.height = targetPosture.leftArm.h; self.leftArm.rotation = targetPosture.leftArm.r; // Right Arm self.rightArm.x = targetPosture.rightArm.x; self.rightArm.y = targetPosture.rightArm.y; self.rightArm.width = targetPosture.rightArm.w; self.rightArm.height = targetPosture.rightArm.h; self.rightArm.rotation = targetPosture.rightArm.r; // Left Forearm self.leftForearm.x = targetPosture.leftForearm.x; self.leftForearm.y = targetPosture.leftForearm.y; self.leftForearm.width = targetPosture.leftForearm.w; self.leftForearm.height = targetPosture.leftForearm.h; self.leftForearm.rotation = targetPosture.leftForearm.r; // Right Forearm self.rightForearm.x = targetPosture.rightForearm.x; self.rightForearm.y = targetPosture.rightForearm.y; self.rightForearm.width = targetPosture.rightForearm.w; self.rightForearm.height = targetPosture.rightForearm.h; self.rightForearm.rotation = targetPosture.rightForearm.r; // Left Hand self.leftHand.x = targetPosture.leftHand.x; self.leftHand.y = targetPosture.leftHand.y; self.leftHand.width = targetPosture.leftHand.w; self.leftHand.height = targetPosture.leftHand.h; self.leftHand.rotation = targetPosture.leftHand.r; // Right Hand self.rightHand.x = targetPosture.rightHand.x; self.rightHand.y = targetPosture.rightHand.y; self.rightHand.width = targetPosture.rightHand.w; self.rightHand.height = targetPosture.rightHand.h; self.rightHand.rotation = targetPosture.rightHand.r; }; }); /****************************************************************************************** */ /************************************* ENERGY BAR CLASS ********************************** */ /****************************************************************************************** */ var EnergyBar = Container.expand(function (maxEnergy, isGuard) { var self = Container.call(this); self.maxEnergy = maxEnergy; self.currentEnergy = maxEnergy; // Background of the energy bar self.frame = self.attachAsset('energyBarBackground', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.energyGradiant = self.attachAsset('energyBar', { anchorX: 0.5, anchorY: 1, alpha: 0.8, y: self.frame.height / 2 - 30 }); // Fill of the energy bar self.fill = self.attachAsset('energyBarFill', { anchorX: 0.50, anchorY: 0, alpha: 0.8, x: 0, y: -self.frame.height / 2 + 30, height: 0, visible: true }); // Lightning icon above the energy bar self.lightningIcon = self.attachAsset(isGuard ? 'shieldIcon' : 'lightning', { anchorX: 0.5, anchorY: 1, alpha: 0.8, x: 0, y: -self.energyGradiant.height / 2 - 50 // Position above the energy bar }); // Update the energy bar display self.updateEnergy = function (energy) { self.currentEnergy = energy; var fillSize = Math.max(0, self.maxEnergy - self.currentEnergy) / self.maxEnergy * (self.energyGradiant.height + 6); self.fill.height = fillSize; }; }); /****************************************************************************************** */ /************************************* GUARD BUTTON CLASS ********************************** */ /****************************************************************************************** */ var GuardButton = Container.expand(function () { var self = Container.call(this); self.buttonAsset = self.attachAsset('guardButton', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.x = 400; // Position button in the bottom center self.y = game.height - 350; self.down = function (x, y, obj) { player.guard(true); // Activate guard state for player self.width *= 0.9; self.height *= 0.9; }; self.up = function (x, y, obj) { player.guard(false); self.width = 600; self.height = 600; }; }); /****************************************************************************************** */ /************************************* HEALTH BAR CLASS *********************************** */ /****************************************************************************************** */ var HealthBar = Container.expand(function (maxHealth, isPlayer, barColor) { var self = Container.call(this); self.maxHealth = maxHealth; self.currentHealth = maxHealth; // Frame of the health bar self.frame = self.attachAsset('healthBarFrame', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Fill of the health bar self.fill = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: -self.frame.width / 2 + 15, y: 0, width: self.frame.width, tint: 0xFF0000, alpha: 0.8 }); self.icon = self.attachAsset('healthIcon', { anchorX: 0.5, anchorY: 0.5, x: -self.frame.width / 2 - 40, tint: isPlayer ? 0xFF0000 : 0x0E78CA, alpha: 0.8 }); // Update the health bar display self.updateHealth = function (health) { self.currentHealth = health; var fillWidth = Math.max(0, self.currentHealth) / self.maxHealth * (self.frame.width - 30); self.fill.width = fillWidth; }; self.updateHealth(100); }); /****************************************************************************************** */ /************************************* PROJECTIONS CLASS ********************************** */ /****************************************************************************************** */ var Projections = Container.expand(function () { var self = Container.call(this); // Projection properties self.speed = 15; // Speed of the projection self.direction = 0; // Direction of the projection in radians // Create and attach a projection asset var projectionGraphics = self.attachAsset('projection', { anchorX: 0.5, anchorY: 0.5 }); // Update function for the projection self.update = function () { // Move the projection based on its speed and direction self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Check if the projection is out of bounds and destroy it if so if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) { self.destroy(); } if (Date.now() - self.startTime > 600) { self.destroy(); } self.speed *= 0.95; }; self.startTime = Date.now(); }); /****************************************************************************************** */ /************************************* PUNCH BUTTON CLASS ********************************** */ /****************************************************************************************** */ var PunchButton = Container.expand(function () { var self = Container.call(this); self.buttonAsset = self.attachAsset('punchButton', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.x = game.width - 400; // Position button on the bottom right self.y = game.height - 350; self.down = function (x, y, obj) { // Simulate button press by triggering punch with left arm player.punch(Math.random() < 0.5); // Randomly choose left or right arm for punching self.width *= 0.9; self.height *= 0.9; }; self.up = function (x, y, obj) { // Simulate button release by triggering punch with right arm self.width = 600; self.height = 600; }; }); /****************************************************************************************** */ /**************************************** RING CLASS ************************************** */ /****************************************************************************************** */ var Ring = Container.expand(function () { var self = Container.call(this); self.leftBorder = 300; self.rightBorder = 1800; self.topBorder = 200; self.bottomBorder = 1750; self.leftCorner = 600; self.rightCorner = 1500; self.topCorner = 500; self.bottomCorner = 1500; self.ringAsset = self.attachAsset('ring', { anchorX: 0.5, anchorY: 0.5 }); self.x = 1024; // Center of the screen horizontally self.y = 1366 - self.height / 6; // Center of the screen vertically }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Init game with black background }); /**** * Game Code ****/ /****************************************************************************************** */ /************************************** GLOBAL VARIABLES ********************************** */ /****************************************************************************************** */ var isPlaying = false; var roundStarted = false; var ring; var punchButton; var guardButton; var player; var opponent; var touchPosition = null; var swipeStart = null; var swipeEnd = null; var playerEnergyBar = null; var playerGuardBar = null; var playerHealthBar = null; var opponentHealthBar = null; var isDebug = false; var debugMarker; /****************************************************************************************** */ /************************************** POSTURES ****************************************** */ /****************************************************************************************** */ var idlePosture = { name: "idlePosture", // Left Arm leftForearm: { x: -110, y: -125, w: 80, h: 120, r: -Math.PI * 0.2 }, leftHand: { x: -110, y: -250, w: 80, h: 180, r: -Math.PI * 0.05 }, leftArm: { x: -120, y: -120, w: 80, h: 150, r: 0 }, // Right Arm rightForearm: { x: 110, y: -125, w: 80, h: 120, r: Math.PI * 0.2 }, rightHand: { x: 110, y: -250, w: 90, h: 180, r: Math.PI * 0.05 }, rightArm: { x: 120, y: -120, w: 80, h: 150, r: 0 }, torso: { x: 0, y: 0, w: 300, h: 150, r: 0 }, head: { x: 0, y: -40, w: 150, h: 190, r: 0 } }; /****************************************************************************************** */ /*********************************** UTILITY FUNCTIONS ************************************ */ /****************************************************************************************** */ function log() { if (isDebug) { var _console; (_console = console).log.apply(_console, arguments); } } /****************************************************************************************** */ /************************************** INPUT HANDLERS ************************************ */ /****************************************************************************************** */ game.down = function (x, y, obj) { if (!roundStarted && !isPlaying) { roundStarted = true; isPlaying = true; } }; game.move = function (x, y, obj) {}; game.up = function (x, y, obj) {}; /****************************************************************************************** */ /************************************ GAME INITIALIZE ************************************* */ /****************************************************************************************** */ function gameInitialize() { log("Game initialize..."); // Initialize Ring ring = game.addChild(new Ring()); punchButton = game.addChild(new PunchButton()); guardButton = game.addChild(new GuardButton()); // Initialize Player player = game.addChild(new Athlete(true)); player.x = 1024; // Center horizontally player.y = game.height * 0.55; // Position towards the bottom // Initialize Opponent opponent = game.addChild(new Athlete()); opponent.x = 1024; // Center horizontally opponent.y = game.height * 0.2; // Center vertically in the middle of the ring opponent.rotation = Math.PI * 0.5; // Initialize Energy Bar for Player playerEnergyBar = game.addChild(new EnergyBar(100)); playerEnergyBar.x = game.width - 75; // Position energy bar on the left side playerEnergyBar.y = game.height * 0.4; // Position towards the top // Initialize Guard Bar for Player playerGuardBar = game.addChild(new EnergyBar(100, true)); playerGuardBar.x = 75; // Position energy bar on the left side playerGuardBar.y = game.height * 0.4; // Position towards the top // Initialize Player Health bar playerHealthBar = game.addChild(new HealthBar(100, true)); playerHealthBar.x = 1024; playerHealthBar.y = 1960; // Initialize Opponent Health bar opponentHealthBar = game.addChild(new HealthBar(100, false)); opponentHealthBar.x = 1024; // Center horizontally opponentHealthBar.y = 35; // Position at the top of the screen if (isDebug) { // Debug Marker debugMarker = LK.getAsset('debugMarker', { anchorX: 0.5, anchorY: 0.5 }); game.addChild(debugMarker); debugMarker.x = 1800; debugMarker.y = 1750; } } /****************************************************************************************** */ /************************************* GAME FUNCTIONS ************************************* */ /****************************************************************************************** */ function handleHit(attacker, defender) { if (!isPlaying) { return; } defender.isHit = true; defender.isTouched = !defender.isGuarding; var backDelta = defender.isGuarding ? 2 : 50; var backHeadDelta = defender.isGuarding ? 4 : 10; // Player hit reaction: head goes back, flash screen red // Calculate defender's current direction and move back accordingly var defenderDirection = Math.atan2(defender.y - attacker.y, defender.x - attacker.x); // Move defender back var newX = defender.x + Math.cos(defenderDirection) * backDelta; var newY = defender.y + Math.sin(defenderDirection) * backDelta; // Check if newX and newY are within ring's corners var withinLimits = newX >= ring.leftCorner && newX <= ring.rightCorner && newY >= ring.topCorner && newY <= ring.bottomCorner; //log("Is in ring ?", withinLimits); if (withinLimits) { defender.x = newX; // Move defender back in the x direction of current movement defender.y = newY; // Move defender back in the y direction of current movement } else { // If out of limits, move attacker back instead /* var attackerDirection = Math.atan2(attacker.y - defender.y, attacker.x - defender.x); attacker.x += Math.cos(attackerDirection) * backDelta; attacker.y += Math.sin(attackerDirection) * backDelta; */ } var impacted = defender.handleHitImpact(attacker); // Emit projections from behind the defender's head on hit var projectionCount = defender.isGuarding ? 2 : 5; for (var i = 0; i < projectionCount; i++) { var projection = new Projections(); projection.x = defender.x + (Math.random() - 0.5) * 100; // Randomize start position around the head projection.y = defender.y + (Math.random() - 0.5) * 100; projection.direction = Math.atan2(defender.y - attacker.y, defender.x - attacker.x) + (Math.random() - 0.5); game.addChild(projection); } var flashColor = defender.isGuarding || !impacted ? 0xcccccc : 0xFF0000; if (defender.isGuarding) { LK.effects.flashObject(defender.leftHand, flashColor, 100); // Flash the defender LK.effects.flashObject(defender.rightHand, flashColor, 100); // Flash the defender } else { LK.effects.flashObject(defender.head, flashColor, 100); // Flash the defender LK.effects.flashObject(defender.torso, flashColor, 100); // Flash the defender } LK.effects.flashObject(defender.leftArm, flashColor, 100); // Flash the defender LK.effects.flashObject(defender.leftForearm, flashColor, 100); // Flash the defender LK.effects.flashObject(defender.rightArm, flashColor, 100); // Flash the defender LK.effects.flashObject(defender.rightForearm, flashColor, 100); // Flash the defender // Arms back movement var members = []; if (defender.isGuarding) { // Move arms back members = [defender.rightHand, defender.leftHand, defender.leftArm, defender.leftForearm, defender.rightArm, defender.rightForearm]; } else { // Move head and torso back members = [defender.head, defender.torso]; } // Apply movement to all members in the array members.forEach(function (member) { member.x += Math.cos(defenderDirection) * backHeadDelta; member.y += Math.sin(defenderDirection) * backHeadDelta; }); if (members.length == 2) { // workaround for head movement members[0].x += Math.cos(defenderDirection) * backHeadDelta; members[0].y += Math.sin(defenderDirection) * backHeadDelta; } (function (defender, defenderDirection, backHeadDelta, members) { LK.setTimeout(function () { // Head returns to normal position members.forEach(function (member) { member.x -= Math.cos(defenderDirection) * backHeadDelta; member.y -= Math.sin(defenderDirection) * backHeadDelta; }); if (members.length == 2) { // workaround for head movement members[0].x -= Math.cos(defenderDirection) * backHeadDelta; members[0].y -= Math.sin(defenderDirection) * backHeadDelta; } /* defender.head.x -= 2.5 * Math.cos(defenderDirection) * backHeadDelta; defender.head.y -= 2.5 * Math.sin(defenderDirection) * backHeadDelta; defender.torso.x -= Math.cos(defenderDirection) * backHeadDelta; defender.torso.y -= Math.sin(defenderDirection) * backHeadDelta; */ defender.isHit = false; if (!defender.isGuarding && !defender.isPunching) { defender.setPosture(idlePosture); } }, 500); })(defender, defenderDirection, backHeadDelta, members); } /****************************************************************************************** */ /************************************** MAIN GAME LOOP ************************************ */ /****************************************************************************************** */ // Game update function game.update = function () { // This section has been removed to prevent redundant player movement handling. // Check for collision between player's hand and opponent's head if (Date.now() - opponent.lastHitTime < opponent.immunityDelayMs || Date.now() - player.lastHitTime < player.immunityDelayMs) { return; } if (player.isPunching && (player.leftHand.intersects(opponent.torso) || player.rightHand.intersects(opponent.torso))) { handleHit(player, opponent); } if (opponent.isPunching && (opponent.leftHand.intersects(player.torso) || opponent.rightHand.intersects(player.torso))) { handleHit(opponent, player); } }; gameInitialize();
===================================================================
--- original.js
+++ change.js
@@ -30,9 +30,9 @@
self.targetStayTimeMs = 3000;
self.body = new Container();
game.addChild(self.body);
var punchDistance = 60; // Define punch distance for punching animation
- var attackDistance = 350;
+ var attackDistance = 375;
self.targetX = self.targetX || 1024; // Default target X
self.targetY = self.targetY || 1366; // Default target Y
self.shadow = self.body.attachAsset('body', {
anchorX: 0.5,
@@ -730,9 +730,9 @@
/****************************************************************************************** */
var Projections = Container.expand(function () {
var self = Container.call(this);
// Projection properties
- self.speed = 5; // Speed of the projection
+ self.speed = 15; // Speed of the projection
self.direction = 0; // Direction of the projection in radians
// Create and attach a projection asset
var projectionGraphics = self.attachAsset('projection', {
anchorX: 0.5,
@@ -746,9 +746,14 @@
// Check if the projection is out of bounds and destroy it if so
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.destroy();
}
+ if (Date.now() - self.startTime > 600) {
+ self.destroy();
+ }
+ self.speed *= 0.95;
};
+ self.startTime = Date.now();
});
/****************************************************************************************** */
/************************************* PUNCH BUTTON CLASS ********************************** */
/****************************************************************************************** */
@@ -961,9 +966,9 @@
}
defender.isHit = true;
defender.isTouched = !defender.isGuarding;
var backDelta = defender.isGuarding ? 2 : 50;
- var backHeadDelta = defender.isGuarding ? 1 : 4;
+ var backHeadDelta = defender.isGuarding ? 4 : 10;
// Player hit reaction: head goes back, flash screen red
// Calculate defender's current direction and move back accordingly
var defenderDirection = Math.atan2(defender.y - attacker.y, defender.x - attacker.x);
// Move defender back
@@ -984,17 +989,15 @@
*/
}
var impacted = defender.handleHitImpact(attacker);
// Emit projections from behind the defender's head on hit
- if (impacted && !defender.isGuarding) {
- var projectionCount = 10;
- for (var i = 0; i < projectionCount; i++) {
- var projection = new Projections();
- projection.x = defender.x + (Math.random() - 0.5) * 100; // Randomize start position around the head
- projection.y = defender.y + (Math.random() - 0.5) * 100;
- projection.direction = Math.atan2(defender.y - attacker.y, defender.x - attacker.x) + (Math.random() - 0.5);
- game.addChild(projection);
- }
+ var projectionCount = defender.isGuarding ? 2 : 5;
+ for (var i = 0; i < projectionCount; i++) {
+ var projection = new Projections();
+ projection.x = defender.x + (Math.random() - 0.5) * 100; // Randomize start position around the head
+ projection.y = defender.y + (Math.random() - 0.5) * 100;
+ projection.direction = Math.atan2(defender.y - attacker.y, defender.x - attacker.x) + (Math.random() - 0.5);
+ game.addChild(projection);
}
var flashColor = defender.isGuarding || !impacted ? 0xcccccc : 0xFF0000;
if (defender.isGuarding) {
LK.effects.flashObject(defender.leftHand, flashColor, 100); // Flash the defender
@@ -1010,9 +1013,9 @@
// Arms back movement
var members = [];
if (defender.isGuarding) {
// Move arms back
- members = [defender.leftArm, defender.leftForearm, defender.rightArm, defender.rightForearm];
+ members = [defender.rightHand, defender.leftHand, defender.leftArm, defender.leftForearm, defender.rightArm, defender.rightForearm];
} else {
// Move head and torso back
members = [defender.head, defender.torso];
}
@@ -1020,15 +1023,25 @@
members.forEach(function (member) {
member.x += Math.cos(defenderDirection) * backHeadDelta;
member.y += Math.sin(defenderDirection) * backHeadDelta;
});
+ if (members.length == 2) {
+ // workaround for head movement
+ members[0].x += Math.cos(defenderDirection) * backHeadDelta;
+ members[0].y += Math.sin(defenderDirection) * backHeadDelta;
+ }
(function (defender, defenderDirection, backHeadDelta, members) {
LK.setTimeout(function () {
// Head returns to normal position
members.forEach(function (member) {
member.x -= Math.cos(defenderDirection) * backHeadDelta;
member.y -= Math.sin(defenderDirection) * backHeadDelta;
});
+ if (members.length == 2) {
+ // workaround for head movement
+ members[0].x -= Math.cos(defenderDirection) * backHeadDelta;
+ members[0].y -= Math.sin(defenderDirection) * backHeadDelta;
+ }
/*
defender.head.x -= 2.5 * Math.cos(defenderDirection) * backHeadDelta;
defender.head.y -= 2.5 * Math.sin(defenderDirection) * backHeadDelta;
defender.torso.x -= Math.cos(defenderDirection) * backHeadDelta;
clear
basic light gray convex round button with a red boxing glove icon. UI
Un gant de boxe bleu vu de dessus. video game
basic light round convex gray button with a raised blue shield icon.. UI
un éclair. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
remove
a basic white heart.. game icon
A boxer has lost the match..
man boxer with red gloves is KO on the ring..