first commit
This commit is contained in:
Executable
+1
@@ -0,0 +1 @@
|
||||
Require all granted
|
||||
Executable
+131
@@ -0,0 +1,131 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>2048 Game</title>
|
||||
<style>
|
||||
body {
|
||||
background: #faf8ef;
|
||||
font-family: "Arial", sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
color: #776e65;
|
||||
}
|
||||
#game-container {
|
||||
width: 400px;
|
||||
margin: 20px auto;
|
||||
background: #bbada0;
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.tile {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
background: #cdc1b4;
|
||||
border-radius: 6px;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
line-height: 90px;
|
||||
color: #776e65;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>2048</h1>
|
||||
<p>Utilizer les flèches pour controler le jeu!</p>
|
||||
<div id="game-container"></div>
|
||||
<script>
|
||||
const container = document.getElementById("game-container");
|
||||
let grid = [];
|
||||
|
||||
function init() {
|
||||
grid = Array.from({length:4}, ()=>Array(4).fill(0));
|
||||
addTile();
|
||||
addTile();
|
||||
draw();
|
||||
}
|
||||
|
||||
function draw() {
|
||||
container.innerHTML = "";
|
||||
for(let i=0;i<4;i++){
|
||||
for(let j=0;j<4;j++){
|
||||
const tile = document.createElement("div");
|
||||
tile.classList.add("tile");
|
||||
if(grid[i][j]!==0){
|
||||
tile.textContent = grid[i][j];
|
||||
tile.style.background = getTileColor(grid[i][j]);
|
||||
tile.style.color = grid[i][j]>4?"#f9f6f2":"#776e65";
|
||||
}
|
||||
container.appendChild(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTileColor(n){
|
||||
const colors = {2:"#eee4da",4:"#ede0c8",8:"#f2b179",16:"#f59563",32:"#f67c5f",64:"#f65e3b",128:"#edcf72",256:"#edcc61",512:"#edc850",1024:"#edc53f",2048:"#edc22e"};
|
||||
return colors[n]||"#3c3a32";
|
||||
}
|
||||
|
||||
function addTile(){
|
||||
let empty = [];
|
||||
for(let i=0;i<4;i++) for(let j=0;j<4;j++) if(grid[i][j]===0) empty.push([i,j]);
|
||||
if(empty.length===0) return;
|
||||
const [i,j] = empty[Math.floor(Math.random()*empty.length)];
|
||||
grid[i][j] = Math.random()<0.9?2:4;
|
||||
}
|
||||
|
||||
function slide(row){
|
||||
let arr = row.filter(v=>v!==0);
|
||||
for(let i=0;i<arr.length-1;i++){
|
||||
if(arr[i]===arr[i+1]){ arr[i]*=2; arr[i+1]=0; }
|
||||
}
|
||||
return arr.filter(v=>v!==0).concat(Array(4-arr.filter(v=>v!==0).length).fill(0));
|
||||
}
|
||||
|
||||
function rotate(grid){
|
||||
return grid[0].map((_,i)=>grid.map(row=>row[i]));
|
||||
}
|
||||
|
||||
document.addEventListener("keydown",e=>{
|
||||
let moved=false;
|
||||
if(e.key==="ArrowLeft"){
|
||||
for(let i=0;i<4;i++){
|
||||
const row=grid[i].slice();
|
||||
grid[i]=slide(grid[i]);
|
||||
if(!moved && row.join()!=grid[i].join()) moved=true;
|
||||
}
|
||||
} else if(e.key==="ArrowRight"){
|
||||
for(let i=0;i<4;i++){
|
||||
const row=grid[i].slice();
|
||||
grid[i]=slide(grid[i].reverse()).reverse();
|
||||
if(!moved && row.join()!=grid[i].join()) moved=true;
|
||||
}
|
||||
} else if(e.key==="ArrowUp"){
|
||||
grid = rotate(grid);
|
||||
for(let i=0;i<4;i++){
|
||||
const row=grid[i].slice();
|
||||
grid[i]=slide(grid[i]);
|
||||
if(!moved && row.join()!=grid[i].join()) moved=true;
|
||||
}
|
||||
grid = rotate(rotate(rotate(grid)));
|
||||
} else if(e.key==="ArrowDown"){
|
||||
grid = rotate(grid);
|
||||
for(let i=0;i<4;i++){
|
||||
const row=grid[i].slice();
|
||||
grid[i]=slide(grid[i].reverse()).reverse();
|
||||
if(!moved && row.join()!=grid[i].join()) moved=true;
|
||||
}
|
||||
grid = rotate(rotate(rotate(grid)));
|
||||
}
|
||||
if(moved) addTile();
|
||||
draw();
|
||||
});
|
||||
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
Require all granted
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Star Wars</title>
|
||||
<script src="../ruffle/ruffle.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #282a36;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#game-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- IMPORTANT: allowfullscreen must be here -->
|
||||
<div id="game-container" allowfullscreen></div>
|
||||
|
||||
<script>
|
||||
const ruffle = window.RufflePlayer.newest();
|
||||
const player = ruffle.createPlayer();
|
||||
|
||||
// Enable Ruffle fullscreen API
|
||||
player.style.width = "100%";
|
||||
player.style.height = "100%";
|
||||
|
||||
document.getElementById("game-container").appendChild(player);
|
||||
|
||||
player.load("AdventCalendar.swf");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
BIN
Binary file not shown.
Executable
+28
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Penguin Dinner</title>
|
||||
<script src="../ruffle/ruffle.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #282a36;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="game-container"></div>
|
||||
|
||||
<script>
|
||||
const ruffle = window.RufflePlayer.newest();
|
||||
const player = ruffle.createPlayer();
|
||||
document.getElementById("game-container").appendChild(player);
|
||||
player.load("Penguindinner.swf"); // change this for each game
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
BIN
Binary file not shown.
Executable
+28
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rollercoaster Creator</title>
|
||||
<script src="../ruffle/ruffle.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #282a36;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="game-container"></div>
|
||||
|
||||
<script>
|
||||
const ruffle = window.RufflePlayer.newest();
|
||||
const player = ruffle.createPlayer();
|
||||
document.getElementById("game-container").appendChild(player);
|
||||
player.load("Rollercoaster.swf"); // change this for each game
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
BIN
Binary file not shown.
Executable
+58
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Boules :o</title>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; background: black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
<script>
|
||||
const canvas = document.getElementById('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
let balls = [];
|
||||
|
||||
canvas.addEventListener('click', e => {
|
||||
balls.push({
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
vx: (Math.random() - 0.5) * 8,
|
||||
vy: (Math.random() - 0.5) * 8,
|
||||
radius: Math.random() * 20 + 10,
|
||||
color: `hsl(${Math.random()*360}, 100%, 50%)`
|
||||
});
|
||||
});
|
||||
|
||||
function animate() {
|
||||
ctx.fillStyle = 'rgba(0,0,0,0.3)';
|
||||
ctx.fillRect(0,0,canvas.width,canvas.height);
|
||||
|
||||
balls.forEach(ball => {
|
||||
ball.x += ball.vx;
|
||||
ball.y += ball.vy;
|
||||
|
||||
if (ball.x < ball.radius || ball.x > canvas.width - ball.radius) ball.vx *= -1;
|
||||
if (ball.y < ball.radius || ball.y > canvas.height - ball.radius) ball.vy *= -1;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2);
|
||||
ctx.fillStyle = ball.color;
|
||||
ctx.fill();
|
||||
});
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
animate();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Emoji Rain</title>
|
||||
<style>
|
||||
body { margin:0; overflow:hidden; background:#222; font-family:sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
<script>
|
||||
const canvas = document.getElementById('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
const emojis = ['😀','😂','😎','🥳','🌟','🍕','💖','🐱','🔥','💀','🐸'];
|
||||
let drops = Array.from({length:50}, ()=>({
|
||||
x: Math.random()*canvas.width,
|
||||
y: Math.random()*canvas.height,
|
||||
speed: Math.random()*3+1,
|
||||
emoji: emojis[Math.floor(Math.random()*emojis.length)]
|
||||
}));
|
||||
|
||||
function animate() {
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
drops.forEach(d=>{
|
||||
ctx.font = '30px serif';
|
||||
ctx.fillText(d.emoji,d.x,d.y);
|
||||
d.y += d.speed;
|
||||
if(d.y>canvas.height){ d.y=0; d.x=Math.random()*canvas.width; }
|
||||
});
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
animate();
|
||||
|
||||
window.addEventListener('resize', () => { canvas.width=window.innerWidth; canvas.height=window.innerHeight; });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="UwU Nixiews UwU" />
|
||||
<meta property="og:description" content="Run Debian and Gentoo, why not after all? Anyway, hope you're not a Windows fanboy because it sucks :3" />
|
||||
<meta property="og:image" content="https://nix.roulaise.net/data/media/Guweiz1.jpeg" />
|
||||
<meta property="og:url" content="https://nix.roulaise.net" />
|
||||
<meta property="og:type" content="website" />
|
||||
<title>Nixiews UwU</title>
|
||||
<link rel="stylesheet" href="/data/style.css">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="data/media/icon_circle.png">
|
||||
</head>
|
||||
<body>
|
||||
<script src="/data/js/bg.js"></script>
|
||||
<video id="bg-video" autoplay muted loop playsinline></video>
|
||||
<img id="bg-image" alt="Background">
|
||||
|
||||
<div class="container">
|
||||
<h1>Nixiews >:3</h1>
|
||||
<header>**OFFICIAL** Discord GIF vendor</header>
|
||||
|
||||
<div class="card">
|
||||
<a href="pong/">PONG</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="2048.html">2048</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="bouncing.html">Bouncing</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="emoji.html">Emoji</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="index.html">Index</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="jeux_flash.html">Jeux Flash</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="snake.html">Snake</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="snow.html">Snow</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="terminal.html">Terminal</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="tictactoe.html">Tic Tac Toe</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<a href="/">Racine</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>Ce serveur fonktionne :)</footer>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Jeux Flash</title>
|
||||
<link rel="stylesheet" href="../data/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Des classiques!</h1>
|
||||
|
||||
<!-- Game Cards -->
|
||||
<div class="card"><a href="Flash/RC.html">Rollercoaster Creator</a></div>
|
||||
<div class="card"><a href="Flash/PD.html">Penguin Dinner</a></div>
|
||||
<!--
|
||||
<div class="card"><a href="game3/index.html">🧩 Game 3: Fancy Pants Adventure</a></div>
|
||||
<div class="card"><a href="game4/index.html">🕹️ Game 4: The Impossible Quiz</a></div>
|
||||
-->
|
||||
|
||||
<!-- Add more games as needed -->
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
© 2025 Classic Web Games • Hosted with ❤️
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
{"name":"@ruffle-rs/ruffle","version":"0.2.0-nightly.2025.10.10","description":"Putting Flash back on the web. Ruffle will polyfill all Flash content and replace it with the Ruffle flash player.","license":"(MIT OR Apache-2.0)","keywords":["flash","swf"],"homepage":"https://ruffle.rs","bugs":"https://github.com/ruffle-rs/ruffle/issues","repository":"github:ruffle-rs/ruffle","main":"ruffle.js"}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pong de Caleb</title>
|
||||
<link rel="stylesheet" href="pong.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="start-screen" class="screen">
|
||||
<h1>PONG</h1>
|
||||
<button id="start-button">Jouer</button>
|
||||
<div class="controls">
|
||||
<h3>Contrôles :</h3>
|
||||
<p>Joueur 1 (Gauche) : W (haut) et S (bas)</p>
|
||||
<p>Joueur 2 (Droite) : Flèches Haut/Bas</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="game-container" style="display: none;">
|
||||
<div id="score">
|
||||
<span id="player1-score">0</span> - <span id="player2-score">0</span>
|
||||
</div>
|
||||
<canvas id="board"></canvas>
|
||||
</div>
|
||||
|
||||
<div id="game-over" class="screen" style="display: none;">
|
||||
<h1>Fin de la partie !</h1>
|
||||
<h2 id="winner-text"></h2>
|
||||
<button id="restart-button">Rejouer</button>
|
||||
</div>
|
||||
|
||||
<script src="pong.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #1a1a2e, #16213e);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.screen {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
z-index: 10;
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
margin-bottom: 2rem;
|
||||
color: #00b4d8;
|
||||
text-shadow: 0 0 10px rgba(0, 180, 216, 0.5);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #90e0ef;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 30px;
|
||||
font-size: 1.2rem;
|
||||
background: #00b4d8;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin: 10px;
|
||||
box-shadow: 0 4px 15px rgba(0, 180, 216, 0.3);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #0096c7;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 180, 216, 0.4);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
#game-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#score {
|
||||
font-size: 2.5rem;
|
||||
color: #fff;
|
||||
margin-bottom: 20px;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
#board {
|
||||
background-color: #0d1b2a;
|
||||
border: 3px solid #00b4d8;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 30px rgba(0, 180, 216, 0.3);
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-top: 2rem;
|
||||
background: rgba(13, 27, 42, 0.8);
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #1b4965;
|
||||
}
|
||||
|
||||
.controls h3 {
|
||||
color: #90e0ef;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.controls p {
|
||||
margin: 0.5rem 0;
|
||||
color: #caf0f8;
|
||||
}
|
||||
|
||||
/* Animation pour le bouton de démarrage */
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
#start-button {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
/* Style pour l'écran de fin de jeu */
|
||||
#game-over {
|
||||
background: rgba(13, 27, 42, 0.95);
|
||||
}
|
||||
|
||||
/* Style pour le score en jeu */
|
||||
#score {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 2rem;
|
||||
color: #fff;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Style pour le canvas */
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Pong Game</title>
|
||||
<style>
|
||||
body {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
background: #222;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Pong 🏓</h1>
|
||||
<canvas id="game" width="600" height="400"></canvas>
|
||||
<p>Joueur à gauche, utilisez W/S pour jouer.</p>
|
||||
<script>
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const paddleWidth = 10, paddleHeight = 80, ballSize = 10;
|
||||
let player = { x: 0, y: canvas.height/2 - paddleHeight/2, dy: 0, score: 0 };
|
||||
let ai = { x: canvas.width - paddleWidth, y: canvas.height/2 - paddleHeight/2, dy: 2, score: 0 };
|
||||
let ball = { x: canvas.width/2, y: canvas.height/2, dx: 4, dy: 4 };
|
||||
|
||||
function drawRect(x, y, w, h, color) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(x, y, w, h);
|
||||
}
|
||||
|
||||
function drawCircle(x, y, r, color) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, r, 0, Math.PI*2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function draw() {
|
||||
drawRect(0, 0, canvas.width, canvas.height, "#222");
|
||||
drawRect(player.x, player.y, paddleWidth, paddleHeight, "lime");
|
||||
drawRect(ai.x, ai.y, paddleWidth, paddleHeight, "red");
|
||||
drawCircle(ball.x, ball.y, ballSize, "white");
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = "20px sans-serif";
|
||||
ctx.fillText(`${player.score} : ${ai.score}`, canvas.width/2 - 20, 30);
|
||||
}
|
||||
|
||||
function update() {
|
||||
ball.x += ball.dx;
|
||||
ball.y += ball.dy;
|
||||
|
||||
// Ball collision with top/bottom
|
||||
if (ball.y < 0 || ball.y > canvas.height) ball.dy *= -1;
|
||||
|
||||
// Ball collision with player paddle
|
||||
if (ball.x < player.x + paddleWidth && ball.x > player.x &&
|
||||
ball.y > player.y && ball.y < player.y + paddleHeight) {
|
||||
ball.dx *= -1;
|
||||
ball.x = player.x + paddleWidth;
|
||||
}
|
||||
|
||||
// Ball collision with AI paddle
|
||||
if (ball.x > ai.x - ballSize && ball.x < ai.x + paddleWidth &&
|
||||
ball.y > ai.y && ball.y < ai.y + paddleHeight) {
|
||||
ball.dx *= -1;
|
||||
ball.x = ai.x - ballSize;
|
||||
}
|
||||
|
||||
// Score
|
||||
if (ball.x < 0) { ai.score++; resetBall(); }
|
||||
if (ball.x > canvas.width) { player.score++; resetBall(); }
|
||||
|
||||
// Move AI
|
||||
if (ball.y < ai.y + paddleHeight/2) ai.y -= ai.dy;
|
||||
else ai.y += ai.dy;
|
||||
if (ai.y < 0) ai.y = 0;
|
||||
if (ai.y + paddleHeight > canvas.height) ai.y = canvas.height - paddleHeight;
|
||||
|
||||
// Move player
|
||||
player.y += player.dy;
|
||||
if (player.y < 0) player.y = 0;
|
||||
if (player.y + paddleHeight > canvas.height) player.y = canvas.height - paddleHeight;
|
||||
}
|
||||
|
||||
function resetBall() {
|
||||
ball.x = canvas.width/2;
|
||||
ball.y = canvas.height/2;
|
||||
ball.dx *= -1;
|
||||
ball.dy = 4 * (Math.random() > 0.5 ? 1 : -1);
|
||||
}
|
||||
|
||||
function gameLoop() {
|
||||
update();
|
||||
draw();
|
||||
requestAnimationFrame(gameLoop);
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", e => {
|
||||
if (e.key === "w") player.dy = -4;
|
||||
if (e.key === "s") player.dy = 4;
|
||||
});
|
||||
document.addEventListener("keyup", e => {
|
||||
if (e.key === "w" || e.key === "s") player.dy = 0;
|
||||
});
|
||||
|
||||
requestAnimationFrame(gameLoop);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+344
@@ -0,0 +1,344 @@
|
||||
// Configuration du jeu
|
||||
const config = {
|
||||
boardWidth: 800,
|
||||
boardHeight: 500,
|
||||
playerWidth: 10,
|
||||
playerHeight: 80,
|
||||
ballSize: 12,
|
||||
winningScore: 5
|
||||
};
|
||||
|
||||
// Éléments du DOM
|
||||
let board, context;
|
||||
let startScreen, gameContainer, gameOverScreen;
|
||||
let scoreElement, player1ScoreElement, player2ScoreElement, winnerText;
|
||||
|
||||
// État du jeu
|
||||
let score1 = 0;
|
||||
let score2 = 0;
|
||||
let gameRunning = false;
|
||||
let animationId = null;
|
||||
|
||||
// Joueurs
|
||||
let player1 = {
|
||||
x: 30,
|
||||
y: config.boardHeight / 2 - config.playerHeight / 2,
|
||||
width: config.playerWidth,
|
||||
height: config.playerHeight,
|
||||
velocityY: 0,
|
||||
speed: 8
|
||||
};
|
||||
|
||||
let player2 = {
|
||||
x: config.boardWidth - 30 - config.playerWidth,
|
||||
y: config.boardHeight / 2 - config.playerHeight / 2,
|
||||
width: config.playerWidth,
|
||||
height: config.playerHeight,
|
||||
velocityY: 0,
|
||||
speed: 8
|
||||
};
|
||||
|
||||
// Balle
|
||||
let ball = {
|
||||
x: config.boardWidth / 2,
|
||||
y: config.boardHeight / 2,
|
||||
width: config.ballSize,
|
||||
height: config.ballSize,
|
||||
velocityX: 5,
|
||||
velocityY: 0
|
||||
};
|
||||
|
||||
// Initialisation du jeu
|
||||
window.onload = function() {
|
||||
// Initialisation des éléments du DOM
|
||||
board = document.getElementById("board");
|
||||
context = board.getContext("2d");
|
||||
|
||||
// Configuration du canvas
|
||||
board.width = config.boardWidth;
|
||||
board.height = config.boardHeight;
|
||||
|
||||
// Récupération des éléments d'interface
|
||||
startScreen = document.getElementById("start-screen");
|
||||
gameContainer = document.getElementById("game-container");
|
||||
gameOverScreen = document.getElementById("game-over");
|
||||
player1ScoreElement = document.getElementById("player1-score");
|
||||
player2ScoreElement = document.getElementById("player2-score");
|
||||
winnerText = document.getElementById("winner-text");
|
||||
|
||||
// Configuration des écouteurs d'événements
|
||||
document.getElementById("start-button").addEventListener("click", startGame);
|
||||
document.getElementById("restart-button").addEventListener("click", resetGame);
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
document.addEventListener("keyup", handleKeyUp);
|
||||
|
||||
// Afficher l'écran de démarrage
|
||||
showScreen("start");
|
||||
};
|
||||
|
||||
// Gestion des écrans
|
||||
function showScreen(screen) {
|
||||
startScreen.style.display = screen === "start" ? "flex" : "none";
|
||||
gameContainer.style.display = screen === "game" ? "block" : "none";
|
||||
gameOverScreen.style.display = screen === "gameOver" ? "flex" : "none";
|
||||
}
|
||||
|
||||
// Démarrer une nouvelle partie
|
||||
function startGame() {
|
||||
resetGame();
|
||||
showScreen("game");
|
||||
gameRunning = true;
|
||||
update();
|
||||
}
|
||||
|
||||
// Réinitialiser le jeu
|
||||
function resetGame() {
|
||||
// Réinitialiser les scores
|
||||
score1 = 0;
|
||||
score2 = 0;
|
||||
updateScore();
|
||||
|
||||
// Réinitialiser les positions des joueurs
|
||||
player1.y = config.boardHeight / 2 - player1.height / 2;
|
||||
player2.y = config.boardHeight / 2 - player2.height / 2;
|
||||
|
||||
// Réinitialiser la balle
|
||||
resetBall();
|
||||
}
|
||||
|
||||
// Réinitialiser la balle au centre
|
||||
function resetBall() {
|
||||
ball.x = config.boardWidth / 2 - ball.width / 2;
|
||||
ball.y = config.boardHeight / 2 - ball.height / 2;
|
||||
ball.velocityX = Math.random() > 0.5 ? 5 : -5;
|
||||
ball.velocityY = (Math.random() * 6) - 3;
|
||||
}
|
||||
|
||||
// Mettre à jour l'affichage des scores
|
||||
function updateScore() {
|
||||
player1ScoreElement.textContent = score1;
|
||||
player2ScoreElement.textContent = score2;
|
||||
|
||||
// Vérifier si un joueur a gagné
|
||||
if (score1 >= config.winningScore || score2 >= config.winningScore) {
|
||||
endGame();
|
||||
}
|
||||
}
|
||||
|
||||
// Fin de la partie
|
||||
function endGame() {
|
||||
gameRunning = false;
|
||||
cancelAnimationFrame(animationId);
|
||||
|
||||
// Déterminer le gagnant
|
||||
const winner = score1 > score2 ? "Joueur 1" : "Joueur 2";
|
||||
winnerText.textContent = `${winner} a gagné !`;
|
||||
|
||||
// Afficher l'écran de fin de partie
|
||||
showScreen("gameOver");
|
||||
}
|
||||
|
||||
// Boucle de jeu principale
|
||||
function update() {
|
||||
if (!gameRunning) return;
|
||||
|
||||
// Effacer le canvas
|
||||
context.clearRect(0, 0, config.boardWidth, config.boardHeight);
|
||||
|
||||
// Dessiner le terrain
|
||||
drawField();
|
||||
|
||||
// Mettre à jour et dessiner les joueurs
|
||||
updatePlayer(player1);
|
||||
updatePlayer(player2);
|
||||
drawPlayer(player1);
|
||||
drawPlayer(player2);
|
||||
|
||||
// Mettre à jour et dessiner la balle
|
||||
updateBall();
|
||||
drawBall();
|
||||
|
||||
// Vérifier les collisions
|
||||
checkCollisions();
|
||||
|
||||
// Continuer la boucle d'animation
|
||||
animationId = requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
// Dessiner le terrain
|
||||
function drawField() {
|
||||
// Fond
|
||||
context.fillStyle = "#0d1b2a";
|
||||
context.fillRect(0, 0, config.boardWidth, config.boardHeight);
|
||||
|
||||
// Ligne médiane en pointillés
|
||||
context.strokeStyle = "rgba(255, 255, 255, 0.2)";
|
||||
context.setLineDash([10, 10]);
|
||||
context.beginPath();
|
||||
context.moveTo(config.boardWidth / 2, 0);
|
||||
context.lineTo(config.boardWidth / 2, config.boardHeight);
|
||||
context.stroke();
|
||||
context.setLineDash([]);
|
||||
}
|
||||
|
||||
// Mettre à jour la position d'un joueur
|
||||
function updatePlayer(player) {
|
||||
// Mettre à jour la position
|
||||
player.y += player.velocityY;
|
||||
|
||||
// Limites du terrain
|
||||
if (player.y < 0) player.y = 0;
|
||||
if (player.y + player.height > config.boardHeight) {
|
||||
player.y = config.boardHeight - player.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Dessiner un joueur
|
||||
function drawPlayer(player) {
|
||||
context.fillStyle = "#00b4d8";
|
||||
context.fillRect(player.x, player.y, player.width, player.height);
|
||||
|
||||
// Effet de brillance
|
||||
const gradient = context.createLinearGradient(player.x, 0, player.x + player.width, 0);
|
||||
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');
|
||||
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
|
||||
context.fillStyle = gradient;
|
||||
context.fillRect(player.x, player.y, player.width / 2, player.height);
|
||||
}
|
||||
|
||||
// Mettre à jour la position de la balle
|
||||
function updateBall() {
|
||||
ball.x += ball.velocityX;
|
||||
ball.y += ball.velocityY;
|
||||
|
||||
// Rebond sur les bords haut et bas
|
||||
if (ball.y <= 0 || ball.y + ball.height >= config.boardHeight) {
|
||||
ball.velocityY *= -1;
|
||||
}
|
||||
|
||||
// Vérifier si un joueur marque un point
|
||||
if (ball.x < 0) {
|
||||
// Joueur 2 marque un point
|
||||
score2++;
|
||||
updateScore();
|
||||
resetBall();
|
||||
} else if (ball.x > config.boardWidth) {
|
||||
// Joueur 1 marque un point
|
||||
score1++;
|
||||
updateScore();
|
||||
resetBall();
|
||||
}
|
||||
}
|
||||
|
||||
// Dessiner la balle
|
||||
function drawBall() {
|
||||
// Effet de brillance
|
||||
const gradient = context.createRadialGradient(
|
||||
ball.x + ball.width / 2,
|
||||
ball.y + ball.height / 2,
|
||||
0,
|
||||
ball.x + ball.width / 2,
|
||||
ball.y + ball.height / 2,
|
||||
ball.width / 2
|
||||
);
|
||||
gradient.addColorStop(0, '#ffffff');
|
||||
gradient.addColorStop(1, '#90e0ef');
|
||||
|
||||
context.fillStyle = gradient;
|
||||
context.beginPath();
|
||||
context.arc(
|
||||
ball.x + ball.width / 2,
|
||||
ball.y + ball.height / 2,
|
||||
ball.width / 2,
|
||||
0,
|
||||
Math.PI * 2
|
||||
);
|
||||
context.fill();
|
||||
|
||||
// Effet de lueur
|
||||
context.shadowColor = '#00b4d8';
|
||||
context.shadowBlur = 15;
|
||||
context.fill();
|
||||
context.shadowBlur = 0;
|
||||
}
|
||||
|
||||
// Vérifier les collisions
|
||||
function checkCollisions() {
|
||||
// Collision avec le joueur 1 (gauche)
|
||||
if (ball.x <= player1.x + player1.width &&
|
||||
ball.x + ball.width >= player1.x &&
|
||||
ball.y + ball.height >= player1.y &&
|
||||
ball.y <= player1.y + player1.height) {
|
||||
|
||||
// Inverser la direction horizontale
|
||||
ball.velocityX = Math.abs(ball.velocityX);
|
||||
|
||||
// Ajuster la direction verticale en fonction de l'endroit où la balle touche la raquette
|
||||
const hitPosition = (ball.y - (player1.y + player1.height / 2)) / (player1.height / 2);
|
||||
ball.velocityY = hitPosition * 8;
|
||||
|
||||
// Augmenter légèrement la vitesse
|
||||
ball.velocityX *= 1.05;
|
||||
ball.velocityY *= 1.05;
|
||||
}
|
||||
|
||||
// Collision avec le joueur 2 (droite)
|
||||
if (ball.x + ball.width >= player2.x &&
|
||||
ball.x <= player2.x + player2.width &&
|
||||
ball.y + ball.height >= player2.y &&
|
||||
ball.y <= player2.y + player2.height) {
|
||||
|
||||
// Inverser la direction horizontale
|
||||
ball.velocityX = -Math.abs(ball.velocityX);
|
||||
|
||||
// Ajuster la direction verticale
|
||||
const hitPosition = (ball.y - (player2.y + player2.height / 2)) / (player2.height / 2);
|
||||
ball.velocityY = hitPosition * 8;
|
||||
|
||||
// Augmenter légèrement la vitesse
|
||||
ball.velocityX *= 1.05;
|
||||
ball.velocityY *= 1.05;
|
||||
}
|
||||
}
|
||||
|
||||
// Gestion des touches enfoncées
|
||||
function handleKeyDown(e) {
|
||||
// Joueur 1 (W/S)
|
||||
if (e.key.toLowerCase() === 'w') {
|
||||
player1.velocityY = -player1.speed;
|
||||
} else if (e.key.toLowerCase() === 's') {
|
||||
player1.velocityY = player1.speed;
|
||||
}
|
||||
|
||||
// Joueur 2 (Flèches)
|
||||
if (e.key === 'ArrowUp') {
|
||||
player2.velocityY = -player2.speed;
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
player2.velocityY = player2.speed;
|
||||
}
|
||||
|
||||
// Touche Espace pour démarrer/redémarrer
|
||||
if (e.code === 'Space' && !gameRunning) {
|
||||
if (startScreen.style.display === 'flex') {
|
||||
startGame();
|
||||
} else if (gameOverScreen.style.display === 'flex') {
|
||||
resetGame();
|
||||
startGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gestion du relâchement des touches
|
||||
function handleKeyUp(e) {
|
||||
// Joueur 1 (W/S)
|
||||
if ((e.key.toLowerCase() === 'w' && player1.velocityY < 0) ||
|
||||
(e.key.toLowerCase() === 's' && player1.velocityY > 0)) {
|
||||
player1.velocityY = 0;
|
||||
}
|
||||
|
||||
// Joueur 2 (Flèches)
|
||||
if ((e.key === 'ArrowUp' && player2.velocityY < 0) ||
|
||||
(e.key === 'ArrowDown' && player2.velocityY > 0)) {
|
||||
player2.velocityY = 0;
|
||||
}
|
||||
}
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
Require all granted
|
||||
Executable
BIN
Binary file not shown.
Executable
+176
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2018 Ruffle LLC <ruffle@ruffle.rs> and Ruffle contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
# ruffle-selfhosted
|
||||
|
||||
ruffle-selfhosted is the intended way to get Ruffle onto your website.
|
||||
|
||||
You may either include it and forget about it, and we will polyfill existing Flash content,
|
||||
or use our APIs for custom configurations or more advanced usages of the Ruffle player.
|
||||
|
||||
## Using ruffle-selfhosted
|
||||
|
||||
For more examples and in-depth documentation on how to use Ruffle on your website, please
|
||||
[check out our wiki](https://github.com/ruffle-rs/ruffle/wiki/Using-Ruffle#web).
|
||||
|
||||
### Host Ruffle
|
||||
|
||||
The `selfhosted` package is configured for websites that do not use bundlers or npm and just want
|
||||
to get up and running. If you'd prefer to use Ruffle through npm and a bundler, please
|
||||
[refer to ruffle core](https://github.com/ruffle-rs/ruffle/tree/master/web/packages/core).
|
||||
|
||||
Before you can get started with using Ruffle on your website, you must host its files yourself.
|
||||
Either take the [latest build](https://github.com/ruffle-rs/ruffle/releases)
|
||||
or [build it yourself](https://github.com/ruffle-rs/ruffle/blob/master/web/README.md), and make these files accessible by your web server.
|
||||
|
||||
Please note that the `.wasm` file must be served properly, and some web servers may not do that
|
||||
correctly out of the box. Please see [our wiki](https://github.com/ruffle-rs/ruffle/wiki/Using-Ruffle#configure-wasm-mime-type)
|
||||
for instructions on how to configure this, if you encounter a `Incorrect response MIME type` error.
|
||||
|
||||
### "Plug and Play"
|
||||
|
||||
If you have an existing website with flash content, you can simply include Ruffle as a script and
|
||||
our polyfill magic will replace everything for you. No fuss, no mess.
|
||||
|
||||
```html
|
||||
<script src="path/to/ruffle/ruffle.js"></script>
|
||||
```
|
||||
|
||||
### Javascript API
|
||||
|
||||
If you want to control the Ruffle player, you may use our Javascript API.
|
||||
|
||||
```html
|
||||
<script>
|
||||
window.RufflePlayer = window.RufflePlayer || {};
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
let ruffle = window.RufflePlayer.newest();
|
||||
let player = ruffle.createPlayer();
|
||||
let container = document.getElementById("container");
|
||||
container.appendChild(player);
|
||||
player.ruffle().load("movie.swf");
|
||||
});
|
||||
</script>
|
||||
<script src="path/to/ruffle/ruffle.js"></script>
|
||||
```
|
||||
|
||||
## Building, testing or contributing
|
||||
|
||||
Please see [the ruffle-web README](https://github.com/ruffle-rs/ruffle/blob/master/web/README.md).
|
||||
+2
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+2
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Executable
BIN
Binary file not shown.
Executable
+1
@@ -0,0 +1 @@
|
||||
{"name":"@ruffle-rs/ruffle","version":"0.2.0-nightly.2025.10.10","description":"Putting Flash back on the web. Ruffle will polyfill all Flash content and replace it with the Ruffle flash player.","license":"(MIT OR Apache-2.0)","keywords":["flash","swf"],"homepage":"https://ruffle.rs","bugs":"https://github.com/ruffle-rs/ruffle/issues","repository":"github:ruffle-rs/ruffle","main":"ruffle.js"}
|
||||
BIN
Binary file not shown.
Executable
+2
File diff suppressed because one or more lines are too long
Executable
+1
File diff suppressed because one or more lines are too long
Executable
+116
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Snake Game</title>
|
||||
<style>
|
||||
body {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
canvas {
|
||||
background: #222;
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Snake 🐍</h1>
|
||||
<canvas id="game" width="400" height="400"></canvas>
|
||||
<p>Use arrow keys to move. Eat the food, don’t hit yourself!</p>
|
||||
<script>
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const grid = 20;
|
||||
let count = 0;
|
||||
|
||||
let snake = {
|
||||
x: 160,
|
||||
y: 160,
|
||||
dx: grid,
|
||||
dy: 0,
|
||||
cells: [],
|
||||
maxCells: 4
|
||||
};
|
||||
|
||||
let food = {
|
||||
x: 320,
|
||||
y: 320
|
||||
};
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function loop() {
|
||||
requestAnimationFrame(loop);
|
||||
|
||||
if (++count < 4) return;
|
||||
count = 0;
|
||||
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
|
||||
snake.x += snake.dx;
|
||||
snake.y += snake.dy;
|
||||
|
||||
if (snake.x < 0) snake.x = canvas.width - grid;
|
||||
else if (snake.x >= canvas.width) snake.x = 0;
|
||||
if (snake.y < 0) snake.y = canvas.height - grid;
|
||||
else if (snake.y >= canvas.height) snake.y = 0;
|
||||
|
||||
snake.cells.unshift({x: snake.x, y: snake.y});
|
||||
|
||||
if (snake.cells.length > snake.maxCells) snake.cells.pop();
|
||||
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(food.x, food.y, grid-1, grid-1);
|
||||
|
||||
ctx.fillStyle = "lime";
|
||||
snake.cells.forEach((cell, index) => {
|
||||
ctx.fillRect(cell.x, cell.y, grid-1, grid-1);
|
||||
|
||||
if (cell.x === food.x && cell.y === food.y) {
|
||||
snake.maxCells++;
|
||||
food.x = getRandomInt(0, 20) * grid;
|
||||
food.y = getRandomInt(0, 20) * grid;
|
||||
}
|
||||
|
||||
for (let i = index + 1; i < snake.cells.length; i++) {
|
||||
if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
|
||||
snake.x = 160;
|
||||
snake.y = 160;
|
||||
snake.cells = [];
|
||||
snake.maxCells = 4;
|
||||
snake.dx = grid;
|
||||
snake.dy = 0;
|
||||
food.x = getRandomInt(0, 20) * grid;
|
||||
food.y = getRandomInt(0, 20) * grid;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", e => {
|
||||
if (e.key === "ArrowLeft" && snake.dx === 0) {
|
||||
snake.dx = -grid; snake.dy = 0;
|
||||
} else if (e.key === "ArrowUp" && snake.dy === 0) {
|
||||
snake.dy = -grid; snake.dx = 0;
|
||||
} else if (e.key === "ArrowRight" && snake.dx === 0) {
|
||||
snake.dx = grid; snake.dy = 0;
|
||||
} else if (e.key === "ArrowDown" && snake.dy === 0) {
|
||||
snake.dy = grid; snake.dx = 0;
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(loop);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Snowfall Fun</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
}
|
||||
#controls {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="controls">
|
||||
<label for="countSlider">Snow Amount: </label>
|
||||
<input type="range" id="countSlider" min="10" max="500" value="100">
|
||||
<span id="countValue">100</span>
|
||||
</div>
|
||||
|
||||
<canvas id="snowCanvas"></canvas>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('snowCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
let snowflakes = [];
|
||||
let snowCount = 100;
|
||||
|
||||
function createSnowflakes(count) {
|
||||
snowflakes = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
snowflakes.push({
|
||||
x: Math.random() * canvas.width,
|
||||
y: Math.random() * canvas.height,
|
||||
char: '.',
|
||||
speed: Math.random() * 2 + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function drawSnowflakes() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.font = "20px monospace";
|
||||
for (let flake of snowflakes) {
|
||||
ctx.fillText(flake.char, flake.x, flake.y);
|
||||
flake.y += flake.speed;
|
||||
if (flake.y > canvas.height) {
|
||||
flake.y = 0;
|
||||
flake.x = Math.random() * canvas.width;
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(drawSnowflakes);
|
||||
}
|
||||
|
||||
const slider = document.getElementById('countSlider');
|
||||
const countValue = document.getElementById('countValue');
|
||||
slider.addEventListener('input', () => {
|
||||
snowCount = parseInt(slider.value);
|
||||
countValue.textContent = snowCount;
|
||||
createSnowflakes(snowCount);
|
||||
});
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
createSnowflakes(snowCount);
|
||||
});
|
||||
|
||||
createSnowflakes(snowCount);
|
||||
drawSnowflakes();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Retro Terminal</title>
|
||||
<style>
|
||||
body { margin:0; background:black; color:#0f0; font-family:monospace; padding:20px; }
|
||||
input { background:black; color:#0f0; border:none; width:100%; font-family:monospace; font-size:16px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Fake Terminal</h3>
|
||||
<div id="output"></div>
|
||||
<input id="cmd" placeholder="Type command..." autofocus>
|
||||
<script>
|
||||
const output=document.getElementById('output');
|
||||
const input=document.getElementById('cmd');
|
||||
|
||||
const responses = {
|
||||
help: "Try: hello, date, joke",
|
||||
hello: "Hello there, human!",
|
||||
date: new Date().toString(),
|
||||
joke: "Why do programmers prefer dark mode? Because light attracts bugs!"
|
||||
};
|
||||
|
||||
input.addEventListener('keydown', e=>{
|
||||
if(e.key==='Enter'){
|
||||
const cmd=input.value.trim();
|
||||
output.innerHTML += `> ${cmd}<br>`;
|
||||
output.innerHTML += (responses[cmd]||"Command not found") + '<br>';
|
||||
input.value='';
|
||||
window.scrollTo(0,document.body.scrollHeight);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tic-Tac-Toe</title>
|
||||
<style>
|
||||
body { display:flex; flex-direction:column; align-items:center; justify-content:center; height:100vh; font-family:sans-serif; }
|
||||
table { border-collapse: collapse; }
|
||||
td { width:80px; height:80px; text-align:center; vertical-align:middle; font-size:50px; border:2px solid black; cursor:pointer; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Tic-Tac-Toe</h2>
|
||||
<table id="board">
|
||||
<tr><td></td><td></td><td></td></tr>
|
||||
<tr><td></td><td></td><td></td></tr>
|
||||
<tr><td></td><td></td><td></td></tr>
|
||||
</table>
|
||||
<button onclick="reset()">Reset</button>
|
||||
<script>
|
||||
let turn = 'X';
|
||||
const cells = document.querySelectorAll('td');
|
||||
|
||||
cells.forEach(cell => cell.addEventListener('click', () => {
|
||||
if(cell.textContent === '') {
|
||||
cell.textContent = turn;
|
||||
if(checkWin(turn)) alert(turn + ' wins!');
|
||||
turn = turn === 'X' ? 'O' : 'X';
|
||||
}
|
||||
}));
|
||||
|
||||
function checkWin(p) {
|
||||
const b = [...cells].map(c=>c.textContent);
|
||||
const wins = [
|
||||
[0,1,2],[3,4,5],[6,7,8],
|
||||
[0,3,6],[1,4,7],[2,5,8],
|
||||
[0,4,8],[2,4,6]
|
||||
];
|
||||
return wins.some(w => w.every(i => b[i]===p));
|
||||
}
|
||||
|
||||
function reset() { cells.forEach(c=>c.textContent=''); turn='X'; }
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user