Pong

Game engine experiences
Open source code

Présentation

Pong est un jeu vidéo inspiré du “tennis de table” développé par Ralph Baer et son équipe à Sanders Associates en 1967. Après y avoir joué lors d’une première démonstration en mai 1972, Nolan Bushnell, créateur de la société Atari, en fait une version améliorée : Pong. Puisque le nom Ping-Pong est déjà une marque déposée, ils l’ont simplement appelé Pong. C’est le premier jeu vidéo à connaître un succès populaire, mais la forme la plus ancienne d’un jeu électronique de ping-pong remonte à un jeu jouable sur un oscilloscope, créé par William A. Higinbotham au laboratoire national de Brookhaven en 1958. Son jeu était intitulé “Tennis for Two”.

Le concept original de Pong est une simulation simpliste de tennis de table (ping-pong). Au tennis de table, les joueurs se tiennent de chaque côté d’une table et manient une raquette pour frapper une petite balle qui se déplace entre eux dans les deux sens. Une petite balle, se déplace à travers l’écran, rebondissant sur les rebords du haut et du bas, et les deux joueurs commandent chacun une raquette, la faisant glisser verticalement entre les extrémités de l’écran à l’aide des contrôles. Si la balle frappe la raquette, elle rebondit vers l’autre joueur. Si elle manque la raquette, l’autre joueur marque un point. La balle rebondit de différentes manières selon la façon dont elle touche la raquette.

Pong peut être joué seul, la raquette opposée est alors commandée par la machine ; ou à deux joueurs, chacun commandant une raquette. Sur les bornes d’arcade la raquette est habituellement commandée par un bouton rotatif (un paddle), répondant avec une vitesse variable selon la façon dont le joueur la tourne.

Son code ultra simple est à la portée de tous, mais cache également, si l’on gratte un peu la surface, des astuces spécifiques à la réalisation de jeux vidéo, c’est pourquoi tout apprenti développeur de jeu DOIT commencer par essayer de créer un simple PONG avant de tenter de placer la barre plus haut.

Le code Javascript


// charger les images du jeu
var balle = new Image();
var joueur = new Image();
var ordi = new Image();
var fond = new Image();
 
balle.src = "assets/balle.jpg";
fond.src = "assets/fond.jpg";
ordi.src = "assets/raquette.jpg";
joueur.src = "assets/raquette.jpg";
 
window.onload = function() {
 
	// récupère le canva et son contexte
	var canvas = document.getElementById('canvas');
	var ctx = canvas.getContext('2d');
 
	// variables
	var W = 512;
	var H = 256;
	var p1 = {};
	var p2 = {};
	var b = {};
	var mouseX;
	var mouseY;
 
	init();
 
	// initialisation du jeu
	function init() {
 
		canvas.width = W;
		canvas.height = H;
 
		b.w = balle.width;
		b.h = balle.height;
		b.x = W/2-5;
		b.y = H/2-5;
		b.vX = (parseInt(Math.random()*2)-1|1)*(Math.random()*6+2);
		b.vY = (parseInt(Math.random()*2)-1|1)*(Math.random()*6+2);
 
		p2.w = ordi.width;
		p2.h = ordi.height;
		p2.x = W-25;
		p2.y = (H-p2.h)/2;
		p2.score = 0;
 
		p1.w = joueur.width;
		p1.h = joueur.height;
		p1.x = 15;
		p1.y = (H-p1.h)/2;
		p1.score = 0;
 
		mouseY = p1.y;
 
		canvas.addEventListener("mousemove", souris, false);
		setInterval(main, 15);
	}
 
	// boucle principale
	function main(){
 
		// ordinateur
		if (b.y<p2.y) p2.y -= 5;
		if (b.y>p2.y) p2.y += 5;
 
		// joueur
		p1.y = mouseY;
 
		// limite des objets
		limites(p1);
		limites(p2);
 
		// balle
		with (b) {	
 
			x += vX;
			y += vY;
			if (y<10) y=10,  vY*=-1;
			if (y>246-h) y=246-h, vY*=-1;
			if (x<0) initBalle(), p2.score++;
			if (x>492) initBalle(), p1.score++;
 
			if(collisions(b,p1)) {
				x = p1.x+p1.w+10;
				vX *= -1;
				vY = -Math.round((p1.y+p1.h/2)-(y+h/2)*.2)%8;
			}
			if(collisions(b,p2)) {
				x = p2.x-b.w-10;
				vX *= -1;
				vY = -Math.round((p2.y+p2.h/2)-(y+h/2)*.2)%8;
			}
		}
 
		// dessin final
		render();
	} 
 
	function initBalle(){
		b.x = W/2-5;
		b.y = H/2-5;
		b.vY = (parseInt(Math.random()*2)-1|1)*(Math.random()*6+2);	
	}
 
	// limites des raquettes
	function limites(ob){
		if (ob.y<10)  ob.y = 10;
		if (ob.y>256-ob.h) ob.y = 256-ob.h;
	}
 
	// collisions
	function collisions(A,B) {
		if (A.y+A.h < B.y || A.y > B.y+B.h || A.x > B.x+B.w || A.x+A.w < B.x) return false;
		return true;
	}
 
	// Dessine le jeu
	function render() {	
		ctx.drawImage(fond,0,0);
		ctx.drawImage(balle, b.x, b.y);
		ctx.drawImage(ordi, p2.x, p2.y);
		ctx.drawImage(joueur, p1.x, p1.y);
		draw_score();
	}
 
	function souris(e){
	  if (e.x != undefined && e.y != undefined){
			mouseX = e.x;
			mouseY = e.y;
        } else {
			// Firefox patch
			mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }
	} 
 
	// Affiche le score
	function draw_score() {		
		ctx.fillStyle = "white";
		ctx.font = "24px Arial";
		ctx.textAlign = "right";
		ctx.fillText(p1.score + " ", W/2, 30);
		ctx.textAlign = "left";
		ctx.fillText(" " + p2.score, W/2, 30);
	}
}

A retenir

PONG est un jeu très simple au programme vraiment accessible, c’est pourquoi j’ai profité de celui-ci pour pousser un peu sur la rédaction du code. Les libertés que j’ai prises ne sont bien évidemment pas une obligation. Cependant en réfléchissant un peu vous trouverez tout un tas d’astuces qui vous permettrons de réduire la taille de votre code sans perdre en lisibilité (voire en y gagnant selon les cas), si pour un programme comme PONG au code simpliste, cela n’a pas un intérêt flagrant, lorsque vous allez vous attaquer à des jeux plus gros cela va rapidement devenir indispensable, notez cependant qu’il vaut mieux toujours privilégier l’optimisation du programme à la compression du code, autrement dit ce n’est pas parce qu’un code est plus court que son fonctionnement est forcément plus optimisé.

Toute l’astuce réside ici dans l’embryon d’intelligence artificielle que l’on donne au programme pour apprendre à jouer. Pour ce genre d’IA toute simple il suffit de créer un comportement parfait que l’on dégrade pour obtenir des réactions imparfaites, on parle en fait plus d’automates que de programme réellement intelligent, mais c’est une base suffisante pour démarrer et qui a le mérite de s’adapter facilement pour de nombreux jeux vidéos.

Commentaires

avatar
  S’abonner  
S'abonner
Facebook Google Linked Skype Twitter
© 2019 Cmarzin - Tous droits réservés | SIRET: 483 511 101 00030 | Mentions légales