/****
* 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 = 350;
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.targetY == ring.bottomCorner ? ring.topCorner : ring.bottomCorner;
} else {
if (other.y > 1044) {
self.targetY = ring.topCorner;
} else {
self.targetY = ring.bottomCorner;
}
self.targetX = other.targetX == ring.bottomCorner ? 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);
});
/****************************************************************************************** */
/************************************* 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 ? 1 : 4;
// 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);
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.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;
});
(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;
});
/*
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();
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..