JeuWeb - Crée ton jeu par navigateur
Map type worldofstargate - 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 : Map type worldofstargate (/showthread.php?tid=3451)

Pages : 1 2


Map type worldofstargate - theptitprince - 14-02-2010

Bonjour à tous!
Dite, je cherche des idées pour coder une carte comme dans le jeu world of stargate... (http://www.worldofstargate.fr/) Vous pouvez avoir un aperçu de leur carte ici: http://www.worldofstargate.fr/images/screens/screen1.png .... Ce que je cherche, c'est savoir comment serait-il possible de la rendre navigable comme dans le jeu, et surtout, si quelqu'un a une idée de comment stocker les coordonnées dans une table SQL, puis les replacer dans la cartes après...
Merci à ceux qui répondront!


RE: Map type worldofstargate - Sephi-Chan - 14-02-2010

Peux-tu expliquer un peu la façon dont on utilise cette carte, savoir ce qu'on peut y faire, etc.
Poser ça sur le papier (sur le forum, en l'occurrence) te permettra d'y voir plus clair et nous permettra de t'aider. Smile

À l'évidence, la carte est définie sur 2 dimensions. Le système est donc assez simple. On doit avoir une table planets avec les colonnes suivantes : id, name, owner_id, galaxy_id, x, y.

Pour générer une carte (en terme de stockage de données), il suffit de créer des planètes et de les associer à une galaxie.

Techniquement, tu crées un tableau à deux dimensions puis tu viens poser des galaxies dessus. Un exemple d'algorithme simple :
  • Tu prends une case de coordonnées aléatoires sur ce tableau ;
  • Tu crée une entrée dans ta table de galaxies (appelons-la galaxies), tu lui donnes un nom et les coordonnées de son centre ;
  • Tu choisis quelques autres cases aléatoires autour de ce point et pour chacun de ces points, tu crée une entrée dans ta table de planètes (appelons-la planets) en leur donnant l'identifiant de galaxie précédemment créée et les coordonnées de la case ;

Après, visuellement, c'est que du HTML et du CSS. Tu génères un bloc pour ton univers, puis dedans tu génères un bloc pour chaque galaxie, puis dans ces blocs tu mets les planètes associées à chaque galaxie. Et tu places tout ça grâce à CSS et les coordonnées que tu as donnés. Tu auras la vue globale de ton univers.

Ensuite, pour faire une vue cible d'une petite zone, c'est une mise à l'échelle d'une petite zone. Une vue relative du type "sur mon rectangle de 500*500, je veux un carré de 40*40 dont le coin supérieur gauche correspond à la case de coordonnées (380; 230).

Après, que tu appelles ça des zones de galaxies, des galaxies, des univers, etc. C'est juste une affaire de nommage de conteneurs.


Sephi-Chan


RE: Map type worldofstargate - xepos - 15-02-2010

Désolé mais je ne comprend pas la partie du HTML et du CSS
Pourrai-tu s'il te plait éclairer ce point ??

Merci d'avance


RE: Map type worldofstargate - Sephi-Chan - 15-02-2010

Pour modéliser mon univers dans le navigateur, je vais générer du HTML qui va décrire mon univers, puis je vais le mettre en forme avec CSS.
Je vais générer dynamiquement un CSS pour mon univers.

Je reprends un exemple d'une expérimentation récente. C'est du Ruby mais je suis sûr que vous comprendrez le principe avec les quelques commentaires que j'ajoute.


class UniversesController < GameController

# Ce code est exécuté quand on envoie une requête HTTP avec la méthode GET aux URL :
# monjeu.com/universes/:id (équivalent à monjeu.com/universes/:id.html)
# monjeu.com/universes/:id.css
def show
@universe = Universe.find(params[:id])

respond_to do |format|
format.html # Va rendre le fichier de vue views/universes/show.html.erb et envoyer un MimeType text/html.
format.css # Va rendre le fichier de vue views/universes/show.css.erb et envoyer un MimeType text/css.
end
end

end

Donc notre contrôleur Universes est capable de donner la représentation HTML et la représentation CSS d'un univers donné.

Dans la vue pour la représentation HTML (views/universes/show.html.erb), on génère le HTML requis :


<link rel="stylesheet"
href="<%= link_to(@universe, :format => :css) %>"
type="text/css"
media="screen"
title="Univers <%= h(@universe.name) %>"
charset="utf-8" />

<div class="universe" id="universe-<%= @universe.id %>">
<% for galaxy in @universe.galaxies %>
<div class="galaxy" id="galaxy-<%= galaxy.id %>">
<% for planet in galaxy.planets %>
<%
ownership = if planet.owner == nil
'belongs_to_nobody'
elsif planet.owner == current_player
'belongs_to_me'
else
'belongs_to_ennemy'
end
%>
<div class="planet <%= ownership %>" id="planet-<%= planet.id %>"></div>
<% end %>
</div>
<% end %>
</div>

Ce sera donc interprété par le serveur, qui va donc générer un HTML qui aura cette tronche là :


<link rel="stylesheet"
href="monjeu.com/universes/1.css"
type="text/css"
media="screen"
title="Univers Alpha"
charset="utf-8" />

<div class="universe" id="universe-1">
<div class="galaxy" id="galaxy-1">
<div class="planet belongs_to_nobody" id="planet-1"></div>
<div class="planet belongs_to_ennemy" id="planet-2"></div>
</div>
<div class="galaxy" id="galaxy-2">
<div class="planet belongs_to_me" id="planet-3"></div>
<div class="planet belongs_to_ennemy" id="planet-4"></div>
<div class="planet belongs_to_nobody" id="planet-5"></div>
</div>
</div>

On a donc un appel à un fichier CSS qui est généré dynamiquement. Ce script (sans doute écrit en PHP, dans votre cas) va renvoyer du texte (souvent vous générez du HTML, là vous allez générer du CSS) et il faudra bien prendre soin de dire au serveur d'envoyer ça comme un fichier CSS, avec le MimeType text/css (pour ça en PHP on utilise la fonction header('Content-type: text/css');).

Pour générer notre CSS, on met donc dans la vue /views/universes/show.css.erb :


.universe {
position: absolute;
background-color: #000;
}

.universe .galaxy {
position: absolute;
}

.universe .planet {
position: absolute
height: 1px;
width: 1px;
background-color: #fff;
}

.universe .planet.belongs_to_me {
background-color: blue;
}

.universe .planet.belongs_to_ennemy {
background-color: red;
}

.universe .planet.belongs_to_nobody {
background-color: grey;
}

#universe-<%= @universe.id %> {
width: <%= @universe.width %>px;
height: <%= @universe.height %>px;
}

/* On boucle sur les galaxies de l'univers. */
<% for galaxy in @universe.galaxies %>
#galaxy-<%= galaxy.id %> {
left: <%= galaxy.x * 10 %>px;
top: <%= galaxy.y * 10 %>px;
}

