JeuWeb - Crée ton jeu par navigateur
Une autre map avec un minimum de requête - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Une autre map avec un minimum de requête (/showthread.php?tid=412)



Une autre map avec un minimum de requête - barst - 09-11-2006

Pour ma map, je pars du principe que celle-ci est constituée de case.
Chaque case contient un type de terrain et peut contenir ou non : un batiment ou un personnage.

Je pars aussi du principe que je n'ai pas envie de déporter la gestion des coordonnées des éléments de la map sur ces éléments.
En effet, les coordonnées n'intéressent que la map.

Donc je créé d'abord 3 tables pour les bâtiments, les persos et les types de terrains.
Code PHP :
<?php 
CREATE TABLE
`batiment` (
`
id` smallint(6) NOT NULL auto_increment,
`
image` varchar(50) NOT NULL default '',
`
name` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`)
);
CREATE TABLE `perso` (
`
id` smallint(6) NOT NULL auto_increment,
`
image` varchar(50) NOT NULL default '',
`
name` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`)
) ;
CREATE TABLE `terrain` (
`
id` smallint(6) NOT NULL auto_increment,
`
image` varchar(50) NOT NULL default '',
`
name` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`)
) ;

J'ai simplifié ces éléments pour qu'il ait chacun un ID, une image associé et un nom.
Vous pouvez à votre guise rajouter d'autre propriété qui seront exploité lorsque vous agirez sur eux.

Ensuite je créé la table de la map
Code PHP :
<?php 
CREATE TABLE
`map` (
`
x` int(11) NOT NULL default '0',
`
y` int(11) NOT NULL default '0',
`
elt_type` enum('1','2','3') NOT NULL default '1',
`
elt_id` smallint(6) NOT NULL default '0',
PRIMARY KEY (`x`,`y`,`elt_type`)
) ;
Ce que cette table montre c'est un ensemble d'élement associé à des coordonnées.
En gros je peux avoir jusqu'à 3 éléments différents sur une même case : un type de terrain, un batiment et un perso.
Ceci est possible mais dans le déroulement du jeu je bloque le fait qu'un perso soit par dessus un batiment.
Je détermine la nature de l'élemetn sur un case par le champ elt_type :
elt_type = 1 alors c'est un terrain
elt_type = 2 alors c'est un batiment
elt_type = 3 alors c'est un perso

Et je connais le perso précis qui est sur la case grâce au champ elt_id qui est la clé vers la table perso. Réciproquement pour les terrains et bâtiments.


Maintenant je vais mettre le code complet du script, il est commenté donc je ne vais le détailler :
Code PHP :
<?php 
<html>
<
head>
<
script type="text/javascript">
function
go(x,y,act)
{
document.getElementById('x').value=x;
document.getElementById('y').value=y;
document.getElementById('act').value=act;
document.getElementById('actionMap').submit();
}
</
script>
</
head>
<
body>
<?
php

//paramètre de la connexion à la base=======================================
$sql_serveur="XXX";
$sql_login="XXX";
$sql_pass="XXX";
$sql_bdd="XXX";
//ouverture de la connexion================================================
mysql_connect("$sql_serveur","$sql_login","$sql_pass");
mysql_select_db("$sql_bdd");

//liste des types d'element possibles=========================================
//sur la map il peut y avoir nu terrain simple, ou un batiment ou un joueur==========
$elt_type = array();
$elt_type['GROUND'] = 1;
$elt_type['BUILD'] = 2;
$elt_type['USER'] = 3;

//taille totale de la map=====================================================
$lim_x = 100;
$lim_y = 50;
//taille de la map visible====================================================
$vis_x = 5;
$vis_y = 5;

//Votre PJ===============================================================
$user_id = 1;

//on regarde s'il y a une action à réaliser=====================================
if(isset($_POST['act']))
{
switch (
$_POST['act'])
{
//si vous ajoutez des caractéristiques particulères à vos batiments, personnage ou terrain, c'est ici qu'il faut les gerer
//ex : ce que l'on peut trouver dans le batiment
//ex : les points de vie du perso attaqué
//ex : si le terrain est mortel : sabel mouvant, mer profonde....
case 'MOVE' :
//on met à jour la position du joueur==============================
mysql_query("update map set x=".$_POST["x"].",y=".$_POST["y"]." where elt_type='".$elt_type['USER']."' and elt_id=".$user_id);
print
'Vous venez de vous déplacer en ['.$_POST["x"].','.$_POST["y"].'].<br />';
break;
case
'ATTACK' :
//on tue le joueur que l'on a attaqué==============================
mysql_query("delete from map where elt_type='".$elt_type['USER']."' and x=".$_POST["x"]." and y=".$_POST["y"]);
print
'Vous venez d\'attaquer.<br />';
break;
case
'EXPLORE' :
//on fouille le batiment=========================================
print 'Vous venez de trouver 100 pièces d\'or.<br />';
break;
}
}

//on recupere la position du joueur par son id et son type========================
$user_pos = mysql_fetch_array(mysql_query("select x,y from map where elt_type='".$elt_type['USER']."' and elt_id='".$user_id."'"));

//on determine les bords du cadre à afficher=================================
$delta_x=floor($vis_x/2); // marge entre le joueur et le bord horizontalement
$delta_y=floor($vis_y/2); // marge entre le joueur et le bord veticalement
$x=1;
$y=1;
//si le joueur est proche du bord gauche====================================
if(1>($user_pos['x']-$delta_x)) $x = 1;
//si le joueur est proche du bord droit======================================
else if($lim_x<($user_pos['x']+$delta_x)) $x= $lim_x-$vis_x;
//sinon================================================================
else $x = ($user_pos['x']-$delta_x);
//si le joueur est proche du bord supérieur=================================
if(1>($user_pos['y']-$delta_y)) $y = 1;
//si le joueur est proche du bord inférieur=================================
else if($lim_y<($user_pos['y']+$delta_y)) $y= $lim_y-$vis_y;
//sinon================================================================
else $y = ($user_pos['y']-$delta_y);

//on recupére tout ce qu'il y a sur le terrain dans le cadre à afficher===========
$qry1="select m1.x X,m1.y Y,m1.elt_type TYPE,t.id ID,t.image IMG,t.name NAME from map m1,terrain t where m1.elt_type='".$elt_type['GROUND']."' and m1.elt_id=t.id and m1.x between ".$x." and ".($x+$vis_x-1)." and m1.y between ".$y." and ".($y+$vis_y-1)." ";
$qry2="select m2.x X,m2.y Y,m2.elt_type TYPE,b.id ID,b.image IMG,b.name NAME from map m2,batiment b where m2.elt_type='".$elt_type['BUILD']."' and m2.elt_id=b.id and m2.x between ".$x." and ".($x+$vis_x-1)." and m2.y between ".$y." and ".($y+$vis_y-1)." ";
$qry3="select m3.x X,m3.y Y,m3.elt_type TYPE,p.id ID,p.image IMG,p.name NAME from map m3,perso p where m3.elt_type='".$elt_type['USER']."' and m3.elt_id=p.id and m3.x between ".$x." and ".($x+$vis_x-1)." and m3.y between ".$y." and ".($y+$vis_y-1)." ";
//on utilise les UNION pour tout récupérer en 1 seule requête=================
$result=mysql_query($qry1." union ".$qry2." union ".$qry3);
//on stocke tout dans un tableau multidimension==============================
$map=array();
while(
$row=mysql_fetch_row($result)) $map[$row[0]][$row[1]][$row[2]]=array("img"=>$row[4],"name"=>$row[5]);
//on libere la connexion==================================================
mysql_close();

//on prepare l'affichage de la map=========================================
$text='<table border="1" cellpadding="0" cellspacing="2">';
$text.='<tr><td>&nbsp;</td>';
for(
$j=$y;$j<($y+$vis_y);$j++) $text.='<td>'.$j.'</td>';
$text.='</tr>';
for(
$i=$x;$i<($x+$vis_x);$i++)
{
$text.='<tr><td>'.$i.'</td>';
for(
$j=$y;$j<($y+$vis_y);$j++)
{
//on affiche toujours le terrain en arrière plan============================
$text.='<td style="background-image:url(\''.$map[$i][$j][$elt_type['GROUND']]['img'].'\');width:40px;height:40px;">';
//si un autre element que le terrain est present sur la case on l'affiche au premier plan====
if(isset($map[$i][$j][$elt_type['BUILD']])) $text.='<img src="'.$map[$i][$j][$elt_type['BUILD']]["img"].'" title="'.$map[$i][$j][$elt_type['BUILD']]["name"].'" />';
else if(isset(
$map[$i][$j][$elt_type['USER']])) $text.='<img src="'.$map[$i][$j][$elt_type['USER']]["img"].'" title="'.$map[$i][$j][$elt_type['USER']]["name"].'" />';
else
$text.='&nbsp;';
$text.='</td>';
}
$text.='</tr>';
}
$text.='</table>';
$text.='<br /><br />';
//on recentre le bord du cadre juste autour de soi pour les déplacements
$x = ($user_pos['x']-1);
$y = ($user_pos['y']-1);
//on construit une rose des vents pour les actions==============================
$text.='<form id="actionMap" method="POST" action="map.php">';
$text.='<input type="hidden" id="x" name="x" value="" />'; //valeur x cible de l'action
$text.='<input type="hidden" id="y" name="y" value="" />'; //valeur y cible de l'action
$text.='<input type="hidden" id="act" name="act" value="" />'; //type d'action
$text.='<table border="1" cellpadding="0" cellspacing="0">';
for(
$i=0;$i<3;$i++)
{
$text.='<tr>';
for(
$j=0;$j<3;$j++)
{
if(isset(
$map[$x+$i][$y+$j]))
{
//c'est un batiment donc on explore=============================
if(isset($map[$x+$i][$y+$j][$elt_type['BUILD']])) $text.='<td style="width:100px;"><input type="button" onClick="go('.($x+$i).','.($y+$j).',\'EXPLORE\')" value="explore" /></td>';
//c'est un user doc on attaque==================================
else if(isset($map[$x+$i][$y+$j][$elt_type['USER']]))
{
//c'est moi meme===========================================
if( (($x+$i)==$user_pos['x']) && (($y+$j)==$user_pos['y'])) $text.='<td style="width:100px;">&nbsp;</td>';
//ce personnage n'est pas moi================================
else $text.='<td style="width:100px;"><input type="button" onClick="go('.($x+$i).','.($y+$j).',\'ATTACK\')" value="attack" /></td>';
}
//c'est un terrain donc on peut y aller===========================
// on met le terrain en dernier car il y a toujours un terrain sous un element c'est donc la valeur par defaut
else if(isset($map[$x+$i][$y+$j][$elt_type['GROUND']])) $text.='<td style="width:100px;"><input type="button" onClick="go('.($x+$i).','.($y+$j).',\'MOVE\');" value="move ['.($x+$i).','.($y+$j).']" /></td>';
}
//sinon cette direction conduit en dehors de la map==================
else $text.='<td style="width:100px;">&nbsp;</td>';
}
$text.='</tr>';
}
$text.='</table></form>';

print
$text;
?>



RE: Une autre map avec un minimum de requête - orditeck - 10-11-2006

L'aide pour ce tutoriel ce trouve à cette adresse :
http://www.jeuweb.org/board/showthread.php?tid=627