GL-MPRI-2014 / Ocawai

OCAWAI
8 stars 3 forks source link

Développement du module interface vers une version d'essai #3

Closed francoisthire closed 9 years ago

francoisthire commented 9 years ago

@VLanvin @iSheeft

Pour aller vers une première version d'essai l'interface devra remplir les points suivants :

(A linker vers les tickets correspondant)

VLanvin commented 9 years ago

Pour bien pouvoir tester il faudrait remplir le dossier resources/textures avec au moins 2 ou 3 tiles. @iSheeft je crois que tu voulais t'en charger non ?

Je suis aussi en train de me dire qu'il faudrait un module Logics qui se chargerait des calculs. Par exemple, étant donné une map et une unité, il calculerait la portée de déplacement de cette unité en fonction du terrain (en renvoyant une Position.t list). Parce qu'il va y avoir plusieurs modules qui vont devoir calculer ça, donc autant centraliser le tout.

francoisthire commented 9 years ago

Faut ouvrir un ticket pour le module de logique !

PLBegay commented 9 years ago

Oui ben ça va, y en a qui ont le cours le jeudi aprèm bordel.

2014-10-16 18:33 GMT+02:00 Saroupille notifications@github.com:

Faut ouvrir un ticket pour le module de logique !

— Reply to this email directly or view it on GitHub https://github.com/VLanvin/GL_MPRI_2014/issues/3#issuecomment-59390686.

VLanvin commented 9 years ago

De toute façon je l'ai ouvert juste après avoir posté mon message.

TheoWinterhalter commented 9 years ago

Quelle taille choisit-on pour les tiles ? J'upload un premier test en 50*50 pixels. Je les édites en eps de toute manière. Est-ce que j'envisage de mettre les eps sur le repo aussi ? Dans un dossier à part ou je ne sais quoi ?

VLanvin commented 9 years ago

Il y a eu quelques ajouts à la partie commune, mais dans la branche interface_dev, notamment sur le module Position. Etant donné que ça a l'air plutôt stable, je vais prochainement merger les changements avec master.

VLanvin commented 9 years ago

Le module Render va avoir besoin de connaître la map, les unités, les joueurs, ainsi que l'unité actuellement sélectionnée. Du coup, je pensais à faire un truc similaire au module "Server" dont on a parlé hier, mais côté interface; c'est à dire un module qui stocke toutes ces données, avec des accesseurs. Comme ça, on balance ça au Render et il se débrouille. Une première interface serait :

type t (un jour, toujours)

val create : Player.t list -> Map.t list -> unit

val select_unit : t -> Unit.t -> unit

val get_selected_unit : t -> Unit.t

val get_map : t -> Map.t

val get_players : t -> Player.t list

Des idées/suggestions ?

Ah et on peut ajouter à cela un module Camera aussi.

TheoWinterhalter commented 9 years ago

Est-ce que le module ne devrait pas avoir également un moyen de connaître le joueur privilégié — s'il ne s'agit pas d'un spectateur — ?

Pour le module Camera, il doit essentiellement connaître la position du curseur non ? Quelles méthodes lui donner ?

Sinon, histoire de prévenir un peu tout le monde, je propose une toute petite implémentation du module Renderqui a pour but de vous offrir le tout premier rendu de notre application qui n'est pas juste une fenêtre noire ! (A tester depuis la branche interface_dev).

VLanvin commented 9 years ago

Joli rendu :)

Oui effectivement il doit connaître le joueur actuel, ne serait-ce que pour afficher le brouillard de guerre. J'avais proposé GameState comme nom de module, en gros il stocke tout ce qu'il faut pour connaître l'état du jeu chez un client à un moment donné.

La Camera doit surtout connaître le curseur, mais il serait bien qu'elle stocke aussi la position du coin haut-gauche. Certes, elle dépend du curseur, mais ça permettrait de gérer le cas où le curseur est collé à un bord par exemple (mieux vaut éviter d'afficher l'extérieur de la map...).

Donc au niveau méthodes je verrais bien :

get_corner : ... -> Position.t
get_cursor : ... -> Position.t
move : ... -> unit

Et peut-être d'autres...

TheoWinterhalter commented 9 years ago

Oui d'accord, je vois. Il faudrait à terme que la caméra soit en mesure de suivre automatiquement les événements quand le joueur regarde les autres (ou quand il s'agit d'un spectateur tout simplement), et qu'elle puisse se centrer aussi sur la position de départ du joueur (pas toujours le coin en haut à gauche quoi).

J'ai ajouté une texture assez moche (mais bon le but c'est juste que ça tourne là) pour les unités. Je peux envisager d'en hardcoder une sur la carte — ce serait très sale — parce que pour l'instant, on n'a pas de truc qui stocke la position des unités.

