PDA

Voir la version complète : Mon projet de DF-like sans nom pour le moment



Tomaka17
16/10/2012, 15h35
Il y a quelques temps j'avais posté ici mon projet de RTS sans nom pour le moment (http://forum.canardpc.com/threads/66440-Mon-projet-de-RTS-sans-nom-pour-le-moment)
Je n'étais pas bloqué par quoi que ce soit (ni même par le temps), mais j'ai décidé de réorienter le projet vers un truc un peu plus simple, et qui sera jouable plus rapidement : un dwarf-fortress-like (que c'est original!)

Les règles sont donc les mêmes : pas de moteur 3D, tout est codé main en C++ et à l'aide de DirectX
Evidemment j'utilise tout de même quelques librairies, mais ce ne sont en aucun cas des frameworks : libavcodec (pour décoder l'audio/vidéo), libarchive (pour dézipper), freeimage (pour charger les images), freetype (pour charger les polices de caractères)


Description

Le jeu proposera donc de gérer en vue de côté des vers de terre qui peuvent creuser le sol et s'aménageront une petite forteresse

Voilà déjà un petit screenshot pour vous faire une idée :
(les petites boules vertes ce sont des vers, le truc bleu c'est le ciel, le truc marron c'est le sol :ninja:)

http://tof.canardpc.com/view/ca257913-6654-43c3-baec-6327305912fc.jpg

Ce qui est déjà fait : (beaucoup de copié-collé :rolleyes:)
- tout ce qui est moteur graphique, c'est à dire que si je veux dessiner quelque chose à un endroit particulier, ça se fait facilement
- tout ce qui est input, en lisant simplement les entrées clavier/souris
- le picking, c'est à dire déterminer quel(s) objet(s) se situe(nt) aux coordonnées où j'ai la souris
- le texte, je peux afficher du texte à l'écran, ça paraît con mais c'est pas simple
- le son, grâce à XAudio2 et libavcodec je peux charger n'importe quel son et le jouer
- le rendu du sol, j'en suis assez satisfait et je ne pense pas en changer avant un bon bout de temps (probablement pour rajouter de l'herbe à la surface ou bien une petite perspective)

