Communauté

Un éditeur "complet...
 
Notifications
Retirer tout

Un éditeur "complet" de niveau pour le Dungeon Crawler old school en LUA

13 Posts
3 Utilisateurs
0 Likes
53 Vu
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

Salut à tous !

Ce n'est pas mon premier projet, car j'en ai d'autres qui sont en cours/pause. Je suis souvent en train de revoir mes ambitions à la baisse, pour trouver LE point de départ de ma progression. Et là, je pense que je tiens le bon bout.

Pour contextualiser ce projet, je vous raconte l'histoire :

J'ai donc décidé d'acheter le guide de programmation coder un dungeon crawler old school. Très rapidement, et pour aller au delà du contenu de l'apprentissage, j'ai enrichi les possibilités et les fonctionnalités, dans la partie "3D" de l'affichage du donjon. Par exemple, j'ai différencié le sol, le plafond, les murs ; j'ai considéré les cases comme des blocs sur lesquels je pouvais éventuellement agir (mur simple, mur escamotable, mur illusoire, porte, passage vers niveau suivant ou précédent, ...) ; mais j'ai aussi implémenté d'évaluation des distances des cases, dans le champ de vision, au joueur, afin de permettre de calculer et dessiner un assombrissement (comme si le joueur tenait une lanterne).

voir pièce jointe.

Je suis très satisfait du prototype jusque là obtenu, dont il me reste encore à gérer tout ce qui n'est pas la carte, donc le joueur et ses caractéristiques, son inventaire, les objets dans le donjon, les mécanismes à interaction (piège, déclencheur, levier et bouton d'ouverture de porte, ...) et, bien sûr, les monstres ou autres PNJs. Et je sens qu'il va y avoir masse utilisation de masques et de couches de map...

Mais à présent, je m'attaque plus sérieusement à la partie éditeur, où je ne vais évidemment pas me contenter de simplement enlever ou mettre un bloc de mur. Et c'est donc là où j'en suis rendu.

Description de l'actuel :

Je vais conserver l'affichage 3D dans cet éditeur, pour la proposer comme "aperçu", à l'utilisateur, lorsqu'il édite son donjon. Petite feature pas toujours présente, dans les éditeurs, ça, d'avoir un rendu réel de la map qu'on est en train d'éditer. Mais ceci va me demander de modifier l'affichage, pour passer des polygones à des textures, exactement comme pour le Jeu en lui-même. Ce qui peut être sensiblement plus simple à gérer.

je viens d'implémenter un ZOOM sur la  map, de façon très simple :

je définie une variable scale et, dans le draw() :

love.graphics.scale(scale,scale)

puis :

function sceneEditeur.wheelmoved(wx, wy)
    local mx = love.mouse.getX() --servira à limiter la zone où le zoom est actif
    local my = love.mouse.getY()

    --local wdir = ""

    if wy > 0 then
        scale = scale+0.5
        if scale > 5 then scale = 5 end --on limite le zoom max
    elseif wy < 0 then
        scale = scale-0.5
        if scale < 0.5 then scale = 0.5 end --on limite le zoom min
    end
    --print("sceneEditeur Mouse at " .. mx .. "." .. my .. ", " .. wdir)
end

Ensuite la difficulté a été de calibrer la souris dans l'affichage, sans oublier de calculer la taille de la carte telle que voulue par l'utilisateur. En tout cas, les coordonnées de la souris sont :

function sceneEditeur.mousepressed(mx, my, mbutton)
    mx = (mx / scale)-translate
    my = (my / scale)-translate

où translate est le décalage appliqué à la fenêtre d'affichage, l'écart ou la marge que l'on met éventuellement entre le bord de la fenêtre du programme et le cadre où on affiche la map ou le donjon :

    love.graphics.translate(donjon.viewX, donjon.viewY)
    love.graphics.setColor(0, 0, 0)
    donjon.draw(dt, "3D")

La fonction complète :