/* On boucle sur les planètes de la galaxie. */
<% for planet in galaxy.planets %>
#galaxy-<%= planet.id %> {
left: <%= galaxy.x * 10 %>px;
top: <%= galaxy.y * 10 %>px;
}
<% end %>
<% end %>

Le CSS ainsi généré aura une tronche comme :


/* Je zappe la partie statique puisqu'elle reste identique. */

#universe-1 {
width: 500px;
height: 500px;
position: relative;
}

#galaxy-1 {
left: 50px;
top: 30px;
}

#planet-1 {
left: -10px;
top: 20px;
}

/* Etc. */

Voilà, voilà, si vous avez des questions : relisez quelques fois.
Si vous avez encore des questions : posez-les. :p


Sephi-Chan


RE: Map type worldofstargate - theptitprince - 15-02-2010

Dans l'ensemble, tu as assez bien compris mon problème Sephi-Chan. C'est vrai que le stockage SQL est simple, une colonne X, une colonne Y, et quelque colonne autre et c'est fini. (Ma question sur ce point est assez idiote)
Pour décrire le fonctionnement simplement:
la carte du bas, comme tu l'auras deviné est une vue d'ensemble sur la galaxie (ou autre selon le jeu). Quand l'on clique dessus sur un endroit précis, le petit rectangle blanc se déplace sur la zone cliquée. Cette zone cliquée, encadrée d'un petit rectangle blanc est donc en fait une petite parcelle de l'univers que l'on aperçoit en plus gros plan sur la carte du haut.
Et seulement sur la carte en haut il est possible d'interagir sur les planètes. J'espère que mon explication est suffisamment claire... sinon n'hésite pas a me faire signe (je peux te prêter ma paire nom d'utilisateur/mot de passe tu veux voir par toi même le fonctionnement)
Ne programmant que en PHP, et ne connaissant rien en RUBY, je vais devoir passer plus de temps afin de comprendre le mécanisme du code...
Ce qui est sur, c'est que l'image de la "carte du haut" n'est pas un simple zoom de la "carte du bas" car trop rapide au chargement, non respect des couleurs, etc etc...


