Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Discussions


Index du Forum » Discussions » Comment faire un jeu en C pour Graph 75 et 35+ ?
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Comment faire un jeu en C pour Graph 75 et 35+ ?

Posté le 27/11/2019 15:12

Bonjour à tous,
Récemment j'ai voulu commencé à faire un jeux en C mais le souci c'est que je ne parvient pas à trouver les alternatives de certaines fonction présente en BASIC comme par exemple:
-Pxlon
-F-Line
-Getkey
-Text

Tout ce qui relève à des fonction spécifique de la calculatrice, dont ces fonctions (celles que je viens d’énoncé au dessus) qui me semble indispensable.

Merci d'avance pour votre aide


Précédente 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 Suivante
Inikiwi Hors ligne Membre Points: 594 Défis: 8 Message

Citer : Posté le 04/11/2021 21:24 | #


"concaténer"? Que veut dire ce mot?
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 04/11/2021 21:26 | #


Fusionner deux chaine de caractère

Ajouté le 04/11/2021 à 22:30 :
Par contre j'ai un autre problème, quand je fais ce code là :

int nb = 3;
static unsigned char str[20];
sprintf((char*)str, "%d", &nb);
PrintMini(1,1,str,1);

la machine m'affiche -2013118684 ce que je ne veut pas évidement
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 04/11/2021 22:31 | #


nb tout seul. &nb c'est quand tu fais sscanf().
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 04/11/2021 22:35 | #


Haaaa ok !
Merci
Spoiler
Cliquer pour enrouler

