mirror of
https://github.com/AudebertAdrien/ft_transcendence.git
synced 2025-12-16 14:07:49 +01:00
merging with branch: yannick
This commit is contained in:
commit
1a392332a3
2
.env
2
.env
@ -12,4 +12,4 @@ DB_HOST=db
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
|
||||||
PROJECT_PATH=/home/mchiboub/42cursus/transcendence/pong
|
PROJECT_PATH=/home/mchiboub/42cursus/transcendence/pong
|
||||||
POSTGRES_DATA_PATH=/home/mchiboub/42cursus/transcendence/data/db
|
POSTGRES_DATA_PATH=/home/mchiboub/42cursus/transcendence/data/db
|
||||||
1
makefile
1
makefile
@ -46,4 +46,3 @@ help:
|
|||||||
@echo " make logs [c=service] # Tail logs of containers"
|
@echo " make logs [c=service] # Tail logs of containers"
|
||||||
@echo " make ps # List containers"
|
@echo " make ps # List containers"
|
||||||
@echo " make help # Show this help"
|
@echo " make help # Show this help"
|
||||||
|
|
||||||
|
|||||||
@ -182,4 +182,4 @@ class Game:
|
|||||||
# match type: 'tournament'
|
# match type: 'tournament'
|
||||||
# -> tournament id
|
# -> tournament id
|
||||||
|
|
||||||
#endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_p2, dur, is_tournoi, name_tournament)
|
#endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_p2, dur, is_tournoi, name_tournament)
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
# Generated by Django 5.0.7 on 2024-07-24 16:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('game', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='best_score',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='m_duration',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='m_nbr_ball_touch',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='m_score_adv_match',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='m_score_match',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='num_participated_tournaments',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='num_won_tournaments',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='p_win',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='total_duration',
|
||||||
|
field=models.DurationField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='total_match',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='player',
|
||||||
|
name='total_win',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -48,4 +48,4 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -50,4 +50,4 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -34,4 +34,4 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.db.models import Max, Sum, F
|
from django.db.models import Max, Sum, F
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
<<<<<<< HEAD
|
||||||
from channels.db import database_sync_to_async
|
from channels.db import database_sync_to_async
|
||||||
|
|
||||||
async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament):
|
async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament):
|
||||||
@ -26,6 +27,26 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_
|
|||||||
await uptdate_player_statistics(p2)
|
await uptdate_player_statistics(p2)
|
||||||
|
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
|
=======
|
||||||
|
|
||||||
|
def endfortheouche(p1, p2, s_p1, s_p2, winner, bt_p1, bt_p2, dur, is_tournoi, name_tournament) :
|
||||||
|
#If he doesn't exist, create player p1
|
||||||
|
if not Player.objects.filter(name=p1).exist():
|
||||||
|
create_player(p1)
|
||||||
|
|
||||||
|
#If he doesn't exist, create player p2
|
||||||
|
if not Player.objects.filter(name=p2).exist():
|
||||||
|
create_player(p2)
|
||||||
|
|
||||||
|
#create Match
|
||||||
|
create_match(p1, p2, s_p1, s_p2, bt_p1, bt_p2, dur, is_tournoi, name_tournamenttournoi)
|
||||||
|
|
||||||
|
#Update data p1 et p2
|
||||||
|
uptdate_player_statistics(p1)
|
||||||
|
uptdate_player_statistics(p2)
|
||||||
|
|
||||||
|
|
||||||
|
>>>>>>> f31331d344927dfd9bca940943bdba9a4d79a2b4
|
||||||
def create_player(
|
def create_player(
|
||||||
name,
|
name,
|
||||||
total_match=0,
|
total_match=0,
|
||||||
@ -60,13 +81,19 @@ def create_player(
|
|||||||
player.save()
|
player.save()
|
||||||
return player
|
return player
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
|
=======
|
||||||
|
>>>>>>> f31331d344927dfd9bca940943bdba9a4d79a2b4
|
||||||
def create_tournoi(name, nbr_player, date, winner):
|
def create_tournoi(name, nbr_player, date, winner):
|
||||||
tournoi = Tournoi(name=name, nbr_player=nbr_player, date=date, winner=winner)
|
tournoi = Tournoi(name=name, nbr_player=nbr_player, date=date, winner=winner)
|
||||||
tournoi.save()
|
tournoi.save()
|
||||||
return tournoi
|
return tournoi
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
|
=======
|
||||||
|
>>>>>>> f31331d344927dfd9bca940943bdba9a4d79a2b4
|
||||||
def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi):
|
def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi):
|
||||||
match = Match(
|
match = Match(
|
||||||
player1=player1,
|
player1=player1,
|
||||||
|
|||||||
@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
def index(request):
|
def index(request):
|
||||||
return render(request, 'index.html')
|
return render(request, 'index.html')
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> f31331d344927dfd9bca940943bdba9a4d79a2b4
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from .models import Player, Tournoi, Match
|
from .models import Player, Tournoi, Match
|
||||||
from .utils import create_player, create_tournoi, create_match
|
from .utils import create_player, create_tournoi, create_match
|
||||||
@ -15,6 +18,11 @@ from django.views.decorators.csrf import csrf_exempt
|
|||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
return render(request, 'index.html')
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def register_user(request):
|
def register_user(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@ -199,4 +207,4 @@ def tournoi_list(request):
|
|||||||
tournois = Tournoi.objects.select_related('winner').all()
|
tournois = Tournoi.objects.select_related('winner').all()
|
||||||
return render(request, 'pong/tournoi_list.html', {'tournois': tournois})
|
return render(request, 'pong/tournoi_list.html', {'tournois': tournois})
|
||||||
|
|
||||||
####################### THEOUCHE PART ############################
|
####################### THEOUCHE PART ############################
|
||||||
|
|||||||
@ -10,6 +10,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const loginPasswordInput = document.getElementById('login-password');
|
const loginPasswordInput = document.getElementById('login-password');
|
||||||
const loginForm = document.getElementById('login-form');
|
const loginForm = document.getElementById('login-form');
|
||||||
const registerForm = document.getElementById('register-form');
|
const registerForm = document.getElementById('register-form');
|
||||||
|
const formBlock = document.getElementById('block-form');
|
||||||
|
|
||||||
|
|
||||||
let socket;
|
let socket;
|
||||||
let token;
|
let token;
|
||||||
@ -17,7 +19,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// Auto-focus and key handling for AUTH-FORM
|
// Auto-focus and key handling for AUTH-FORM
|
||||||
nicknameInput.focus();
|
nicknameInput.focus();
|
||||||
nicknameInput.addEventListener('keypress', function(event) {
|
nicknameInput.addEventListener('keypress', function (event) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
checkNicknameButton.click();
|
checkNicknameButton.click();
|
||||||
@ -28,6 +30,86 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
registerButton.addEventListener('click', handleRegister);
|
registerButton.addEventListener('click', handleRegister);
|
||||||
loginButton.addEventListener('click', handleLogin);
|
loginButton.addEventListener('click', handleLogin);
|
||||||
|
|
||||||
|
|
||||||
|
/// THEOUCHE NOT CERTAIN ///
|
||||||
|
async function createPlayer(name, totalMatch = 0, totalWin = 0, pWin = null, mScoreMatch = null, mScoreAdvMatch = null, bestScore = 0, mNbrBallTouch = null, totalDuration = null, mDuration = null, numParticipatedTournaments = 0, numWonTournaments = 0) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/create_player/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name,
|
||||||
|
total_match: totalMatch,
|
||||||
|
total_win: totalWin,
|
||||||
|
p_win: pWin,
|
||||||
|
m_score_match: mScoreMatch,
|
||||||
|
m_score_adv_match: mScoreAdvMatch,
|
||||||
|
best_score: bestScore,
|
||||||
|
m_nbr_ball_touch: mNbrBallTouch,
|
||||||
|
total_duration: totalDuration,
|
||||||
|
m_duration: mDuration,
|
||||||
|
num_participated_tournaments: numParticipatedTournaments,
|
||||||
|
num_won_tournaments: numWonTournaments
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json();
|
||||||
|
throw new Error(errorData.error || 'Network response was not ok');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
// Afficher l'erreur avec un message plus spécifique
|
||||||
|
console.error('Error creating player:', error.message);
|
||||||
|
alert(`Failed to create player: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createTournoi(name, nbr_player, date, winner_id) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/create_tournoi/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ name, nbr_player, date, winner_id })
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating tournoi:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createMatch(player1_id, player2_id, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi_id) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/create_match/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ player1_id, player2_id, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi_id })
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating match:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// THEOUCHE NOT CERTAIN ///
|
||||||
|
|
||||||
async function handleCheckNickname() {
|
async function handleCheckNickname() {
|
||||||
const nickname = nicknameInput.value.trim();
|
const nickname = nicknameInput.value.trim();
|
||||||
if (nickname) {
|
if (nickname) {
|
||||||
@ -38,28 +120,28 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
loginForm.style.display = 'block';
|
loginForm.style.display = 'block';
|
||||||
// Auto-focus and key handling for LOGIN-FORM
|
// Auto-focus and key handling for LOGIN-FORM
|
||||||
loginPasswordInput.focus();
|
loginPasswordInput.focus();
|
||||||
loginPasswordInput.addEventListener('keypress', function(event) {
|
loginPasswordInput.addEventListener('keypress', function (event) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
loginButton.click();
|
loginButton.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
authForm.style.display = 'none';
|
authForm.style.display = 'none';
|
||||||
registerForm.style.display = 'block';
|
registerForm.style.display = 'block';
|
||||||
// Auto-focus and key handling for REGISTER-FORM
|
// Auto-focus and key handling for REGISTER-FORM
|
||||||
passwordInput.focus();
|
passwordInput.focus();
|
||||||
passwordInput.addEventListener('keypress', function(event) {
|
passwordInput.addEventListener('keypress', function (event) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
confirmPasswordInput.focus();
|
confirmPasswordInput.focus();
|
||||||
confirmPasswordInput.addEventListener('keypress', function(event) {
|
confirmPasswordInput.addEventListener('keypress', function (event) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
registerButton.click();
|
registerButton.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error checking user existence:', error);
|
console.error('Error checking user existence:', error);
|
||||||
@ -90,8 +172,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
try {
|
try {
|
||||||
const result = await registerUser(nickname, password);
|
const result = await registerUser(nickname, password);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
//await createPlayer(nickname);
|
||||||
registerForm.style.display = 'none';
|
registerForm.style.display = 'none';
|
||||||
gameContainer.style.display = 'flex';
|
gameContainer.style.display = 'flex';
|
||||||
|
formBlock.style.display = 'none';
|
||||||
startWebSocketConnection(token);
|
startWebSocketConnection(token);
|
||||||
} else {
|
} else {
|
||||||
alert('Registration failed. Please try again.');
|
alert('Registration failed. Please try again.');
|
||||||
@ -127,6 +211,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (result) {
|
if (result) {
|
||||||
loginForm.style.display = 'none';
|
loginForm.style.display = 'none';
|
||||||
gameContainer.style.display = 'flex';
|
gameContainer.style.display = 'flex';
|
||||||
|
formBlock.style.display = 'none';
|
||||||
startWebSocketConnection(token);
|
startWebSocketConnection(token);
|
||||||
} else {
|
} else {
|
||||||
alert('Authentication failed. Please try again.');
|
alert('Authentication failed. Please try again.');
|
||||||
@ -195,6 +280,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
document.getElementById('player1-name').textContent = `${player1_name}`;
|
document.getElementById('player1-name').textContent = `${player1_name}`;
|
||||||
document.getElementById('player2-name').textContent = `${player2_name}`;
|
document.getElementById('player2-name').textContent = `${player2_name}`;
|
||||||
document.addEventListener('keydown', handleKeyDown);
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
|
|||||||
@ -1,32 +1,53 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Pong Game</title>
|
<title>Pong Game</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'styles.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'styles.css' %}">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="{% static 'logo-42-perpignan.png' %}" alt="Logo">
|
||||||
|
</div>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="auth-form">
|
<div class="background">
|
||||||
<label for="nickname">Enter your nickname:</label>
|
<div class="stars" id="stars"></div>
|
||||||
<input type="text" id="nickname" name="nickname">
|
|
||||||
<button id="check-nickname">Check Nickname</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="register-form" style="display: none;">
|
<div class="pong-elements">
|
||||||
<label for="password">Enter your password:</label>
|
<div class="paddle paddle-left"></div>
|
||||||
<input type="password" id="password" name="password">
|
<div class="paddle paddle-right"></div>
|
||||||
<label for="confirm-password">Confirm your password:</label>
|
<div class="ball_anim"></div>
|
||||||
<input type="password" id="confirm-password" name="confirm-password">
|
|
||||||
<button id="register">Register</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="login-form" style="display: none;">
|
|
||||||
<label for="login-password">Enter your password:</label>
|
<div class="container" id="block-form">
|
||||||
<input type="password" id="login-password" name="login-password">
|
<h1>BIENVENUE DANS LE PONG 42</h1>
|
||||||
<button id="login">Login</button>
|
<div class="input-container">
|
||||||
|
<div id="auth-form">
|
||||||
|
<label for="nickname">Enter your nickname:</label>
|
||||||
|
<input type="text" id="nickname" name="nickname">
|
||||||
|
<button id="check-nickname">Check Nickname</button>
|
||||||
|
</div>
|
||||||
|
<div id="register-form" style="display: none;">
|
||||||
|
<label for="password">Enter your password:</label>
|
||||||
|
<input type="password" id="password" name="password">
|
||||||
|
<label for="confirm-password">Confirm your password:</label>
|
||||||
|
<input type="password" id="confirm-password" name="confirm-password">
|
||||||
|
<button id="register">Register</button>
|
||||||
|
</div>
|
||||||
|
<div id="login-form" style="display: none;">
|
||||||
|
<label for="login-password">Enter your password:</label>
|
||||||
|
<input type="password" id="login-password" name="login-password">
|
||||||
|
<button id="login">Login</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="game1" style="display: none;">
|
<div id="game1" style="display: none;">
|
||||||
<div id="gameCode" class="game-code">Game Code: </div>
|
<div id="gameCode" class="game-code">Game Code : </div>
|
||||||
<div id="player1-name" class="name">Player 1</div>
|
<div id="player1-name" class="name">Player 1</div>
|
||||||
<div id="player2-name" class="name">Player 2</div>
|
<div id="player2-name" class="name">Player 2</div>
|
||||||
<div id="game2">
|
<div id="game2">
|
||||||
@ -37,6 +58,22 @@
|
|||||||
<div id="ball"></div>
|
<div id="ball"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="{% static 'game.js' %}"></script>
|
<script src="{% static 'game.js' %}"></script>
|
||||||
|
<script>
|
||||||
|
const starsContainer = document.getElementById('stars');
|
||||||
|
for (let i = 0; i < 500; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = 'star';
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDuration = `${Math.random() * 2 + 1}s`;
|
||||||
|
starsContainer.appendChild(star);
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(createTrail, 100);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
BIN
pong/static/logo-42-perpignan.png
Normal file
BIN
pong/static/logo-42-perpignan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
@ -1,15 +1,18 @@
|
|||||||
/* General styles */
|
/* General styles */
|
||||||
body {
|
body,
|
||||||
|
html {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
color: #ffffff;
|
color: #00ffff;
|
||||||
background-color: #000000;
|
background-color: #0a0a2a;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -23,8 +26,23 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
padding: 10px 20px;
|
background-color: #00ffff;
|
||||||
|
color: #000033;
|
||||||
|
border: none;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #000033;
|
||||||
|
color: #00ffff;
|
||||||
|
box-shadow: 0 0 20px #00ffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#game1 {
|
#game1 {
|
||||||
@ -32,6 +50,8 @@ button {
|
|||||||
height: 500px;
|
height: 500px;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
border: 3px solid #00ffff;
|
||||||
|
box-shadow: 0 0 30px #00ffff, inset 0 0 20px #00ffff;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -55,11 +75,13 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#player1-name {
|
#player1-name {
|
||||||
left: 10px; /* Adjust player score position */
|
left: 10px;
|
||||||
|
/* Adjust player score position */
|
||||||
}
|
}
|
||||||
|
|
||||||
#player2-name {
|
#player2-name {
|
||||||
right: 10px; /* Adjust bot score position */
|
right: 10px;
|
||||||
|
/* Adjust bot score position */
|
||||||
}
|
}
|
||||||
|
|
||||||
#game2 {
|
#game2 {
|
||||||
@ -69,7 +91,8 @@ button {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 2px solid red; /* Add red border */
|
border: 2px solid white;
|
||||||
|
/* Add red border */
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -82,11 +105,13 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#player1-score {
|
#player1-score {
|
||||||
left: 50px; /* Adjust player score position */
|
left: 50px;
|
||||||
|
/* Adjust player score position */
|
||||||
}
|
}
|
||||||
|
|
||||||
#player2-score {
|
#player2-score {
|
||||||
right: 50px; /* Adjust bot score position */
|
right: 50px;
|
||||||
|
/* Adjust bot score position */
|
||||||
}
|
}
|
||||||
|
|
||||||
.pad {
|
.pad {
|
||||||
@ -107,7 +132,122 @@ button {
|
|||||||
#ball {
|
#ball {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
background-color: #ff0000;
|
background-color: #ffffff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
font-size: 3rem;
|
||||||
|
color: #00ffff;
|
||||||
|
text-shadow: 0 0 15px #00ffff;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stars {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: twinkle 2s infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pong-elements {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddle {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: #00ffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 15px #00ffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddle-left {
|
||||||
|
left: 50px;
|
||||||
|
animation: paddleMove 5s infinite alternate ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddle-right {
|
||||||
|
right: 50px;
|
||||||
|
animation: paddleMove 4s infinite alternate-reverse ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ball_anim {
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #00ffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 20px #00ffff;
|
||||||
|
left: 80px;
|
||||||
|
top: 50%;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
animation: ballMove 3s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes paddleMove {
|
||||||
|
0% {
|
||||||
|
transform: translateY(10vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateY(70vh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ballMove {
|
||||||
|
0% {
|
||||||
|
transform: translateZ(0) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translateZ(-500px) scale(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateZ(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
background-color: rgba(0, 0, 40, 0.8);
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 3px solid #00ffff;
|
||||||
|
box-shadow: 0 0 30px #00ffff, inset 0 0 20px #00ffff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user