[EDIT]Je viens de trouver une meilleure soluce qui permet de mieux conserver le coté objet.
Je nettoie et met cette autre solution dans mon post suivant.
Je laisse ce code-ci qui peut toujours servir, puisque fonctionnel aussi.
Cette solution fonctionne, à défaut de trouver mieux, cela me permet de récupérer la liste chaînée de la Dll pour pouvoir l'exploiter dans mon programme principal.
Le code à compiler en "ClassPersonnage.dll"
Code : Tout sélectionner
; Code à compiler en "ClassPersonnage.dll"
;*********************************
;* Title : ClassPersonnage.dll
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011
;* Compatibility
;* Windows x86 [?] | Windows x64 [Ok]
;* Linux x86 [?] | Linux x64 [Ok]
;* MacOs PPC [?] | MacOs intel [?]
;* Unicode [?]
;* Demo version [Ok]
;*********************************
EnableExplicit
Interface PersonnageObject
DestroyObject()
RecevoirDegats(nbDegats.i)
Attaquer(*adresseVictime)
BoirePotionDeVie(quantitePotion.i)
ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
EstVivant.d()
GetNiveauVie.i()
SetNewObjectDansInventaire(newElement$)
EndInterface
Interface ExtendsPersonnageObject Extends PersonnageObject
QuelCouleur()
EndInterface
;-CLASS TEMPLATE.
Structure _PersonnageClassTemplate
*vTable
; Attributs privés.
m_vie.i
m_mana.i
m_nomArme$
m_degatsArme.i
nomPersonnage$
List InventaireObjet$()
EndStructure
Structure sInventaire
List InventaireObjetCopy$()
EndStructure
;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL AttachProcess(instance)
MessageRequester("Message", "Dll Chargée")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;-CREATE AN INSTANCE OF A PERSONNAGE CLASS.
;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL.i NewPersonnageObject(personnage$, vie.i = 100) ; personnage$,
Protected *object._PersonnageClassTemplate
;Attempt to allocate memory for a new class template.
*object = AllocateMemory(SizeOf(_PersonnageClassTemplate))
If *object
;Make sure the *vTable field points to our virtual table.
*object\vTable = ?VTable_PersonnageClass
;Initialise the length and width.
*object\m_vie = vie
*object\nomPersonnage$ = personnage$
; On initialise certaines valeurs par défaut.
; Sinon on aurait pu ajouter des paramètres au constructeur, ou créer une fonction pour initialiser tout ça.
*object\m_nomArme$ = "Couteau"
*object\m_degatsArme = 1
InitializeStructure(*object, _PersonnageClassTemplate)
;MessageRequester("Mémoire début", Str(*object))
; La liste est prête à être utilisée.
; Tous les persos ont un couteau dés le début dans leur inventaire.
AddElement(*object\InventaireObjet$())
*object\InventaireObjet$() = "Couteau"
EndIf
;;MessageRequester("Acces", "Instance créée.")
;Return a pointer to our object.
; Permet de vérifier que l'instance a bien été créée.
ProcedureReturn *object
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;CLASS METHODS
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_DestroyObject(*this._PersonnageClassTemplate)
;All we need do here is free the memory previously allocated for this object.
FreeMemory(*this)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_RecevoirDegats(*this._PersonnageClassTemplate, nbDegats.i)
*this\m_vie = *this\m_vie - nbDegats; // On enlève le nombre de dégâts reçus à la vie du personnage
If *this\m_vie < 0 ;// Pour éviter d'avoir une vie négative
*this\m_vie = 0 ; // On met la vie à 0 (ça veut dire mort)
EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_Attaquer(*this._PersonnageClassTemplate, *adresseVictime._PersonnageClassTemplate)
Protected message$
PersonnageClass_RecevoirDegats(*adresseVictime, *this\m_degatsArme)
message$ = "------- Au Final on peut dire que :" + #CRLF$
message$ + "L'attaquant est >> : "+ *this\nomPersonnage$ +" >> que son arme est : "+ *this\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*this\m_degatsArme) + #CRLF$
message$ + "La victime est >> : "+ *adresseVictime\nomPersonnage$ +" >> que son arme est : "+ *adresseVictime\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*adresseVictime\m_degatsArme) + #CRLF$
MessageRequester("Info suite à attaque.", message$)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_BoirePotionDeVie(*this._PersonnageClassTemplate, quantitePotion.i)
*this\m_vie = *this\m_vie + quantitePotion;
If *this\m_vie > 100 ; // Interdiction de dépasser 100 de vie
*this\m_vie = 100;
EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_ChangerArme(*this._PersonnageClassTemplate, nomNouvelleArme$, degatsNouvelleArme.i)
*this\m_nomArme$ = nomNouvelleArme$;
*this\m_degatsArme = degatsNouvelleArme;
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure.d PersonnageClass_EstVivant(*this._PersonnageClassTemplate)
; If (m_vie > 0) // Plus de 0 de vie ?
; {
; Return true; // VRAI, il est vivant !
; }
; Else
; {
; Return false; // FAUX, il n'est plus vivant !
; }
Debug "Vie restante : "+ Str(*this\m_vie)
If *this\m_vie > 0
ProcedureReturn #True ;// VRAI, il est vivant !
Else
ProcedureReturn #False ;// VRAI, il est vivant !
EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure.i PersonnageClass_GetNiveauVie(*this._PersonnageClassTemplate)
ProcedureReturn *this\m_vie
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_SetNewObjectDansInventaire(*this._PersonnageClassTemplate, newElement$)
AddElement(*this\InventaireObjet$())
*this\InventaireObjet$() = newElement$
; ForEach *this\InventaireObjet$()
; Debug *this\InventaireObjet$()
; Next
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_GetColor(*Self)
MessageRequester("MyObjectEtendu", "Rouge")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL GetInventaire(*maListe.sInventaire, *adressePerso._PersonnageClassTemplate) ; personnage$,
Protected inventaire$
InitializeStructure(*maListe, sInventaire)
inventaire$ = ">>> Inventaire de "+ *adressePerso\nomPersonnage$ + #CRLF$
Debug "===== Inventaire arme ====="
ForEach *adressePerso\InventaireObjet$()
AddElement(*maListe\InventaireObjetCopy$()) : *maListe\InventaireObjetCopy$() = *adressePerso\InventaireObjet$()
Debug *maListe\InventaireObjetCopy$()
inventaire$ + *maListe\InventaireObjetCopy$() + #CRLF$
Next
Debug "======================="
MessageRequester("Inventaire de "+ *adressePerso\nomPersonnage$, inventaire$)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;-VIRTUAL TABLES.
;/////////////////////////////////////////////////////////////////////////////////
DataSection
VTable_PersonnageClass:
Data.i @PersonnageClass_DestroyObject()
Data.i @PersonnageClass_RecevoirDegats()
Data.i @PersonnageClass_Attaquer()
Data.i @PersonnageClass_BoirePotionDeVie()
Data.i @PersonnageClass_ChangerArme()
Data.i @PersonnageClass_EstVivant()
Data.i @PersonnageClass_GetNiveauVie()
Data.i @PersonnageClass_SetNewObjectDansInventaire()
Data.i @PersonnageClass_GetColor()
EndDataSection
;/////////////////////////////////////////////////////////////////////////////////
Le programme utilisant la Dll
Code : Tout sélectionner
;*********************************
;* Title : Utilisation de : ClassPersonnage.dll
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011
;* Compatibility
;* Windows x86 [?] | Windows x64 [Ok]
;* Linux x86 [?] | Linux x64 [Ok]
;* MacOs PPC [?] | MacOs intel [?]
;* Unicode [?]
;* Demo version [Ok]
;*********************************
EnableExplicit
Interface PersonnageObject
DestroyObject()
RecevoirDegats(nbDegats.i)
Attaquer(*adresseVictime)
BoirePotionDeVie(quantitePotion.i)
ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
EstVivant.d()
GetNiveauVie.i()
SetNewObjectDansInventaire(newElement$)
EndInterface
Structure _PersonnageClassTemplate
*vTable
; Attributs privés.
m_vie.i
m_mana.i
m_nomArme$
m_degatsArme.i
nomPersonnage$
List InventaireObjet$()
EndStructure
Structure sInventaire
List InventaireObjetCopy$()
EndStructure
Prototype.i Proto_NewPersonnageObject(personnage$, vie.i = 100)
Prototype Proto_GetInventaire(*thisi.sInventaire, *adressePerso._PersonnageClassTemplate)
If OpenLibrary(0, "ClassPersonnage.dll")
; On récupère l'adresse de notre fonction d'initialisation.
Global NewObject.Proto_NewPersonnageObject = GetFunction(0, "NewPersonnageObject") ; Renvoi le pointeur de la DLL.
Global GetInventaire.Proto_GetInventaire = GetFunction(0, "GetInventaire")
; Instanciation des Objets
Define *seb.PersonnageObject = NewObject("Seb", 98)
Define *goliath.PersonnageObject = NewObject("Goliath")
Debug "-----Niveau de vie DEPART-----"
Debug "Seb : "+Str(*seb\GetNiveauVie())
Debug "Goliath : "+Str(*goliath\GetNiveauVie())
Debug "-------------------------------"
Debug "-----Récup d'armes sur des cadavres puants-----"
*seb\SetNewObjectDansInventaire("Batte")
*seb\SetNewObjectDansInventaire("Flingue")
Debug "-----L'enfoiré de Gogo attaque le pôv Seb et lui retire 1 point de vie-----"
*goliath\Attaquer(*seb)
Debug "-----Niveau de vie de Seb-----"
Debug "Seb : "+Str(*seb\GetNiveauVie())
Debug "-----Seb BOIT POTION qui lui redonne 2 points de vie-----"
*seb\BoirePotionDeVie(2)
Debug "-----Niveau de vie de Seb après POTION-----"
Debug "Seb : "+Str(*seb\GetNiveauVie())
; Récupération de l'inventaire dans une liste.
Define ListeInventaireSeb.sInventaire
Debug "======Liste objet(s) dans l'inventaire==========="
GetInventaire(@ListeInventaireSeb, *seb)
Debug ListSize(ListeInventaireSeb\InventaireObjetCopy$())
ResetList(ListeInventaireSeb\InventaireObjetCopy$())
While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
Wend
; Seb récupère une super grosse sulfateuse.
*seb\SetNewObjectDansInventaire("Super grosse sulfateuse ki fè plein de mores")
MessageRequester("Action", "Liste après avoir récupéré une super grosse sulfateuse.")
Debug "======Liste objet(s) dans l'inventaire==========="
GetInventaire(@ListeInventaireSeb, *seb)
Debug ListSize(ListeInventaireSeb\InventaireObjetCopy$())
ResetList(ListeInventaireSeb\InventaireObjetCopy$())
While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
Wend
Debug "======Goliath change d'arme : Hache avec 30 de dégâts et attaque le pôv Seb==========="
*goliath\ChangerArme("AstéroHache", 30)
*goliath\Attaquer(*seb)
Debug "-----Niveau de vie de Seb après attaque fulgurante-----"
Debug "Seb : "+Str(*seb\GetNiveauVie())
Debug "-----Seb se casse, ça vaut mieux pour lui.-----"
; Bon on détruit les objets avant de se barrer pour de nouvelles aventures.
*seb\DestroyObject()
*goliath\DestroyObject()
CloseLibrary(0)
Else
MessageRequester("Erreur", "Ne peut pas ouvrir la DLL")
EndIf
Ce jeu s'appelle "Seb contre Goliath".
Sa durée de jeu est d'environ... ... ...

7 secondes.
Mais comme dirait Actibidon, le jeu est court, mais c'est pour éviter la répététivitée (répétition aurait été plus jolie).
Bye et bon jeu

.