Praticule Verison Stable coming soon
(Genre vraiment, avec docu en plus, il reste plus que quelques blocks à faire avant qu'elle soit prête)


Ajouté le 08/11/2021 à 21:04 :
Petite question, est que je suis obligé de mettre en static la liste TempLst ou pas la peine dans le cas ci dessous ?

class ClassTest {
public:
    int* Datas;


    ClassTest() {
    };
};

void Prog(){
ClassTest* object1 = LoadSys();
(suite du programme...)
}

ClassTest* LoadSys(){
ClassTest* object1 = new ClassTest();
int TempLst[ ] = {0,1,3};
object1->Datas = TempLst;

return object1;
}


"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 08/11/2021 21:22 | #


Le code est en effet invalide actuellement, puisque le tableau {0,1,3} est sur la pile donc il disparaît quand la fonction se termine. Deux options ; le mettre en static, ou (mieux) l'allouer dans le tas.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 08/11/2021 21:53 | #


D'accord, c'est bien ce que je pensais.
Et du coup ça serait quoi la syntaxe si je veux allouer (la deuxième proposition) ?
ça serait ça ?

ClassTest* LoadSys(){
ClassTest* object1 = new ClassTest();
int *TempLst = new int[3];
TempLst[0] = 0;
TempLst[1] = 1;
TempLst[2] = 3;
object1->Datas = TempLst;

return object1;
}

"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/11/2021 07:09 | #


Oui c'est ça ! Et delete[] pour libérer (dans le destructeur de ClassTest probablement). Note que si le tableau n'a que 3 éléments tu peux mettre un int Datas[3], et s'il peut en avoir un nombre variable peut-être que tu as besoin de noter la longueur quelque part.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 11:49 | #


Merci beaucoup pour ces clarification.
Concernant la taille c'est déjà pris en compte et la taille de la liste est variable mais merci pour ces rappelles
"La créativité est contagieuse faites la tourner"
Albert Einstein
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 13:20 | # | Fichier joint


Lephenixnoir excuse moi encore te déranger, mais il y a un truc que je comprend pas, c'est que le jeu fonctionne mais pas dans la durée, c'est à dire que au bout de quelques minutes il plante sans même que j'ai appuyé sur une touche.
Est-ce que tu peux jeter un coup d'oeil s'il te plait.

Le principale du code se trouve dans ParticuleEngine.h, je penses que c'est une erreur de mémoire.
(Les images sont stocké dans Ressources.h)
Tu vas remarqué que je n'ai pas toujours mis les delete, c'est parce que j'ai peur qu'il supprime des éléments qui sont en communs car tout est interconnecté, notamment les Texture, donc si tu pouvais me donner ton avis dessus.

Autre chose aussi, les lignes 949 à 960 qui sont des choses comme ça
Texture* Texture_UUID_355aae99_e49f_4a07_b7b8_ecf7673e547c= new Texture("Texture",16,20,UUID_355aae99_e49f_4a07_b7b8_ecf7673e547c);

j'aimerai les mettre à l'extérieur à la ligne 882 par exemple, car sinon il est rappelé plusieurs fois, le soucis c'est que ça compile mais il y a une erreur de mémoire, j'ai beau mettre en static rien n'y fait.

Une dernière chose c'est les List<...>, je ne sais pas si il faut en faire un pointer ou pas, genre Lis<int>*

Merci d'avance, comme c'est le moteur de Particule, ça m'embêterai de publier un code mal fait.
(Si tu as d'autre remarque sur le code que ceux que j'ai énoncé je suis preneur)
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/11/2021 14:02 | #


C'est très gros donc je ne peux pas tout lire, mais voilà au moins quelques retours.

    Object(const char* name, const char* UUID=NULL) {
        this->name = (unsigned char*)name;
        this->ID = (unsigned char*)UUID;
    }

    ~Object() {
        delete name;
        delete ID;
    }

Tu n'as pas copié le nom et l'ID donc tu ne peux pas les delete (moralement c'est pas toi qui en es le propriétaire). En particulier un const char * ça peut être un littéral comme "x" (entre guillemets) auquel cas personne n'en est le propriétaire. Dans un programme complexe comme ça il est capital d'avoir une politique très rigoureuse de «propriété» qui indique qui doit libérer quoi et quand, sinon tu t'exposes à beaucoup d'ennuis.

Aussi concernant Object, il y a un adage de C++ qui est qu'une classe virtuelle doit avoir un destructeur virtuel. C'est logique quand on y pense, sinon tes méthodes virtuelles héritées vont manipuler la classe mais ensuite le destructeur de base va libérer les données, ce qui ne peut pas bien marcher. Ton destructeur n'est pas virtuel actuellement, ce qui veut dire que les champs spécifiques aux classes héritées, comme Component::tag, ne sont pas détruits dans les contextes polymorphes.

Je sais pas avec quoi tu compiles, mais si tu supportes du C++ moderne tu peux mettre override sur les méthodes virtuelles héritées au lieu de virtual ; comme ça si tu te trompes en écrivant le nom le compilateur te donne une erreur au lieu de croire que tu ajoutes une nouvelle méthode à la hiérarchie virtuelle.

Tu as beaucoup, beaucoup de triggers et ça fait des tables virtuelles très grandes ; peut-être que ce serait plus simple de les créer à la demande. (Je suis pas sûr, c'est juste une suggestion.)

(Le pluriel de "child" c'est "children")

    Texture() : Object("None", NULL) {
        const unsigned char None[] = { 0x0 };
        textureData = (unsigned char*)None;
        this->width = 0;
        this->height = 0;
    };

Ici None est créé sur la pile, tu ne peux pas faire ça (ça fait fuiter un pointeur vers la pile qui se met à pointer vers n'importe quoi). Il suffit de faire textureData = "". De tes questions précédentes tu sembles penser que les char * et les unsigned char * sont des choses différentes. En fait ça ne fait aucune différence, la seule chose qui change c'est la valeur que tu obtiens quand tu convertis un des octets de la chaîne en int (dans un cas l'octet est lu comme un entier signé, dans l'autre c'est lu comme un entier non signé). Mais en termes de données ça ne change rien. Si t'as des warnings tu peux cast genre (unsigned char *)"Hello World" et c'est bon.

Cela dit quand t'as pas de texture je suggère de mettre NULL, parce que si tu es rigoureux de toute façon ton code ne doit pas dépasser les bornes du tableau, et comme width=height=0 le tableau est de longueur 0 donc tous les accès sont interdits.

Allouer un new Vector2() sur le tas c'est franchement inutile, tu paies 4 octets pour stocker le pointeur + un accès mémoire supplémentaire à chaque usage de la donnée + 8 octets dans le tas pour stocker le vecteur mais aussi 4/8 octets d'overhead de malloc(), et tu perds de la localité ; mets-le directement dans la structure, eg. Vector2 Rigidbody::velocity.

Je devine qu'une partie du contrôleur du joueur est générée automatiquement ?

Ton header ne contient pas le moindre template ; le code devrait être dans un fichier C++.

-

Lephenixnoir excuse moi encore te déranger, mais il y a un truc que je comprend pas, c'est que le jeu fonctionne mais pas dans la durée, c'est à dire que au bout de quelques minutes il plante sans même que j'ai appuyé sur une touche.

C'est l'intuition que j'ai aussi : tu ne libères pas ta mémoire donc au bout d'un certain temps tu épuises le tas et là c'est la catastrophe.

La bonne solution (la seule solution) c'est de gérer tes objets jusqu'au bout et de les delete quand tu n'en as plus besoin. Tes craintes par rapport à l'interconnexion des objets sont on ne peut plus justifiées : c'est un problème très sérieux et on ne peut pas le résoudre à l'improviste. Personnellement je découple méticuleusement les références pour éviter les pointeurs quand c'est possible, et limiter les connexions directes. Je peux aussi suggérer un trick consistant à marquer les objets pour suppression mais à attendre la fin du frame pour les supprimer réellement, le temps que l'information sur la suppression soit détectée par les objets connectés. Parfois ça aide.

j'aimerai les mettre à l'extérieur à la ligne 882 par exemple, car sinon il être rappelé plusieurs fois, le soucis ces que ça compile mais il y a une erreur de mémoire, j'ai beau mettre en static rien n'y fait.

Tu ne peux pas ; si les objets étaient statiques tu pourrais, mais ça ne résoudrait que la moitié du problème. La raison pour laquelle tu ne peux pas c'est que le new + le constructeur c'est du code, et tu n'as le droit d'exécuter du code quand dans des fonctions (ou via des constructeurs pour des objets statiques).

À mon sens, la vraie "solution" c'est d'avoir une procédure d'initialisation quelque part que tu prends bien soin de n'appeler qu'une seule fois.

Une dernière chose c'est les List<...>, je ne sais pas si il faut en faire un pointer ou pas, genre Lis<int>*

Quand c'est des arguments de fonctions, le plus élégant en général c'est de les passer par référence ; list<int> & si on veut la modifier, const list<int> & sinon.

Quand c'est des attributs dans des classes, il n'y a aucun intérêt à en faire des pointeurs ; tu vas les créer/stocker de toute façon.

-

Voilà voilà j'espère que ça aide
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 14:54 | #


Donc pour Object je devrais mettre ça ?
virtual ~Object() {
        delete name;
        delete ID;
    }


Mais du coup comment je fais pour les attribuer le nom et l'ID comment tu as dit ?
Car en gros les noms et les IDs des objets sont de simple guillemets qui sont donner vers la fin du code de ParticuleEngine.h, mais ces nom peuvent changer durant l'execution, donc ça serai quoi la meilleure solution ?
ça serait de retirer le const char * ou de copier la variable ?

Pour le destructeur, est-ce que les destructeur mère sont appelé aussi par les destructeur fille.
Par exemple Component qui hérite de Object, est-ce que le destructeur appelle aussi celui de Object ?

Je suppose que tu appelles les trigger les lignes de code du style :
virtual void Awake() {}

Si c'est ça, c'est voulu totalement.
Il faut que les class fille puisse avoir les mêmes noms.
(Eventuellement je ferai un tris pour réduire le nombre)

children corrigé du coup
Idem pour Texture

En effet, j'ai pas mal fait de C# mais pas suffisement de C ou de C++, c'est vraiment nouveau pour moi donc je suis pas très à l'aise avec les pointer, les adresses, les références ainsi que libéré la mémoire.
C'est pour ça que les types unsigned char* et char* c'est un peu confu dans ma tête.
Et ce projet et aussi une occasion pour moi d'apprend le C++.

Pour les Vector2 ils vont varié plus tard (je l'ai pas encore codé c'est pour ça)

En effet, le PlayerController est généré par Particule ainsi que toutes les lignes de codes qui suivent.
C'est pour ça qu'il y a des choses qui se répètent.
Mais s'il y a des lignes qui sont fausses j'aimerai bien être au courant pour que je puisse le rectifier dans Particule


Je vois pas trop l'utilité des template dans mon code.
Et vois pas non plus plus l'utilité d'un fichier .cpp
(en fait comme Particule génère du code, j'évite de lui demander d'écrire à plusieur endroit)

Je prend note des référence, je vais voir si je peux arranger ça

Du coup pour les List<> dans mon code, c'est correct j'ai pas à modifier si j'ai bien compris?
En tout cas merci d'avoir pris le temps de regarder
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/11/2021 15:06 | #


Oui le virtual devant le destructeur c'est ça. (Bien sûr une fois que tu auras enlevé les delete il n'y aura plus rien.)

Ne pas détruire les noms et les ID ça ne veut pas dire que tu ne peux pas les changer. Ce qu'il faut voir c'est que là tu fais ça :

const char *nom = "...";
delete nom;

Ce qui est incroyablement faux (tu ne peux/dois delete que ce qui a été alloué par new). La solution est simple : tu décides que la classe Object n'est pas propriétaire des données pointées par name et ID, donc elle peut les lire, mais elle n'y écrit pas, et elle ne les libère pas. Le code qui crée l'objet se débrouille pour que (1) le nom et l'ID soient alloués, et (2) le nom et l'ID restent en vie tant que l'objet est en vie ; et les deux considérations sont triviales puisque les chaînes sont littérales.

Pour le destructeur, est-ce que les destructeur mère sont appelé aussi par les destructeur fille.
Par exemple Component qui hérite de Object, est-ce que le destructeur appelle aussi celui de Object ?

Oui.

Pour les Vector2 ils vont varié plus tard (je l'ai pas encore codé c'est pour ça)

Tant qu'ils ne font que 8 octets (ce qui semble probable) la remarque s'applique

Je vois pas trop l'utilité des template dans mon code.
Et vois pas non plus plus l'utilité d'un fichier .cpp
(en fait comme Particule génère du code, j'évite de lui demander d'écrire à plusieur endroit)

Le code C++ doit aller dans un fichier .cpp ; les en-têtes n'existent que pour les définitions de classes (sans le code), et les templates (parce les templates ça peut pas se compiler à part). Si tu n'as pas besoin des classes dans d'autres fichiers alors tu peux juste renommer .cpp et ça ira tout seul. Mais tu ne dois pas faire de #include sur un fichier comme ça.

Du coup pour les List<> dans mon code, c'est correct j'ai pas à modifier si j'ai bien compris?

Oui c'est bon
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 15:36 | #


J'ai pas compris pour la fin, mais du coup si je le renomme je peux pas l'utiliser dans Tutoriel.cpp ?
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/11/2021 15:43 | #


Pourquoi tu ne pourrais pas ? Tu laisses dans un fichier .hpp les définitions des classes (ie. la liste des propriétés/méthodes) et tu mets le code des méthodes dans un fichier .cpp. Sinon dès que tu #include dans deux fichiers différents tu te retrouves avec beaucoup de problèmes (eg. du code en double).
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 16:02 | # | Fichier joint


Mais ce code là il est pas bon et pourtant j'ai suivis tes indications (voir fichier join)
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/11/2021 16:28 | #


D'abord tu devrais laisser les définitions des enums dans le header ; en plus de ça, les listes d'initialisation ne vont que côté source et les valeurs par défaut que côté header :

// .hpp faux
    Component(const char* name, GameObject* gameObject, const char* UUID = NULL) : Object(name, UUID);
// .hpp OK
    Component(const char* name, GameObject* gameObject, const char* UUID = NULL);

// .cpp faux
    Component(const char* name, GameObject* gameObject, const char* UUID = NULL) : Object(name, UUID) {
// .cpp OK
    Component(const char* name, GameObject* gameObject, const char* UUID) : Object(name, UUID) {

Et surtout tu ne remets pas la classe entière dans ton .cpp, que les définitions des méthodes :

// Pas de bloc class {}, on définit juste la méthode
// Le "Transform::" indique qu'on est dans la classe Transform
void Transform::SetParent(Transform* transform) {
    if (parent != NULL) {
       parent->children.Remove(this);
    }
    transform->children.Add(this);
    parent = transform;
}

Un bon tutoriel de C++ t'enseignera toute la syntaxe nécessaire ; même si les notions sont proches de C# tu ne peux pas trop passer à côté.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 09/11/2021 16:42 | #


Du coup je suis obliger de refaire toute la syntaxe, on peux pas juste copier coller malheureusement.
Bon bah en tout cas merci beaucoup pour toutes ces explications

Ajouté le 12/11/2021 à 18:42 :
Est-ce que c'est normal que quand je quitte le programme que j'ai fait en retournant sur le menu de la calculatrice, je ne peux plus le relancer, ou que ça me fait une erreur quand je le relance ?
J'ai remarqué que ce bug était aussi sur d'autres jeux d'ici
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 12/11/2021 19:56 | #


C'est pas trop normal non. Si tu quittes avec GetKey(), tu dois pouvoir rerentrer. Si tu finis main(), c'est normal que tu ne puisses plus rerentrer.

L'émulateur a aussi un bug où si tu n'utilises pas du tout GetKey() dans l'add-in, il plante quand tu lances une autre application du menu après avoir quitté. (Les vieilles SH3 aussi.) C'est anecdotique.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 12/11/2021 21:50 | #


Ha ok, bon bah je vais voir ce que je peux faire, merci pour l'info.

Ajouté le 05/02/2022 à 19:09 :
Est-ce qu'il y a moyen avec Gint de faire un agrandissement (en plus de la découpe) de l'image avec un dsubimage ?
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 05/02/2022 20:48 | # | Fichier joint


Non. Mais tu peux créer une copie agrandie d'une image, exemple ci-joint.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi En ligne Membre Points: 1375 Défis: 0 Message

Citer : Posté le 05/02/2022 20:59 | #


Ok merci !

Ajouté le 06/02/2022 à 18:47 :
Il y a une limite de taille pour un Addin, pour Graph 90 ?
Car je veux mettre beaucoup d'image
"La créativité est contagieuse faites la tourner"
Albert Einstein
Précédente 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 245 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd