2017-01-05 5 views
0

Donc je travaille sur un jeu pour mon cours de science informatique en utilisant Dev-C++ 5.11 et Allegro 4.2, j'arrive à la fin du projet et je veux enfin régler un problème que j'ai eu pendant un certain temps maintenant. Mon code est assez long pour utiliser un seul fichier .cpp, mais quand j'essaie de placer mes fonctions dans un fichier séparé, je reçois une série de "définitions multiples" des erreurs "définies ici". J'ai regardé en ligne et la plupart des gens qui ont ce problème ont inclus leur fichier. Cpp dans leur principal ou quelque chose d'équivalent, mais je n'ai pas fait cela et ne peux pas comprendre pourquoi cela ne fonctionnera pas. Les erreurs pointent vers toutes les variables que je déclare dans l'en-tête (les bitmaps ainsi que le tableau char et ints).Erreurs de définition multiple; C++ travailler avec Allegro

Fichiers:

asteroidsMain.cpp 
functions.cpp 
asteroids.h 

J'utilise également un fichier de données.

Fichier principal:

#include <allegro.h> 
#include <alfont.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include "asteroids.h" 
#include "asteroids_data.h" 

//Creating movement timer (also used for typing) 
volatile long speed_counterA = 0; 

void increment_speed_counterA() { 
    speed_counterA++; 
} 
END_OF_FUNCTION(increment_speed_counterA); 

//Creating laser timer 
volatile long speed_counterB = 0; 

void increment_speed_counterB() { 
    speed_counterB++; 
} 
END_OF_FUNCTION(increment_speed_counterB); 

//Creating asteroid timer 
volatile long speed_counterC = 0; 

void increment_speed_counterC() { 
    speed_counterC++; 
} 
END_OF_FUNCTION(increment_speed_counterC); 


