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 Hors ligne Membre Points: 1380 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 ··· 5, 6, 7, 8, 9, 10, 11, 12, 13 Suivante
Slyvtt Hors ligne Maître du Puzzle Points: 2410 Défis: 17 Message

Citer : Posté le 06/04/2022 23:33 | #


Exact, mais std::array t’empêche a coup sur d’écrire au delà de la limite du tableau.

Je sais pas si tous les compilateurs C sont capables de voir a la compilation ce genre de problème avec int tableau standard
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 06/04/2022 23:38 | #


Si tu spécifies la taille, oui :

int sum_of_array_1(int array[10])
{
    // ...
}

int sum_of_array_2(std::array<int,10>)
{
    // ...
}

mais bien sûr aucun compilateur ne peut décider si le résultat d'un calcul va sortir des bornes.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 07/04/2022 02:01 | #


Ha par contre ça m'embête ce que vous venez de dire, parce que moi je voulais faire un truc dans ce style là, mais si j'ai bien compris ça va pas marcher :

int * load_Array(unsigned char *path)
{
    FILE *fp = fopen((const char*)path, "r");
    int size;
    fread(&size, sizeof size, 1, fp);
    int * array = new int[size];
    fread(array, sizeof *array, size, fp);
    fclose(fp);
    return array;
}

"La créativité est contagieuse faites la tourner"
Albert Einstein
Slyvtt Hors ligne Maître du Puzzle Points: 2410 Défis: 17 Message

Citer : Posté le 07/04/2022 08:09 | #


Dans ce cas le plus simple pour toi serait peut être de créer une structure qui contient la taille et les data :

typedef struct myArray
{
int size;
int *data;  // ou int data[];
};

myArray * load_Array(unsigned char *path)
{
    FILE *fp = fopen((const char*)path, "r");
    
    myArray *data = new myArray;

    int size;
    fread(&size, sizeof size, 1, fp);
    int * array = new int[size];
    fread(array, sizeof *array, size, fp);
    fclose(fp);

    data->size = size; // on rempli la structure
    data->data = array;

    return data; // et on la retourne
}

// ou récupérer les données
myArray *myData = load_Array("Data.dat");

// ... on utilise les données de la structure
// via les membres de celle-ci, par exemple

for( int k=0; k<myData->size; k++)
{
    // on bricole avec les données
    myData->data[k] *= 10;   // Dummy code : on multiplie chaque valeur par 10
}

//penser à libérer avec les delete
delete [] myData->data; // désallouer les données en premier pour ne pas tuer le pointeur vers celles-ci
delete myData; // ensuite la structure



j'ai pas testé et fait ça à la va vite, mais tu comprends le principe. Faudra certainement debugger un peu, Lephe sait taper du code juste directement, mais pas moi

Sinon, comme tu sembles être en C++ (opérateur new), je te conseille vraiment de passer par la STL avec ses containers (effectivement comme écrit par Lephé, dans ce cas un std::vector serait très certainement le meilleur choix). Si tu as besoin, on peut t'aider à utiliser µSTL dans ton projet. Dis nous juste.

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 07/04/2022 08:51 | #


Farhi a écrit :
Ha par contre ça m'embête ce que vous venez de dire, parce que moi je voulais faire un truc dans ce style là, mais si j'ai bien compris ça va pas marcher :

int * load_Array(unsigned char *path)
{
    FILE *fp = fopen((const char*)path, "r");
    int size;
    fread(&size, sizeof size, 1, fp);
    int * array = new int[size];
    fread(array, sizeof *array, size, fp);
    fclose(fp);
    return array;
}

Si, parfait, ça c'est bon. array ne connaît pas sa taille, mais toi tu la connais (c'est size), donc tout va bien
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2410 Défis: 17 Message

Citer : Posté le 07/04/2022 09:27 | #


Lephenixnoir a écrit :

Si, parfait, ça c'est bon. array ne connaît pas sa taille, mais toi tu la connais (c'est size), donc tout va bien


Et du coup tu récupères la taille indirectement en dehors de la fonction avec un truc du genre.

int* data=load_Array("Data.dat");
int SizeOutOf = sizeof(data)/sizeof(int);


C'est ça ? car sinon la taille (contenue dans 'size') ne sort pas du scope de la fonction load_Array().
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Potter360 Hors ligne Rédacteur Points: 1255 Défis: 2 Message

Citer : Posté le 07/04/2022 09:53 | #


Merci pour l’explication Lephenixnoir, c’est plus clair comme ça
Globalement, coder. Mal, mais coder.
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 07/04/2022 10:08 | #


Slyvtt a écrit :
Et du coup tu récupères la taille indirectement en dehors de la fonction avec un truc du genre.

int* data=load_Array("Data.dat");
int SizeOutOf = sizeof(data)/sizeof(int);


C'est ça ? car sinon la taille (contenue dans 'size') ne sort pas du scope de la fonction load_Array().

