<
/
}
]
[
=
*
o

NOUS LES DEVS

A qui le tour ?

A la conquête du jeux vidéo partie 13

Niveau : expert(e)
</> </> </>

Qui commence ?

C’est bien beau de lancer la partie mais si je ne définis pas qui doit commencer, les joueurs ne pourront rien faire.

Donc maintenant je vais distribuer des indexes au joueurs, et parmi les indexes distribués, je vais en tirer un aléatoirement et c’est celui-ci qui commencera la partie.

J’ajoute une nouvelle propriété à la partie, que j’ai nommée « courant » et qui va me servir à stocker les données courantes du jeu. Au passage, je définis la notion du jour, la météo et l’argent.

init_partie(id){
	e("> init partie");
	//attribution des index au joueurs
	let index_id = 0;
	for(let index in this.parties[ id ].list_players ){
		this.parties[ id ].list_players[index]["index"] = index_id; 
		index_id++;
	}
	
	//get random index
	let random_index = Math.floor( Math.random() * parseInt(this.parties[ id ].map.nbr_joueur) );
	let player_id 	 = Object.keys(this.parties[ id ].list_players)[random_index];
	
	//parametre courant
	this.parties[ id ].courant = {
		beginner 			: random_index,
		aquiletour_index 	: random_index,
		aquiletour  		: player_id,
		jour 				: 1,
		units				: {}		
	};
	
	//propriete
	this.parties[ id ].properties = {
		fog 	: true,
		weather : "sun",
		money 	: 2000
	}

	//initialisaiton argent joueur 1	
	this.parties[ id ].list_players[ player_id ].money = this.parties[ id ].properties.money;
}

Maintenant que je sais qui commence la partie, j’adapte les données envoyées pour chaque joueur de cette partie.

this.init_partie(params.partie_id);

for(let token in this.parties[ params.partie_id ].list_players ){
	this.users[ token ].state = "fight";
	this.send_to_specific_client( this.users[token].socket_id, "message", { action : "response_launch_partie", params : { 
		result 		: true, 
		map 		: this.parties[ params.partie_id ].map,
		aquiletour  	: this.parties[ params.partie_id ].courant.aquiletour,
		jour		: this.parties[ params.partie_id ].courant.jour,
		money		: this.parties[ params.partie_id ].list_players[ token ].money,
	} });	
}

Index

Dans la méthode response_launch_partie, j’ajoute une classe color concaténée avec l’index du joueur, à la grille des unités, ce qui va permettre de coloriser plus facilement les unités.

response_launch_partie(params){	
	if( params.result == true ){
		//...
		
		//ajout de la classe pour stylisé les unités
		$("#grid #map_units").addClass("color_" + this.index_player);

	}
}

Menu

Au niveau de l’interface, j’ajoute une section interface_jeu, dans laquelle je vais mettre les différentes options du jeu en phase de combat. Et j’ajoute le premier bouton pour donner la posibilité au joueur de finir son tour.

<div id="interface">
	<a href="#" id="action_end_turn">Finir le tour</a>
</div>

J’adapte de nouveau la méthode response_launch_partie pour afficher ou masquer l’interface et si c’est au joueur de commencer alors je lance la méthode launch_start_turn.

response_launch_partie(params){	
	if( params.result == true ){
		//...
		
		//check is my turn
		if( this.token == params.aquiletour ){
			$("#interface").addClass("current_turn");
			this.launch_start_turn(params);
		}else{
			$("#interface").removeClass("current_turn");
		}
	}
}

Et je crée le système d’événements qui va me permettre de finir le tour.

launch_start_turn(params){
	//bindage des evenements en cours du tour
	$("#interface").off("click.end_turn").on("click.end_turn", "#action_end_turn", () => this.event_end_turn() );
}

Fin de tour côté client

Lorsqu’un joueur clique sur le bouton « Finir le tour », la requête request_end_turn est envoyée au serveur.

event_end_turn(){
	this.send_to_server("message",{ action : "request_end_turn" , params : { token : this.token } });	
}

Fin de tour côté serveur

Lorsque le serveur reçoit une demande de « fin de tour », je vérifie que le joueur a bien le droit de passer le tour (en gros je vérifie que c’est le joueur courant). Si oui, je lance la requête de validation de fin de tour et j’exécute la méthode next_turn pour récupérer les données du prochain joueur que je stocke dans dans la propriété « courant » de la partie et je gère l’incrémentation du jour et l’ajout de l’argent pour le nouveau joueur. Je lance la requête response_start_turn pour que le prochain joueur puisse commencer son tour.

request_end_turn(user_socket, params){
	e("Request end turn");
	e("================");
	
	let partie_id = this.users[ params.token ].current_partie;
	
	//verification de la fin du tour d'un joueur
	if( params.token == this.parties[ partie_id ].courant.aquiletour ){			
		//definir la fin du tour au joueur qui envois la requete
		this.send_to_client( user_socket, "message" , { action : "response_end_turn" } );

		//process tour joueur suivant
		let player_id = this.next_turn( params.token, partie_id );

		this.send_to_specific_client(this.users[ player_id ].socket_id, "message", { action : "response_start_turn", params : {
			aquiletour  : this.parties[ partie_id ].courant.aquiletour,
			jour		: this.parties[ partie_id ].courant.jour,
			money		: this.parties[ partie_id ].list_players[ player_id ].money,
		} });			
	}else{
		//cas ou un joueur lance une requete de fin de tour mais que ce n'est pas sont tour
	}
}

next_turn(user_token, partie_id){
	e("BEGIN NEXT TURN");
	e("================");

	let player_id = null;

	//increment index next players
	let index = this.parties[ partie_id ].courant.aquiletour_index + 1;
	if( index >= this.parties[ partie_id ].map.nbr_joueur ){
		index = 0;
	}

	//ajout des valeurs de aquiletour
	this.parties[ partie_id ].courant.aquiletour_index = index;
	player_id = Object.keys(this.parties[ partie_id ].list_players)[ index ];
	this.parties[ partie_id ].courant.aquiletour = player_id;

	//incrementation du jour si ont reviens sur le owner
	if( index == this.parties[ partie_id ].courant.beginner){
		this.parties[ partie_id ].courant.jour++;
	}
	
	//ajout argent (pour le moment simple addition)
	let money = this.parties[ partie_id ].list_players[ player_id ].money;
	if(money == null){
		money = 0;
	}
	this.parties[ partie_id ].list_players[ player_id ].money = money + this.parties[ partie_id ].properties.money;

	return player_id;
}

Réponse

Quand le joueur reçoit la validation de la fin de son tour, alors l’interface est masqué.

response_end_turn(){
	$("#interface").removeClass("current_turn");
}

Début du tour

Lorsque le serveur procède au changement de tour, le prochain joueur recoit la réponse response_start_turn qui va afficher l’interface et appeler la méthode launch_start_turn.

response_start_turn(params){
	$("#interface").addClass("current_turn");
	this.launch_start_turn(params);
}

Et ça marche super bien, quand j’ouvre deux navigateurs et que je passe le tour sur l’un, alors le bouton disparait et l’option apparait sur l’autre navigateur.

18/08/2016

Yann Vangampelaere - nouslesdevs -

NOUS LES DEVS

Vous aimez ce que je fais ? Vous voulez que j'en fasse plus ? dans le développement du blog.