int main() { 
    //Initializations 
    allegro_init(); 
    alfont_init(); 
    set_color_depth(desktop_color_depth()); 
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); 
    install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL); 
    install_keyboard(); 
    install_mouse(); 
    install_timer(); 

    //Movement timer 
    LOCK_VARIABLE(speed_counterA); 
    LOCK_FUNCTION(increment_speed_counterA); 
    install_int_ex(increment_speed_counterA, BPS_TO_TIMER(60)); 
    //Laser firing timer 
    LOCK_VARIABLE(speed_counterB); 
    LOCK_FUNCTION(increment_speed_counterB); 
    install_int_ex(increment_speed_counterB, BPS_TO_TIMER(60)); 
    //Asteroid generation timer 
    LOCK_VARIABLE(speed_counterC); 
    LOCK_FUNCTION(increment_speed_counterC); 
    install_int_ex(increment_speed_counterC, BPS_TO_TIMER(60)); 

    //Randomizing seed 
    srand(time(0)); 

    //Creating/loading BITMAPs formain game 
    BITMAP *buffer = create_bitmap(800, 600); 
    shipStopped = loadImage("shipStopped"); 
    shipMoving = loadImage("shipMoving"); 
    laserSprite = loadImage("laser"); 
    smallAsteroid = loadImage("small_Asteroid"); 
    medAsteroid = loadImage("med_Asteroid"); 
    largeAsteroid = loadImage("large_Asteroid"); 

    //General use variables for screen control 
    int onScreen = 0, i = 0, j = 0; 
    bool quit = false; 

    //Retrieving and sorting scores 
    numOfScores = getHighs(name, score); 
    sortHighs(name, score); 

    //Loads main screen 
    onScreen = changeScreen(0); 

    while (!quit) { 
     //If there was an issue loading datafile, error is returned 
     if (onScreen == -1) { 
      return 1; 
     } 
     else if (onScreen == 0) { 
      while (onScreen == 0) { 
       //Primary check is for quitting program, other buttons lead to separate screens 
       if ((mouse_b & 1) && mouse_x > 400 - 75 && 
       mouse_x < 400 + 75 && mouse_y > 450 && mouse_y < 4505 + quitButton->h) { //For clicking Quit 
        quit = true; 
        onScreen = -2; 
       } 
       else if ((mouse_b & 1) && mouse_x > 400 - 75 && 
       mouse_x < 400 + 75 && mouse_y > 150 && mouse_y < 150 + playButton->h) { //For clicking Play 
        onScreen = changeScreen(2); 
       } 
       else if ((mouse_b & 1) && mouse_x > 400 - 75 && 
       mouse_x < 400 + 75 && mouse_y > 250 && mouse_y < 250 + highsButton->h) { //For clicking Highscores 
        onScreen = changeScreen(3); 
       } 
       else if((mouse_b & 1) && mouse_x > 400 - 75 && 
       mouse_x < 400 + 75 && mouse_y > 350 && mouse_y < 350 + creditsButton->h) { //For clicking Credits 
        onScreen = changeScreen(4); 
       } 
      } 
     } 
     else if (onScreen == 2) { //Difficulty choice screen 
      if ((mouse_b & 1) && mouse_x > 600 - (playButton->w/2) && 
       mouse_x < 600 + (playButton->w/2) && mouse_y > 192 && mouse_y < 192 + playButton->h) { 
        onScreen = changeScreen(1); 
     } 
      else if ((mouse_b & 1) && mouse_x > 635 && mouse_x < 775 && 
      mouse_y > 575 - menuButton->h && mouse_y < 575) { //Returns to main menu 
       onScreen = changeScreen(0); 
      } 
     } 
     else if (onScreen == 3) { //Highscore screen 
      if ((mouse_b & 1) && mouse_x > 635 && mouse_x < 775 && 
      mouse_y > 575 - menuButton->h && mouse_y < 575) { //Returns to main menu 
       onScreen = changeScreen(0); 
      } 
     } 
     else if (onScreen == 4) { //Credit screen 
      if ((mouse_b & 1) && mouse_x > 635 && mouse_x < 775 && 
      mouse_y > 575 - menuButton->h && mouse_y < 575) { //Returns to main menu 
       onScreen = changeScreen(0); 
      } 
     } 
     else if (onScreen == 51) { //Game over screen 

      if (points <= score[9]) { 
       if ((mouse_b & 1) && mouse_x > 25 && mouse_x < 175 && 
        mouse_y > 575 - menuButton->h && mouse_y < 575) { //Begins a new game 
        onScreen = changeScreen(2); 
       } 
       else if ((mouse_b & 1) && mouse_x > 635 && mouse_x < 775 && 
         mouse_y > 575 - menuButton->h && mouse_y < 575) { //Returns to main menu 
        onScreen = changeScreen(0); 
       } 
      } 
      else { 
       if (mouse_b & 1) { 
        //Adding new highschore to array 
        score[9] = points; 
        strcpy(name[9], ""); 

        if (numOfScores < 10) { 
         numOfScores++; 
        } 
        onScreen = changeScreen(52); 
       } 
      } 
     } 
     else if (onScreen == 52) { 
      speed_counterA = 0; 

      int keyEnt = 0, len = 0; 
      char keyHold; 

      //Text entering for highscore name, moves to next screen on enter 
      while (!key[KEY_ENTER]) { 
       //Preventing multiple printing of same key 
       while (keypressed() && speed_counterA % 3 == 0) { 
        //Reading key from keyboard and making it useable 
        keyEnt = readkey(); 
        keyHold = keyEnt & 0xff; 

        if (keyHold >= 32 && keyHold <= 126) { //Adding chars to name string 
         len = strlen(name[9]); 

         if (len < 19) { //Restricting the number of characters you can enter, beyond this does not save properly 
         name[9][len] = keyHold; 
         name[9][len + 1] = '\0'; 
        } 
        } 
        else if (key[KEY_BACKSPACE]) { //Deleting if backspace char is pressed 
         name[9][len] = '\0'; 
         len--; 
        } 
        clear_keybuf(); 
       } 
       //Printing text 
       textprintf_centre_ex(buffer, font, 400, 300, WHITE, -1, "What is your name: %s", name[9]); 
       textprintf_centre_ex(buffer, font, 400, 500, WHITE, -1, "** press enter to conitue **"); 
       // Blit the buffer 
       blit(buffer, screen, 0, 0, 0, 0, 800, 600); 
       clear(buffer); 

      } 
      onScreen = changeScreen(53); 
     } 
     else if (onScreen == 53) { 
      if ((mouse_b & 1) && mouse_x > 25 && mouse_x < 175 && 
       mouse_y > 575 - menuButton->h && mouse_y < 575) { //Begins a new game 
       onScreen = changeScreen(2); 
      } 
      else if ((mouse_b & 1) && mouse_x > 635 && mouse_x < 775 && 
        mouse_y > 575 - menuButton->h && mouse_y < 575) { //Returns to main menu 
       onScreen = changeScreen(0); 
      } 
     } 
     else if (onScreen == 1) { //Game screen 
      //Defining 
      Laser laser[50]; 
      Asteroid asteroid[10]; 

      //Initializing lasers and asteroids 
      for (i = 0; i < 50; i++) { 
       laser[i].pos.x = 0; 
       laser[i].pos.y = 0; 
       laser[i].angle = 0; 
       laser[i].onScreen = false; 
      } 
      for (i = 0; i < 10; i++) { 
       asteroid[i].pos.x = 0; 
       asteroid[i].pos.y = 0; 
       asteroid[i].angle = 0; 
       asteroid[i].onScreen = false; 
      } 

      //Game specific variables, reset for every new game 
      int move = 0, lasers= 0, asteroids = 0; 
      float angle = 0; 
      bool collide = false; 

      points = 0; 

      //Spawning ship when game screen loads 
      Coordinate ship; 
      ship.x = 400 - (shipStopped->w/2); 
      ship.y = 300 - (shipStopped->h/2); 

      //Reseting game timers 
      speed_counterA = 0; 
      speed_counterB = 0; 
      speed_counterC = 0; 

      while (onScreen == 1) { //Game screen 
       while (speed_counterA > 0) { 

        //Ship movement 
        if (key[KEY_UP] && key[KEY_RIGHT]){ 
         ship.y -= 3; 
         ship.x += 3; 
         angle = 32; 
        } 
        else if (key[KEY_UP] && key[KEY_LEFT]){ 
         ship.y -= 3; 
         ship.x -= 3; 
         angle = 224; 
        } 
        else if (key[KEY_DOWN] && key[KEY_RIGHT]) { 
         ship.y += 3; 
         ship.x += 3; 
         angle = 96; 
        } 
        else if (key[KEY_DOWN] && key[KEY_LEFT]) { 
         ship.y += 3; 
         ship.x -= 3; 
         angle = 160; 
        } 
        else if (key[KEY_UP]){ 
         ship.y -= 6; 
         angle = 0; 
        } 
        else if (key[KEY_RIGHT]) { 
         ship.x += 6; 
         angle = 64; 
        } 
        else if (key[KEY_LEFT]) { 
         ship.x -= 6; 
         angle = 192; 
        } 
        else if (key[KEY_DOWN]) { 
         ship.y += 6; 
         angle = 128; 
        } 

        //Laser movement 
        for (i = 0; i < 50; i++) { 
         laser[i] = moveLaser(laser[i]); 
        } 

        //Asteroid movement 
        for (i = 0; i < 10; i++) { 
         asteroid[i] = moveAsteroid(asteroid[i]); 
        } 

        speed_counterA--; 
       } 

       //Key trigger for laser firing, if is first as having timer first 
       //would cause many hits not to be properly registered especially if 
       //tapping too fast, this allows firing at will with a fastest firing of every 0.15s 
       if (key[KEY_SPACE]) { 
        //Laser firing timer 
        while (speed_counterB > 9) { 
         //Laser shooting 
         laser[lasers] = fireLaser(angle, ship.x, ship.y); 

         if (lasers >= 49) { 
          lasers = 0; 
         } 

         lasers++; 

        speed_counterB -= 10; 
        } 
       } 

       //Asteroid spawning counter 
       while (speed_counterC > 59) { //Spawns an asteroiud every second 

        //Keeping asteroids within array range 
        if (asteroids >= 9){ 
         asteroids = 0; 
        } 

        //Generating asteroid 
        asteroid[asteroids] = genAsteroid(1, -1); 

        asteroids++; 
        speed_counterC -= 60; 
       } 

       //If ship goes out top, it comes in bottom; vice versa 
       if (ship.y <= 0 - ((shipStopped->h/2))) { 
        ship.y += (600); 
       } 
       else if (ship.y >= 600 - ((shipStopped->h/2))) { 
        ship.y -= (600); 
       } 

       //If ship goes out left, it comes in right; vice versa 
       if (ship.x <= 0 - ((shipStopped->w/2))) { 
        ship.x += (800); 
       } 
       else if (ship.x >= 800 - ((shipStopped->w/2))) { 
        ship.x -= (800); 
       } 

       //Drawing lasers 
       for (i = 0; i < 50; i++) { 
        if (laser[i].onScreen) { 
         rotate_sprite(buffer, laserSprite, laser[i].pos.x, laser[i].pos.y, ftofix(laser[i].angle)); 
        } 
       } 

       //Drawing ship 
       if (key[KEY_UP] || key[KEY_DOWN] || key[KEY_LEFT] || key[KEY_RIGHT]) { 
        rotate_sprite(buffer, shipMoving, ship.x, ship.y, ftofix(angle)); //Ship sprite with engines firing 
       } 
       else { 
        rotate_sprite(buffer, shipStopped, ship.x, ship.y, ftofix(angle)); //Ship sprite no flames 

       } 

       //Drawing asteroids 
       for (i = 0; i < 10; i++) { 
        if (asteroid[i].onScreen == true) { 
         //Drawing sprite based on asteroid type 
         if (asteroid[i].type == 1) { //Large asteroid 
          draw_sprite(buffer, largeAsteroid, asteroid[i].pos.x, asteroid[i].pos.y); 
         } 
         else if (asteroid[i].type == 2) { //Medium asteroid 
          draw_sprite(buffer, medAsteroid, asteroid[i].pos.x, asteroid[i].pos.y); 
         } 
         else if (asteroid[i].type == 3) { //Small asteroid 
          draw_sprite(buffer, smallAsteroid, asteroid[i].pos.x, asteroid[i].pos.y); 
         } 
        } 
       } 

       //Checks bb collisions 
       for (i = 0; i < 50; i++) { 
        for (j = 0; j < 10; j++) { 
         if (laser[i].onScreen && asteroid[j].onScreen) { 
          collide = checkCollision(asteroid[j].type, 0, asteroid[j].pos, laser[i].pos); 
          if (collide) { 
           laser[i].onScreen = false; 
           asteroid[j].onScreen = false; 

           points += 100 * asteroid[j].type; 

           //Splitting med or large asteroids into 2 asteroids one type down 
           if (asteroid[j].type < 3) { 
            asteroid[asteroids] = splitAsteroid(1, asteroid[j]); 
            asteroid[j] = splitAsteroid(2, asteroid[j]); 
            asteroids++; 
           } 
          } 
         } 
        } 
       } 

       //Printing score 
       textprintf_ex(buffer, font, 10, 5, WHITE, -1, "Score: %d", points); 
       textprintf_ex(buffer, font, 660, 5, WHITE, -1, "Press esc to quit"); 

       // Blit the buffer 
       blit(buffer, screen, 0, 0, 0, 0, 800, 600); 
       clear(buffer); 

       for (i = 0; i < 10; i++) { 
        if (asteroid[i].onScreen) { 
         collide = checkCollision(asteroid[i].type, 1, asteroid[i].pos, ship); 

         if (collide) { 
          onScreen = changeScreen(51); 
         } 
        } 
       } 

       //To leave game screen and return to main menu 
       if (key[KEY_ESC]) { 
        onScreen = changeScreen(0); 
       } 
      } 
     } 
    } 

    //Freeing memory 
    destroy_bitmap(playButton); 
    destroy_bitmap(highsButton); 
    destroy_bitmap(creditsButton); 
    destroy_bitmap(quitButton); 
    destroy_bitmap(shipStopped); 
    destroy_bitmap(shipMoving); 
    destroy_bitmap(laserSprite); 
    destroy_bitmap(smallAsteroid); 
    destroy_bitmap(medAsteroid); 
    destroy_bitmap(largeAsteroid); 

    return 0; 
} 
END_OF_MAIN() 

