| Server IP : 139.59.63.204 / Your IP : 216.73.217.62 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ubuntu-s-1vcpu-1gb-blr1-01 6.8.0-110-generic #110-Ubuntu SMP PREEMPT_DYNAMIC Thu Mar 19 15:09:20 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/crmapp/public/ |
Upload File : |
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Minimal 2P Fighting Game</title>
<style>
html,body {height:100%;margin:0;background:#111;color:#eee;font-family:system-ui;}
#game {display:flex;align-items:center;justify-content:center;height:100%;}
canvas {background:linear-gradient(#222,#111);box-shadow:0 6px 30px rgba(0,0,0,.7);}
#hud{position:fixed;left:10px;right:10px;top:10px;display:flex;justify-content:space-between;pointer-events:none}
.bar{width:45%;height:20px;background:#333;border-radius:6px;overflow:hidden}
.fill{height:100%;background:linear-gradient(#f33,#c00);width:100%}
.fill.p2{background:linear-gradient(#3df,#08c)}
#msg{position:fixed;left:0;right:0;top:50%;text-align:center;font-size:28px;transform:translateY(-50%);pointer-events:none}
#controls{position:fixed;bottom:10px;left:10px;font-size:13px;color:#aaa}
</style>
</head>
<body>
<div id="hud">
<div class="bar"><div id="p1bar" class="fill"></div></div>
<div class="bar"><div id="p2bar" class="fill p2"></div></div>
</div>
<div id="msg"></div>
<div id="controls">
Player1: A/D move, W jump, S attack | Player2: ←/→ move, ↑ jump, ↓ attack
</div>
<div id="game"><canvas id="c" width="900" height="400"></canvas></div>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const W = canvas.width, H = canvas.height;
const gravity = 0.9;
const groundY = H - 60;
class Fighter {
constructor(x,color,keys){
this.x = x; this.y = groundY;
this.vx = 0; this.vy = 0;
this.w = 50; this.h = 80;
this.color = color;
this.facing = 1; // 1 right, -1 left
this.onGround = true;
this.speed = 4;
this.jumpStrength = -15;
this.health = 100;
this.attackTimer = 0;
this.attackCooldown = 24; // frames
this.attackRange = 30;
this.keys = keys;
this.blocking = false;
}
update() {
// movement
this.vx *= 0.9;
this.x += this.vx;
// gravity
if (!this.onGround) this.vy += gravity;
this.y += this.vy;
if (this.y >= groundY) { this.y = groundY; this.vy = 0; this.onGround = true; }
// bounds
this.x = Math.max(10, Math.min(W - this.w - 10, this.x));
// attack cooldown countdown
if (this.attackTimer > 0) this.attackTimer--;
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y - this.h, this.w, this.h);
// face indicator
ctx.fillStyle = '#0008';
const fx = this.facing === 1 ? this.x + this.w - 6 : this.x + 6;
ctx.fillRect(fx, this.y - this.h + 14, 6, 6);
}
tryAttack(opponent) {
if (this.attackTimer > 0) return false;
this.attackTimer = this.attackCooldown;
// attack hitbox in front
const ax = this.facing === 1 ? this.x + this.w : this.x - this.attackRange;
const aw = this.attackRange;
const ay = this.y - this.h + 10;
const ah = this.h - 20;
// collision simple AABB
if (rectOverlap(ax,ay,aw,ah, opponent.x, opponent.y-opponent.h, opponent.w, opponent.h)) {
// apply damage
const dmg = 10;
opponent.health = Math.max(0, opponent.health - dmg);
return true;
}
return false;
}
}
function rectOverlap(x1,y1,w1,h1,x2,y2,w2,h2){
return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2;
}
const keys = {};
window.addEventListener('keydown', e => { keys[e.key.toLowerCase()] = true; });
window.addEventListener('keyup', e => { keys[e.key.toLowerCase()] = false; });
const p1 = new Fighter(120,'#e04444',{left:'a',right:'d',jump:'w',attack:'s'});
const p2 = new Fighter(W-170,'#3a9fe0',{left:'arrowleft',right:'arrowright',jump:'arrowup',attack:'arrowdown'});
let roundMessage = '';
let roundTimer = 0;
function startRound(msg) {
p1.x = 120; p2.x = W-170;
p1.y = p2.y = groundY;
p1.health = p2.health = 100;
p1.vx = p2.vx = 0;
roundMessage = msg || '';
roundTimer = 120;
}
startRound('Ready');
function handleInput() {
// p1 controls
if (keys[p1.keys.left]) { p1.vx = -p1.speed; p1.facing = -1; }
else if (keys[p1.keys.right]) { p1.vx = p1.speed; p1.facing = 1; }
if (keys[p1.keys.jump] && p1.onGround) { p1.vy = p1.jumpStrength; p1.onGround = false; }
if (keys[p1.keys.attack]) { p1.tryAttack(p2); }
// p2 controls
if (keys[p2.keys.left]) { p2.vx = -p2.speed; p2.facing = -1; }
else if (keys[p2.keys.right]) { p2.vx = p2.speed; p2.facing = 1; }
if (keys[p2.keys.jump] && p2.onGround) { p2.vy = p2.jumpStrength; p2.onGround = false; }
if (keys[p2.keys.attack]) { p2.tryAttack(p1); }
}
function update() {
handleInput();
// simple facing update based on opponent position
p1.facing = (p2.x > p1.x) ? 1 : -1;
p2.facing = (p1.x > p2.x) ? 1 : -1;
p1.update(); p2.update();
// check KO
if (p1.health <= 0 || p2.health <= 0) {
const winner = p1.health > p2.health ? 'Player1' : 'Player2';
roundMessage = `${winner} Wins`;
roundTimer = 180;
// freeze controls by setting both health to 0+ and leaving positions but disable input by clearing keys temporarily
for (let k in keys) keys[k] = false;
// schedule new round after timer ends in loop below
}
}
function draw() {
ctx.clearRect(0,0,W,H);
// ground
ctx.fillStyle = '#2a2a2a';
ctx.fillRect(0, groundY+1, W, H-groundY);
// draw fighters
p1.draw(); p2.draw();
// draw attack arcs (visual when attacking)
if (p1.attackTimer > p1.attackCooldown - 8) drawAttackArc(p1);
if (p2.attackTimer > p2.attackCooldown - 8) drawAttackArc(p2);
// health bars handled in DOM
document.getElementById('p1bar').style.width = p1.health + '%';
document.getElementById('p2bar').style.width = p2.health + '%';
// message
const msgEl = document.getElementById('msg');
msgEl.textContent = roundMessage;
}
function drawAttackArc(f) {
const ax = f.facing === 1 ? f.x + f.w : f.x - f.attackRange;
ctx.fillStyle = 'rgba(255,255,255,0.06)';
ctx.fillRect(ax, f.y - f.h + 10, f.attackRange, f.h - 20);
}
let frame = 0;
function loop() {
frame++;
update();
draw();
if (roundTimer > 0) {
roundTimer--;
if (roundTimer === 0 && (p1.health <= 0 || p2.health <= 0)) {
startRound('Ready');
} else if (roundTimer === 0) {
roundMessage = '';
}
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>