Par ailleurs, pourrait-on envisager un pull sur master ? Les modules Tile et Battlefieldsont marqués comme temporaires donc ça ne devrait déstabiliser personne.

EDIT — Pour la caméra, le coin en haut à gauche ne suffit pas selon moi. En fait, la taille de la fenêtre a peu de chance de toujours correspondre à un nombre entier de cases. Elle doit donc prendre en considération une position qui est plus proche des pixels.

VLanvin commented 9 years ago

Pour le pull, tu peux faire ton pull request (voire merger, je crois que c'est possible en collaborateur non ?)

La caméra je ne voyais pas ça comme ça en fait. Ca dépendra déjà de savoir si on veut un mouvement fluide (pixel par pixel) ou plutôt case par case à la advance wars. Je pensais la déplacer case par case, et ajuster la taille d'une tile en fonction de la résolution choisie pour éviter qu'un joueur voie vraiment beaucoup plus qu'un autre. Du coup, le coin supérieur gauche tomberait toujours juste, ainsi que le coté droit si la taille des tiles est bien choisie. Le seul "mauvais raccord" potentiel serait le bas (selon la résolution), mais ce n'est pas trop génant, il suffirait d'afficher une ligne de plus dans le pire des cas. Donc effectivement, la caméra devrait prendre en paramètres deux entiers correspondant à la résolution, mais dans ce cas, le coin supérieur gauche suffirait au reste.

Après, peut-être que tout ça n'est qu'une vaste mauvaise idée..

TheoWinterhalter commented 9 years ago

C'est fait !

En revanche, pour la caméra, je pensais en effet à quelque chose de plus smooth. Si c'est possible — dans le cas où la carte s'étend suffisamment dans tous les sens —je pensais que la case où se trouve le curseur serait parfaitement centrée. J'allais commencer le module mais j'imagine qu'il nous faut en discuter un peu plus pour se mettre d'accord.

francoisthire commented 9 years ago

Le hardcoding des pixels pour la tile fait resoulever la question de paramètres pour le rendering :

Est-ce qu'on encapsule les paramètres dans une classe/module , ou bien laisser tel quel un enregistrement passé en paramètre ?

Pour ma part, je prend l'option classe/module, mais je sais que Victor tu n'étais pas partant hier et je ne comprend toujours pas pourquoi.

TheoWinterhalter commented 9 years ago

Là c'est hardcodé parce qu'on a rien décidé. Je suis plutôt pour un affichage qui s'adapte à l'écran (au moins à la taille de la fenêtre) de l'utilisateur.

francoisthire commented 9 years ago

Oui, mais tu ne penses pas que :

TheoWinterhalter commented 9 years ago

Okay, on n'avait juste pas la même notion de paramètres. Effectivement, on peut le gérer. Eventuellement ça peut se retrouver au niveau de la caméra.

VLanvin commented 9 years ago

Tout à fait d'accord, c'est exactement le role de la caméra de gérer ce genre de choses. Il faudra vraiment créer l'objet GameState d'ailleurs, ça évitera de tout hardcoder dans le module Render.

Pour GameState je vois bien un objet global, sans classe puisqu'il ne sera instancié qu'une seule fois, au tout début du programme.

Sinon, j'ai push un joli effet dans le module Render :) Et j'ai aussi push un hotfix de ma fonction neighbours qui était terriblement buguée, le pire c'est que j'ai mis longtemps à trouver le bug. Il faudra re-merge avec master quand ça sera stable, il ne faudrait pas que le moteur utilise la fonction buguée.

EDIT -- D'ailleurs il faudrait faire une jolie texture en noir et blanc pour la fonction de highlight. Pour l'instant c'est qu'un carré gris à bords blancs, il faudrait au moins un joli dégradé partant du centre.

EDIT2 -- On y voit plus rien parce que j'ai un peu trop poussé la transparence. Suffit de changer le paramètre alpha. De toute façon, ça ne sera activé que quand on clique sur une unité.

francoisthire commented 9 years ago

J'y vois plus rien avec ton nouvel effet.

Et oui, c'est bien au niveau de la caméra de gérer ce genre de chose.

TheoWinterhalter commented 9 years ago

C'est sympa Victor :) Et François, soit pas si négatif. Il s'agit de l'highlight des cases qui est appliqué dans des conditions particulières. Il ne s'agit pas juste de décoration. C'est aussi le cas dans Advance Wars.

VLanvin commented 9 years ago

Je suis quand même d'accord qu'on ne distingue plus le "concrete" des "plains". Et la transparence n'y change pas grand chose. En fait je retire ce que j'ai dit, une texture en noir et blanc c'est pas une bonne idée. Il faudrait une texture toujours en dégradé central mais uniquement blanche et avec un alpha de ~30-50 au milieu et ~200 sur les bords. Comme ça on verrait bien le centre de la tile en dessous.

francoisthire commented 9 years ago

Oui c'est exactement ça !

TheoWinterhalter commented 9 years ago

Après, c'est un peu du détail… Le débat autour de la caméra et du GameState est plus important selon moi.

VLanvin commented 9 years ago

Tout à fait, mais c'était pour l'aspect fonctionnel du jeu, même si c'est loin d'être important vu l'état dans lequel il est !

Bref, le GameState, un objet global ça vous paraît bien ? Ou une classe ? A noter qu'il peut se charger d'instancier, dès la construction, la fenêtre, la caméra, etc.. Après il faut trouver un moyen pour qu'il puisse récupérer les données Players/Map/etc.. en provenance du serveur. Ca en ferait un objet avec des champs option mutables.

TheoWinterhalter commented 9 years ago

Ce serait lui qui serait chargé de communiquer avec le serveur ? Je suis pas hyper fan du nom après :p

VLanvin commented 9 years ago

Le nom n'est pas définitif, c'est parce que j'étais resté sur l'idée d'une "state machine", qui au final n'est peut-être pas très utile pour ce qu'on fait.

Nop ça serait pas au module $name_not_found de communiquer avec le serveur, ceux qui gèrent l'interface client/serveur sont censés développer une interface à part. Par contre, il faut que cette interface, après avoir récupéré (parsé, etc..) les données du serveur, stocke les résultats dans le-dit module. En fait, je vois ça uniquement comme un module de stockage, rien de plus. Un moyen d'envoyer toutes les données représentant le jeu aux modules qui en ont besoin, quitte à ce qu'ils n'utilisent pas tout.

TheoWinterhalter commented 9 years ago

Remarque, State ça peut aller (a-t-on besoin de Game ?) et puis je trouve pas mieux. Peut-être qu'un objet nous permettrait d'écrire

state#camera

plutôt que

let camera = State.get_camera

Je ne sais pas si c'est nécessaire après. Mais on pourrait ainsi imaginer le passer à tout le monde.

Après, je propose qu'on ait des objets pour symboliser les parties dans le jeu, elles seraient instanciées par le menu qui est aussi un objet. Les deux ont en commun le fait qu'ils implémentent un main_loop (on va quand même virer tout ça du main).

VLanvin commented 9 years ago

Sinon il y a ClientState, Data, ClientData, ...

Je ne faisais pas spécialement ça pour la syntaxe, mais surtout car ce module a pour but de stocker des données. En général, quand un module manipule un type simple (pair, array, list,...) je ne fais qu'un type abstrait, mais quand il stocke plusieurs données, je préfère un objet à un record. Mais ce sont des goûts purement personnels.

Et pour la boucle je suis d'accord, par contre ça se rapprocherait beaucoup plus d'un State justement. En fait, chaque partie/menu pourrait instancier cette classe abstraite "State" et implémenter l'intérieur de la fonction main_loop. Ensuite, tu envoies cette nouvelle classe à une StateMachine, qui l'empile sur un stack, et son rôle est d'exécuter en boucle la fonction main_loop de la classe en haut de son stack. Je ne sais pas si je suis très clair dans mes idées là. Mais ça permet de changer facilement de menu/gui/partie en empilant/dépilant.

Par contre il faudrait dans ce cas distinguer State de Data :)

