Outils pour utilisateurs

Outils du site


javascript:game_dev:brick_breaker_example

Exemple: Brick Breaker

Il s'agit d'une exemple très basique (et non terminé) de Brick Breaker, dans lequel une boule se déplace sur l'écran alors que le jouer contrôle un paddle qu'il déplace de gauche à droite en utilisant les touches fléchées du clavier.

Brick Breaker

Structure du projet

/BrickBreaker
    /css
        main.css
    /img
        ball.png
    /src
        Ball.js
        Game.js
        InputHandler.js
        main.js
        Paddle.js
    index.html

Page HTML et CSS

Ne pas oublier d'utiliser la propriété type=“module” dans la balise script lorsqu'on inclut le script JS principal !!!

index.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<title>Brick Breaker</title>
	<link rel="stylesheet" href="css/main.css">
</head>
<body>
 
	<!-- Canvas -->
	<canvas id="gamescreen" class="gamescreen"></canvas>
 
	<!-- Les images sont incluses dans l'HTML mais -->
	<!-- elles sont cachées au niveau du CSS       -->
	<img id="imgBall" src="img/ball.png">
 
	<!-- Inclure script principal en tant que module -->
	<script type="module" src="src/main.js"></script>
 
</body>
</html>
css/main.css
html, body {
	margin: 0;
	padding: 0;
	overflow: hidden;
}
 
img {
	/* rendre les images invisibles */
	display: none;
}
 
.gamescreen {
	background: #EEF;
}

Module principal

src/main.js
import Game from './Game.js';
 
let canvas = document.getElementById("gamescreen");
let context = canvas.getContext("2d");
 
// Mettre le canvas aux dimensions de la fenêtre
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
 
let game = new Game(canvas.width, canvas.height);
game.start();
 
let lastTime = 0;
 
function gameLoop(timestamp) {
	let deltaTime = timestamp - lastTime;
	lastTime = timestamp;
 
	context.clearRect(0, 0, canvas.width, canvas.height);
 
	game.update(deltaTime);
	game.draw(context);
 
	requestAnimationFrame(gameLoop);
}
 
requestAnimationFrame(gameLoop);

Classe Game

src/Game.js
import Paddle       from "./Paddle.js";
import InputHandler from "./InputHandler.js";
import Ball         from "./Ball.js";
 
export default class Game {
 
	constructor(gameWidth, gameHeight) {
		this.gameWidth = gameWidth;
		this.gameHeight = gameHeight;
	}
 
	start() {
		this.paddle = new Paddle(this);
		this.ball = new Ball(this);
 
		this.gameObjects = [
			this.ball,
			this.paddle,
		];
 
		new InputHandler(this.paddle);
	}
 
	update(deltaTime) {
		this.gameObjects.forEach(object => object.update(deltaTime));
	}
 
	draw(context) {
		this.gameObjects.forEach(object => object.draw(context));
	}
 
}

Classe Paddle

src/Paddle.js
export default class Paddle {
 
	constructor(game) {
		this.gameWidth = game.gameWidth;
		this.gameHeight = game.gameHeight;
 
		this.width = 150;
		this.height = 30;
 
		this.maxSpeed = 7;
		this.speed = 0;
 
		this.position = {
			x: this.gameWidth / 2 - this.width / 2,
			y: this.gameHeight - this.height - 10,
		}
	}
 
	moveLeft() {
		this.speed = -this.maxSpeed;
	}
 
	moveRight() {
		this.speed = this.maxSpeed;
	}
 
	stop() {
		this.speed = 0;
	}
 
	update(deltaTime) {
		this.position.x += this.speed;
 
		if(this.position.x < 0)
			this.position.x = 0;
 
		if(this.position.x + this.width > this.gameWidth)
			this.position.x = this.gameWidth - this.width;
	}
 
	draw(context) {
		context.fillStyle = '#0ff';
		context.fillRect(
			this.position.x,
			this.position.y,
			this.width,
			this.height
		);
	}
 
}

Classe Ball

src/Ball.js
export default class Ball {
 
	constructor(game) {
		this.image = document.getElementById("imgBall");
 
		this.gameWidth = game.gameWidth;
		this.gameHeight = game.gameHeight;
 
		this.position = {
			x: 10,
			y: 10,
		};
 
		this.speed = {
			x: 5,
			y: 3,
		};
 
		this.size = 16;
	}
 
	update(deltaTime) {
		this.position.x += this.speed.x;
		this.position.y += this.speed.y;
 
		if(this.position.x + this.size > this.gameWidth || this.position.x < 0) {
			this.speed.x = -this.speed.x;
		}
 
		if(this.position.y + this.size > this.gameHeight || this.position.y < 0) {
			this.speed.y = -this.speed.y;
		}
	}
 
	draw(context) {
		context.drawImage(this.image,
			this.position.x, this.position.y, 
			this.size, this.size);
	}
 
}

Classe InputHandler

src/InputHandler.js
export default class InputHandler {
 
	constructor(paddle) {
 
		document.addEventListener("keydown", event => {
			switch(event.keyCode) {
				case 37:
					paddle.moveLeft();
					break;
				case 39:
					paddle.moveRight();
					break;
			}
		});
 
		document.addEventListener("keyup", event => {
			switch(event.keyCode) {
				case 37:
					if(paddle.speed < 0)
						paddle.stop();
					break;
				case 39:
					if(paddle.speed > 0)
						paddle.stop();
					break;
			}
		});
	}
 
}
javascript/game_dev/brick_breaker_example.txt · Dernière modification: 2020/06/27 09:53 (modification externe)