function sceneEditeur.mousepressed(mx, my, mbutton)
    mx = (mx / scale)-translate
    my = (my / scale)-translate
    if mbutton == 1 then
        if
            mx >= translate and mx <= (translate + donjon.largeur*donjon.tailleCase) and my >= translate and
                my <= (translate + donjon.hauteur*donjon.tailleCase)
         then
            local ligne = math.floor(my / donjon.tailleCase) + 1
            local colonne = math.floor(mx / donjon.tailleCase) + 1
            --
            donjon.changeCase(ligne, colonne, editType)
        end
    elseif mbutton == 2 then
        if
           mx >= translate and mx <= (translate + donjon.largeur*donjon.tailleCase) and my >= translate and
                my <= (translate + donjon.hauteur*donjon.tailleCase)
         then
            local ligne = math.floor(my / donjon.tailleCase) + 1
            local colonne = math.floor(mx / donjon.tailleCase) + 1
            --
            donjon.changeCase(ligne, colonne, 99)
        end
    end

Ici, je place un bloc avec le bouton gauche et je le retire avec le bouton droit. On est sur le code d'origine du cour, pour ainsi dire.

A partir de maintenant, ça va être création d'un menu (sauvegarde, chargement, divers paramètres), des boutons de sélection de types de blocs, une sélection du style de textures, avec aperçu dans le bouton du type de bloc lié (plancher en chêne sur bouton sol, mur de brique rouge sur bouton mur, etc...), un défilement multidirectionnel dans l'affichage de la map (qui dépassera forcément le cadre si on zoome à fond).

J'ai déjà un système d'encodage en json avec lecture/écriture de fichier, pour assurer la sauvegarde et le chargement des cartes, ou plutôt, du donjon au complet. Ce qui implique deux boutons ajouter et supprimer un niveau.