fichier d'en-tête est:

#ifndef ASTEROIDS_H_ 
#define ASTEROIDS_H_ 

#define WHITE makecol(255, 255, 255) 
#define BLACK makecol(0, 0, 0) 

#include <allegro.h> 
#include <alfont.h> 

//Made global so size pointers can be used throughout 
BITMAP *playButton; 
BITMAP *playAgainButton; 
BITMAP *highsButton; 
BITMAP *creditsButton; 
BITMAP *quitButton; 
BITMAP *menuButton; 
BITMAP *shipStopped; 
BITMAP *shipMoving; 
BITMAP *laserSprite; 
BITMAP *smallAsteroid; 
BITMAP *medAsteroid; 
BITMAP *largeAsteroid; 

//Highscore variables are made global; technically bad, 
//but makes simplifies printing greatly 
int score[10], numOfScores, points; 
char name[10][20]; 

struct Coordinate { 
    int x, y; 
}; 

struct Laser { 
    Coordinate pos; 
    float angle; 
    bool onScreen; 
}; 

struct Asteroid { 
    Coordinate pos; 
    int type; 
    int angle; 
    bool onScreen; 
}; 

int changeScreen(int toLoad); 
BITMAP* loadImage(const char image[20]); 
int getHighs(char name[][20], int high[]); 
void sortHighs(char name[][20], int score[]); 
void saveHighs(const char name[][20], const int score[], int numOfScores); 
Laser fireLaser(float angle, int ship_x, int ship_y); 
Laser moveLaser(Laser laser); 
Asteroid genAsteroid(int difficulty, int type); 
Asteroid splitAsteroid(int order, Asteroid asteroid); 
Asteroid moveAsteroid(Asteroid asteroid); 
bool checkCollision(int typeA, int typeB, Coordinate asteroid, Coordinate object); 

#endif 

Le fichier fonctions se résume à:

#include <allegro.h> 
#include <alfont.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include "asteroids.h" 
#include "asteroids_data.h" 

/*~500 lines of functions*/ 

Tout fonctionne quand je mets simplement les fonctions ci-dessous la principale

Copie du journal de compilation:

g++.exe -c asteroidsMain.cpp -o asteroidsMain.o -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" -I"C:/Program Files (x86)/Dev-Cpp/include" -m32 
g++.exe asteroidsMain.o functions.o -o POPE_Greg_Asteroids.exe -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32" -L"C:/Program Files (x86)/Dev-Cpp/lib" -lalfont -lalleg -m32 
functions.o:functions.cpp:(.bss+0x0): multiple definition of `playButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x0): first defined here 
functions.o:functions.cpp:(.bss+0x4): multiple definition of `playAgainButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x4): first defined here 
functions.o:functions.cpp:(.bss+0x8): multiple definition of `highsButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x8): first defined here 
functions.o:functions.cpp:(.bss+0xc): multiple definition of `creditsButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0xc): first defined here 
functions.o:functions.cpp:(.bss+0x10): multiple definition of `quitButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x10): first defined here 
functions.o:functions.cpp:(.bss+0x14): multiple definition of `menuButton' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x14): first defined here 
functions.o:functions.cpp:(.bss+0x18): multiple definition of `shipStopped' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x18): first defined here 
functions.o:functions.cpp:(.bss+0x1c): multiple definition of `shipMoving' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x1c): first defined here 
functions.o:functions.cpp:(.bss+0x20): multiple definition of `laserSprite' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x20): first defined here 
functions.o:functions.cpp:(.bss+0x24): multiple definition of `smallAsteroid' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x24): first defined here 
functions.o:functions.cpp:(.bss+0x28): multiple definition of `medAsteroid' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x28): first defined here 
functions.o:functions.cpp:(.bss+0x2c): multiple definition of `largeAsteroid' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x2c): first defined here 
functions.o:functions.cpp:(.bss+0x40): multiple definition of `score' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x40): first defined here 
functions.o:functions.cpp:(.bss+0x68): multiple definition of `numOfScores' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x68): first defined here 
functions.o:functions.cpp:(.bss+0x6c): multiple definition of `points' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x6c): first defined here 
functions.o:functions.cpp:(.bss+0x80): multiple definition of `name' 
asteroidsMain.o:asteroidsMain.cpp:(.bss+0x80): first defined here 
collect2.exe: error: ld returned 1 exit status 