Les prochaines étapes :
- l'UI
- le système de jeu (la gravité, l'impossibilité de passer à travers le sol, etc.)

Contrairement au projet de RTS qui était plus là pour le fun et pour apprendre (je l'avais dit dès l'OP), ce jeu-là je compte bien le mener le plus loin possible, d'où l'ouverture d'un topic dédié


Téléchargement

La toute première version compilée il y a tout juste 5mn est disponible ici (https://dl.dropbox.com/u/12938337/version-2012-10-16.zip) (23 Mo)
Utilisez les touches fléchées et la molette de la souris pour déplacer la caméra
C'est très limité, vous pouvez juste voir la même chose que les screenshots mais en vrai, et si vous cliquez sur une case de terre les vers iront la creuser
Mais surtout, vous pourrez me dire ce que vous en pensez, et si le programme fonctionne chez vous, et ça ça n'a pas de prix

Vous aurez besoin de directx 10+ et du runtime VC++ 2012 (http://www.microsoft.com/fr-fr/download/details.aspx?id=30679)

S'il vous dit "msvc-quelque chose introuvable", téléchargez le runtime VC++ 2012 (http://www.microsoft.com/fr-fr/download/details.aspx?id=30679) (dans 6 mois/1 an tous les logiciels et jeux vous le demanderont de toute manière)

Si jamais le programme plante, ce serait sympa de me copier-coller le contenu de "log.txt" qui s'est normalement créé dans le même répertoire que le programme ;)

http://tof.canardpc.com/view/5baf9ee7-a17b-44c6-96c3-d0683b9b34bc.jpg

Louck
16/10/2012, 22h12
L'idée est très original. Je suis curieux de voir jusqu’où tu vas mener ton projet ;).


J'ai une erreur en exécutant ta démo : Il me manque le fichier "MSVCR110.dll", alors que j'ai installé le runtime VC++ (via ton lien).

Tomaka17
17/10/2012, 12h01
J'ai une erreur en exécutant ta démo : Il me manque le fichier "MSVCR110.dll", alors que j'ai installé le runtime VC++ (via ton lien).

Ouaip je pense que tout le monde aura cette erreur en fait
Tous les jeux et logiciels dont le développement commence en ce moment demanderont d'installer ce truc pour y jouer, et le mien ne fait pas exception


Sinon j'avais parlé dans mon précédent projet du moteur de rendu CSS
Celui-ci avance pas trop mal

Voici une mini interface que j'ai faite en 5mn l'autre jour quand je l'ouvre dans mon navigateur :

http://tof.canardpc.com/view/23e43de7-3af7-449d-9496-3e2efda52a3b.jpg

Voici la même une fois intégrée au jeu :

http://tof.canardpc.com/view/6ea0c510-6cdd-456f-8ed2-4755c3de53ac.jpg

Je ne gère pas encore le font-family, les images, le text-align, les retours à la ligne (qui sont désactivés car un bug fait ramer le jeu) et les dégradés (ça ne se voit pas bien mais c'est un dégradé sur le premier screen) mais sinon ça commence à être sympa je trouve

Bientôt j'en serai au même niveau qu'IE ^_^

Tomaka17
18/10/2012, 18h56
Vous pouvez télécharger ici le build d'aujourd'hui (https://dl.dropbox.com/u/12938337/version-2012-10-18.zip) pour ceux qui sont intéressés ;)

http://tof.canardpc.com/view/aed35890-b95f-42a9-966d-a62349489f37.jpg

J'ai pas mal avancé depuis avant-hier :
- on peut faire click droit pour placer une pente (vers la gauche uniquement, pour vers la droite je n'ai pas encore fait le code pour l'afficher à l'écran et j'ai pas autorisé à en placer)
- un début d'UI
- la gravité et le pathfinding sont implémentés (mais ça reste très buggé, faut que je nettoie tout ça)

Attention : si vous donnez trop d'ordres hors d'atteinte, ça va commencer à ramer
En fait à chaque frame les vers inoccupés essayent d'atteindre les endroits à creuser via l'algo de pathfinding
Je pense pouvoir optimiser grandement tout ça en vérifiant simplement si la case est théoriquement accessible par un des côtés avant de balancer une recherche de chemin
Et puis le pathfinding en soi est assez lent car j'ai fait ça vraiment en mode bourrin

Les boutons de l'UI ne marchent toujours pas, mais on peut commencer à creuser des galleries avec click gauche/click droit
Cela dit il y a énormément d'ajustements à faire : les vers cachent la moitié de l'écran, parfois il devrait pouvoir passer mais il ne peut pas, si vous cliquez sur une case déjà vide ben il ira quand même creuser, si vous double-cliquez il creuse deux fois, etc.

Prochaines étapes :
- nettoyer le code du pathfinding et de la gravité
- l'UI qui fonctionne
- jouer un petit son quand on creuse

Et sinon vous pouvez vous amuser à modifier game_ui.htm pour mettre un petit code html dedans, mais si c'est trop complexe il y a de grandes chances que ça fasse planter le jeu

Tomaka17
22/10/2012, 12h03
Un petit screen avant d'aller bosser pour de vrai :

http://tof.canardpc.com/view/c67913c7-66cd-4065-a9dd-4a8fea345b79.jpg

Fonctionnent désormais :
- les cases désignées pour être creusées apparaissent maintenant en surbrillance
- les boutons de l'UI marchent, malgré qu'ils soient déformé : on clique sur le bouton ("dig", "g" pour "gauche" ou "dr" pour "droite" en attendant d'avoir des icônes), puis on clique sur la/les cases ; click droit annule la sélection, et en maintenant appuyé on peut désigner plein de cases d'un coup
- les vers se baladent à nouveau aléatoirement quand ils n'ont rien à faire
- de bien meilleurs perfs en faisant juste 2/3 ajustements

J'ai sauté la partie "ajouter un son quand on creuse", car je vais rajouter les sons en même temps que les petites animations

À noter que les lignes grises bizarres n'apparaissent que quand j'active l'anti-aliasing, j'ai pas encore déterminé d'où ça venait

Prochaine étape :
- le bouton "cancel" qui marche (c'est à dire "annuler la désignation")
- affichage correct de l'UI

Après je vais probablement implémenter quelque chose de neuf, par exemple les objets, les besoins (soifs, faim, repos, etc.), l'eau, etc.
Je ne sais pas encore quoi

J'ai pas l'impression de déchaîner les foules pour l'instant :emo:

rOut
22/10/2012, 12h20
J'ai pas l'impression de déchaîner les foules pour l'instant :emo:

C'est à mon avis le plus difficile quand on bosse sur un projet.
J'admire les gens qui arrivent à garder leur motivation jusqu'au bout et je te souhaite bien du courage, mais je vais être honnête et je vais dire que pour le moment c'est bien trop au stade de prototype (et assez moche pour le moment, désolé mais ne nous voilons pas la face) pour déchaîner les foules.
D'autant plus que des DF-like tu en trouves des tripotées à présent et que comparé à l'original, la barre est très très haute pour avoir quelque chose d'attractif.

Mais bon, si je peux te donner un conseil, ce serait de continuer à faire ce qui te plait, et ne pas trop compter sur l'enthousiasme des gens. Tu peux parler de ton avancement, et c'est intéressant à suivre, mais ne fais pas ça juste pour avoir des retours ou tu risques d'être déçu.

Tomaka17
22/10/2012, 12h55
Je ne m'attends pas à ce qu'on me dise "lol, je kiffe ton projet", mais juste un peu d'animation sur le topic, comme sur mon précédent topic (http://forum.canardpc.com/threads/66440-Mon-projet-de-RTS-sans-nom-pour-le-moment) par exemple
Par exemple en montrant où en était mon moteur CSS, je m'attendais à ce qu'on me demande les perfs ou le code par exemple
Mais sinon je sais très bien que vu de l'extérieur ça ne ressemble à rien pour le moment

Après c'est pas une histoire de déception ou quoi que ce soit, c'est juste que c'est dommage de poster dans le vent
Si j'ai une réponse toutes les 3 semaines, autant ne pas perdre de temps à alimenter le topic si tu vois le raisonnement

Si je faisais ça pour les retours ou la reconnaissance je posterais beaucoup plus souvent d'ailleurs
Là par exemple j'ai bossé dessus 8h/jour ce week end sans que ça ne me préoccupe de montrer ce que j'avais accompli, à part tout à l'heure en diagonale

beuargh
22/10/2012, 13h24
Si ça peut te rassurer, j'ai pas vu beaucoup de topics sur ce sous-forum déchaîner les foules.

Personnellement, je suis de loin, sans intervenir forcément sur les topics. Ou pas.

Edit : good luck, sinon :)

LaVaBo
22/10/2012, 14h11
Je pense aussi que dans les lecteurs, il y a ceux qui savent faire la même chose et ne se posent pas trop de questions, et ceux qui débutent et à qui un projet aussi jeune ne parlera pas. Ou alors il faudrait que tu décrives à chaque fois ce que tu voulais faire, la méthode employée, et pourquoi elle est pertinente, mais tu passerais plus de temps à faire de la doc qu'à bosser sur ton projet.
Sebum le fait (détailler un peu le pourquoi de chaque bout de code), mais c'est relativement concis pour pas nécessiter 10 pages par magazine, et les projets developpez couché restent assez simples pour être accessibles aux débutants. Le temps de rédaction / temps de dev est sûrement assez élevé.

Tomaka17
23/10/2012, 19h21
Bon je commence à être vraiment content de mon moteur CSS là :lol:

Résultat voulu : http://cssdesk.com/KEuJP

Résultat obtenu :

http://tof.canardpc.com/view/6de8a141-cfff-4384-9382-ee792f2b2522.jpg

Par contre je vois pas comment je peux centrer le texte à l'intérieur d'un bouton (EDIT : verticalement)
On voit que si on remplace par exemple <button> par <span> dans mon HTML (et en spécifiant inline-block pour les span), le texte n'est pas centré en utilisant un navigateur classique, ça prouve bien que les navigateurs classiques ont une règle spéciale pour centrer le texte dans les <button>
Et moi je voudrais une règle CSS qui fasse ça...

À part ça il me manque le box-shadow et le text-align, et tout sera bon

Tomaka17
28/10/2012, 12h58
Hop, petit screenshot :

http://tof.canardpc.com/view/5fc45708-e90d-48f2-8205-5ac8c353a696.jpg

J'ai rajouté vite fait les pierres, ce sont les cases blanches qui sont pour le moment distribuées aléatoirement.
Quand j'en aurai l'envie je ferai le code pour générer un monde, comme ça la surface aura des reliefs, et les pierres (ainsi que les ressources) seront distribuées de manière logiques dans le sous-sol.

Sinon comme vous le voyez, on peut maintenant placer des échelles. Celles-ci ne fonctionnent pas encore (c'est à dire qu'on ne peut pas y grimper) mais ça ne saurait tarder.

Tomaka17
29/10/2012, 20h33
J'ai commencé à mettre en place le système d'objets.
J'ai prévu le chargement des types d'objets au moment du runtime, de façon à ce que ce soit à la fois plus facile pour moi à modifier et potentiellement moddable :


itemTypes = {
-- basic materials
wood = {
graphics = "textures/items/wood"
},
stone = { graphics = "textures/items/rock" },

-- trees
tree = {
isTree = true,
onChop = { wood = 2 }
},

-- workshops


-- wood items
ladder = {
graphics = "textures/items/ladder",
isLadder = true,
craft =
{ input = { wood = 2 },
output = 1
}
}

}


J'ai déjà un bon petit wrapper lua fait maison (quand je dis "petit", en fait il 1200 lignes, c'est un gros truc à base de templates que j'ai développé il y a quelques années et dont je suis assez fier), donc ça devrait être assez simple de charger ça.


EDIT : sans erreur dans le lua c'est mieux

Hideo
29/10/2012, 22h06
Je viens de trouver le topic et de finir de le lire, et bien c'est un régal :)

J'ai lu un peu ton ancien topic aussi du coup, et j'aime beaucoup ta façon de nous donner des nouvelles, comme d'autres, je n'interviens pas forcement mais compte sur moi pour suivre le topic et tester les prochains builds !

Bonne chance;)

Tomaka17
31/10/2012, 21h41
Voilà, les types d'objets sont désormais chargés depuis le fichier lua.

Il est également désormais possible de donner l'ordre de placer un objet quelque part. Par exemple si je clique sur le bouton "lit" puis à un endroit, je donne en fait l'ordre de placer un "objet lit" à cet endroit, pour qu'il devienne un "bâtiment lit" où on pourra dormir.
La prochaine étape ça va être le craft. Je n'ai pas encore d'interface pour ça, mais je vais temporairement rendre ça automatique (c'est à dire un ordre de craft d'un objet est automatiquement donné quand on veut placer un objet de ce type).

Une fois le craft fait, je vais rajouter des arbres qu'on pourra couper, et j'aurai déjà un bon petit résultat sympatique.

rOut
31/10/2012, 21h56
Tiens tu gères comment le picking d'ailleurs ? Tu stockes un genre de quadtree de tous les objets affichés et ensuite à chaque clic tu vas voir dedans quel objet correspond ? Ou bien différemment ?

Tomaka17
31/10/2012, 22h14
Tiens tu gères comment le picking d'ailleurs ? Tu stockes un genre de quadtree de tous les objets affichés et ensuite à chaque clic tu vas voir dedans quel objet correspond ? Ou bien différemment ?

Pour l'instant chaque objet a une petite fonction "collisionTest", et je prends tous les objets un par un du plus au dessus jusqu'à tout en dessous, et je regarde s'il touche le point en question (multiplié par l'inverse de la matrice de l'objet).
C'est basique et pour l'instant c'est suffisant.

J'ai pas d'implémentation de quadtree sous la main, mais je sais que je vais devoir m'y coller tôt ou tard si je ne veux pas que mon jeu rame avec trop d'objets affichés.

rOut
31/10/2012, 22h25
Perso j'avais pensé ajouter, à la phrase de rendu, un rendu rapide dans une texture de tous les objets, en ne rendant que leur "id" en tant que couleur, et ensuite en récupérant la couleur à la position du pixel, tu obtenais directement l'id de l'objet touché, mais je ne sais pas trop si c'est plus efficace, ca alourdit peut être un peu la passe de rendu et ça nécessite de récupérer ensuite le contenu de la texture depuis le GPU (mais ça à la limite ca peut s'alléger en ne récupérant que les alentours des la position du curseur).

Tomaka17
01/11/2012, 08h31
Plus simple que de stocker l'id de l'objet, tu peux carrément stocker un pointeur void* dans la texture. Par contre faut éviter le multisampling :p

Mais le problème de ta technique c'est que tu ne peux au final connaître que l'objet le plus au dessus.

Par exemple si je clique sur la commande "Déplacer un objet" et que je veux cliquer sur une échelle sous un personnage, ben je serais emmerdé car je ne pourrais pas "filtrer" le perso.

Tomaka17
01/11/2012, 21h10
Bon ben j'ai pas mal avancé.
Le craft "fonctionne", dans le sens où les personnages vont vers le composant le plus proche (par exemple du bois), et le résultat (par exemple une échelle) pop par miracle quelque part sans que le composant ne soit détruit.

En fait il faut que je refasse ça plus proprement, car selon les cas soit on va ramener tous les composants au même endroit que le premier et crafter sur place, soit on va ramener tous les composants sur le lieu final (par exemple pour créer un atelier), soit on va ramener tous les composants à un atelier. Du coup là je me suis pas pris la tête et j'ai fait ça à l'arrache.

Là je pense avoir finalisé mon interface serveur-client, c'est à dire que j'ai clairement défini les limites du jeu.
Cela signifie que je peux maintenant coder entièrement l'UI et la partie client.

Les prochains trucs à faire c'est :
* faire fonctionner les échelles, car les personnages ne peuvent pas encore s'en servir pour monter/descendre
* faire le code qui génère le monde, avec des reliefs et des arbres
* faire le code UI qui permet de signaler au serveur qu'on veut couper un arbre
* faire le code qui affiche un objet transparent à l'endroit où on veut placer le-dit objet (pour l'instant ça s'affiche mais il est opaque, du coup on comprend pas)

Le but c'est d'arriver à un milestone "on peut couper des arbres pour fabriquer des échelles et ainsi creuser les galeries comme on veut".
Une fois tout ça fait je sortirai un p'tit build.

Il ne me restera plus alors qu'à créer l'UI, décrire les propriétés de tous les types d'objets possibles dans mon fichier lua, dessiner tout ça (le plus difficile), débugger le code du serveur qui est pour l'instant pas très robuste, et enfin rendre le tout le plus joli possible.

Sahnvour
03/11/2012, 19h16
Comme beaucoup d'autres je suis avec intérêt sans participer, sache le :p

Tu parles de ton wrapper lua, un peu plus de détails dessus (une release :rolleyes:) c'est possible ? Je m'intéresse un peu à voir comment on peut utiliser lua comme langage de script dans un jeu mais sans vraiment d'exemple concret ni d'expérience personnelle. Vu de loin les wrappers existants ont pas l'air folichons. :(

Tomaka17
03/11/2012, 19h45
Hop, une petite release (http://www.mediafire.com/?lu1nl1jqdtvidnj).
Ca compile et ça fonctionne, mais c'est encore un p'tit peu bancal (ça le sera moins quand MSVC++ supportera les templates variadiques).

Exemple avec mon wrapper :

LuaContext lua;
lua.writeVariable("x", 5);
lua.executeCode("x = x+1");
lua.readVariable<int>("x"); // renvoie 6

En gros dans Lua, tout est considéré comme une variable, même les fonctions.
Du coup tu peux aisément fournir des fonctions à un script lua qui va ensuite les utiliser :


// attention c'est de la syntaxe C++11, si tu comprends pas c'est normal
lua.writeVariable("log", std::function<void (std::string)>([](const std::string& str) {
std::cout << str << std::endl;
}));

lua.executeCode("log('bonjour');"); // va appeller la fonction plus haut et donc std::cout


Tu peux également fournir des objets :


class Personnage {
void deplacer();
};

Personnage* p;

lua.registerFunction("deplacer", &Personnage::deplacer);
lua.writeVariable("joueur", p);
lua.executeCode("joueur:deplacer();"); // appelle p->deplacer();

Evidemment en pratique tu vas rarement appeller executeCode avec du code directement dedans, mais plutôt lire le contenu d'un fichier .lua.
Après la limite c'est ton imagination.

Sahnvour
04/11/2012, 00h05
Super je vais regarder ça, merci ;)

Tomaka17
04/11/2012, 08h24
Cela dit il est possible que mes deux derniers exemples ne fonctionnent plus, vu que j'ai un peu retouché le code pour ce jeu -.-'

Tomaka17
04/11/2012, 20h26
Bon ben le bouton "gather" fonctionne :lol:

On clique sur "gather", on clique sur un arbre, et un personnage vient pour couper l'arbre.
L'idée c'est que le bouton "gather" servira à désigner les arbres et les plantes pour être récoltées.

(note : le screen est orange, c'est à cause de l'utilitaire f.lux)

Ci-dessous : un arbre normal, un arbre désigné pour être coupé, un arbre une fois coupé (le tas de bois).

http://tof.canardpc.com/view/c3ea752a-705b-49b0-aba8-2f0c2da73782.jpg

Tomaka17
06/11/2012, 15h33
J'ai dessiné des petits arbres, qui sont plus agréables visuellement même si ça manque un peu de cohérence.

http://tof.canardpc.com/view/291a4260-c821-4738-b6cf-0340f733a2b1.jpg

Tomaka17
09/11/2012, 17h58
Bon ben le relief est désormais généré aléatoirement grâce à un algo fractal.

L'idée c'est que je détermine d'abord aléatoirement la hauteur du sol aux extrémités gauche et droite de la map. La surface forme alors une ligne qui relie les deux extrémités. Je la coupe en deux au milieu et j'ajoute une valeur aléatoire à la hauteur à cet endroit.
J'ai donc à ce moment là deux lignes, que je coupe chacune en deux à leur milieu pour en obtenir quatre, avec comme avant une valeur aléatoire ajoutée à l'endroit de la coupure. Et ainsi de suite.
Plus on avance plus la valeur aléatoire est faible, ce qui fait que les premières coupures sculptent le relief général, et les coupures suivantes ajoutent à chaque fois des détails.

Evidemment l'algo est pas réellement aléatoire, c'est à dire que je peux rentrer une seed, et si je rentre deux fois la même seed ça me génèrera deux fois le même terrain.

Là pour le screen j'ai pris un coin avec un gros relief mais dans l'ensemble c'est relativement plat, et c'est ce que je veux. Après faudra éventuellement ajuster tout ça en fonction de la taille définitive des personnages.

http://tof.canardpc.com/view/64ca8ca3-e5ed-4690-94c9-9dc228f2bf9e.jpg

Par contre j'ai une hésitation au niveau des cases là. J'hésite entre mettre les définitions dans un fichier lua que je charge au moment du lancement, ou alors les ancrer directement dans le code du jeu.
Ce serait pas mal si je prenais cette décision rapidement, ça me permettrait de finaliser la partie terrain.

Patate
11/11/2012, 13h09
Chouette boulot !
Tu entends quoi par "Par contre j'ai une hésitation au niveau des cases là" ?

Tomaka17
11/11/2012, 17h06
Ben j'ai découpé tout le terrain, et même tout le monde, en cases.
Ca se voit bien sur le screenshot avec les petits carrés blancs et marrons ; ce sont à chaque fois des cases.
La grande majorité des jeux type RTS/gestion utilisent cette "technique", sauf qu'ils le masquent bien.

Poussin Joyeux
11/11/2012, 18h54
Ben j'ai découpé tout le terrain, et même tout le monde, en cases.
Ca se voit bien sur le screenshot avec les petits carrés blancs et marrons ; ce sont à chaque fois des cases.
La grande majorité des jeux type RTS/gestion utilisent cette "technique", sauf qu'ils le masquent bien.

Mais comment se fait-il alors que la taille de chaque case semble différente et qu'aucune ne semble avoir d'angle droit?
Si c'est juste une histoire de dessin de sprite alors ça signifie que tu ne pourrais pas en mettre deux côte à côte sans qu'elle se superpose donc je m'interroge... :O

Tomaka17
11/11/2012, 20h26
Mais comment se fait-il alors que la taille de chaque case semble différente et qu'aucune ne semble avoir d'angle droit?
Si c'est juste une histoire de dessin de sprite alors ça signifie que tu ne pourrais pas en mettre deux côte à côte sans qu'elle se superpose donc je m'interroge... :O

Justement, je masque un peu le subterfuge ;)

Dans la mémoire vive et dans le système de jeu tout est découpé sous forme de carrés. Par contre au moment d'afficher le terrain je rajoute une petite translation.
L'astuce c'est que la translation est calculée en fonction de la position du sprite. Par exemple la case à (-10,-5) sera toujours en réalité à (-10.07,-4.9) (ce sont des nombres que je donne au pif, pas forcément ça).
Du coup les cases sont quand même collées entre elles.

En fait les sprites sont carrés, mais je les déforme. Comme c'est une déformation très légère et que les sprites ne sont pas des images très détaillées, ça ne se voit pas.

Patate
11/11/2012, 21h17
Ben j'ai découpé tout le terrain, et même tout le monde, en cases.
Ca se voit bien sur le screenshot avec les petits carrés blancs et marrons ; ce sont à chaque fois des cases.
La grande majorité des jeux type RTS/gestion utilisent cette "technique", sauf qu'ils le masquent bien.

Ok je vois. Tu comptes faire comment par la suite pour que cette ligne de crête est un aspect lissée ?

Tomaka17
11/11/2012, 21h24
En fait si tu zoomes sur le screenshot tu remarques que le sprite (le truc marron) est "lissé", c'est juste la bordure noire qui fait un escalier (ça se voit bien juste à gauche du sapin).
J'ai mis une bordure noire à la frontière entre les cases d'air et les autres, et à l'époque j'ai pas pensé aux pentes.

Du coup c'est juste la bordure noire qui est à corriger.

Patate
12/11/2012, 07h08
Exact je n'avais pas fait gaffe aux sprites qui ont déjà la forme de la pente. Interessant, du coup ton sprite est juste modifier à l'affichage non ? A en voir les arbres, ils possèdent toujours un forme carré. Chaud pour les collisions non ?

Tomaka17
12/11/2012, 07h29
Pour l'instant le sprite de pente et le sprite normal sont deux textures différentes.
Le problème c'est que si j'ai des cases de terre, de pierre, de fer, d'or, et ainsi de suite, ça va être chiant de devoir faire deux versions de chaque texture.
Du coup je pense modifier ça pour faire comme tu pensais, c'est à dire le couper au moment de l'affichage.

Plus concrètement, dans le code du jeu je vais remplacer ça :

setTile(GROUND_NORMAL);
setTile(GROUND_LEFT_SLOPE);
Par ça :

setTile(GROUND, NORMAL);
setTile(GROUND, LEFT_SLOPE);
Les gens qui ont déjà programmé un peu comprendront ce que je veux dire.


Et oui les arbres c'est juste une image que je dessine par dessus. Dans le code du jeu ils sont totalement séparés du terrain.
Pour rendre ça plus joli je compte :
1 - mettre les arbres sous le terrain, pour éviter de voir le tronc qui flotte
2 - ne pas générer d'arbre aux endroits où il n'y a pas la place (comme on en voit sur le screen plus haut)
3 - rajouter une petite couche d'herbe au dessus de la terre

Avec ces trois trucs je pense que ça devrait passer plus naturellement.

Tomaka17
12/11/2012, 21h30
À la base j'étais parti pour faire des vers, mais au final... je me dis que... peut être ben... des nains ce serait mieux quoi :)

Du coup tout à l'heure j'ai commencé à travailler un peu sur un skin de nain dont voici un premier jet.

http://tof.canardpc.com/view/c8b135f1-9972-4220-bb43-a5fa7e7701a0.jpg

Je pensais faire une animation de personnage un peu comme dans Don't starve par exemple (vu que j'y joue en ce moment), c'est à dire seulement 3 directions possibles : de face, vers la gauche, ou vers la droite, avec un seul dessin pour ces deux derniers cas puisqu'il suffit de retourner l'image.

C'est pas nécessairement une volonté artistique, c'est surtout que je suis pas bon en dessin, et que moi je dessine mieux je me porte.

Louck
12/11/2012, 22h01
Avis perso: Il y a déjà trop de jeu de nains (DF like).
Après c'est sûr que ca a plus de gueule que des vers, mais bon niveau originalité :p.

Tomaka17
13/11/2012, 12h46
Avis perso: Il y a déjà trop de jeu de nains (DF like).
Après c'est sûr que ca a plus de gueule que des vers, mais bon niveau originalité :p.

Certes, mais une créature ou un peuple qui établit des villes sous-terraines j'en connais pas des masses.
À la limite des zombies ou des gnomes.

Sinon je commence à chopper le mojo inkscape.
Moi qui n'ai jamais dessiné de ma vie je trouve que je m'en sors pas trop mal.

http://i.imgur.com/uRIRi.png

L'atelier de bois et la pelle vont certainement ressembler à ça dans la version finale, le reste c'est du WIP.

http://i.imgur.com/0Q70x.png

Aulren
13/11/2012, 13h28
Certes, mais une créature ou un peuple qui établit des villes sous-terraines j'en connais pas des masses.
À la limite des zombies ou des gnomes.


Justement, ton idée de vers t'offrait une plus forte identité que de reprendre quelque chose qui est plus ou moins à la mode. Un truc à la worms pourrait être sympa.
Au pire tu peux te rabattre sur les fourmis ou les thermites ^^

Tomaka17
13/11/2012, 13h54
Justement, ton idée de vers t'offrait une plus forte identité que de reprendre quelque chose qui est plus ou moins à la mode. Un truc à la worms pourrait être sympa.
Au pire tu peux te rabattre sur les fourmis ou les thermites ^^

Ou l'autre possibilité qui me plait plus c'est de partir sur un système générique et d'offrir du multi-races.
On pourrait aussi bien diriger des nains que des vers ou des fourmies.
Et en plus ce serait dans l'esprit Dwarf Fortress avec plusieurs civilisations.

En fait à partir du moment où je pars sur un système d'animation simple, je peux rendre ça facilement générique.
Pour chaque race il me faudrait dessiner :
- une tête de face
- une tête de profil
- un corps de face
- un corps de profil
- une jambe de face
- une jambe de profil
- un bras de face
- un bras de profil

Ensuite je gère les animations via mon code en bougeant chaque partie séparément.

Pour les objets équipables, les casques se mettront simplement par dessus la tête, les armes entre les deux mains, et pour les vêtements je changerai la couleur de la texture.

Evidemment pour l'instant je vais partir sur une seule race, et j'ajouterai les autres après.

Tomaka17
14/11/2012, 21h52
En ce moment j'ai la tête dans mon boulot principal, et c'est pas forcément évident de se focaliser à 100 % sur une implémentation de quadtree ou de trucs du genre quand t'as une deadline qui approche.
Du coup ben je profite de mon temps libre pour rajouter des objets au jeu. On ne peut pas encore les voir in-game puisqu'il n'y a toujours pas d'interface de craft (à part pour le rocher qui se créé lors de la génération de la map), mais comme j'ai déjà grosso modo bien cerné tous les aspects du jeu, ben je peux quand même avancer là dessus.

http://i.imgur.com/Iiwk2.png

Poussin Joyeux
16/11/2012, 11h12
Justement, je masque un peu le subterfuge ;)

Dans la mémoire vive et dans le système de jeu tout est découpé sous forme de carrés. ...
En fait les sprites sont carrés, mais je les déforme. Comme c'est une déformation très légère et que les sprites ne sont pas des images très détaillées, ça ne se voit pas.

Merci pour l'explication! ;)
Grâce à tes subterfuges, l'illusion est parfaite et on n'a pas l'impression que tout est géré par un "tableau" finalement. Intéressant!

LaVaBo
16/11/2012, 13h49
D'ailleues, tu optimises en ne chargeant qu'une partie du monde autour des persos, avec des chargements dynamique, ou tu charges la totalité du monde en mémoire ?

Tomaka17
16/11/2012, 14h02
Non j'ai tout de chargé en permanence car le monde n'est pas illimité.
Au début je voulais le faire de manière illimitée, mais non seulement ça n'a pas vraiment d'intérêt (entre un monde immense et un monde infini, il y a vraiment une différence ?) mais en plus ça m'embête pour le pathfinding.

Pour l'instant le monde fait 1024x1024, et j'ai une valeur d'enum pour chaque case.
Du coup les infos n'occupent "que" 4 Mo de mémoire.

Mais je pourrais optimiser ça, déjà en utilisant une enum class unsigned char à la place d'un enum tout court, ce qui diviserait par 4 cette quantité.
Après je pourrais encore plus optimiser en stockant deux cases par octet, mais à ce moment les accès seront très légèrement plus lents.
Certes le ralentissement ne se verra absolument pas, mais d'un autre côté 512ko c'est également considéré comme négligeable de nos jours.

Poussin Joyeux
16/11/2012, 15h29
...
Pour l'instant le monde fait 1024x1024, et j'ai une valeur d'enum pour chaque case.
Du coup les infos n'occupent "que" 4 Mo de mémoire.
...

Cette phrase m'avait intrigué et après une rapide recherche googlesque, j'ai découvert qu'un enum ne "coûtait" pas un octet comme je le pensais, mais 255 enum oui. (
On en apprend tous les jours! :)

Quand tu dis que tu te sers d'une valeur d'enum pour chaque case, ok mais ça doit quand même quelque part te prendre 1024x1024 int (ou autre) pour sauvegarder le contenu de ta case non? Ou bien, tu crées un objet par case?
Je te pose la question car j'avais essayé de faire des petits jeux Android à une époque et ce qui m'avait limité avec le système de tableau, c'était la taille mémoire prise par le tableau (et donc l'exécution plantait dès que c'était un peu grand). Du coup, je m'étais dit qu'il valait mieux laisser les tableaux (ou faire des niveaux plus petits).
Je précise que tu n'es pas obligé de répondre à ces questions si tu veux garder un peu de secret de fabrication! ;)

Tomaka17
16/11/2012, 16h26
Je sépare totalement les cases et les objets. Les unités et les objets (type arbre ou autres) sont dans une liste totalement à part.
Donc l'ensemble des données concernant le terrain ne me coûte que 1024*1024*la taille d'un enum

Mais sinon si par exemple je n'ai que 4 valeurs possibles dans mon enum, je pourrais stocker ça sur 2 bits. Du coup la taille totale ne ferait que 1024 * 1024 / 4, c'est à dire 256ko au lieu de 4 Mo.
Evidemment c'est le genre d'optimisations à faire quand le jeu est presque fini, parce que si tu veux rajouter une cinquième valeur t'as bien l'air con à modifier la moitié de ton code.

Après si t'as des problèmes de mémoire tu peux faire ça autrement. Par exemple j'aurais pu considérer que tout ce qui est en dessous de 0 est par défaut considéré comme de la terre, et tout ce qui est au dessus de 0 est considéré par défaut comme de l'air, et je ne stocke que les différences dans un tableau associatif (hash table ou quadtree ou ce que tu veux).
Du coup si tu veux savoir comment est la case (x,y), tu regardes d'abord dans ton tableau associatif. Si la case y est, ben tu sors la valeur. Si la case n'y est pas, tu regardes 'y' : si c'est > 0 c'est de l'air, si c'est < 0 c'est de la terre.
C'est le genre de truc que j'aurais fait si mes niveaux étaient de taille illimitée.

Poussin Joyeux
16/11/2012, 20h25
Je sépare totalement les cases et les objets. Les unités et les objets (type arbre ou autres) sont dans une liste totalement à part.
Donc l'ensemble des données concernant le terrain ne me coûte que 1024*1024*la taille d'un enum

Mais sinon si par exemple je n'ai que 4 valeurs possibles dans mon enum, je pourrais stocker ça sur 2 bits. Du coup la taille totale ne ferait que 1024 * 1024 / 4, c'est à dire 256ko au lieu de 4 Mo.
Evidemment c'est le genre d'optimisations à faire quand le jeu est presque fini, parce que si tu veux rajouter une cinquième valeur t'as bien l'air con à modifier la moitié de ton code.

Après si t'as des problèmes de mémoire tu peux faire ça autrement. Par exemple j'aurais pu considérer que tout ce qui est en dessous de 0 est par défaut considéré comme de la terre, et tout ce qui est au dessus de 0 est considéré par défaut comme de l'air, et je ne stocke que les différences dans un tableau associatif (hash table ou quadtree ou ce que tu veux).
Du coup si tu veux savoir comment est la case (x,y), tu regardes d'abord dans ton tableau associatif. Si la case y est, ben tu sors la valeur. Si la case n'y est pas, tu regardes 'y' : si c'est > 0 c'est de l'air, si c'est < 0 c'est de la terre.
C'est le genre de truc que j'aurais fait si mes niveaux étaient de taille illimitée.

Ok, merci Tomaka. C'est clair!
Il me reste juste à aller regarder "quadtree" sur internet car je ne connaissais pas ce terme (tout à apprendre!).

Merci et au plaisir de lire ta prochaine mise à jour sur ton jeu prometteur! :)
(et vivement une petite démo ou un prototype à télécharger pour pouvoir expérimenter tes dernières innovations!)

Tomaka17
05/12/2012, 18h14
Hop, ma deadline IRL est passée. J'ai encore pas mal de boulot en ce moment donc pas énormément de temps pour bosser dessus.

J'ai commencé tout à l'heure à refaire le code du serveur proprement. Pour l'instant c'était une seule grosse classe, qui là commence à atteindre les 1000 lignes, donc il est temps de splitter un peu tout ça.

Pour décrire un peu le fonctionnement du bousin, j'ai simplement une classe abstraite nommée "GameListener" qui sert à la communication entre client et serveur.
J'ai remarqué que peu importe la complexité d'un jeu, tout est toujours simplifiable à quelques règles relativement précises.
Par exemple dans un FPS ou un beat'em'all j'aurais des fonctions du type "setHitPoints", alors que dans un RPG j'aurais des fonctions plus génériques du type "setCaracteristic(HITPOINTS, valeur)". Mais dans tous les cas je n'aurais pas énormément de fonctions.

Là par exemple je pense avoir défini un peu toutes les règles du jeu, et ma classe GameListener fait 115 lignes, soit deux enum et 29 fonctions qui sont tout ce qu'il me faut pour la totalité de la communication client-serveur.
Cette interface contient également les fonctions de callback, par exemple "setCallbackWhenPlayerCutsTree" (ça s'appelle pas comme ça mais vous comprenez le principe). Pas besoin d'un "PlayerActionsListener" donc, puisqu'il suffit d'appeller le callback qui a été défini par le serveur.
Notez que je dis "client-serveur", ça ne veut pas dire que je vais faire du multijoueur ou quoi que ce soit, c'est juste une façon de découper proprement le programme en deux.

Côté client j'ai donc une classe "GameDisplayer" qui implémente ce GameListener et qui affiche toutes les infos reçues du serveur à l'écran.

Côté serveur je suis parti sur un ensemble de "systèmes".
Pour commencer j'ai une classe "GroundSystem" qui contient un pointeur vers mon GameListener. Je ne communique pas directement avec le GameListener mais via le GroundSystem. Par exemple si je modifie une case, le GroundSystem va récupercuter ça automatiquement sur le GameListener. Le GroundSystem me permet aussi de calculer le pathfinding et ce genre de trucs.

J'ai ensuite le UnitsSystem qui contient un pointeur vers le GroundSystem et vers le GameListener. Le UnitsSystem me permet de créer des unités, de leur demander d'aller à tel endroit (ce qui nécessite de connaître l'état du monde qu'on obtient grâce au GroundSystem), de définir un callback quand ils sont arrivés à destination, etc.

J'ai par dessus un JobsSystem qui me permet de créer des jobs (couper un arbre, crafter tel truc, etc.), et qui prend un pointeur vers mon UnitsSystem. Il va donner l'ordre à chaque unité d'aller à l'endroit où le job doit être réalisé et s'occupe de leur réalisation effective.

Tout se fait de cette façon sous forme de couches. J'ai donc un ItemTypesSystem, un ItemsSystem, un TilesTypesSystem, un CraftRecipesSystem, un RacesSystem, etc. Plus tard je pourrai rajouter un "CivilizationsSystem", un "InvasionSystem", et ainsi de suite.

Contrairement au principe d'entités (qui est vanté par certains sites web et utilisé par certains jeux pro), tout n'est pas centralisé, ce qui je trouve est beaucoup plus clair.


V'là.

Tomaka17
09/12/2012, 16h51
Hop.
Pour m'amuser j'ai téléchargé libtcod et j'ai fait ça en deux petites heures :

http://tof.canardpc.com/view/dc1ebee8-4dcf-4982-9416-9c5e66aa14e7.jpg

Pour l'instant je bosse sur le code du serveur avec cette interface.
L'avantage pour moi c'est que j'ai pas de temps de chargement et que je suis à peu près sûr que ce que je vois à l'écran est équivalent à ce qui se trouve sur le serveur, c'est à dire qu'il n'y a pas de bug graphique.

Cela dit l'inconvénient c'est qu'en fait ça marche avec la SDL et pas du tout en mode console. En plus libtcod est loin d'être parfaite, notamment il est impossible de redimensionner la fenêtre une fois ouverte.
Si vous connaissez une lib à la ncurses qui me permette d'avoir le même résultat sous windows et sous terminal nux, je pense que je garderai un mode comme ça au final vu que ça ne demande pas beaucoup de temps.

deathdigger
14/01/2013, 09h10
Ça serait allé plus vite si tu l'avais fait en C# ou en Windev :trollface:
Sinon, c'est assez sympa, pour l'univers, ça pourrait être marrant si tu foutais justement des gobelins en persos avec des méchants nains qui viennent les emmerder ;)

saroumana
27/01/2013, 14h26
Moi qui ne touche que médiocrement le C#, je suis toujours impressionné par ceux qui développent leurs jeux en C++. Je crois pas que j'aurais un jours le courage ou la folie de tenter d'apprendre ce langage alors que je commet d’innombrable erreurs en C#. Et comme en plus ton concept est fun, n’hésite pas a nous donner plus de compte rendu de ton avancé !

Tomaka17
27/01/2013, 15h18
Ben pour l'instant faut encore je change ce système de dessin du sol, qui est un petit foutoir (vu que j'ai jamais vraiment fait ça, je m'y reprends à plusieurs fois) et j'arrive pas à me motiver >_<

C'est con, suffit que je passe cet obstacle et je pourrai continuer sur ma lancée.

saroumana
27/01/2013, 16h13
C'est ce qu'on se dit souvent pour se donner bonne conscience.:trollface:

tompalmer
27/03/2013, 22h09
Des nouvelles ?

Tomaka17
28/03/2013, 06h54
En fait je suis en train de passer tout le jeu en système d'entités, qui est un truc assez fantastique.

---------- Post added at 06h54 ---------- Previous post was at 06h36 ----------

Donc en fait auparavant j'avais un système bateau : une partie serveur organisée un peu comme on peut, et qui envoie des infos à une partie client qui s'occupe d'afficher le tout à l'écran et de renvoyer les actions utilisateur au serveur. C'est pas une histoire de réseau, juste de découpe du code.

Avec le système d'entités, j'ai simplement un gros machin nommé "EntitiesManager" qui représente l'état du jeu, et qui est simultanément modifié par certaines parties du programme et lu par d'autres parties du programme. Le système d'affichage par exemple lit les infos, et le système d'IA les modifie.
Ce système n'est pas neuf, c'est juste que certains aspects pratiques font justement qu'il n'était pas pratique. Du coup je l'ai légèrement adapté à ma sauce.

Tout est une entité. Les nains sont une entité, les objets sont une entité, etc. et on personnalise l'entité lors de sa création pour lui donner toutes ses caractéristiques.
Par exemple pour poser un objet par terre, je créé une entité avec les caractéristiques : "affiché sous forme de sprite", "position à tel endroit", "objet physique", etc.
Le code d'affichage va alors détecter la création d'un "affiché sous forme de sprite" et s'occuper de charger le sprite et d'afficher tout ça à la bonne position.

L'avantage est bien sûr que c'est très modulable. L'autre avantage est que c'est facile à sérialiser (c'est à dire à convertir en texte pour pouvoir sauvegarder).
En fait le système de sauvegarde et chargement fonctionneraient déjà, il manque juste un bouton pour le faire.
D'ailleurs pour initier le jeu je charge depuis une sauvegarde (une "fausse" sauvegarde) qui contient le status du début de partie.

Louck
28/03/2013, 10h09
Avec le système d'entités, j'ai simplement un gros machin nommé "EntitiesManager" qui représente l'état du jeu, et qui est simultanément modifié par certaines parties du programme et lu par d'autres parties du programme. Le système d'affichage par exemple lit les infos, et le système d'IA les modifie.

Plus que classique en effet, je crois que c'est utilisé dans la majorité des jeux ce système :) (à vrai dire, je ne connais pas d'autres moyens).

De mon côté (avis perso donc), ce n'est pas un EntitiesManager que j'utilise, mais simplement une entité "Root" qui sera le père de tous les entités. Ca fonctionne de la même façon, mais avec un système père->fils assez optimisé, et avec un arrière gout de "Composants" (un peu comme le tiens en faite).
Par contre niveau manipulation des entités depuis l'extérieur, c'est bien plus limité. Mais c'est voulu pour rester cohérent avec les objets :).

Bon je développe sous Java et non du HTML5&co, donc je pense que ce genre de système serait bien plus complexe et "lourd" à mettre en place pour le web. Je n'ai jamais tenté à vrai dire, mais c'est à tenter :).

