Untitled

 avatar
unknown
plain_text
a month ago
10 kB
5
Indexable
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Retro Baseball Bros Arcade</title>
    <style>
        body {
            margin: 0;
            background-color: #222;
            color: white;
            font-family: 'Arial', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            overflow: hidden;
        }
        h1 {
            margin: 5px 0;
            font-size: 24px;
            text-transform: uppercase;
            letter-spacing: 2px;
            color: #ffcc00;
        }
        #gameContainer {
            position: relative;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
        }
        canvas {
            background-color: #3e8e41; /* Field green */
            border: 4px solid #fff;
            display: block;
        }
        .controls {
            margin-top: 10px;
            font-size: 14px;
            color: #aaa;
            text-align: center;
        }
        span.key {
            background: #444;
            color: #fff;
            padding: 2px 6px;
            border-radius: 4px;
            border: 1px solid #666;
            font-weight: bold;
        }
    </style>
</head>
<body>

    <h1>Baseball Bros Arcade</h1>
    <div id="gameContainer">
        <canvas id="gameCanvas" width="500" height="600"></canvas>
    </div>
    <div class="controls">
        <p>As Batter: Press <span class="key">SPACEBAR</span> to Swing | As Pitcher: Press <span class="key">SPACEBAR</span> to Throw</p>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // Game States: 'PITCHING', 'BALL_IN_AIR', 'HIT', 'OUT', 'HOMERUN', 'STRIKE'
        let gameState = 'PITCHING'; 
        let score = 0;
        let strikes = 0;
        let outs = 0;
        let feedbackText = "PRESS SPACE TO PITCH";
        let feedbackTimer = 0;

        // Pitcher properties
        const pitcher = { x: 250, y: 180, radius: 15, color: '#3357FF' };

        // Batter properties
        const batter = { x: 250, y: 500, radius: 15, color: '#FF3333', isSwinging: false, swingTimer: 0 };

        // Ball properties
        const ball = { x: 250, y: 180, radius: 6, vx: 0, vy: 0, active: false, speed: 7, curve: 0 };

        // Home plate zone marker
        const homePlateY = 500;

        // Event listener for user interactions
        window.addEventListener('keydown', function(e) {
            if (e.code === 'Space') {
                handleAction();
            }
        });

        function handleAction() {
            if (gameState === 'PITCHING') {
                // Pitch the ball with a slight random break/curve trajectory
                ball.x = pitcher.x;
                ball.y = pitcher.y;
                ball.vy = ball.speed + (Math.random() * 3); // Variable velocity
                ball.vx = (Math.random() - 0.5) * 2;       // Slight horizontal movement
                ball.active = true;
                gameState = 'BALL_IN_AIR';
                feedbackText = "";
            } else if (gameState === 'BALL_IN_AIR' && !batter.isSwinging) {
                // Trigger bat swing
                batter.isSwinging = true;
                batter.swingTimer = 8; // Frames the swing remains active
                
                // Detect hit based on precise collision window near home plate
                let distanceToBat = Math.abs(ball.y - homePlateY);
                if (distanceToBat < 25 && ball.active) {
                    processHit();
                }
            } else if (gameState === 'OUT' || gameState === 'HOMERUN' || gameState === 'STRIKE') {
                // Reset state for next pitch sequence
                resetPitch();
            }
        }

        function processHit() {
            gameState = 'HIT';
            ball.vy = -(ball.speed + 5 + Math.random() * 5); // Launch ball up field
            ball.vx = (Math.random() - 0.5) * 10;            // Spray angle left/right
            
            // Power calculation determined by perfect timing sweet-spot
            let timingAccuracy = Math.abs(ball.y - homePlateY);
            if (timingAccuracy < 8) {
                gameState = 'HOMERUN';
                score += 1;
                triggerFeedback("HOME RUN! +1 POINT");
            } else {
                // Randomly assign standard safe hit or field out
                if (Math.random() > 0.4) {
                    score += 1;
                    triggerFeedback("BASE HIT!");
                    setTimeout(() => { resetPitch(); }, 1500);
                } else {
                    gameState = 'OUT';
                    outs += 1;
                    triggerFeedback("FLY OUT!");
                }
            }
        }

        function triggerFeedback(text) {
            feedbackText = text;
            feedbackTimer = 90; // Frame duration text displays
        }

        function resetPitch() {
            ball.active = false;
            ball.x = pitcher.x;
            ball.y = pitcher.y;
            ball.vx = 0;
            ball.vy = 0;
            batter.isSwinging = false;
            if (outs >= 3) {
                // Reset game session details upon 3 outs
                feedbackText = "GAME OVER! FINAL SCORE: " + score;
                score = 0;
                strikes = 0;
                outs = 0;
                gameState = 'PITCHING';
            } else {
                gameState = 'PITCHING';
                feedbackText = "PRESS SPACE TO PITCH";
            }
        }

        // Main game logic update loop
        function update() {
            if (gameState === 'BALL_IN_AIR') {
                ball.y += ball.vy;
                ball.x += ball.vx;

                // Check for missed swing / strike zone exit boundary
                if (ball.y > 550) {
                    strikes += 1;
                    if (strikes >= 3) {
                        outs += 1;
                        strikes = 0;
                        gameState = 'OUT';
                        triggerFeedback("STRIKE 3! YOU'RE OUT");
                    } else {
                        gameState = 'STRIKE';
                        triggerFeedback("STRIKE!");
                    }
                }
            }

            if (gameState === 'HIT' || gameState === 'HOMERUN') {
                ball.y += ball.vy;
                ball.x += ball.vx;
                
                // Keep hit balls within boundary walls or handle out of bounds flight paths
                if (ball.y < -10 || ball.x < 0 || ball.x > canvas.width) {
                    if (gameState !== 'HOMERUN') resetPitch();
                }
            }

            // Handle swinging animation cycles
            if (batter.isSwinging) {
                batter.swingTimer--;
                if (batter.swingTimer <= 0) {
                    batter.isSwinging = false;
                }
            }

            if (feedbackTimer > 0) feedbackTimer--;
        }

        // Visual asset rendering loop
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Draw baseball diamond field elements
            ctx.strokeStyle = "rgba(255,255,255,0.6)";
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(250, 520); // Home Plate apex
            ctx.lineTo(80, 350);  // 3rd Base line
            ctx.lineTo(250, 180); // 2nd Base center
            ctx.lineTo(420, 350); // 1st Base line
            ctx.closePath();
            ctx.stroke();

            // Draw Outfield Warning Track Arc
            ctx.beginPath();
            ctx.arc(250, 520, 480, Math.PI, 2 * Math.PI);
            ctx.strokeStyle = "#e67e22";
            ctx.lineWidth = 8;
            ctx.stroke();

            // Render Pitcher Mound
            ctx.beginPath();
            ctx.arc(pitcher.x, pitcher.y, pitcher.radius, 0, Math.PI * 2);
            ctx.fillStyle = pitcher.color;
            ctx.fill();
            ctx.closePath();

            // Render Batter Box Position
            ctx.beginPath();
            ctx.arc(batter.x, batter.y, batter.radius, 0, Math.PI * 2);
            ctx.fillStyle = batter.color;
            ctx.fill();
            ctx.closePath();

            // Render active bat swing visual indicator
            if (batter.isSwinging) {
                ctx.beginPath();
                ctx.arc(batter.x, batter.y, batter.radius + 18, 0, Math.PI, true);
                ctx.strokeStyle = '#ffff00';
                ctx.lineWidth = 5;
                ctx.stroke();
            }

            // Render Baseball
            if (ball.active || gameState === 'HIT' || gameState === 'HOMERUN') {
                ctx.beginPath();
                ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
                ctx.fillStyle = '#ffffff';
                ctx.fill();
                ctx.strokeStyle = '#e74c3c';
                ctx.lineWidth = 1;
                ctx.stroke();
                ctx.closePath();
            }

            // Onscreen HUD (Heads-Up Display) Data
            ctx.fillStyle = "#ffffff";
            ctx.font = "bold 16px Arial";
            ctx.fillText("SCORE: " + score, 20, 30);
            ctx.fillText("STRIKES: " + "X".repeat(strikes), 20, 55);
            ctx.fillText("OUTS: " + "●".repeat(outs) + "○".repeat(3 - outs), 20, 80);

            // Large center UI text updates
            if (feedbackText && (feedbackTimer > 0 || gameState === 'PITCHING')) {
                ctx.fillStyle = (gameState === 'HOMERUN') ? '#ffcc00' : '#ffffff';
                ctx.font = "bold 24px Arial";
                ctx.textAlign = "center";
                ctx.fillText(feedbackText, canvas.width / 2, canvas.height / 2 + 50);
                ctx.textAlign = "start"; // Reset orientation
            }
        }

        // Native browser core game execution loop
        function gameLoop() {
            update();
            draw();
            requestAnimationFrame(gameLoop);
        }

        // Launch operational instances
        gameLoop();
    </script>
</body>
</html>
Editor is loading...
Leave a Comment