Noooon. Tu récupères la taille comme ça :

int size;
int *data = load_Array("Data.dat", &size);

//...

int * load_Array(unsigned char *path, int *size_ptr)
{
    FILE *fp = fopen((const char*)path, "r");
    int size;
    fread(&size, sizeof size, 1, fp);
    int * array = new int[size];
    fread(array, sizeof *array, size, fp);
    fclose(fp);
    *size_ptr = size;
    return array;
}

Tu fais bien de le mentionner, j'avais pas remarqué que la taille était perdue après.

N'oubliez pas : sizeof n'est qu'une coquille vide que le compilateur remplace par l'espace mémoire occupée par la valeur ou le type indiqué. Le compilateur n'existe plus à l'exécution, il est incapable de donner la taille du tableau si la taille n'est connue qu'à l'exécution. sizeof(...) c'est toujours une constante absolue, quoi qu'il arrive, donc si tu comptes utiliser sizeof() pour obtenir un résultat non constant (par exemple, qui dépend du contenu d'un fichier) c'est triplement impossible.

Alors c'est quoi sizeof(array) tu vas me dire ? C'est la taille du pointeur menant au tableau, ie. 4. Et c'est là la différence absolue entre int array[8] et int *ptr. Les deux sont plus ou moins équivalents dans la façon dont on les utilise (et si tu écris array tout seul il est «affaibli» en int *, ce qui est source de pas mal de confusion), mais les deux types sont différents, le premier a un sizeof de 32 et le second a un sizeof de 4.

Ton code ci-dessus donne une taille de 1 dans tous les cas.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2410 Défis: 17 Message

Citer : Posté le 07/04/2022 11:34 | #


Effectivement c'était pas clair dans ma tête non plus.
C'est vraiment hyper piégeur ces notions de tableaux/pointeurs. On a vraiment vite fait de faire une boulette.
Et du coup mon code avec la structure, c'est viable ou pas ?
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 07/04/2022 11:39 | #


Oui absolument. Attention int data[] dans la définition de la structure c'est différent - ça met les données à la fin de la structure, ce qui te donne une structure dont la taille est variable et que tu alloues d'un seul coup avec malloc. int *data c'est plus simple.

Je serais juste tenté de passer la structure par valeur plutôt que de l'allouer dans le tas, mais bon c'est un détail.

Idéalement autant passer à la STL si c'est du C++, comme tu l'as dit.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 07/04/2022 19:12 | #


alors j'ai essayer ta fonction et ça n'a pas marché, je me retrouve avec une liste interminable, avec des valeurs qui ne sont pas correct du style :
(ces tests on été fait sur pc)

16777216 33554432 50331648 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451.....

"La créativité est contagieuse faites la tourner"
Albert Einstein
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 07/04/2022 19:22 | # | Fichier joint


J'ai mis en pièce jointe les fichiers de tests
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 07/04/2022 19:40 | #


Tu sauvegardes en big-endian, ce qui est correct pour la calculatrice, mais le PC est little-endian. C'est normal que ça ne marche pas.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 08/04/2022 01:21 | #


