Adoranda : Un Aventura-like rafraîchissant
Posté le 10/08/2021 00:44
Salut !
C'est l'été (malgré la météo quelque peu désagréable), et été rime avec projet pour moi !
Comme vous avez peut-être pu le voir, j'ai commencé depuis peu un nouveau projet grandement inspiré de
Aventura, le Royaume Poudingue (dont je vous invite à aller voir le
Press Shift)
Alors non ce ne sera pas un remake, juste un jeu répondant aux mêmes principes c'est à dire :
Une grande carte accessible dès le début
La possibilité de progresser comme on le souhaite
Pouvoir xp d'une certaine façon
Je n'ai pas encore une idée bien claire du gameplay ou de l'histoire, mais je suis dans l'optique de faire un jeu avec un univers propre et détaillé. C'est pour cela que j'ai rajouté des personnages avec qui vous pouvez discuter
Au niveau développement, j'ai privilégié le côté esthétique au technique :
Les cartes sont créées avec
Tiled et peuvent posséder 2 layers.
Les collisions/objets sont indiquées directement dans le tileset grâce aux valeurs de Tiled. Il n'y a donc rien de plus simple que de définir un mur !
Le joueur est constamment
affiché au centre à la manière d'un jeu pokémon. La carte est donc affichée autour du joueur et non pas l'inverse.
Le joueur est animé.
Des personnages peuvent être dissimilés partout sur la carte avec des dialogues uniques.
(Vous n'êtes pas à l'abri d'apparaître dans le jeu sauf refus catégorique )
Au niveau de ce que je souhaite rajouter :
Un intérieur (aléatoire ?) des maisons
Des capacités et de quoi xp
La carte sera divisée en 4 parties. Une par saison selon mes prévisions.
Une sauvegarde évidemment
Un tileset complet, pour l'instant c'est une partie de celui de pokémon rouge feu
Et des choses en plus, je ne vais quand même pas tout raconter !
Ce projet est avant tout un moyen d'apprendre le C et de découvrir les fabuleux outils de
Lephenixnoir. Notamment fxconv qui est juste génial
Je vais donc continuer tranquillement le développement du jeu en essayant de donner des nouvelles de temps en temps. Pour vous teaser, voici une panoplie de screenshots de l'état actuel du projet (la carte sert de test, je ne compte pas la garder) :
Voilà le git du projet si vous souhaitez suivre le développement :
https://github.com/bgiraudr/Adoranda
Hope you enjoy
@RDP <- C'est drôle, je me donne du travail pour dimanche
Fichier joint
Citer : Posté le 25/01/2022 09:36 | #
Super ! Pour les monstres tu as un plan graphique quelque part ? Je me demandais s'il y avait pas moyen de trouver des sprites dans des fangames Pokémon à un moment. Ou alors peut-être que tu veux les faire toi-même ?
Citer : Posté le 25/01/2022 16:58 | # | Fichier joint
J'ai bien envie d'essayer d'en faire par moi-même. Même si ça risque d'être difficile je n'ai pas besoin d'en avoir 50 différents.
Par contre je ne pense les animer, déjà je trouve les animations complexes à faire (en termes de programmation + niveau dessin), de plus cela risque de prendre beaucoup de places.
Si je n'y arrive pas j'irais chercher des idées dans des fangames
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 11/02/2022 20:50 | #
Ahah ! Je suis dans le jeu !
Citer : Posté le 13/02/2022 22:48 | # | Fichier joint
Ahah ! Je suis dans le jeu !
Et bientôt tu seras un monstre !
Je réveille un peu ce topic suite à de récentes mises à jour liées aux combats. Je me rends compte à l'instant que je n'en ai jamais parlé ici.
J'ai adopté des combats au tour par tour à la manière de pokémon. Retenez bien que mon "à la manière de" représentant un "c'est une copie de pokémon".
Tout d'abord voici un aperçu de l'environnement de combat :
Un environnement très simple se permettant juste de lister vos différentes attaques. Comme pour un jeu pokémon vous et votre adversaire possédez des statistiques. Et c'est là que je vais pouvoir détailler.
Les statistiques
Les statistiques actuelles sont simples, elles regroupent :
Attaque
Défense
PV
Niveau
XP
Un monstre est défini dans un fichier json ressemblant à ceci :
"name":"test",
"sprite":"test",
"stats":{
"atk":10,
"def":50,
"pv":20,
"level":1,
"xp":300,
"max_pv":20
},
"moves":[
0,
1,
2
]
}
Les monstres possèdent donc un movepool lié à l'identifiant des différentes attaques.
Ces statistiques ne sont pas des valeurs "brutes". Il s'agit en fait d'une base servant à définir la puissance d'un monstre en fonction de son niveau. Voici la formule régissant l'évolution de ces statistiques.
base : Valeur de base de la statistique de ce monstre
niveau : Niveau souhaité du monstre
Ainsi prenons le monstre situé plus haut. Son niveau de point de vie va donc suivre la courbe en rouge, son niveau de défense la courbe en bleu :
Le joueur est régi par la même croissance.
Les statistiques c'est mignon, mais concrètement elles servent à quoi ?
Voici la formule du calcul des dégâts :
niveau : niveau de l'attaquant
attaque_attaquant : statistique de l'attaque de l'attaquant
attaque_capacité : taux de dégât de la capacité
défense_cible : statistique de défense de la cible
Pas de courbe ici, prenons un exemple.
Nous avons la capacité "Charge" avec 45 de dégâts. Notre monstre est au niveau 10 et possède donc une statistique d'attaque de 22. Admettons que la cible a une stat de défense de 10.
La capacité va donc infliger : 13.88 arrondis à 13 HP.
Si la cible avait une défense telle que notre monstre (base de 50 = 30 à ce niveau) l'attaque aurait infligée seulement 5 HP.
Ok très bien mais comment le niveau du joueur est défini ?
En vainquant un monstre vous gagnez de l'expérience, cette expérience est calculée de cette manière :
base_xp : Le taux d'expérience que le monstre donne (dans l'exemple 300)
niveau_vaincu : Le niveau du monstre vaincu
Eh oui, deux monstres ne vont pas forcément rapporter la même quantité d'expérience. En fonction de la base d'expérience, vous allez gagner plus ou moins d'expérience.
Cette expérience permet d'augmenter votre niveau de cette manière :
En gros, un équivalent de la racine cubique de l'expérience.
Voilà qui fait beaucoup de formules différentes, mais globalement cela permet d'avoir une progression plutôt agréable
Bien sûr il faut encore faire des ajustements sur les différents coefficients, mais maintenant nous pouvons améliorer notre joueur et ça c'est déjà quelque chose de bien !
Voilà voilà, j'ai pu aussi travailler sur d'autres petits trucs. Mais l'ajout principal reste cette gestion des statistiques
À bientôt !
@RDP
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 15/02/2022 02:20 | # | Fichier joint
Je me suis motivé un peu et ai commencé à travailler sur l'interface en combat. Sans trop de surprise on dirait un jeu pokémon. Décidément, je me demande ce que je suis en train de faire
En tout cas vous pouvez comparer, quand l'interface est agréable ça donne directement beaucoup plus envie !
Avant c'était ça ahah
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 15/02/2022 10:28 | #
C'est solide ! C'est marrant que tu sois parti en mode full Pokémon sur les combats, ça permettra de récupérer les mécaniques
Citer : Posté le 28/02/2022 12:05 | # | Fichier joint
Je suis en train de rédiger la RDP, j'ai besoin d'une image.
J'ai pu rajouter un système de "zone" directement sur la carte Tiled. Avec ses rectangles il est très facile de donner le niveau moyen d'une zone ainsi que de spécifier les monstres que le joueur risque de rencontrer (probabilité égale).
J'ai également pu rajouter deux trois petites choses que vous pourrez voir dans la revue
Ajouté le 27/03/2022 à 01:51 :
Yo vous vous souvenez de ce topic ?
Aujourd'hui, pour changer un peu ce n'est pas pour annuler le projet que j'envoie un message mais plutôt pour vous demander deux choses :
1 - Quelles mécaniques de combat souhaitez-vous en priorité ?
En effet pour l'instant je n'ai pas implémenté énormément de choses, à vrai dire il n'y a que des attaques physiques et des attaques pour améliorer ses statistiques le temps d'un combat.
Voulez-vous, à la manière d'un pokémon (quitte à copier jusqu'au bout), un système de type ou encore un système d'attaque spéciale et défense spéciale sur des statistiques différentes ?
Au niveau contenu de combat j'ai aussi rajouté les coups critiques (probabilité 1/16) et une chance de rater son attaque en fonction de la précision.
Et voilà la question intéressante :
2 - Comment implémenter le système d'évènements ?
Quand je parle d'évènement je parle des actions que certains pnj / objets / interactions peuvent vous donner. Genre parler avec quelqu'un qui vous apprend une capacité ou trouver un objet sur le sol qui vous améliore vos stats.
Vu que je n'ai jamais programmé de RPG je ne sais pas trop comment gérer ça, j'ai pensé à un système qui me plaît plutôt bien et reste simple à mettre en place :
Un attribut "event" sur chacun des éléments pouvant avoir un évènement. Lié à un identifiant et 0 si aucun évènement.
Et un simple appel vers une fonction spécifique qui redirige vers le bon évènement programmé en dur dans le code.
J'aime bien cette solution, mais à voir si vous avez des propositions plus intéressantes et moins programmé en "dur"
Au niveau du changelog depuis la dernière fois :
• Fix dialogue (merci Lephé)
• Les zones peuvent contenir plusieurs monstres qui apparaissent tous de manière aléatoire.
De ce côté il s'agit juste d'un attribut "monster" dans les zones avec les identifiants des monstres en question sous cette forme : id;id;id. Pour me simplifier la vie j'ai aussi cette syntaxe : id1-id2;id3 avec id1 et id2 un range entre deux monstres.
Pour les probabilités d'apparition on peut simplement rajouter plusieurs fois un même id pour augmenter sa probabilité d'apparition.
• Le joueur apprend des capacités en montant de niveau.
Et voilà, c'est tout
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 27/03/2022 03:51 | #
Salut Tituya, je suis un believer.
Quelles mécaniques de combat as-tu absolument besoin pour que le jeu fonctionne ? Conserve celles-ci et jette le reste (ou au moins met le de côté pour bien plus tard), ça ne te servira à rien d'avoir un combat ultra complet si le contenu n'en a pas besoin (sauf si ton jeu est centré autour du combat évidement, mais dans ce cas tu ne poserais pas cette question). Ce conseil s'applique également aux statistiques.
J'ai une proposition à te faire. Il y a peut-être mieux, mais il y a aussi bien pire.
Les événements peuvent être déclarés dans une structure contenant les informations associées : le type, que tu as mentionné, et d'autres attributs propres à certains événements (contenus dans des unions).
union EventArg {
int i;
char *s;
};
struct Event {
unsigned int type;
union EventArg a, b, c;
};
Tu as la possiblité de déclarer des listes de struct Event terminéees un ET_NONE pour rendre leur parcours facile :
{ ET_XP, 69 },
{ ET_SAY, {.s = "Nice!"} },
{ ET_GIVE, 42, {.s = "gold"} },
{ ET_DEATH },
{ 0 },
};
Tu peux process les événements dans un switch (event.type).
J'espère que ça te donne une idée.
J'attend de voir les propositions d'autres personnes, je suis curieux.
#TituyaAdmin
Citer : Posté le 27/03/2022 10:20 | #
Au niveau du système de combat, j'ai un faible pour celui d'Omori (très inspiré de Pokemon) qui est très simple mais diablement efficace.
En gros, il y a trois types basés sur les émotions :
– Joie, qui augmente la rapidité et la chance mais diminue la puissance des coups. Fort contre Colère.
– Colère, qui augmente les dégats mais diminue la défense. Fort contre Tristesse.
– Tristesse, qui augmente la défense et diminue la vitesse, et "tank" une partie des dégats vers les points de magie. Fort contre Joie.
– Neutre, l'état par défaut.
À noter que les émotions se déclinent en trois variations de plus en plus puissantes (angry → enraged → furious) qui accentuent leurs propriétés. Là où c'est intéressant c'est que les personnages et les ennemis ont des attaques spéciales qui permettent de modifier les émotions d'une ou plusieurs personnes afin de le tourner à son avanatage : Par exemple, le perso A peut énerver le perso C, le perso B peut rendre triste l'ennemi et le perso C frapper : grâce aux changements d'état il inflige plus de dégâts. L'avantage c'est qu'on rentre dans des combats beaucoup plus dynamiques vu que le type n'est pas figé et que l'ennemi peut emmêler nos émotions aussi
(Combats d'autant plus dynamiques qu'il y a des follow-up, c'est-à-dire des attaques supplémentaire QTE qui consomment des points spéciaux et qui ont pleeein d'effets mais je développerai pas là-dessus )
Bien évidemment si tu reprends ce système faudra tout changer pour pas copier, mais le concept est là. Sinon, dans l'absolu fait ce qu'il te plaît
Citer : Posté le 27/03/2022 10:54 | #
Personnellement je pense que l'approche full Pokémon se vaut bien ; si tu regardes le système Gen 1. c'est pas monstrueux ; t'as 5 stats, des types sur les mon et les attaques, 2 types d'attaques, buffs et STAB. En tous cas ça te donnerait une répartition conception/implémentation très orientée implem, donc si tu sèches sur le design ça peut être cool.
Perso j'ai encore moins symbolique que KikooDX. Le "piège" avec l'approche de KikooDX (un peu rencontré dans Rogue Life) c'est que y'a potentiellement pléthore d'événements très variés et une fois que tu es commit à une enum + un switch t'es un peu obligé de faire un type pour chacun.
Je représenterais un événement par une chaîne de caractères. Certaines seraient génériques comme "give:poke_ball*20" et d'autres seraient très au cas-par-cas comme "special:old_man_demo". De cette façon, tu pourrais pas exemple les intégrer aux dialogues si, disons, le premier caractère de la section soit ~ (au hasard pur). Par exemple, le dialogue
Pour gérer les événements je mettrais une fonction très générique qui a accès à l'information complète du jeu (game_t *game représente ça). Tu pourrais alors traiter les événements génériques de façon générique (ce qui te permet d'en ajouter dans le jeu sans le recoder à chaque fois) et les événements spéciaux comme bon te semble (avec peu d'overhead, juste un test en plus).
bool handle_event(game_t *game, char const *event)
{
if(!strncmp(event, "give:", 5)) {
event += 5;
// Isoler le nom et la quantité
int len=strlen(event), qty=1;
char *star = strchr(event, '*');
if(star) len=star-event, qty=atoi(star+1);
// Trouver l'item et la donner au joueur
item_t item = get_item_by_name(event, len);
// Peut échouer (inventaire plein)
return player_give_item(item, qty);
}
// ...
else if(!strcmp(event, "special:old_man_demo")) {
game->start_battle(demo_battle);
// etc, n'importe quoi de compliqué
return true;
}
}
J'ai pas pris en compte le fait que selon les cas il faut "désactiver" l'événement ici. Mon idée ce serait que tu as un événement pour faire avancer les dialogues/l'histoire et donc si tu veux te débarrasser de la ligne de dialogue qui donne des Poké Balls tu changes le dialogue avec le mécanisme classique pour le scénario (contrôlé par un événement, potentiellement).
Citer : Posté le 10/05/2022 17:00 | # | Fichier joint
Hey vous vous souvenez de ce topic ?
Comment ça non... Pourtant je fais de mon mieux pour le garder actif, regardez la date du dernier mess- Ouais finalement non, ne regardez pas
Bon, depuis la dernière fois j'ai pu avancer un peu, rien de bien méchant mais c'est important de le noter quelque part :
Évènements
Le système proposé juste au dessus par Lephenixnoir est vraiment performant et permet une grande flexibilité. Implémenté directement dans les dialogues, on a la possibilité de réaliser n'importe quelle action à partir d'un dialogue banal. C'est vraiment intéressant.
Pour l'instant 3 actions peuvent provoquer des évènements :
Je reviendrais après le changelog sur les évents. J'ai quelques problèmes et j'aimerais bien votre avis
Merci encore à lephé pour cette idée de qualité
Items et inventaire
Je parlais plus tôt des items et de l'inventaire du joueur. En effet à présent le joueur possède à présent son propre inventaire limité à 30 places.
L'inventaire n'est pas infini. Dans le sens où lorsqu'un item de même nature est ajouté il occupe une place supplémentaire. Il ne se "stack" pas aux autres.
Chaque item est défini par son fichier Json suivant cette forme :
"name":"Test1",
"id":1,
"sprite":"item",
"description":"Redonne 20HP",
"action":[
"pp:all",
"give:Obj2*3"
]
}
Avec un sprite, sa description et sa liste d'évènements qui seront lancés lors de sa sélection.
Comme tout inventaire, vous pouvez consulter vos objets, en supprimer ou encore en remplacer si vous n'avez plus de place. Rien de particulier ni de mystique de ce côté là.
Pour l'instant voici ce à quoi il ressemble. Attention vous allez être surpris devant tant de beauté
Types
Un jeu tour par tour sans système de type = un jeu où celui qui possède la plus grosse attaque gagne à coup sûr.
J'ai donc implémenté un système de type à la pokémon (étonnant non ? )
Je n'ai pas encore de liste de type. Ça va dépendre de la tournure de l'histoire (@Shadow15510). Pour l'instant j'ai réalisé des tests sur des rôles sur le forum.
En tout cas il y a 4 réactions possibles aux types :
Les monstres, le joueur ainsi que les attaques possèdent donc un type (un seul pour éviter des petits problèmes). En fonction de la table des types, les différents coefficients sont appliqués.
Il y a également un système de STAB. Si le lanceur possède le même type que l'attaque qu'il lance, il profite d'un buff de *1.5 sur la puissance de l'attaque.
La table des types est présentée sous la forme d'un fichier CSV (une grille en gros). Avec comme abscisse le type en défense et en ordonné le type attaquant.
│ type │ Administrateur │ Modérateur │ Rédacteur │ Labélisateur │
├────────────────┼────────────────┼─────────────┼────────────┼───────────────┤
│ Administrateur │ 0 │ 1 │ 1 │ 2 │
│ Modérateur │ 0 │ 0,5 │ 2 │ 2 │
│ Rédacteur │ 2 │ 1 │ 0,5 │ 1 │
│ Labélisateur │ 2 │ 0,5 │ 1 │ 0 │
└────────────────┴────────────────┴─────────────┴────────────┴───────────────┘
Il est donc très simple de lire les faiblesses des différents type ainsi que de les modifier
Le type du joueur va pouvoir être changé au fil de l'aventure à l'aide de pnjs placés sur la carte. Vous obligeant à parcourir le monde avant de faire certaines parties trop dure
Autre
Le joueur possède deux stats de plus : attaque spéciale et défense spéciale. Il y a donc un nouveau type d'attaque permettant de taper sur le physique ou sur le spécial. Ça amène plus de diversité dans les combats
Voilà, c'est un peu prêt tout pour les modifications importantes sur le projet. À présent place aux problèmes mais dans un futur message, je n'ai pas trop le temps de l'écrire maintenant.
Il reste encore des choses à faire, mais théoriquement à l'aide du système d'évènement le jeu peut bientôt être commencé. Il faut également qu'on se mette d'accord sur un scénario, mais à ce niveau je compte un peu sur Shadow et ses idées magistrales !
@RDP, ça fait longtemps qu'on a pas parlé d'un projet simple
Ajouté le 10/05/2022 à 20:36 :
OK, j'ai un peu plus de temps place aux questions.
1 - Les évènements doivent être désactivés après leur activation.
Concrètement il faut enregistrer dans la structure du joueur quelque chose permettant d'identifier de manière sûre l'évènement. Je ne peux pas vraiment ajouter un identifiant unique à un event à cause de son fonctionnement de base (sous forme de string, pas ). Alors je reste à votre disposition concernant cette mécanique.
On en avait plus ou moins parlé sur la shout, concernant un hash notamment. Le mieux c'est d'en reparler de manière claire et durable sur le topic
2 - J'ai un petit problème concernant les évènements et les zones.
Bon, vous commencez à me connaître j'ai souvent des problèmes un peu basiques à cause de mon manque d'expérience en C
Bon, alors les Zones sont définies par cette structure :
int start_x, start_y, end_x, end_y;
char *event; // le string lié aux évenements à lancer lors de l'arrivée dans la zone
int level;
int nbMonsters;
short *monsters; // un tableau comportant les identifiants des monstres qui peuvent spawn dans la zone
};
Donc chacune des cartes possèdent sa liste de zone. Ainsi nous avons cette définition par carte :
int zone_count;
struct Zone *zones;
};
Ok à présent place aux problèmes
Les cartes sont converties grâce à fxconv, et c'est là qu'il y a sûrement un problème. Voici la méthode responsable de la conversion des zones :
zone = fxconv.Structure()
for i in layer["objects"]:
origin = (int(i['x']/16), int(i['y']/16))
to = (int(origin[0]+i['width']/16)-1, int(origin[1]+i['height']/16)-1)
zone += fxconv.u32(origin[0])
zone += fxconv.u32(origin[1])
zone += fxconv.u32(to[0])
zone += fxconv.u32(to[1])
zone += fxconv.string(i["properties"][0]["value"]) #event
monsters = bytes()
zone += fxconv.u32(int(i["properties"][1]["value"]) if i["properties"][1]["value"] != "" else -1) #level
monster_list_raw = []
if i["properties"][2]["value"] != "": monster_list_raw = i["properties"][2]["value"].split(";") #monster list
monster_list = []
#x-y notation generate an array
for i in monster_list_raw:
if "-" in i:
a = i.split("-")
monster_list.extend(list(range(int(a[0]),int(a[1])+1)))
else:
monster_list.append(int(i))
zone += fxconv.u32(len(monster_list))
print(f"zone {origin}:{to}")
for j in monster_list:
print(int(j))
monsters += fxconv.u16(int(j))
zone += fxconv.ptr(monsters)
return zone
Aucun problème au niveau de la détection des monstres dans la carte, ils sont correctement placés dans le tableau monster_list.
Avant de les rajouter dans la map en question à l'aide d'un simple :
nbZone = len(layer["objects"])
zone = parseZone(layer)
structMap += fxconv.ptr(zone)
Enfin bref. Depuis que j'ai rajouté le char * lié aux évènements, j'ai une erreur mémoire sur l'accès au tableau des monstres dans l'ensemble des zones excepté sur la dernière compilée.
Le nombre de monstre est bien défini, le string lié à l'évènement aussi. Juste l'accès au tableau provoque une magnifique erreur système.
Je suppose que le tableau n'est pas bien généré, si je me rend dans une zone (contenant des monstres ça c'est sûr et vérifié) et que je lance un simple
L'erreur est provoquée. Preuve d'un tableau malformé.
Actuellement je n'ai pas forcément d'idée concernant l'origine de ce problème, le seul truc que je sais c'est qu'en enlevant le char* il n'y a aucun problème. Et que la dernière zone compilée possède correctement le tableau de monstres.
Si vous avez une idée je suis preneur.
merci
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 10/05/2022 22:48 | #
Content de voir que tu progresses
La question 2 j'en ai aucune idée (je sais pas utiliser fxconv), je peux tenter la 1.
Trouve une bonne fonction de hash (j'ai vu djb2 après quelques recherches). Crée un tableau. Quand tu exécutes un dialogue, vérifie si le hash se trouve dedans, si c'est le cas lance les événements sinon place le hash à la fin du tableau. Si t'as besoin de sauvegarder, dump le contenu du tableau dans un fichier.
Citer : Posté le 11/05/2022 08:59 | #
Parfois ce sera évident pour une raison externe : un objet va être consommé après avoir été activé, les statistiques de l'histoire vont évoluer et désactiver des interactions sur la map, ou les personnages vont changer de dialogues.
Une des options vraiment triviales c'est de faire en sorte que chaque dialogue contenant un événement unique soit remplacé après son exécution, en utilisant le même mécanisme que pour faire avancer l'histoire. Et ce, quitte à avoir les mêmes répliques mais avec l'événement retiré (ce que tu peux peut-être générer automatiquement).
Une autre idée naturelle c'est d'avoir un identifiant unique pour traquer le statut de chaque événement qui doit être unique, et noter d'une façon ou d'une autre lesquels ont déjà été exécutés.
J'avoue que j'ai du mal à faire confiance à une fonction de hash "triviale" pour un truc comme ça ; y'a plein de collisions et je sais pas exactement quelle est la probabilité que ce soit un problème vs. le bordel pour le debugger.
Vue la quantité d'informations que tu vas avoir à stocker de toute façon pour suivre la progression du joueur dans l'histoire, les interactions réalisées, etc. je serais plutôt tenté de stocker là-dedans. Par exemple, je stockerais plutôt l'information par-PNJ, pour lesquels tu as sans doute déjà un identifiant unique.
Ça a l'air correct de loin. Je n'ai pas le temps de tester en détail, mais je me demande si ce serait pas un problème de référence sur fxconv.ptr(monsters) dans fxconv. Est-ce que tu saurais voir si les données sont correctes en désassemblant ?
Citer : Posté le 31/05/2022 00:20 | # | Fichier joint
En relisant un peu ce topic je me rends compte que je n'ai pas montré la nouvelle tête de l'inventaire. À la manière de mon précédent message sur les combats je vous montre un petit avant-après du nouvel inventaire
Il n'y a rien de particulier concernant cet inventaire, suite à quelques plaintes de la part de mes collègues je me demande si je ne vais pas instaurer un système de tri par nom dans l'inventaire. À voir si c'est intéressant
Petit détail qui a son importance, vous ne pouvez pas utiliser un item s'il ne provoque aucune modification. Si vous avez l'ensemble de vos points de vies, prendre une potion ne va servir à rien et le jeu vous l'indique.
Si vous voyez des informations à rajouter dans l'inventaire je suis preneur. Je le trouve globalement assez complet pour l'instant et j'aime beaucoup le design que j'ai réussi à lui donner.
J'ai quelques petits ajouts à droite et à gauche qui sont intéressants, je vais essayer de préparer une petite démo du moteur histoire de vous montrer ce qu'il est possible de faire à présent. Restez au courant !
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 31/05/2022 07:12 | #
Ow elles sont jolies ces potions :3
Tu comptes mettre quoi dans la section du dessous ?
Citer : Posté le 31/05/2022 08:41 | #
Jolies potions ouais, tu les as faites à la main ? :o
La ligne parallèle tout en bas à droite contribue beaucoup à la structure à mon avis, mais il m'a fallu longtemps pour la voir. Il y a peut-être moyen de la mettre plus en valeur sans grignoter trop d'espace ?
Citer : Posté le 31/05/2022 09:20 | #
Alors je vais vous décevoir mais non, je n'ai pas fait les potions à la main. Elles sortent tout droit de ce site je me suis juste occupé de l'adapter en 32x32 Je suis d'accord, elles sont vraiment belles et ce site est une petite perle pour trouver de l'inspiration.
Tu comptes mettre quoi dans la section du dessous ?
Pour le moment je n'ai pas prévu de la remplir. En fait initialement je ne voulais pas avoir de fond gris pour laisser le jeu en arrière plan, mais à cause de certaines actions avec les items (boite de dialogue, contexte dans lequel l'inventaire est ouvert), il y avait parfois des résidus vraiment pas agréables
À terme je pense que je ne vais pas avoir assez de place pour la description complète des items, il se pourrait que je profite de l'espace du bas pour étendre la description. Il y a également certaines actions possibles dans l'inventaire comme activer la suppression ou (peut-être) le trier. Je peux également utiliser cet espace libre pour ajouter les boutons et leurs actions respectives.
La ligne parallèle tout en bas à droite contribue beaucoup à la structure à mon avis, mais il m'a fallu longtemps pour la voir. Il y a peut-être moyen de la mettre plus en valeur sans grignoter trop d'espace ?
Merci ! J'aime beaucoup rajouter ces petites lignes parallèles dans mes UI, je trouve que ça rajoute un sentiment de "solidité" / de finition dans les interfaces. Je vais essayer de la mettre un peu plus en valeur histoire de mieux la voir.
Concernant le tri, trouvez-vous ça pertinent de l'ajouter ?
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 31/05/2022 09:35 | #
Le tri je pense que c'est une bonne idée, pas forcément automatique mais au moins avec un bouton.
Citer : Posté le 06/07/2022 00:13 | # | Fichier joint
Après tout ce temps de développement (), je me rends compte que je ne vous ai jamais donné une version du jeu.
Vous trouverez donc ci-joint une sorte de version démo d'Adoranda, permettant de tester l'ensemble des fonctionnalités présentent dans le jeu
Elle n'est pas forcément claire au niveau des interfaces, ce n'est pas son but premier, je vais tout de même vous expliquer un peu les actions que vous pouvez réaliser.
Sur la carte :
Passer les dialogues, interagir : SHIFT
Se déplacer : Pavé numérique (il faut encore que je fix la répétition des touches)
Afficher les attaques et les statistiques du joueur : OPTN (Pour sortir de ce menu : OPTN)
Ouvrir l'inventaire : F1
En général pour sortir d'un menu : EXIT
Revenir au menu principal : MENU
Dans l'inventaire :
Utiliser un item : SHIFT
Activer/Désactiver la suppression : OPTN
Trier par ordre alphabétique : F6
Sortir : EXIT
En combat :
Sélectionner une capacité : Pavé numérique
Lancer une capacité : SHIFT
Afficher les statistiques du joueur : OPTN
Pour la suite du projet j'aimerais notamment rajouter des animations sur les monstres en combat. Ils sont un peu trop statiques pour l'instant.
N'hésitez pas à me faire des retours, positifs comme négatifs !
Voilà c'est tout pour moi
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 06/07/2022 18:35 | #
UP parce que ton timing était nul Toutouille.
Checkez la démo les gens !
Citer : Posté le 24/07/2022 23:02 | # | Fichier joint
Right donc j'ai testé la démo moi aussi !
La répétition des touches c'est vraiment vraiment casse-pieds. À mon avis c'est un problème de gint et pas de ton code, donc j'ai poussé un fix et je joins le G3A avec la répétition parce que j'aurais rage quit avant d'arriver au bord de la map sinon. xD
Note : la répétition utilise le défaut de 400 ms pour la première, 40 ms pour les suivantes, ce qu'il faudrait sans doute changer. En fait tu devrais vraiment abandonner getkey() et utiliser les événements ici !
J'ai aussi soumis une PR avec les tweaks qu'il m'a fallu pour réussir à compiler.
J'ai plus le temps de rédiger un test sérieux ce soir, alors je repasserai une autre fois (désolé !).