RE: Map type worldofstargate - Sephi-Chan - 15-02-2010

Donc ton problème, c'est de réaliser une viewbox de la carte globale.

Je ne sais pas comment eux font, mais je vais te proposer deux pistes : la première et la deuxième.

La première piste utilise Javascript. Si tu représentes ton univers dans une bloc de 500*500px, tu as juste à récupérer les coordonnées du clic (relatives au bloc dans lequel on clique) et tu as alors les coordonnées du coin supérieur gauche (je le prends par convention) de ta viewbox.

Exemple : si l'utilisateur clique au point 80, 120 et que ta viewbox fait 100*100, tu sais que l'utilisateur veut afficher le rectangle dont les angles (dans l'ordre supérieur gauche, supérieur droit, inférieur droit, inférieur gauche) sont (80; 120), (80 + 100; 120), (80 + 100; 120 + 100), (80; 120 + 100). Il te suffit donc de chercher les planètes dont les coordonnées absolues sont dans ce carré (je partais du principe qu'on stockait des coordonnées relatives à la galaxie, mais rien n'empêche de stocker ces coordonnées relatives et les absolus (on peut aussi calculer ces derniers aux besoin, mais c'est du gâchis de ressources)).

La deuxième consiste à proposer des viewbox pour une galaxie entière. Si tu as des galaxies dont la représentation graphique (avec les images de planètes, etc.) est plus grande que la viewbox, tu peux oublier (à moins de faire du paning façon Google Maps).

Voilà. N'hésite pas à dessiner et/ou faire des découpages pour modéliser une viewbox. Si comme moi tu es un matheux à chier, ça t'aidera beaucoup. Faut juste accepter d'avoir l'air con si quelqu'un passe.


Sephi-Chan


RE: Map type worldofstargate - theptitprince - 15-02-2010

Edit (18:32 )
C'est bon, j'ai trouvé une solution finale.
Ma carte d'ensemble est donc une image (immuable et clicable) comprise dans un div faisant exactement les dimensions de l'image (la carte). Je récupère les coordonnées de mon clic dans cette div ou sur cette image grâce a un petit javascript, qui une fois exécuté (le javascript) va actualiser un div contenant la carte "zoomée". Cette carte "zoomée" sera généré par php qui récupérera les coordonnées X et Y du javascript d'appel (deux arguments a passer en $_GET[X] et $_GET[Y])...

En fait, ma page pourrait ressembler de loin a ça:

Code :
<html>
<head>

<styleE type="text/css">
<!--
.img_map{
    position:absolute;
    top : 50px;
    left : 20px;  
}
-->
</style>

