footballl

Pasted Oct 9, 2026, 3:13 PM1 file391 lines

Scan to open on your phone

Point a camera at the QR code - it opens this exact paste, no app needed.

https://codepastes.com/zzgt08frtkp7x952
67
<!DOCTYPE html> 

<html lang="en"> 

<head> 

    <meta charset="UTF-8"> 

    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 

    <title>Football Bros 2-Player Clone</title> 

    <!-- Importing the open-source Phaser 3 game framework from CDN --> 

    <script src="https://jsdelivr.net"></script> 

    <style> 

        body { margin: 0; background: #1a1a1a; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: 'Arial Black', sans-serif; overflow: hidden;} 

        canvas { border: 6px solid #fff; box-shadow: 0 10px 30px rgba(0,0,0,0.7); border-radius: 4px; } 

    </style> 

</head> 

<body> 

  

<script> 

const config = { 

    type: Phaser.AUTO, 

    width: 900, 

    height: 500, 

    physics: { 

        default: 'arcade', 

        arcade: { 

            gravity: { y: 1100 }, // Heavy arcade gravity match 

            debug: false 

        } 

    }, 

    scene: { preload: preload, create: create, update: update } 

}; 

  

const game = new Phaser.Game(config); 

  

let player1, player2, football, ground; 

let leftGoalPost, rightGoalPost; 

let cursors, spaceKey, wasd, fKey; 

let p1Score = 0, p2Score = 0, timeRemaining = 60; 

let uiText, timerText, gameOverText; 

let matchActive = true; 

  

function preload() { 

    let canvas = document.createElement('canvas'); 

    let ctx = canvas.getContext('2d'); 

  

    // Player 1 Graphic (Blue Custom Uniform Block) 

    canvas.width = 44; canvas.height = 44; 

    ctx.fillStyle = '#0055ff'; ctx.fillRect(0, 0, 44, 44); 

    ctx.fillStyle = '#ffffff'; ctx.fillRect(28, 10, 8, 8); // Eyes 

    ctx.fillStyle = '#000000'; ctx.fillRect(32, 12, 4, 4);  

    this.textures.addCanvas('p1Tex', canvas); 

  

    // Player 2 Graphic (Red Custom Uniform Block) 

    ctx.clearRect(0,0,44,44); 

    ctx.fillStyle = '#ff2222'; ctx.fillRect(0, 0, 44, 44); 

    ctx.fillStyle = '#ffffff'; ctx.fillRect(8, 10, 8, 8); // Eyes 

    ctx.fillStyle = '#000000'; ctx.fillRect(8, 12, 4, 4); 

    this.textures.addCanvas('p2Tex', canvas); 

  

    // Football Graphic (Pro Leather Oval with Laces) 

    canvas.width = 30; canvas.height = 20; 

    ctx.clearRect(0,0,30,20); 

    ctx.fillStyle = '#8B4513'; ctx.beginPath(); ctx.ellipse(15, 10, 15, 10, 0, 0, 2 * Math.PI); ctx.fill(); 

    ctx.fillStyle = '#ffffff'; ctx.fillRect(10, 9, 10, 2); // White Laces 

    ctx.fillRect(12, 7, 2, 6); ctx.fillRect(16, 7, 2, 6); 

    this.textures.addCanvas('ballTex', canvas); 

} 

  

function create() { 

    // 1. Draw Field & Football Yard Lines 

    this.add.rectangle(450, 250, 900, 500, 0x2e6f40);  

    for(let i = 100; i < 900; i += 100) { 

        this.add.rectangle(i, 235, 4, 430, 0xffffff, 0.15); // Yard stripes 

    } 

     

    // 2. Static Ground Floor 

    ground = this.add.rectangle(450, 475, 900, 50, 0x1c4426); 

    this.physics.add.existing(ground, true); 

  

    // 3. Goal Crossbars (Left & Right Nets) 

    leftGoalPost = this.add.rectangle(25, 330, 50, 240, 0xffffff, 0.3); 

    rightGoalPost = this.add.rectangle(875, 330, 50, 240, 0xffffff, 0.3); 

    this.physics.add.existing(leftGoalPost, true); 

    this.physics.add.existing(rightGoalPost, true); 

  

    // 4. Instantiate Players 

    player1 = this.physics.add.sprite(200, 350, 'p1Tex').setCollideWorldBounds(true).setDragX(1200); 

    player2 = this.physics.add.sprite(700, 350, 'p2Tex').setCollideWorldBounds(true).setDragX(1200); 

  

    // 5. Instantiate Bouncy Football 

    football = this.physics.add.sprite(450, 150, 'ballTex').setCollideWorldBounds(true).setBounce(0.75).setDragX(120); 

  

    // 6. Physics Rules Configuration 

    this.physics.add.collider(player1, ground); 

    this.physics.add.collider(player2, ground); 

    this.physics.add.collider(football, ground); 

    this.physics.add.collider(player1, player2); // Players bump into each other 

  

    this.physics.add.collider(player1, football, (p, b) => { b.setVelocityX(p.body.velocity.x * 1.3 + 80); }); 

    this.physics.add.collider(player2, football, (p, b) => { b.setVelocityX(p.body.velocity.x * 1.3 - 80); }); 

  

    // 7. Map Controls Keys 

    cursors = this.input.keyboard.createCursorKeys(); 

    spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); 

    wasd = this.input.keyboard.addKeys({ 

        up: Phaser.Input.Keyboard.KeyCodes.W, 

        left: Phaser.Input.Keyboard.KeyCodes.A, 

        down: Phaser.Input.Keyboard.KeyCodes.S, 

        right: Phaser.Input.Keyboard.KeyCodes.D 

    }); 

    fKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F); 

  

    // 8. Head-up Display (UI) 

    uiText = this.add.text(450, 45, 'P1: 0  |  P2: 0', { fontSize: '32px', fill: '#fff' }).setOrigin(0.5); 

    timerText = this.add.text(450, 90, 'TIME: 60', { fontSize: '22px', fill: '#ffeb3b' }).setOrigin(0.5); 

     

    gameOverText = this.add.text(450, 220, '', { fontSize: '48px', fill: '#fff', backgroundColor: '#000', padding: 15 }).setOrigin(0.5).setVisible(false); 

  

    // Run Clock Timer Loop Tick every 1000ms (1 Second) 

    this.time.addEvent({ delay: 1000, callback: updateTimer, callbackScope: this, loop: true }); 

} 

  