Tomaka17
28/03/2013, 10h28
En gros tu fais de l'héritage dans de la programmation orienté objet.
Le principe des entités a justement été imaginé pour se détacher de ce vieux schéma, qui lui est pour le coup utilisé dans la majorité des jeux.

Si l'on s'en tient à la théorie, il y a au final peu de différences entre un système d'entités et du simple héritage orienté objet.

Le système d'entités permet en fait d'avoir quelque chose de plus souple, puisqu'on est proche d'un typage faible (comme dans javascript, PHP, etc.) au contraire du typage fort si tu utilises des classes.
De plus les composants représentent plus ou moins des comportements. Tu ne verras jamais de composants qui s'appellent "Unit", "Building" ou "Item". Tu n'auras que des composants comme "Position", "Physics", "Script", "HasInventory", "Targetable", etc.
Et l'autre principe de base de ce système c'est de séparer les données du code qui modifie les données. Tu ne verras jamais "entity->update()" par exemple. Tu verras "physicsEngine->update(entity)".


(et sinon tu t'es gouré de topic, je fais ça en C++ pas en HTML)

Louck
28/03/2013, 11h01
(et sinon tu t'es gouré de topic, je fais ça en C++ pas en HTML)

Ah merde, je me suis trompé de topic de programmation :p.

J'avais aussi débuté avec un système d'EntitiesManager dans mon premier vrai projet (HATU), avant d'exploiter l'héritage d'objets.
Il est sûr qu'on est un peu plus libre avec un EM qu'avec une série d'entités père->fils. Mais je trouve plus facile et logique de coder avec de l'héritage, surtout si je dois tracer les erreurs possibles lorsqu'une entité est créée (qui est le coupable ?) et lorsque certaines entités doivent être dépendantes d'autres. Plus tard, ca sera aussi utilisé pour le multi-threading.

Pour dire vrai, mon système est un mélange de tout: Il exploite bien le système d'héritage, mais il est aussi possible de stocker toutes les entités à la racine si on veut utiliser un EM perso. Les entités sont aussi stockées par "régions" et ils ont aussi des composants (Position, Physics, etc..). C'est un très gros bazar au final.


J'essaye de rendre mon engin moins bordélique au fur et à mesure des prototypes et des jeux que je réalise. Donc je suis bien loin d'un vrai moteur de jeu tout propre et qui fait le café :p.

Aulren
28/03/2013, 13h24
Tout est une entité. Les nains sont une entité, les objets sont une entité, etc. et on personnalise l'entité lors de sa création pour lui donner toutes ses caractéristiques.
Par exemple pour poser un objet par terre, je créé une entité avec les caractéristiques : "affiché sous forme de sprite", "position à tel endroit", "objet physique", etc.
Le code d'affichage va alors détecter la création d'un "affiché sous forme de sprite" et s'occuper de charger le sprite et d'afficher tout ça à la bonne position.

L'avantage est bien sûr que c'est très modulable. L'autre avantage est que c'est facile à sérialiser (c'est à dire à convertir en texte pour pouvoir sauvegarder).
En fait le système de sauvegarde et chargement fonctionneraient déjà, il manque juste un bouton pour le faire.
D'ailleurs pour initier le jeu je charge depuis une sauvegarde (une "fausse" sauvegarde) qui contient le status du début de partie.

Ça risque pas de générer des problèmes de perf d'avoir 20 milliards d'entités indépendantes ?

Tomaka17
28/03/2013, 13h33
J'ai un système de callbacks.

Par exemple mon code qui gère les déplacements commence par enregistrer un callback.
Ensuite à chaque fois qu'une entité qui possède un composant "mouvement" est créée, le code qui gère les déplacements est alerté et peut ajouter cette entité à une liste.
Lorsque je fais "movementSystem->update()" il va simplement prendre chaque entité de sa liste. Il sait que toutes celles qui sont dedans ont forcément un composant de mouvement.

De même j'ai un callback quand un composant est modifié.
Par exemple lorsque je créé un composant "affiché sous forme de sprite", le code qui gère l'affichage est alerté, puis charge le sprite en question (dont le nom est stocké dans le composant) et créé tout le bordel pour l'afficher.
Si jamais ce composant est modifié, le code qui gère l'affichage est alerté, vérifie si le nom du sprite a changé. Si oui il répercute la modif.

En fait le seul problème de perf que je vois, c'est qu'à chaque modification il y a deux/trois lectures dans des hash maps.
Cela dit lire une hash map n'est pas très lent, et puis les modifications dans l'état du jeu il n'y en a pas des milliers par frame.

---------- Post added at 13h33 ---------- Previous post was at 13h30 ----------

Mon .hpp (http://codepad.org/R9oluHTX)
Mon .cpp (http://codepad.org/3XzJhbDb)

(attention c'est pas forcément du niveau débutant)

J'ai un système d'ID numérique à la place de pointeurs vu qu'il faut pouvoir sérialiser tout ça.

Il manque deux/trois trucs, comme pouvoir modifier un composant "in-place", c'est à dire sans faire une grosse copie.

war-p
28/03/2013, 21h00
Windev :trollface:


BAN!

Tomaka17
28/04/2013, 10h46
Bon, je me suis finalement bougé le cul et j'ai bossé sur le fait que le terrain puisse avoir des "demi-tiles".

http://tof.canardpc.com/view/2b79e2ed-e1f1-4a90-a677-b11e51a65801.jpg

Bon là c'est tout aliasé, mais l'AA c'est pas vraiment ma priorité.


S'il y a des gens que ça intéresse de savoir comment j'ai fait, voilà mon shader : http://pastebin.com/Hh82jGyX

En fait je génère sur le CPU un tableau de points et je les mets dans mon vertex buffer. Chaque point correspond au bord bas-gauche de chaque case.
J'ai une texture 2D (variable "tileStatusTexture") qui contient pour chaque tile quatre nombres. Chaque case est découpée en quatre (en haut, gauche, droite, en bas), et je stocke dans chaque élément de la texture le numéro du type de sol de chacun de ces quatre morceaux.
Par exemple si la roche c'est 1 et que le cuivre c'est 2, alors une case full roche contiendra quatre fois 1, une case full cuivre contiendra quatre fois 2, une case mi-roche-mi-cuivre avec une pente contiendra deux 1 et deux 2.

J'ai également un tableau de textures (variable "tileTextures") contenant toutes les textures des différents tiles (texture du sol, texture de la roche, etc.)

Dans le vertex shader je vais lire dans la texture le type de sol de la case en cours ainsi que des huit cases avoisinantes.
Dans le geometry shader je construis les quatre triangles représentant les quatre morceaux et je détermine s'il faut dessiner une bordure autour du tile, dans la diagonale, ou dans les coins. Je rajoute également dans la position un petit nombre aléatoire (mais généré aléatoirement à partir d'une seed non aléatoire, sinon ça vibrerait à l'écran) afin de donner le petit effet cartoon.
Dans le fragment shader je détermine si je suis à l'intérieur d'une bordure (auquel cas je renvois la couleur noir), et si ce n'est pas le cas je lis le tableau de textures au bon offset. Je rajoute un petit bruit aléatoire et le tour est joué.

C'est un peu compliqué mais je vois pas comment j'aurais pu faire plus simple.
Reste éventuellement à optimiser un peu le tout, et à remettre les systèmes de "shadow" (par exemple si je veux modifier une case, il faut que la modification soit affichée en surbrillance) et de sélection d'une case (la petite bordure rouge lorsqu'on met la souris dessus).

tompalmer
20/05/2013, 03h04
Du nouveau !

Moen
27/05/2013, 12h42
Oui ! On veut des nouvelles !! Viiiiteee Viiiteee !!!

Tomaka17
27/05/2013, 12h56
Euh... euh... ben j'ai pas de nouvelles !

Techniquement j'ai rencontré un petit soucis avec mon système de composants.
C'est un peu difficile à expliquer, mais si on prend par exemple les déplacements. Si je veux connaître quelle est la direction de déplacement d'une entité, je suis obligé de connaître tous les autres composants (IA, souffle d'une explosion, etc.), ce qui est contre l'idée du "separation of concerns".

Par conséquent j'ai un peu changé mon design pour permettre les "liens" entre composants. Par exemple un composant IA va se lier au composant mouvement pour lui indiquer quel est le déplacement à faire.

Du coup je suis tranquillement en train de transformer mes vieux composants en nouveaux, au rythme de 3 lignes de code par semaine :ninja:

Tomaka17
13/06/2013, 12h05
Bon, j'ai un peu plus de temps libre à partir de maintenant.
Je viens de recommencer à bosser dessus sérieusement.

J'ai entamé quelques changements techniques depuis mes derniers posts.


Tout d'abord j'ai remplacé le système de callbacks de mon manager par une liste d'événements qui est lue à chaque frame.

Avant j'avais un simple système de callbacks, c'est à dire que j'appelais une liste de fonctions dès qu'un événement se produisait. Mais ça pose de gros problèmes. En effet si un événement se produit et qu'un callback fait se produire un autre événement, on a les fonctions qui seront appelées dans le mauvais ordre, c'est à dire que certaines fonctions recevront d'abord l'événement B avant l'événement A. Si en plus j'essaye de multithreader tout ça (c'est à dire faire s'exécuter simultanément plusieurs choses), on va rentrer dans un chaos total.

Maintenant lorsque quelque chose se produit, on a simplement un événement qui se rajoute à la fin d'une liste, sans aucun appel de fonction. La liste d'événements est alors lue à chaque frame. L'avantage c'est que je peux demander à plusieurs parties du programme (l'affichage, le son, les inputs) de lire simultanément la liste d'événements. Et ensuite je commit toutes les modifications (position, mécaniques de jeu, etc.), qui seront affichées à la frame suivante.


La deuxième modification c'est que j'ai fait hériter tous les composants d'une classe parente Component.
À la base je voulais profiter de la puissance templatique du C++. Mais le langage manque en fait trop de reflection (http://en.wikipedia.org/wiki/Reflection_(computer_programming)) pour que je puisse aller au bout de mon idée.
J'ai donc maintenant des fonctions virtuelles "serialize", "unserialize", "getScriptVariablesList", etc.


Je pense que je vais enchaîner sur l'animation des personnages, ça va pas être une mince affaire.

Tomaka17
13/06/2013, 23h13
J'arrive à un petit résultat niveau animation.

En fait pour chaque unité dans le jeu, je vais mettre un petit fichier en YAML qui décrit toutes les parties du corps de cette unité et toutes ses animations.

Par exemple là j'ai un fichier "dwarf.yaml" qui contient les noms des fichiers image qui composent le nain, ainsi que la position, taille et rotation de ces différentes images lors de chaque keyframe de chaque animation.
Donc pour l'instant j'arrive à enchaîner les keyframes. Je voulais faire un petit gif et le mettre ici, mais pour une raison inconnue Fraps ne fonctionne pas dans mon jeu.

Il me reste juste à interpoler les positions entre deux keyframes.
Je vais également rajouter un petit coefficient comme c'est le cas dans Adobe Flash qui permet de rendre l'interpolation plus rapide au début puis ralentit, ou au contraire lente au début puis accélère.
Je sais pas trop comment ça marche dans flash, mais je pense que c'est tout simplement une courbe de bézier, avec le coefficient qui sert à indiquer où est le point intermédiaire.

Tomaka17
14/06/2013, 16h12
Bon ben j'ai installé la dernière version de Fraps et j'arrive de nouveau à capturer l'écran. Apparemment c'était à cause d'une mise à jour windows.

Bref, mon petit code d'animation marche du tonnerre.
Reste à faire les animations. Ouai. Ça va pas être simple.

En fait le problème c'est qu'il n'y a pas vraiment d'outil gratuit permettant d'animer des images existantes (et encore moins d'exporter les animations), du coup je devoir tout me taper à la main.

Du coup j'ai inventé mon propre format. Par exemple ce fichier YAML :


body:
- resource: textures/units/dwarfArmSide
center: [ 0.5, 0.97 ]
dimensions: [ 0.17, 0.26 ]
- resource: textures/units/dwarfFootSide
center: [ 0.42, 0.97 ]
dimensions: [ 0.29, 0.16 ]
- resource: textures/units/dwarfBodySide
center: [ 0.5, 0.5 ]
dimensions: [ 0.52, 0.50 ]
- resource: textures/units/dwarfHeadSide
center: [ 0.5, 0.5 ]
dimensions: [ 0.53, 0.60 ]
- resource: textures/units/dwarfArmSide
center: [ 0.5, 0.97 ]
dimensions: [ 0.17, 0.26 ]
animations:
walking:
- duration: 0.5
acceleration: 0.2
body:
- position: [ 0, 0.25 ]
rotation: 0.79
- position: [ 0, 0.08 ]
rotation: -0.05
- position: [ 0, 0.28 ]
- position: [ 0, 0.70 ]
- position: [ 0, 0.25 ]
rotation: -0.79
- duration: 0.5
acceleration: -0.2
body:
- position: [ -0.05, 0.25 ]
rotation: -0.79
- position: [ 0.01, 0.08 ]
rotation: 0.05
- position: [ 0, 0.28 ]
- position: [ 0, 0.71 ]
- position: [ 0.05, 0.25 ]
rotation: 0.79


Me donne ce résultat :

http://i.imgur.com/qWpih4R.gif

tompalmer
14/06/2013, 18h51
on dirait prison architect

Poussin Joyeux
14/06/2013, 23h49
C'est vrai que ça y ressemble!

C'est pas mal.
Et en tout cas, c'est toujours mieux que les animations des personnages dans Gnomoria ou DF :)

rOut
15/06/2013, 00h13
Tu devrais tester Spine : http://esotericsoftware.com/spine-download/

Tomaka17
15/06/2013, 09h24
Ah, pas mal ce truc ! Je sais pas comment je suis passé à côté de ça.
C'est vraiment très complet, et c'est pile ce qu'il me faut.

Moen
15/06/2013, 15h31
C'est payant malheureusement, mais pour 60€ je pense que je vais craquer, surtout que pixi.js que j'utilise le supporte nativement depuis la dernière release !

Sinon il est classe ton nain ! Mais il est Not amused !!! :)

Tomaka17
16/06/2013, 14h59
Hop, je me suis payé ce petit soft

C'est assez simple de créer des trucs avec :

http://img198.imageshack.us/img198/8992/yl8.gif

Reste à faire le code C++ qui lit l'animation.

tompalmer
16/06/2013, 15h02
manque un petit roulement d'oeil

rOut
16/06/2013, 22h16
T'as des runtime déjà écrites aussi pour spine : http://esotericsoftware.com/spine-runtimes/

Tomaka17
16/06/2013, 22h45
Ouai, j'ai vu, mais v'là le code un peu merdique quoi.

Là mon code à moi marche à part quelques bugs, et en terme de lignes de code il fait la taille de chacun de ses fichiers pris individuellement.

Tomaka17
17/06/2013, 09h02
Voilà, ça marche en 500 lignes de code :

http://img594.imageshack.us/img594/6189/ln3.gif

http://pastebin.com/k3913U8N
http://pastebin.com/mmnSethJ

Faudrait optimiser un peu ça, mais à part la possibilité de changer la couleur des sprites et la possibilité de mettre des gifs animés, tout est implémenté.


J'ai juste un problème, c'est que les dimensions sont arbitraires puisque ce sont en fait les dimensions en pixels des images qui sont prises. Par exemple si mon buste fait 400px de haut et ma tête 300px, le tout fera à peu près 700 unités de haut in-game, et il n'y a rien qui permet de savoir ça.

Du coup je ne sais pas de combien réduire la taille pour que ça coincide avec le décor.

rOut
17/06/2013, 10h23
Pourquoi est-ce que tu fais systématiquement des conversions vers std::string lorsque tu accèdes à ta hashtable ? Pourquoi ne pas faire simplement mCharacterInfos["bones"], plus lisible ?
Je pense aussi que tu peux t'économiser des lignes et des ifs avec des valeurs de fallback du genre : nodeX.as< float >(0).

Ton calcul de la courbe de bezier est un peu barbare aussi, et ne fonctionne certainement pas si la courbe passe plusieurs fois par le même x, tu devrais retourner la coordonnée d'un point pour t passé en paramètre au lieu d'essayer de le faire pour un x donné.

Tomaka17
17/06/2013, 11h00
Pour le mCharacterInfos["bones"] et le nodeX.as<float>(0) c'est parce que j'utilise la librairie YAML.
Si j'écris mCharacterInfos["bones"], il me met une erreur parce que la lib utilise des templates, et a prévu le cas const char* mais pas le cas const char[N]. Peut être qu'une mise à jour de la lib corrigerait ça, j'ai pas testé.

Pour nodeX.as<float>(0), c'est pareil, la lib ne supporte pas ça.



Pour la courbe de bézier, en fait l'axe X représente le temps entre les deux keyframes, et l'axe Y représente la progression de l'animation. Du coup il me faut une méthode pour convertir de X en Y.
Juste après avoir posté le code j'ai changé l'algorithme pour faire ça par dichotomie. C'est à dire qu'au lieu de faire t=0, puis t=0.01, puis t=0.02, etc. je fais t=0.5, et en fonction de si on trouve un résultat trop grand ou trop petit je pars sur t=0.25 ou t=0.75.

Mais j'ai eu une autre idée tout à l'heure : je vais tout bêtement garder en mémoire le "t" qui a été trouvé lors du précédent appel de fonction, et chercher à partir de là.



Je vais encore rien optimiser, mais je pense que je gagnerai beaucoup de temps en gardant en mémoire tout simplement les étapes d'animation actuelles, plutôt que de rechercher l'étape actuelle à chaque frame.

rOut
17/06/2013, 11h08
La version 0.5.1 de yaml-cpp a bien la méthode as(S const& fallback) et je pense que char[N] aussi est supporté.
http://code.google.com/p/yaml-cpp/source/browse/include/yaml-cpp/node/node.h?name=release-0.5.1#51
http://code.google.com/p/yaml-cpp/source/browse/include/yaml-cpp/node/impl.h?name=release-0.5.1#358

Tomaka17
17/06/2013, 11h20
Ouaip ça marche, merci.
En fait pour le char[N], c'était une structure qui s'appelle convert<T>, donc c'est pas ce bout de code là avec to_value_t. Mais ça a l'air d'avoir été corrigé dans la 0.5.1.

Tomaka17
28/06/2013, 22h20
J'ai eu l'idée d'externaliser le code qui génère le terrain (http://pastebin.com/qY3eN1T9).

Seule couille : ça prend environ une minute pour générer un pauvre terrain de 512x512.
Après profilage, c'est la partie interface entre le C++ et le Lua qui bouffe 99 % du temps. J'ai à peu près 200 000 appels de fonction de Lua vers C++.
Du coup va falloir que je passe un peu de temps à optimiser ça.

Tomaka17
09/07/2013, 13h53
Bon, je me suis dit que j'allais créer un petit snapshot de là où j'en suis.
Je vous préviens tout de suite : c'est pas super intéressant si vous n'êtes pas programmeur, mais ça dévoile l'envers du décor.

Ça se télécharge ici. (http://www.mediafire.com/download/19ovr0j1msl9s9k/jeu.rar)
Attention : je suis passé à Visual C++ 2013, et comme c'est tout neuf il y a de grandes chances que vous ayez besoin d'installer "Redistribuable Visual C++ pour Visual Studio 2013", qui est téléchargeable ici (http://www.microsoft.com/visualstudio/fra/2013-downloads#d-additional-software).

Il y a trois gros bugs connus : au bout d'un certain nombre de clicks à l'écran ça plante (je suspecte un bug dans un code de la STL de Visual C++), parfois il y a un popup "exception while calculating path, blabla, we are inside a solid tile" suivi d'un crash, et on ne peut pas descendre les pentes qui vont vers la droite.

http://tof.canardpc.com/view/97e65bce-d609-4406-af6b-fb62575f6e32.jpg

Fonctionnement

Donc l'idée, c'est que je suis passé à un système d'entités dynamiques.
Lorsqu'on démarre le programme, celui-ci charge "resources/game-start.yaml" (qui contient l'état initial du jeu), puis exécute "resources/game-init.lua" (qui se charge pour l'instant juste de créer le terrain de manière aléatoire). J'ai choisi le yaml comme format de sauvegarde de la game, et en chargeant game-start.yaml c'est en fait le même code que si je chargeais une save.

Tout ce qui existe à l'écran ou dans la mémoire du jeu est décrit dans ces deux fichiers, il n'y a rien de caché.
Par exemple le personnage que vous voyez à l'écran est décrit dans game-start.yaml :

- name: character
components:
position:
x: 1.5
y: 0.12
characterDisplay:
model: textures/units/dwarf
colliding:
collidesWithOthers: false
collidesWithGround: true
bumpOnCollision: true
destination:
x: 12
y: 10
taskAssignment:
autoAssign: true
task: ~
animated:
animation: walk
speed: 1

Par exemple vous pouvez modifier "walk" en "idle" ou bien modifier la valeur de "animated" -> "speed", pour que le personnage s'anime différemment. Vous pouvez mettre "collidesWithGround" à false afin de permettre au personnage de s'enfoncer dans le sol.
Le model "textures/units/dwarf" désigne le fichier "resources/textures/units/dwarf.json" généré par spine, qui contient quant à lui les noms des images composant le nain.

La "destination" désigne l'endroit où doit se déplacer le personnage. Mon algo de pathfinding se charge automatiquement de calculer le chemin. Celui-ci est un peu buggé encore, puisque je ne peux par exemple pas descendre les pentes qui vont vers la droite.


Les interactions

Vous remarquez que lorsqu'on clique sur une case au niveau du sol, le personnage s'y dirige.
En fait c'est un morceau de code dans game-init.lua qui fait ça, ligne 83 :

entity:add("interactive")
entity.interactive.scriptOnClick = [[
Entities[2].destination.x = This.position.x
Entities[2].destination.y = This.position.y

local e = Entities:new("digJob")
e:add("assignable")
e.assignable.maxAssignments = 1
]]

Je suis à l'intérieur d'une boucle for, et "entity" désigne la case de terrain actuellement en cours de création.
J'ajoute à la case un composant "interactive", et lorsqu'on clique sur la case, le contenu de "entity.interactive.scriptOnClick" sera exécuté. Note : en lua, les [[ ]] permet de faire un bloc de texte multiligne.

Le bout de code en question modifie la destination de l'entité n°2 (c'est à dire le personnage) pour qu'il vienne sur la case sur laquelle on a cliquée. Les trois lignes suivantes sont simplement là parce que j'ai commencé à refaire le système de jobs, mais c'est pas encore fini, et donc elles ne servent à rien.

Si vous cliquez sur une case en l'air ou sur une case sous-terraine, la destination est bien modifiée mais le personnage n'arrive pas à s'y diriger et donc ne bouge pas.


La caméra

Autre exemple : la caméra.
La caméra est gérée de façon manuelle. J'ai une entité spéciale nommée "meta-entité" qui se charge de désigner quelle est la caméra actuelle :

- name: meta-entity
components:
camera:
cameraEntity: 1

La caméra est quant à elle simplement une entité qui possède une position, et qui est dirigée par le joueur uniquement car elle possède un composant "playerControl".

- name: camera
components:
ownerMovements:
x: 0
y: 0
position:
x: 2
y: 10
playerControl:
maxSpeed: 0.2

Si vous enlevez "playerControl: maxSpeed: 0.2" vous ne pourrez plus diriger la caméra.
Si vous copiez-coller les composants de la caméra pour les mettre sur le personnage, vous pourrez manuellement diriger celui-ci à l'aide du clavier.

Tomaka17
30/07/2013, 12h11
Histoire de donner des nouvelles, je fais toujours mumuse avec mon moteur de jeu.

http://i.imgur.com/htOGXpi.gif

(le gif est assez lent, je sais pas pourquoi)

J'ai rajouté un système d'entités "templates", qui me permet notamment de créer des spawners.
Vous voyez les personnages à droite apparaître. En fait c'est un spawner invisible qui se déplace vers la droite et fait apparaître des personnages à intervalle régulier.

Mon GUI fonctionne à nouveau à peu près correctement.
Les boutons en bas à droite fonctionnent.

deathdigger
03/08/2013, 11h05
Pour les animations, si je ne dis pas de conneries, la technique usuelle est d'utiliser une planche de ton perso contenant toutes les étapes possibles de chaque animation (pour une question de charge de mémoire, c'est moins gourmand qu'une image par étape d'animation) :
http://3.bp.blogspot.com/-k-FIGg9k3yE/TnBuRQ6VHNI/AAAAAAAAACg/PPyciU7PrCE/s1600/walksequence_spritesheet.png

(Cherche animation sprite sheet sur google).
Ta méthode est je pense moins gourmande en mémoire (puisque ce n'est pas la totalité de la texture que tu redessines à chaque fois), mais tu ne pourras faire d'animations avancées.

Tomaka17
03/08/2013, 11h39
Ça c'est la méthode classique, que j'exclus car ça prend énormément de temps de dessiner tout ça et que je ne sais de toute façon pas dessiner correctement.

Au pire des cas je peux toujours utiliser ce principe avec Spine, puisque celui-ci permet de changer de sprite au cours de l'animation. Donc ma méthode ne va absolument pas me limiter en quoi que ce soit.

tompalmer
23/09/2013, 05h58
Des news cher tomaka ?

Tomaka17
23/09/2013, 15h17
De nouveau, il y a que ça compile sous Linux et que mon pathfinding est maintenant à peu près niquel. J'ai aussi un GUI qui marche un peu mieux.
J'ai réglé plein de petits détails avec mon moteur. Il faudrait juste que je remettre ça au propre.

En gros pour l'instant quand je lance le jeu, je peux donner l'ordre de couper des arbres ou de creuser le sol. Un nain est automatiquement assigné et effectue la tâche.

Ce qui me bloque un peu c'est l'UI. Il faut que je bosse un peu là dessus si je veux avancer. En fait je pourrais par exemple créer un bouton "poser une échelle" et le faire marcher. Mais le problème c'est que je ne vais pas créer un bouton pour chaque objet constructible. Du coup il me faut un petit système de fenêtres et tout le bordel.

Aristynax
13/10/2013, 15h29
Est-ce que Survivor of Ragnarok t'as inspiré ? Le pitch de départ semble plutôt similaire :


http://www.youtube.com/watch?v=NjSOZ2mMzZk
C'est aussi du DF-Like, centré sur la gestion des unités, quoique avec peut-être une touche plus importante de gestion des caractéristiques.

Tomaka17
13/10/2013, 15h44
Je connais pas du tout ce jeu, mais il a l'air bien sympa.


En tout cas même si j'ai pas encore de prototype à montrer (plein de trucs qui marchent pas et de trucs qui marchent mais bien hacky), j'ai eu plein d'idées vis à vis du jeu.

J'aime beaucoup les jeux "d'exploration" que l'on découvre au fur et à mesure, et je vais faire un jeu de ce genre. C'est à dire concrètement que par exemple au lieu de dire dans un tuto "vous devez récolter du fer pour fabriquer des épées", je laisserai au joueur découvrir le fer et ferai apparaître les recettes à ce moment-là. Et je vais essayer de remplir le jeu de ça.

Tomaka17
27/01/2014, 18h33
Petit post pour dire que non, non, ce n'est pas mort, j'avance toujours.

http://tof.canardpc.com/view/3537bd09-69a7-4d2b-825c-de9de48fc065.jpg

tompalmer
14/08/2014, 00h57
Et là ?

Tomaka17
14/08/2014, 08h26
Petit sacripant :p

En fait j'ai découvert récemment le langage Rust, qui est absolument magnifique, et j'ai décidé de réécrire le jeu en Rust.
Je sais que c'est typiquement le genre de décision qu'il ne faut absolument pas prendre si on veut que ça avance, mais vu que ce n'est pas mon gagne-pain je me suis dit "rien-n'à-battre j'aime trop ce langage".

Catel
14/08/2014, 08h46
No updates in eight months -- great just another scam I guess. My money is lost forever. How can I get a refund ? We should take a class action.

Tomaka17
29/11/2014, 15h01
Bon, pour faire plaisir à tompalmer, j'ai décidé de finir un prototype d'ici la fin de l'année. EDIT : de l'année 2014.

Tomaka17
02/12/2014, 14h08
Et même que je vais poster l'avancement au fur et à mesure tous les 3/4 jours. C'est parti pour la première version (https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-02.rar).
(touches fléchées pour se déplacer, molette souris pour zoomer/dézoomer, les boutons en bas servent à placer des bâtiments)

(note : le jeu n'a absolument aucun intérêt pour le moment, c'est juste pour les éventuels curieux, et je fais aussi ça pour me forcer moi à avancer dessus)

http://tof.canardpc.com/view/1852b80f-c240-4186-99f7-a9292f839ace.jpg

J'ai bossé sur quelques sprites/modèles supplémentaires.
Le but du jeu sera de construire sa base autour d'un chargement d'or qu'il s'agit de défendre contre les hordes d'envahisseurs.

Tomaka17
04/12/2014, 10h37
Comme promis, je poste mes versions : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-04.rar

J'ai pas mal avancé en deux jours : les nains effectuent maintenant leur tâches (à savoir couper les arbres et construire les bâtiments), ils ne sont plus bloqués en animation de marche permanente, déambulent quand ils n'ont rien à faire, les bâtiments ne peuvent plus se chevaucher, et quelques autres changements mineurs.

tompalmer
04/12/2014, 10h57
:lol:

Tomaka17
04/12/2014, 11h25
Pour ceux que ça intéresse, j'utilise uniquement les libs suivantes :

https://github.com/bjz/cgmath-rs
https://github.com/tomaka/glium
https://github.com/tomaka/spine-rs
https://github.com/tomaka/glutin
https://github.com/PistonDevelopers/image
https://github.com/tomaka/rust-package

Tomaka17
05/12/2014, 15h51
Version du jour : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-05.rar

- Ajout du "système de combats", les zombies tapent mais les nains ne se défendent pas encore
- Ajout des barres de vie (oui je sais que c'est moche)
- Ajout des murs (le 4ème bouton en bas), les zombies sont bloqués par les murs
- Certains arbres sont maintenant des rochers qui fournissent des cailloux ou du fer (le fer est très moche)

Bon là j'avance vite, mais je vais pas forcément tenir ce rythme. L'idée c'est d'avoir un gameplay d'ici la fin de l'année.

Hideo
07/12/2014, 14h43
Je test :lol:

Tomaka17
07/12/2014, 14h59
:lol:

Cela dit comme dit plus haut ce n'est pas "jouable". Y a des trucs qui bougent à l'écran, mais y a pas d'objectif, de skill ou quoi que ce soit.

Rekka
08/12/2014, 13h18
J'ai voulu tester mais j'ai un message comme quoi mon système n'est pas compatible. C'est du 64bits only?

Tomaka17
08/12/2014, 13h27
Ah oui zut, je compile en 64bits.
Le prochain snapshot je le fais en 32bits.

Tomaka17
09/12/2014, 11h11
Snapshot du jour : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-09.rar (en 32 bits ce coup-ci)

C'est toujours pas "jouable" mais on s'en rapproche peu à peu.

- Les nains doivent désormais amener des matériaux aux sites de construction au lieu de construire directement (pour l'instant 4 bois pour chaque bâtiment)
- Remplacement des barres de vie par des ronds mal samplés, avec la barre de faim sur la droite ; à l'intérieur du rond il y aura la tâche en train d'être effectuée
- J'ai enlevé les envahisseurs pour l'instant afin de me focaliser sur l'aspect gestion

Rekka
09/12/2014, 12h14
Toujours le même message d'erreur pour moi :
"La version de ce fichier est incompatible avec la version de Windows que vous utilisez. Consultez les informations système de l'ordinateur pour savoir si vous avez besoin d'une version x86 (32 bits) ou x64 (64 bits), puis contactez l'éditeur du logiciel"

Pour info je suis sous 7 Pro 32 bits là. Je testerai chez moi où je suis sous 7 pro 64.

Tomaka17
09/12/2014, 12h28
Je suis un étourdi, j'avais de nouveau compilé en 64 bits.
Ça devrait être bon dans 5 minutes, le temps que ça upload (même lien qu'au dessus).

Tomaka17
09/12/2014, 22h14
Un autre snapshot pour aujourd'hui car j'ai beaucoup avancé (je suis dessus non-stop depuis ce matin) : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-09b.rar

http://tof.canardpc.com/view/444219f9-bd80-4b90-9b7f-3e6c84616db1.jpg

- Il faut maintenant cliquer sur les icônes au dessus des arbres/cailloux pour qu'ils soient récoltés
- Plus d'arbres/cailloux
- Ajout d'objets de départ (planches, nourriture et autre)
- Les nains vont maintenant se nourrir lorsque leur faim diminue, heureusement ils ne peuvent toujours pas mourir
- Ajout d'icônes dans la barre en bas ainsi qu'une interaction lorsqu'on passe la souris dessus
- Ajout d'une icône sous chaque unité pour indiquer ce qu'elle fait

Nattefrost
09/12/2014, 22h43
Cette brute de travail :o
Je suis ça depuis le début et c'est cool que tu t'y remette, pis ce sera l'occasion de nous faire un retour plus complet concernant Rust sur le topic de la programmation ;).

Je download.

tompalmer
09/12/2014, 23h56
Tomaka en pleine gamejam ludum dare de l'E3

Tomaka17
10/12/2014, 07h27
Je suis ça depuis le début et c'est cool que tu t'y remette, pis ce sera l'occasion de nous faire un retour plus complet concernant Rust sur le topic de la programmation ;).

Ah ben le retour je l'ai déjà fait il y a quelques temps. Le Rust c'est le successeur du C.

Pour l'instant dans tout ce boulot, le nombre de "plantages" que j'ai eu se compte sur les doigts d'une main (et par plantage j'entends "le programme se ferme volontairement avec un message d'erreur parce qu'il a détecté un truc pas normal" ; des "vrais" plantages type segfault j'en ai eu aucun).
Et malgré toute cette sécurité le jeu tourne toujours à 1000 fps.

Tomaka17
10/12/2014, 21h07
https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-10.rar

- Ajout d'un écran de chargement et d'une mini "cinématique" d'intro ("cinématique" est un peu exagéré)
- Affichage de l'inventaire des unités et bâtiments (sauf ceux en construction)
- Les éléments de l'overlay ne se chevauchent plus (ouai, je sais que c'est bordélique)
- Ajout du système de production pour les bâtiments, très très expérimental

J'ai deux-trois bugs connus, notamment lorsqu'un inventaire contient plusieurs types d'objets différents.

Tomaka17
15/12/2014, 09h36
Bon, ça fait cinq jours sans update : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-15.rar

J'ai corrigé quelques trucs qui marchaient moyennement, et j'ai fait fonctionner l'affichage de texte (c'pour ça qu'il y a des DLLs dans le zip maintenant) et j'ai commencé la partie audio. En plus de ça j'ai eu quelques soucis techniques qui m'ont empêché d'avancer, mais qui sont maintenant quasi corrigés.

Tomaka17
21/12/2014, 18h32
Hop : https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-18.rar

- Ajout d'une musique de fond trouvée sur le net en 10mn et libre de droits
- Ajout des boutons permettant d'ajuster le nombre de workers pour chaque job (l'UI c'est chiant)

J'ai avancé vite, mais en ce moment je m'attaque aux trucs chiants. J'ai notamment une grosse session de bugfixes/écriture de tests à faire.

Karantoer
23/12/2014, 13h22
Franchement en comparaison avec le début, y-a pas photo le jeu ne ressemble plus du tout à la base. C'est devenu pas mal du tout. Comme quoi tu à bien fait de changer pour le Rust.

Tomaka17
24/12/2014, 14h46
Mine de rien j'avance beaucoup plus vite et plus facilement en Rust, malgré le fait que le langage change tout le temps et que je passe pas mal de temps à mettre à jour tout ce que j'utilise.

Sinon la version du jour: https://dl.dropboxusercontent.com/u/12938337/game/version-2014-12-24.rar
- Ajout du système qui permet de faire spawner les éléments naturels (arbres, rochers) au fur et à mesure ; dans le futur la caméra sera verrouillée à cette région
- Ajout d'un cycle jour-nuit
- Les ennemis attaquent la nuit
- Ajout de pitis lapins qui se baladent (qui serviront à la chasse)
- Amélioration de l'affichage du texte (tout le monde s'en fout, mais j'ai passé presque une journée entière là dessus, donc je le mets quand même)

Par contre pour le gameplay avant la fin de l'année, c'est mal barré, mais je vais évidemment continuer à bosser dessus.

tompalmer
26/12/2015, 04h39
Un an après, le projet est toujours vivant ?

Tomaka17
26/12/2015, 08h50
Mince je suis grillé.

Mais il y a des chances que mon prochain projet te plaise tompalmer.

elfangor
08/01/2016, 21h22
Salut Tomaka !

J'étais tombé sur un lien vers https://github.com/tomaka/android-rs-glue sur le reddit de rust, repo qui semble être à toi. C'est drole de te retrouver ici (si c'est bien toi !) :)
Je suis en train d'apprendre le rust, et je voulais savoir si les sources de ton jeu étaient disponibles ? Je sais qu'il n'est pas fini, mais l'idée c'est de voir l'architecture et le génération.
Si tu ne souhaites pas les mettre à dispo ce n'est pas très grave, je pense pouvoir trouver d'autres jeux en rust (hématite par exemple).

Ton prochain jeu est aussi en rust ? N'hésites pas à dès que tu des choses à montrer !

Tomaka17
09/01/2016, 08h30
Salut,
Oui c'est bien moi !

Je suis pas très chaud au fait de publier les sources (pour plein de raisons). Mais si t'as des questions sur comment faire un truc, je peux y répondre.

Tomaka17
14/01/2016, 16h36
J'aurais bien envie d'ouvrir le topic de mon nouveau projet, mais en même temps j'ai pas grand chose à montrer de jouable pour l'instant.

Grhyll
14/01/2016, 17h40
S'pas grave, commence à générer de la hype.

Tomaka17
15/01/2016, 09h47
Hop : http://forum.canardpc.com/threads/103413-Mon-jeu-de-grande-stratégie-sans-nom-pour-le-moment