--EDIT : D'ailleurs j'ai oublié de te répondre François, en fait je suis tout à fait d'accord pour instancier une classe qui stocke les configurations et qu'on peut passer en paramètre (ça serait un peu le rôle de la caméra d'ailleurs). J'ai bugué sur le concept jeudi et à vrai dire je ne me rappelle plus exactement pourquoi, mais effectivement, c'est plus extensible, entre autres si on veut créer plusieurs modules partageant les même configs. My bad.

--EDIT2 : Il risque d'y avoir un problème avec la caméra (comme en témoignent les restes de ma fonction "project" éparpillés dans Camera.ml). Si on centre bien la case du curseur, il reste deux solutions pour les bords :

J'ai testé la première solution, et le problème c'est que les tiles sur les bords ne tombent pas juste, du coup on se retrouve avec des moitiés de tiles. Et il est très difficile (pour ne pas dire impossible) de trouver une taille de tile telle que les bords tombent juste sur tous les côtés, et ce quelque soit la résolution choisie, tout en gardant des tiles carrées.

On peut aussi rester sur la deuxième solution, et changer le fond pour en mettre un plus joli.

TheoWinterhalter commented 9 years ago

(En passant vite fait, je regarderai plus en détail, mais là sur la branche interface_dev ça ne compile pas)

EDIT — Bon c'était FloatRect le fautif. C'est un problème de version @VLanvin ?

VLanvin commented 9 years ago

Ouep tout à fait, sur la dernière version de Ocsfml (celle de git), FloatRect est un module, ce qui n'était pas le cas avant. Normalement si je ne mets pas FloatRect je n'ai qu'un warning, donc ça devrait aller, au pire je ferais un downgrade de ma version.

TheoWinterhalter commented 9 years ago

Okay. Sinon, il n'est pas possible de linker ta version à opam ? Je sais que brew est d'accord pour gérer des paquets qu'il n'a pas installé. Ainsi, tu fais juste un opam switch avant de compiler.

Pour la caméra d'accord pour afficher du noir (après tout, advance wars fait ça, en tout cas dans le 2 il me semble) ou tout autre fond (mais pour l'instant je propose du noir).