function update() { 

    if (!matchActive) return; 

  

    // --- PLAYER 1 CONTROLS (ARROWS) --- 

    if (cursors.left.isDown) player1.setVelocityX(-280); 

    else if (cursors.right.isDown) player1.setVelocityX(280); 

    if (cursors.up.isDown && player1.body.touching.down) player1.setVelocityY(-480); 

  

    // Player 1 Ball Strike Kick 

    if (Phaser.Input.Keyboard.JustDown(spaceKey)) { 

        if (Phaser.Math.Distance.Between(player1.x, player1.y, football.x, football.y) < 60) { 

            football.setVelocityX(550); 

            football.setVelocityY(-350); 

        } 

    } 

  

    // --- PLAYER 2 CONTROLS (WASD) --- 

    if (wasd.left.isDown) player2.setVelocityX(-280); 

    else if (wasd.right.isDown) player2.setVelocityX(280); 

    if (wasd.up.isDown && player2.body.touching.down) player2.setVelocityY(-480); 

  

    // Player 2 Ball Strike Kick 

    if (Phaser.Input.Keyboard.JustDown(fKey)) { 

        if (Phaser.Math.Distance.Between(player2.x, player2.y, football.x, football.y) < 60) { 

            football.setVelocityX(-550); 

            football.setVelocityY(-350); 

        } 

    } 

  

    // --- SCORING DETECTION LINES --- 

    if (football.x >= 850 && football.y > 210) { 

        p1Score++; 

        triggerGoal("PLAYER 1 SCORED!"); 

    } else if (football.x <= 50 && football.y > 210) { 

        p2Score++; 

        triggerGoal("PLAYER 2 SCORED!"); 

    } 

} 

  

function updateTimer() { 

    if (!matchActive) return; 

    timeRemaining--; 

    timerText.setText('TIME: ' + timeRemaining); 

  

    if (timeRemaining <= 0) { 

        matchActive = false; 

        football.setVisible(false); 

        let winner = p1Score > p2Score ? "PLAYER 1 WINS!" : p2Score > p1Score ? "PLAYER 2 WINS!" : "IT'S A TIE GAME!"; 

        gameOverText.setText('GAME OVER\n' + winner).setVisible(true); 

    } 

} 

  

function triggerGoal(message) { 

    uiText.setText(`P1: ${p1Score}  |  P2: ${p2Score}`); 

    matchActive = false; 

     

    let notice = game.scene.scenes[0].add.text(450, 200, message, { fontSize: '40px', fill: '#ffeb3b', backgroundColor: '#111', padding: 10 }).setOrigin(0.5); 

     

    game.scene.scenes[0].time.delayedCall(1500, () => { 

        notice.destroy(); 

        if (timeRemaining > 0) { 

            matchActive = true; 

            resetFormations(); 

        } 

    }); 

} 

  

function resetFormations() { 

    football.setPosition(450, 150).setVelocity(0, 0); 

    player1.setPosition(200, 350).setVelocity(0,0); 

    player2.setPosition(700, 350).setVelocity(0,0); 

} 

</script> 

  

</body> 

</html> 

7,873 chars · codepastes.com