</head>
<body>

<script language="JavaScript" type="text/javascript">
function Actualise_BigMap(this_){
var map_x = event.clientX - this_.offsetLeft;
var map_y = event.clientY - this_.offsetTop;
document.getElementById('BigMap').contentWindow.document.location.href="map.php?x=" + map_x + "&y=" + map_y;
}
</script>

<div id="BigMap">
</div>

<img src="map.gif" class="img_map" onclick="Actualise_BigMap(this);">

</body>
</html>
Ou map.php me créé une image en fonction de X et Y passé en variable avec la bibliothèque GD et les données stockées que SQL...

Bien entendu, afin de centrer l'image de BigMap, on peut ajouter ou soustraire un petit quelque chose a nos map_x et map_y...

Bon, le code n'a pas été testé, mais dite moi déjà ce que vous en pensez, amélioration possible...? La position de l'image ne me parait pas superbe déjà...? Et la modification de la position de l'image entrainerai des changements dans le JS... Si quelqu'un a une idée... (Je ne maitrise pas vraiment le JS, j'ai fait avec quelque bride de code trouvées a droite a gauche...)


RE: Map type worldofstargate - Sephi-Chan - 15-02-2010

Je ne sais pas si utiliser GD est très judicieux : la génération des images est coûteuse et sera presque systématique tant le nombre de possibilités de viewbox est important.

S'il s'agit juste de positionner des images de planètes, CSS ne fait-il pas l'affaire ?

Concernant Javascript, je ne peux que te conseiller d'utiliser une librairie telle que jQuery. Là, ta solution va à l'encontre de pas mal de bonnes pratiques du développement Javascript. On pourra probablement t'aider sur ce point là. Smile


Sephi-Chan


RE: Map type worldofstargate - theptitprince - 15-02-2010

CSS n'est pas forcément suffisent pour positionner les planètes puisque le nombre de planète par viewbox peut varier...
Quoi en passant encore par des DIV positionnées.... (désolé, je réfléchi en écrivant) Mais chaque planète doit avoir un identifiant différent, car renvoi vers des possibilités différentes selon si elles sont: déjà sous l'emprise d'un autre joueur; inutilisées; ou avec un statuts particulier... (Je compte faire afficher des infos pour chaque planète)...
Cela reste donc encore a creuser de mon coté...

Je vais me renseigner aussi a propos de JQuery (bien que je me demande si ce n'est pas griller les étapes puisque mes connaissances en javascript avoisinent le zéro absolu, voir même un zéro négatif si ça existe Wink )


RE: Map type worldofstargate - Sephi-Chan - 15-02-2010

(15-02-2010, 09:10 PM)theptitprince a écrit : CSS n'est pas forcément suffisent pour positionner les planètes puisque le nombre de planète par viewbox peut varier...
Quoi en passant encore par des DIV positionnées.... (désolé, je réfléchi en écrivant) Mais chaque planète doit avoir un identifiant différent, car renvoi vers des possibilités différentes selon si elles sont: déjà sous l'emprise d'un autre joueur; inutilisées; ou avec un statuts particulier... (Je compte faire afficher des infos pour chaque planète)...
Cela reste donc encore a creuser de mon coté...

Je vais me renseigner aussi a propos de JQuery (bien que je me demande si ce n'est pas griller les étapes puisque mes connaissances en javascript avoisinent le zéro absolu, voir même un zéro négatif si ça existe Wink )

Avoir un CSS dynamique n'est pas un problème du tout, comme en témoigne ma démonstration précédente.
On peut tout à fait imaginer un contrôleur viewbox capable de répondre en HTML et en CSS à une requête de viewbox donnée.

Essaye de voir avec GD mais les risques de plomber les performances sont réelles puisqu'il te sera impossible de mettre en place un dispositif de cache.


Sephi-Chan

Ps : avec quel éditeur développes-tu sur Mac OS ?