A venir :

  • pour l'édition de la carte : bouton "gomme" ou on reste sur le bouton droit pour effacer (ce qui remplace par un bloc "sol") ?
  • défilement dans la carte zoomée : bouton du milieu ou bouton droit (si on a un bouton "gomme") ?
  • un canvas auto-généré, de la taille définie, vide, en deux modes : carte fermée (intérieur, donc ceinte d'un mur) ou carte ouverte (extérieur, gérant le passage d'une carte à l'autre quand le joueur arrive au bord, donc ceinte d'un "mur" de blocs de entrée/sortie - ou bien sans aucune bordure, tout est à placer par l'utilisateur)
  • plusieurs couches à une carte :
    • architecture (la map de base),
    • les éléments de décors et les mécanismes (y compris les portes, les alcôves dans les murs, les fenêtres, les pièges, les trucs magiques),
    • les objets divers,
    • les créatures
  • les boutons d'édition
  • le chargement des packs de textures
  • le menu de l'appli avec ses fonctionnalités (surtout sauvegarde/chargement du donjon)
Ce message a été modifié Il y a 4 semaines par Rey

   
Citation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

Réflexion du jour :

J'ai besoin d'un cadre, où afficher la map, avec des barres de défilement. J'ai besoin d'un menu avec des outils de gestion des fichiers, j'ai aussi besoin de listes déroulantes, pour le choix des blocs à placer. Parce que finalement, des boutons, ça va pas le faire, étant donné le nombre variable d'éléments plaçable sur la map.

Et je ne trouve AUCUNE aide ni exemple, pour réaliser ça en lua/löve2d (et le wiki love est une vraie purge).

Donc, sauf miracle, je me demande si je vais pas faire ça avec des outils qui m'offre ce dont j'ai besoin : C# .Net et donc faire mon éditeur en winform .Net et basta.


   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

Un miracle a eu lieu, j'ai un module Listbox.


   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

Et j'abandonne LUA et LOVE.

love.window.getDimensions( ) a fini de me convaincre que non seulement le wiki LOVE est une sombre merde, mais aussi que je n'obtiendrais RIEN de bien avec LUA/LOVE.
Ca ne veut juste PAS marcher du tout et le wiki n'explique RIEN du tout, comme je l'ai déjà dit. Donc, Basta !


   
RépondreCitation
(@supergauje)
New Member
Inscription: Il y a 7 ans
Posts: 3
 

@buissonolivier apparemment on peut faire des jeux en lua et love et édité. Mais pour moi aussi cela reste obscure. Rien que l'export sur différents support.


   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

@supergauje Oui oui, on peut. J'ai déjà fait. Mais là, je cherche à faire un truc complet et c'est bien trop compliqué avec lua et love2d.


   
RépondreCitation
(@oktopuss)
Membre Admin
Inscription: Il y a 6 ans
Posts: 23
 

Hello @buissonolivier !

Il est tout à fait possible de créer des cadres ainsi que des menu déroulant, ou bien des barres de progression avec Love2D, seulement il faut créer ta propre bibliothèque GUI ou bien utiliser une bibliothèque déjà créée par quelqu'un d'autre.

Love2D est un framework bas niveau, et tu recherches des fonctionnalitées haut niveau. À toi de les créer à partir du framework.

Tu as sur le wiki une section concernant les libs créées par d'autres utilisateurs : https://www.love2d.org/wiki/Library peut-être y trouveras-tu quelque chose d'intéressant.

Je vais te donner un exemple. Dans Love2D il n'y a pas de fonction pour créer un bouton, du coup si tu veux un bouton tu dois le créer toi même. Tout d'abord c'est quoi un bouton ? C'est un élément graphique, sur lequel on passe la souris, et si on clique ça provoque un évenement. Cet élément graphique peut-être du texte, une image, voir la combinaison des deux. Partons sur le principe du bouton image contenant un texte.

Pour manipuler des boutons, nous pouvons créer plusieurs fonctions : création du bouton, affichage du bouton, mise à jour du bouton :

function btnDraw()

end

function btnUpdate() 

end

function creaBtn() 

end

L'ordre des fonctions à son importance, je met le draw et l'update volontairement avant le creaBtn, j'expliquerais plus tard pourquoi.

 

Tout d'abord, notre fonction creaBtn va nous permettre de créer x boutons, on va lui passer différents paramètres : position, images, texte

Sachant qu'un bouton doit avoir au minimum une image par défaut, et une image au survol (hover).

function creaBtn(x, y, imgDefault, imgHover, text) 

    local tab = {}
    tab.x = x
    tab.y = y
    tab.imgDefault = imgDefault
    tab.imgHover = imgHover
    tab.w = tab.imgDefault:getWidth()
    tab.h = tab.imgDefault:getHeight()
    tab.txt = text
    tab.hover = false
    tab.pressed = false

    -- Fonctions d'affichage et de mise à jour
    tab.draw = btnDraw
    tab.update = btnUpdate

    return tab
end

On crée une référence des fonctions d'affichage et de mise à jour dans la fonction de création de bouton, c'est pour cela que j'ai placé les fonctions avant, afin que le programme sache qu'elles existent. On peut palier à ça en créant des prototypes de fonctions sinon.

Nous avons notre fonction pour créer nos boutons, ainsi dans notre code nous pourrons faire :

boutonJouer = creaBtn(10, 25, imgBoutonDefault, imgBoutonHover, "Jouer")
boutonOptions = creaBtn(10, 50, imgBoutonDefault, imgBoutonHover, "Options")
boutonQuitter = creaBtn(10, 75, imgBoutonDefault, imgBoutonHover, "Quitter")

Il ne nous reste plus qu'à remplir les fonctions d'affichage et de mise à jour, et les appeler dans notre code pour chacun de nos boutons :

function love.update(dt)
    boutonJouer:update()
    boutonOptions:update()
    boutonQuitter:update()
end

function love.draw()
    boutonJouer:draw()
    boutonOptions:draw()
    boutonQuitter:draw()
end

Et voilà, on a une lib qui permet d'utiliser des boutons !!

bah du coup c'est pareil pour n'importe quel élément graphique.

Bon courage pour ton projet 👍 

Ce message a été modifié Il y a 3 semaines parRaphytator

   
RépondreCitation
(@oktopuss)
Membre Admin
Inscription: Il y a 6 ans
Posts: 23
 

@buissonolivier

Posté par: @buissonolivier

love.window.getDimensions( ) a fini de me convaincre que non seulement le wiki LOVE est une sombre merde, mais aussi que je n'obtiendrais RIEN de bien avec LUA/LOVE.
Ca ne veut juste PAS marcher du tout et le wiki n'explique RIEN du tout, comme je l'ai déjà dit. Donc, Basta !

love.window.getDimensions() est une fonction dépréciée, comme indiqué dans l'encadré rouge qui est la première information qu'on voit sur la fonction (voir pièce jointe).

À la place, tu dois utiliser la fonction love.graphics.getDimensions()

Ce message a été modifié Il y a 3 semaines parRaphytator

   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

@oktopuss tiens donc, la même politique que chez Unity : reclasser des fonctions dans des classes moins logique qu'à l'origine.


   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

@oktopuss Les boutons ça va. Mais ce n'est malheureusement pas le plus adapté pour un éditeur, où on doit aller faire des sélections dans des listes et rechercher des fichiers.

Comme on me l'a fait remarquer, ce que j'essaie de faire sort des capacités du langage et de ce framework.

Et C#, pour gérer du winform ET du graphisme/jeu, en même temps... Bah c'est galère. Tout est trop séparé, catégorisé.

Au delà de ça, je ne sais pas faire. Donc, nouvelle ENORME perte de temps supplémentaire. J'en ai déjà eu pas mal, pour diverses raisons (entre les trucs infaisables, les impossibilités matérielles, les empêchements divers, les défections de ceux qui devaient travailler avec moi, etc...), qui ont causé une grosse perte de motivation et de moral, donc là, stop.

Ce message a été modifié Il y a 3 semaines parRey

   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

Bon ! Je vais pas abandonner comme ça. Je déteste abandonner.

J'explore les pistes.

@oktopuss, tes explications sur les boutons vont m'aider, ton approche est très claire et correspond plus à ma façon de faire que ce que j'ai pu voir ailleurs.

Ceci-dit, je vais tout de même avoir besoin de liste et j'ai trouvé ça (dis-moi ce que tu en penses) :

https://github.com/darkmetalic/ListBox/tree/master


   
RépondreCitation
(@oktopuss)
Membre Admin
Inscription: Il y a 6 ans
Posts: 23
 

Je pense que tu devrais plus te tourner vers un autre type de framework, car même s'il est possible avec Lua et Love2D d'obtenir le résultat que tu souhaites, cela sera beaucoup trop gourmand en terme de temps dans la mesure où tu devras tout faire de A à Z.

Je te suggère donc de regarder du côté de QT : https://www.qt.io/

Il s'agit de divers outils spécialisés dans la création de logiciels Cross plateform avec tout le nécessaire pour naviguer dans Windows, MAC OS, Linux, et pleins de ressources dont une GUI complète.


   
RépondreCitation
 Rey
(@buissonolivier)
Active Member
Inscription: Il y a 3 ans
Posts: 12
Début du sujet  

@oktopuss Oui, mais ce serait oublier le côté formateur de tout faire soi-même.

En échangeant avec CryptoLogiq, j'ai trouvé des solutions pour faire à peu près ce que je veux. Il me manquera juste les barres de défilement, mais j'estime que c'est de la feature de confort.

Je vais pouvoir faire des combobox, au passage.


   
RépondreCitation
Share:

Dialoguez avec les autres membres de la gamecodeur school.

Accédez maintenant à notre serveur Discord privé : Entraide, Game Jams, Partage de projets, etc.

Vous devez être membre de la Gamecodeur School Premium pour être autorisé à accéder au serveur.