0% found this document useful (0 votes)
7 views12 pages

Código

The document outlines the structure and functionality of a web-based soccer game, including the user interface elements such as buttons, an analog stick, and a scoreboard. It details the game's mechanics, including player movement, ball physics, scoring, and game state management. The game is designed to be responsive and interactive, adapting to different screen sizes and touch controls.

Uploaded by

oficialffmax27
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views12 pages

Código

The document outlines the structure and functionality of a web-based soccer game, including the user interface elements such as buttons, an analog stick, and a scoreboard. It details the game's mechanics, including player movement, ball physics, scoring, and game state management. The game is designed to be responsive and interactive, adapting to different screen sizes and touch controls.

Uploaded by

oficialffmax27
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

<!

DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,
user-scalable=yes">
<title>Pro Soccer Game</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
overflow: hidden;
position: fixed;
width: 100%;
height: 100%;
background-color: #0e3b1c;
}
canvas {
background: linear-gradient(135deg, #0d3519 0%, #0e3b1c 25%, #0e3b1c 75%, #0d3519
100%);
display: block;
touch-action: none;
width: 100%;
height: 100%;
}
.button-container {
position: fixed;
bottom: 40px;
right: 40px;
display: flex;
gap: 20px;
z-index: 10;
}
.button {
width: 90px;
height: 90px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-weight: bold;
font-size: 16px;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
transform: scale(1);
transition: transform 0.15s ease;
cursor: pointer;
}
.button:active {
transform: scale(0.92);
}
#buttonA {
background: radial-gradient(circle, #ff3838 0%, #e62020 100%);
box-shadow: 0 4px 15px rgba(255,0,0,0.3);
}
#buttonB {
background: radial-gradient(circle, #2ed573 0%, #26ae60 100%);
box-shadow: 0 4px 15px rgba(46,213,115,0.3);
}
#analog-stick {
position: fixed;
bottom: 40px;
left: 40px;
width: 150px;
height: 150px;
background: rgba(255, 255, 255, 0.1);
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
touch-action: none;
z-index: 10;
}
#analog-knob {
position: absolute;
width: 60px;
height: 60px;
background: radial-gradient(circle, rgba(255,255,255,0.95) 0%, rgba(200,200,200,0.95)
100%);
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
cursor: grab;
}
#analog-knob:active {
cursor: grabbing;
}
#placar {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
color: white;
font-family: Arial, sans-serif;
font-size: 24px;
background: rgba(0,0,0,0.5);
padding: 10px 20px;
border-radius: 10px;
z-index: 10;
}
.timer {
position: fixed;
top: 70px;
left: 50%;
transform: translateX(-50%);
color: white;
font-family: Arial, sans-serif;
font-size: 20px;
background: rgba(0,0,0,0.5);
padding: 5px 15px;
border-radius: 8px;
z-index: 10;
}
.gol-mensagem {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
color: white;
font-family: Arial, sans-serif;
font-size: 48px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
z-index: 20;
}
.gol-mensagem.active {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
.goal {
position: absolute;
width: 20px;
height: 30%;
border: 4px solid rgba(255, 255, 255, 0.8);
background: rgba(255, 255, 255, 0.1);
z-index: 5;
}
.goal-net {
position: absolute;
width: 100%;
height: 100%;
background:
repeating-linear-gradient(45deg,
rgba(255, 255, 255, 0.1) 0px,
rgba(255, 255, 255, 0.1) 2px,
transparent 2px,
transparent 8px
),
repeating-linear-gradient(-45deg,
rgba(255, 255, 255, 0.1) 0px,
rgba(255, 255, 255, 0.1) 2px,
transparent 2px,
transparent 8px
);
}
.goal-left {
left: 0;
top: 50%;
transform: translateY(-50%);
}
.goal-right {
right: 0;
top: 50%;
transform: translateY(-50%);
}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<div id="analog-stick">
<div id="analog-knob"></div>
</div>
<div class="button-container">
<div id="buttonB" class="button">PASSE</div>
<div id="buttonA" class="button">CHUTE</div>
</div>
<div id="placar">
<span id="placarTime1">0</span>
:
<span id="placarTime2">0</span>
</div>
<div class="timer">10:00</div>
<div class="gol-mensagem">GOL!</div>
<div class="goal goal-left"><div class="goal-net"></div></div>
<div class="goal goal-right"><div class="goal-net"></div></div>
<script>
class Game {
constructor() {
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.setupConstants();
this.setupGameState();
this.setupControls();
this.setupGoals();

this.resetPositions();

window.addEventListener('resize', () => {
this.handleResize();
});
window.addEventListener('orientationchange', () => {
setTimeout(() => {
this.handleResize();
}, 300);
});

this.gameTime = 600;
this.isGameActive = false;
this.lastFrameTime = Date.now();

// Start the game loop


this.gameLoop();
}

setupConstants() {
this.PLAYER_MAX_SPEED = 2.5;
this.PLAYER_ACCELERATION = 1.5;
this.PLAYER_FRICTION = 0.92;
this.PLAYER_RADIUS = 16;
this.BALL_RADIUS = 8;
this.BALL_FRICTION = 0.95;
this.BALL_BOUNCE = 0.7;
this.KICK_POWER = 15;
this.PASS_POWER = 10;
}

setupGameState() {
this.score1 = 0;
this.score2 = 0;
this.resetPositions();
this.analogPosition = { x: 0, y: 0 };
this.isAnalogActive = false;
this.buttonAPressed = false;
this.buttonBPressed = false;
this.lastKickTime = 0;
this.ballRotation = 0;
this.analogTouchId = null;
}

setupGoals() {
this.goals = {
left: {
x: 0,
y: this.canvas.height * 0.35,
width: 20,
height: this.canvas.height * 0.3
},
right: {
x: this.canvas.width - 20,
y: this.canvas.height * 0.35,
width: 20,
height: this.canvas.height * 0.3
}
};
}

updateTimer() {
if (this.isGameActive) {
const currentTime = Date.now();
const deltaTime = (currentTime - this.lastFrameTime) / 1000;
this.lastFrameTime = currentTime;
this.gameTime -= deltaTime;
if (this.gameTime <= 0) {
this.gameTime = 600;
this.score1 = 0;
this.score2 = 0;
document.getElementById('placarTime1').textContent = this.score1;
document.getElementById('placarTime2').textContent = this.score2;
}
}
const minutes = Math.floor(this.gameTime / 60);
const seconds = Math.floor(this.gameTime % 60);
document.querySelector('.timer').textContent =
`: ''`;
}

handleResize() {
const playerRelativeX = this.player.x / this.canvas.width;
const playerRelativeY = this.player.y / this.canvas.height;
const ballRelativeX = this.ball.x / this.canvas.width;
const ballRelativeY = this.ball.y / this.canvas.height;

this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;

this.player.x = playerRelativeX * this.canvas.width;


this.player.y = playerRelativeY * this.canvas.height;
this.ball.x = ballRelativeX * this.canvas.width;
this.ball.y = ballRelativeY * this.canvas.height;

this.setupGoals();
}

setupControls() {
const analogStick = document.getElementById('analog-stick');
const analogKnob = document.getElementById('analog-knob');
const maxDistance = 45;

const updateAnalogPosition = (clientX, clientY) => {


const rect = analogStick.getBoundingClientRect();
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const x = clientX - rect.left - centerX;
const y = clientY - rect.top - centerY;
const distance = Math.min(Math.hypot(x, y), maxDistance);
const angle = Math.atan2(y, x);
const normalizedX = (distance / maxDistance) * Math.cos(angle);
const normalizedY = (distance / maxDistance) * Math.sin(angle);
const knobX = centerX + (normalizedX * maxDistance);
const knobY = centerY + (normalizedY * maxDistance);
analogKnob.style.transform = `translate(px, px)`;
this.analogPosition = { x: normalizedX, y: normalizedY };
this.isAnalogActive = distance > 0;
};

const resetAnalog = () => {


analogKnob.style.transform = 'translate(-50%, -50%)';
this.analogPosition = { x: 0, y: 0 };
this.isAnalogActive = false;
this.analogTouchId = null;
};

analogStick.addEventListener('touchstart', (e) => {


if (this.analogTouchId === null) {
this.analogTouchId = e.touches[0].identifier;
updateAnalogPosition(e.touches[0].clientX, e.touches[0].clientY);
}
});

document.addEventListener('touchmove', (e) => {


for (let i = 0; i < e.touches.length; i++) {
if (e.touches[i].identifier === this.analogTouchId) {
e.preventDefault();
updateAnalogPosition(e.touches[i].clientX, e.touches[i].clientY);
break;
}
}
}, { passive: false });

document.addEventListener('touchend', (e) => {


if (e.changedTouches[0].identifier === this.analogTouchId) {
resetAnalog();
}
});

document.addEventListener('touchcancel', (e) => {


if (e.changedTouches[0].identifier === this.analogTouchId) {
resetAnalog();
}
});

document.getElementById('buttonA').addEventListener('touchstart', () =>
this.buttonAPressed = true);
document.getElementById('buttonA').addEventListener('touchend', () =>
this.buttonAPressed = false);
document.getElementById('buttonB').addEventListener('touchstart', () =>
this.buttonBPressed = true);
document.getElementById('buttonB').addEventListener('touchend', () =>
this.buttonBPressed = false);
}

resetPositions() {
const centerX = this.canvas.width / 2;
const centerY = this.canvas.height / 2;

this.player = {
x: centerX - 100,
y: centerY,
vx: 0,
vy: 0,
rotation: 0
};

this.ball = {
x: centerX,
y: centerY,
vx: 0,
vy: 0
};
}

checkGoal() {
if (this.ball.x < this.goals.left.width &&
this.ball.y > this.goals.left.y &&
this.ball.y < this.goals.left.y + this.goals.left.height) {
this.score2++;
document.getElementById('placarTime2').textContent = this.score2;
this.showGolMessage();
this.resetPositions();
return true;
}

if (this.ball.x > this.canvas.width - this.goals.right.width &&


this.ball.y > this.goals.right.y &&
this.ball.y < this.goals.right.y + this.goals.right.height) {
this.score1++;
document.getElementById('placarTime1').textContent = this.score1;
this.showGolMessage();
this.resetPositions();
return true;
}

return false;
}

showGolMessage() {
const golMessage = document.querySelector('.gol-mensagem');
golMessage.classList.add('active');
setTimeout(() => {
golMessage.classList.remove('active');
}, 2000);
}

updatePlayer() {
if (this.isAnalogActive) {
const targetVX = this.analogPosition.x * this.PLAYER_MAX_SPEED;
const targetVY = this.analogPosition.y * this.PLAYER_MAX_SPEED;
this.player.vx += (targetVX - this.player.vx) * this.PLAYER_ACCELERATION;
this.player.vy += (targetVY - this.player.vy) * this.PLAYER_ACCELERATION;
this.player.rotation = Math.atan2(this.analogPosition.y, this.analogPosition.x);
} else {
this.player.vx *= this.PLAYER_FRICTION;
this.player.vy *= this.PLAYER_FRICTION;
}

this.player.x += this.player.vx;
this.player.y += this.player.vy;

this.player.x = Math.max(this.PLAYER_RADIUS, Math.min(this.canvas.width -


this.PLAYER_RADIUS, this.player.x));
this.player.y = Math.max(this.PLAYER_RADIUS, Math.min(this.canvas.height -
this.PLAYER_RADIUS, this.player.y));

const dx = this.ball.x - this.player.x;


const dy = this.ball.y - this.player.y;
const distance = Math.hypot(dx, dy);
const minDist = this.PLAYER_RADIUS + this.BALL_RADIUS;

if (distance < minDist) {


const angle = Math.atan2(dy, dx);
const ballSpeed = Math.hypot(this.ball.vx, this.ball.vy);

this.ball.x = this.player.x + Math.cos(angle) * minDist;


this.ball.y = this.player.y + Math.sin(angle) * minDist;

const normalX = Math.cos(angle);


const normalY = Math.sin(angle);
const relativeVelX = this.ball.vx - this.player.vx;
const relativeVelY = this.ball.vy - this.player.vy;
const normalVel = relativeVelX * normalX + relativeVelY * normalY;

if (normalVel < 0) {
const bounceX = normalVel * normalX;
const bounceY = normalVel * normalY;

this.ball.vx = this.player.vx - bounceX * this.BALL_BOUNCE;


this.ball.vy = this.player.vy - bounceY * this.BALL_BOUNCE;

if (this.buttonAPressed) {
const kickAngle = this.player.rotation;
this.ball.vx = Math.cos(kickAngle) * this.KICK_POWER;
this.ball.vy = Math.sin(kickAngle) * this.KICK_POWER;
} else if (this.buttonBPressed) {
const passAngle = this.player.rotation;
this.ball.vx = Math.cos(passAngle) * this.PASS_POWER;
this.ball.vy = Math.sin(passAngle) * this.PASS_POWER;
}
}
}
}
updateBall() {
this.ball.vx *= this.BALL_FRICTION;
this.ball.vy *= this.BALL_FRICTION;

this.ball.x += this.ball.vx;
this.ball.y += this.ball.vy;

this.ballRotation += Math.hypot(this.ball.vx, this.ball.vy) * 0.1;

if (!this.checkGoal()) {
if (this.ball.x < this.BALL_RADIUS || this.ball.x > this.canvas.width -
this.BALL_RADIUS) {
this.ball.vx *= -this.BALL_BOUNCE;
this.ball.x = this.ball.x < this.BALL_RADIUS ? this.BALL_RADIUS :
this.canvas.width - this.BALL_RADIUS;
}

if (this.ball.y < this.BALL_RADIUS || this.ball.y > this.canvas.height -


this.BALL_RADIUS) {
this.ball.vy *= -this.BALL_BOUNCE;
this.ball.y = this.ball.y < this.BALL_RADIUS ? this.BALL_RADIUS :
this.canvas.height - this.BALL_RADIUS;
}
}

this.isGameActive = Math.abs(this.ball.vx) > 0.01 || Math.abs(this.ball.vy) > 0.01;


}

drawPlayer() {
this.ctx.save();
this.ctx.translate(this.player.x, this.player.y);
this.ctx.rotate(this.player.rotation);
this.ctx.fillStyle = '#1a73e8';
this.ctx.beginPath();
this.ctx.arc(0, 0, this.PLAYER_RADIUS, 0, Math.PI * 2);
this.ctx.fill();
this.ctx.restore();
}

drawBall() {
this.ctx.save();
this.ctx.translate(this.ball.x, this.ball.y);
this.ctx.rotate(this.ballRotation);

// Draw the ball


this.ctx.beginPath();
this.ctx.arc(0, 0, this.BALL_RADIUS, 0, Math.PI * 2);
this.ctx.fillStyle = 'white';
this.ctx.fill();

// Draw the pattern on the ball


this.ctx.beginPath();
this.ctx.moveTo(-this.BALL_RADIUS * 0.5, 0);
this.ctx.lineTo(this.BALL_RADIUS * 0.5, 0);
this.ctx.moveTo(0, -this.BALL_RADIUS * 0.5);
this.ctx.lineTo(0, this.BALL_RADIUS * 0.5);
this.ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
this.ctx.stroke();

this.ctx.restore();
}

gameLoop() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

this.updatePlayer();
this.updateBall();
this.updateTimer();

this.drawPlayer();
this.drawBall();

requestAnimationFrame(() => this.gameLoop());


}
}

// Start the game


new Game();
</script>
</body>

You might also like