Ha ok merci pour l'info.
sinon j'aimerai refaire la même chose que les codes d'avant avec des unsigned char* et des unsigned char**.
En gros j'aimerai sauvegarder et lire une chaines de caractère et un tableau de chaines de caractère :
var1 = "exemple"
var2 = ["exemple1","exemple2"]
Alors j'ai regarder la docu des struct donc pour var1 ça devrai être facile car c'est comme un tableau d'entier je supposes (en changeant '>i' par '>B'), mais pour var2 qui est un tableau de tableau, là je ne sais pas trop comment m'y prendre.
(à noté que dans les deux cas, le script ne connais pas la taille de var1 et de var2, ni la longueur des éléments de var2. Il faudra donc utilisé la technique que tu m'a montré je supposes)
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 08/04/2022 09:11 | #


Bienvenue dans le monde de la sérialisation. Pour un format binaire comme ça, ultimement tu peux procéder ainsi :

00 00 00 02 | 00 00 00 08 | 65 78 65 6d 70 6c 65 31 | 00 00 00 08 | 65 78 65 6d 70 6c 65 32
longueur    | première chaîne                       | deuxième chaîne
            | longueur    | données                 | longueur    | données

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 08/04/2022 16:11 | #


Alors du coup j'ai essayer de faire un truc dans le genre :
Python :

def SaveArrayOfString(fp,lst):
    for i in lst:assert(type(i)==str)
    #assert(type(fp)==_io.BufferedWriter)
    fp.write(struct.pack('>i', len(lst)))
    for i in lst:
        fp.write(struct.pack('>i', len(i)))
        fp.write(b''.join(struct.pack('>B', n) for n in str.encode(i)))


C++ :

unsigned char** DeserializeArrayOfString(FILE* fp,int *size_ptr) {
    int size;
    fread(&size, sizeof size, 1, fp);
    *size_ptr = size;
    unsigned char** array = new unsigned char* [size];
    for (int i = 0; i < size; i++)
    {
        int sizeSTR;
        fread(&sizeSTR, sizeof sizeSTR, 1, fp);
        unsigned char* str = new unsigned char[sizeSTR];
        fread(str, sizeof * str, sizeSTR, fp);
        array[i] = str;
    }
    return array;
}

....

    int count = 1;
    unsigned char** testText;
    int size;
    FILE* fp;
    if (fp = fopen((const char*)"textSave.bin", "r")) {
        testText = DeserializeArrayOfString(fp, &size);
    }
   for (int i = 0; i < size; i++)
   {
    dtext(0,i*20,C_WHITE,testText[i]);
   }


ça affiche bien le texte mais ça rajoute des lettres en plus à chaque lignes. (des u et des s uniquement)
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 08/04/2022 16:14 | #


Oui, impeccable. N'oublie juste pas que la représentation en mémoire d'une chaîne de caractères, en C, doit se terminer par un NUL (un octet de valeur zéro).

Donc au lieu de :

unsigned char* str = new unsigned char[sizeSTR];
fread(str, sizeof * str, sizeSTR, fp);

Il faut bien penser à ajouter le NUL :

unsigned char* str = new unsigned char[sizeSTR+1]; // +1 ici
fread(str, sizeof * str, sizeSTR, fp);
str[sizeSTR] = '\0';

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 08/04/2022 16:20 | #


Ho ça marche ! Parfait merci, Nickel !
Mais du coup quand je vais libéré la mémoire, est-ce que je dois libéré chaque élément un à un :

for(int i=0;i<size;i++){
delete testText[i];
}
delete[] testText;

ou juste faire:

delete[] testText;


parce que je ne comprends pas bien comment fonctionne les delete
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 08/04/2022 16:26 | #


Excellente question. La règle d'or c'est : chaque new/new[] doit correspondre à exactement un delete/delete[], et donc la réponse c'est le premier.

new/delete c'est exactement comme malloc()/free(), si tu es familier avec ça∞.

Sinon, c'est pas très dur : chaque new ou new[] réserve de la mémoire pour une valeur ou un tableau de valeurs, et te donne un pointeur vers la mémoire réservée. Chaque delete ou delete[] rend (on dit "libère") la mémoire en question.

Au moment où tu fais delete[] testText, tu libères le tableau de pointeurs. Mais les pointeurs originaux pointent toujours vers de la mémoire réservée, parce que c'est pas "transitif" ! Et en plus après delete[] testText tu n'as plus le droit de lire testText[i], donc comme tu l'as justement écrit il faut bien libérer les éléments du tableau en premier.

(Plus généralement : en C++, new et delete invoquent aussi les constructeurs et destructeurs. Les constructeurs et destructeurs sont des fonctions quelconques et peuvent faire n'importe quoi. Par exemple, la plupart des objets vont libérer la mémoire de leur variables internes quand tu fais delete dessus. Donc quand tu as des vrais objets C++, il devient important de comprendre qui est responsable de libérer chaque allocation pour s'assurer que toute la mémoire est libérée. Mais avec des variables classiques du C comme des tableaux, c'est toujours toi qui es responsable de tout.)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Farhi Hors ligne Membre Points: 1380 Défis: 0 Message

Citer : Posté le 08/04/2022 16:36 | #


Alors justement, parce que ce que tu as dis c'est ce que je pensais avant mais je me suis embrouillé avec cette fonction :
void GameManager::LoadMap(int index) {
char path[20];
sprintf(path, "DATA_RPG/%d.MAP", index);
FILE* fp;
fp = fopen((const char*)path, "r");
.....
fclose(fp);
};
Je voulais libérer path après le fclose(fp), donc j'ai essayer delete[] et delete, les deux ne marchaient pas. Enfin si, delete[] marche qu'une fois, c'est à dire que je l'appel une fois elle marche, je la rappel à nouveau elle marche plus. (et quand il a pas de delete[] ça marche à tous les coups)
"La créativité est contagieuse faites la tourner"
Albert Einstein
Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 08/04/2022 16:41 | #


Ici path n'est pas alloué sur le tas (malloc()/new/new[]), c'est juste une variable locale allouée sur la pile. Comme le int index que tu as en paramètre ou le int sizeSTR de la fonction plus haut. Tu n'as pas besoin de la libérer.

Cheat sheet :

char path[20];
// Données (20 octets) sur la pile, pas de libération

char *path = malloc(20);
// Le pointeur (4 octets) est sur la pile, les données (20 octets) dans le tas
free(path);

char *path = new char;
// Le pointeur (4 octets) est sur la pile, la donnée (1 octet) dans le tas
delete path;

char *path = new char[20];
// Le pointeur (4 octets) est sur la pile, les données (20 octets) dans le tas
delete[] path;

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Précédente 1, 2, 3 ··· 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 128 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