EDIT — Sinon, je propose de calculer la définition du joueur (width * height que l'on peut obtenir avec get_full_screen_mode) et charger des textures qui dépendent de la définition (avec des répertoires dans textures selon que ce soit hd ou je ne sais quoi).

VLanvin commented 9 years ago

Je sais pas trop pour la version sur opam, on verra si vraiment ça pose problème.

Je viens de vérifier, Advance Wars fait un mix des deux, il utilise la solution 1 et affiche un joli fond vert en cas de débordement. Je vais voir ce que je peux faire avec ça. Sinon, jolies les flèches !

TheoWinterhalter commented 9 years ago

Sinon, le comportement de la caméra est suffisant pour une première version non ? On peut se garder ça de côté pour la suite.

Merci pour les flèches. Je les ai mises à jour et maintenant le rendu a l'air d'être correct. (J'aime hardcoder des chemins !).

VLanvin commented 9 years ago

Ouep d'accord pour la caméra.

Le rendu des flèches hardcodées est top ! Par contre il va falloir cleaner tous ces trucs hardcodés un jour, parce que ça commence à se superposer xD

En attendant qu'on obtienne une implémentation décente du module Unit pour pouvoir avancer encore dans les tests, je me demandais, comment on code le déplacement exactement ? Je pensais à quelque chose comme :

Reste le cas où on sort le curseur de la portée, et qu'on le fait réentrer à un tout autre endroit. Dans ce cas, je partirais sur la même solution que précédemment, à savoir reset du chemin et recalcul du plus court chemin jusqu'au curseur.

--EDIT : DAT EASTER EGG ! Le nouveau ground est énorme :)

TheoWinterhalter commented 9 years ago

Je suis d'accord. A part que si on sort et rentre, je trouverais sympa de tester d'abord (avec Dijkstra) si on peut y arrive depuis le dernier point, sinon on repart du début.

Un autre truc, fait-on une résolution des boucles ? leftpuis rightse traduit par le neutre (clairement sinon c'est pas pratique pour revenir d'une case), mais il y a une boucle dans l'exemple que j'ai dessiné. Je vois pas trop quel intérêt on peut avoir à faire ça… Je sais plus si advance wars le permet. A la limite c'est pas très grave pour le moment, on peut l'ignorer.

VLanvin commented 9 years ago

Nop advance wars ne le permet pas. Si on essaie d'ajouter une case à un déplacement qui était déjà là, on reprend à partir de ladite case. Je pense que c'est ce qu'il y a de mieux, et ça s'implémente hyper facilement.

Par contre, il se passe quoi avec la caméra là ? Pourquoi le curseur ne peut pas aller en (0,0) et peut dépasser d'une case (en (100,100)) ? Avant tout marchait bien..

TheoWinterhalter commented 9 years ago

Pour les boucles, ça peut avoir un intérêt si on rajoute des mines dans le terrain et qu'on veut faire sauter des unités faibles.

En effet, c'est étrange. C'est l'occasion d'utiliser git bisect. Si tu sais à quel commit ça marchait encore.

VLanvin commented 9 years ago

Arf j'ai compris. T'as ajouté un décalage de texture_size/2 dans le rendu, mais je calculais déjà un décalage de tile_size/2 dans la caméra. Du coup, on fait quoi ? On le met où ?

TheoWinterhalter commented 9 years ago

En fait, je fais ce décalage pour que l'origine de la tile soit son centre dans le cas où je veux faire une rotation. Si c'est — comme par défaut — sont coin haut-gauche, la rotation n'est pas très intéressante.

EDIT — Est-ce qu'on peut envisager de faire un nouveau merge dans master ? On a fait pas mal de trucs (je sais qu'il y a beaucoup de hardcoding donc c'est peut-être pas idéal…). On peut peut-être s'occuper de virer les constantes dans Cameraetc. Par exemple la position de départ peut-être une caractéristique de Battlefield non ?

VLanvin commented 9 years ago

J'ai enlevé le décalage de Camera, c'est plus propre. Et j'ai enlevé le subf de l'origine de la tile, comme ça c'est son centre qui sera affiché au milieu de l'écran, plutôt que son coin haut-gauche.