C:\Users\Greg\Documents\Asteroids B\Makefile.win:25: recipe for target 'POPE_Greg_Asteroids.exe' failed 
mingw32-make.exe: *** [POPE_Greg_Asteroids.exe] Error 1 
+2

Ce n'est pas le problème, mais les noms qui contiennent deux traits de soulignement consécutifs ('__ASTEROIDS_H_INCLUDED__') et les noms commençant par un trait de soulignement suivi d'une lettre majuscule sont réservés à l'implémentation. Ne les utilisez pas dans votre code. –

+0

Affiche le journal de construction. Nous devons voir au moins quelques-uns des messages d'erreur exacts. Les messages indiqueront clairement où et quelles sont les multiples définitions. C'est évidemment des informations vitales pour cette question. – kaylum

+0

"Je reçois une série de" définitions multiples "des erreurs" définies ici "- avez-vous ** lu ** les messages d'erreur? Je n'ai jamais vu un compilateur qui donne ce genre de message d'erreur sans mentionner les ** noms ** des symboles qui sont multipliés, et c'est un grand indice sur la façon de résoudre le problème. Recherchez ces noms, et supprimez ** le code qui ne les concerne pas, jusqu'à ce que vous ayez le plus petit programme possible pour montrer le problème. Vous pourriez juste voir comment le réparer vous-même. –

Répondre

0

Ajoutez ces fichiers dans le même projet.