2013-03-20 9 views
14

Mi sono allenato per utilizzare l'oggetto di programmazione orientata in C++, ma continuo a ricevere questo errore:irreversibile LNK1169 errore: uno o più simboli moltiplicano definiti trovati nella programmazione del gioco

1>main.obj : error LNK2005: "int WIDTH" ([email protected]@3HA) already defined in GameObject.obj 
1>main.obj : error LNK2005: "int HEIGHT" ([email protected]@3HA) already defined in GameObject.obj 
1>Spaceship.obj : error LNK2005: "int WIDTH" ([email protected]@3HA) already defined in GameObject.obj 
1>Spaceship.obj : error LNK2005: "int HEIGHT" ([email protected]@3HA) already defined in GameObject.obj 
1>C:\Users\ted\documents\visual studio 2010\Projects\fullSpace\Debug\fullSpace.exe : fatal error LNK1169: one or more multiply defined symbols found 

Tuttavia a me, sembra che l'intero codice è scritto correttamente e le due int sono solo menzionate nell'intestazione Global e tutti gli oggetti sembrano ereditare correttamente. Comunque, come ho appena detto, sono un principiante in OOP quindi ho davvero bisogno di un'opinione: vale anche la pena ricordare che sto usando allegro 5 per creare uno sparatutto laterale.

Questo è il codice:

(principale):

#include <allegro5/allegro.h> 
#include <allegro5/allegro_image.h> 
#include <allegro5/allegro_primitives.h> 
#include <allegro5/allegro_font.h> 
#include <allegro5\allegro_ttf.h> 
#include <allegro5\allegro_audio.h> 
#include <allegro5\allegro_acodec.h> 

#include <list> 


#include "GameObject.h" 
#include "Spaceship.h" 
#include "Globals.h" 



//controls 

bool keys[] = {false, false, false, false, false}; 
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE}; 

//globals 
Spaceship *ship; 

std::list <GameObject *> objects; 
std::list <GameObject *>::iterator iter; 
std::list <GameObject *>::iterator iter2; 



//prototypes 



//main function 
int main(int argc, char **argv) 
{ 
    //shell variables 
    bool done = false; 
    bool render = false; 

    float gameTime = 0; 
    int frames = 0; 
    int gameFPS = 0; 

    //project variables 

    ship = new Spaceship(); 


    ALLEGRO_BITMAP *shipImage = NULL; 
    ALLEGRO_BITMAP *cometImage= NULL; 
    ALLEGRO_BITMAP *explImage = NULL; 
    ALLEGRO_BITMAP *bgImage = NULL; 
    ALLEGRO_BITMAP *mgImage = NULL; 
    ALLEGRO_BITMAP *plImage = NULL; 
    ALLEGRO_BITMAP *mgImage2 = NULL; 
    ALLEGRO_BITMAP *fgImage = NULL; 
    ALLEGRO_BITMAP *titleImage= NULL; 
    ALLEGRO_BITMAP *lostImage = NULL; 


    //allegro variables 
    ALLEGRO_DISPLAY *display = NULL; 
    ALLEGRO_EVENT_QUEUE *event_queue = NULL; 
    ALLEGRO_TIMER *timer; 
    ALLEGRO_FONT *font18; 



    //initiate variables 
    if(!al_init()) 
     return -1; 

    display = al_create_display(WIDTH, HEIGHT); 
    if(!display) 
    return -1; 

    //addon installation 

    al_install_keyboard(); 
    al_init_image_addon(); 
    al_init_font_addon(); 
    al_init_ttf_addon(); 
    al_init_primitives_addon(); 
    al_install_audio(); 
    al_init_acodec_addon(); 

    //project init 

    font18 = al_load_font("arial.ttf", 18, 0); 
    al_reserve_samples(15); 




    bgImage = al_load_bitmap("layer1.png"); 
    mgImage = al_load_bitmap("layer2.png"); 
    plImage = al_load_bitmap("starMG.png"); 
    mgImage2 = al_load_bitmap("layer3.png"); 
    fgImage = al_load_bitmap("layer4.png"); 




    shipImage = al_load_bitmap("spaceship.png"); 
    al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255)); 



    cometImage = al_load_bitmap("asteroid-1-96.png"); 
    explImage = al_load_bitmap("explosion_3_40_128.png"); 

    titleImage = al_load_bitmap("Shooter_Title.png"); 
    lostImage = al_load_bitmap("Shooter_Lose.png"); 



    //object init 
    ship->init(shipImage); 


    //iter list 
    objects.push_back(ship); 


    srand(time(NULL)); 

    //timer init and startup 

    event_queue = al_create_event_queue(); 
    timer = al_create_timer(1.0/60); 

    al_register_event_source(event_queue, al_get_timer_event_source(timer)); 
    al_register_event_source(event_queue, al_get_keyboard_event_source()); 

    al_start_timer(timer); 
    gameTime = al_current_time(); 

    while(!done) 
    { 
     ALLEGRO_EVENT ev; 
     al_wait_for_event(event_queue, &ev); 

     //input 
     if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 
     { 
      switch(ev.keyboard.keycode) 
      { 
      case ALLEGRO_KEY_ESCAPE: 
       done = true; 
       break; 
      case ALLEGRO_KEY_LEFT: 
       keys[LEFT] = true; 
       break; 
      case ALLEGRO_KEY_RIGHT: 
       keys[RIGHT] = true; 
       break; 
      case ALLEGRO_KEY_UP: 
       keys[UP] = true; 
       break; 
      case ALLEGRO_KEY_DOWN: 
       keys[DOWN] = true; 
       break; 
      case ALLEGRO_KEY_SPACE: 
       keys[SPACE] = true; 
       break; 


      } 
     } else if(ev.type == ALLEGRO_EVENT_KEY_UP) 
     { 
      switch(ev.keyboard.keycode) 
      { 
      case ALLEGRO_KEY_ESCAPE: 
       done = true; 
       break; 
      case ALLEGRO_KEY_LEFT: 
       keys[LEFT] = false; 
       break; 
      case ALLEGRO_KEY_RIGHT: 
       keys[RIGHT] = false; 
       break; 
      case ALLEGRO_KEY_UP: 
       keys[UP] = false; 
       break; 
      case ALLEGRO_KEY_DOWN: 
       keys[DOWN] = false; 
       break; 
      case ALLEGRO_KEY_SPACE: 
       keys[SPACE] = false; 
       break; 
      } 
     } 



     else if (ev.type == ALLEGRO_EVENT_TIMER) 
     { 
      render = true; 

      //fps 
      frames++; 
      if(al_current_time() - gameTime >= 1) 
      { 
       gameTime = al_current_time(); 
       gameFPS = frames; 
       frames = 0; 
      } 

      //shipUpdate 

      if(keys[UP]) 
       ship ->moveUp(); 
      else if(keys[DOWN]) 
       ship ->moveDown(); 
      else 
       ship->resetAnim(1); 

      if(keys[LEFT]) 
       ship ->moveLeft(); 
      else if(keys[RIGHT]) 
       ship -> moveRight(); 
      else 
       ship ->resetAnim(0); 

     } 
     //render 

      if(render && al_is_event_queue_empty(event_queue)) 
      { 
       render = false; 

       //begin render 
       for(iter = objects.begin(); iter != objects.end(); ++iter) 
        (*iter)->render(); 




       //Flip Buffers 
       al_flip_display(); 
       al_clear_to_color(al_map_rgb(0,0,0)); 
      } 
     } 

       //destroy objects 



     //visual objects 
    al_destroy_bitmap(cometImage); 
    for(iter = objects.begin(); iter != objects.end(); ++iter) 
     (*iter)->destroy(shipImage); 
     iter = objects.erase(iter); 

    al_destroy_bitmap(explImage); 
    al_destroy_bitmap(bgImage); 
    al_destroy_bitmap(mgImage); 
    al_destroy_bitmap(fgImage); 
    al_destroy_bitmap(titleImage); 
    al_destroy_bitmap(lostImage); 

     //audio objects 
    /* 
    al_destroy_sample(shot); 
    al_destroy_sample(boom); 
    al_destroy_sample(song); 
    al_destroy_sample_instance(songInstance); 
    */ 


     //shell objects 
    al_destroy_font(font18); 
    al_destroy_timer(timer); 
    al_destroy_event_queue(event_queue); 
    al_destroy_display(display); 

    return 0; 
} 

(Globals.h):

#pragma once 

int WIDTH = 1024; 
int HEIGHT = 800; 

enum ID{PLAYER, ENEMY, BULLET, BORDER, MISC}; 
enum STATES{TITLE, PLAYING, LOST}; 

(GameObject.h):

#pragma once 


#include "Globals.h" 
#include <iostream> 

#include <allegro5/allegro5.h> 

#include <allegro5/allegro_primitives.h> 



class GameObject 
{ 
private: 
    int ID; 
    bool alive; 
    bool collidable; 

protected: 
    float x; 
    float y; 

    float velX; 
    float velY; 

    int dirX; 
    int dirY; 

    int boundX; 
    int boundY; 

    int maxFrame; 
    int curFrame; 
    int frameCount; 
    int frameDelay; 
    int frameWidth; 
    int frameHeight; 
    int animationColumns; 
    int animationDirection; 

    ALLEGRO_BITMAP *image; 

public: 
    GameObject(); 
    void virtual destroy(ALLEGRO_BITMAP *image); 

    void init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY); 
    void virtual update(); 
    void virtual render(); 

    float getX() {return x;} 
    float getY() {return y;} 

    void setX(float x) {GameObject::x = x;} 
    void setY(float y) {GameObject::y = y;} 

    int getBoundX() {return boundX;} 
    int getBoundY() {return boundY;} 

    int getID() {return ID;} 
    void setID(int ID) {GameObject::ID = ID;} 

    bool getAlive() {return alive;} 
    void setAlive(bool alive) {GameObject::alive = alive;} 

    bool getCollidable() {return collidable;} 
    void setCollidable(bool collidable) {GameObject::collidable = collidable;} 

    bool checkCollisions(GameObject *otherObject); 
    void virtual collided(int objectID); 
    bool collidableCheck(); 
}; 

(GameObject.cpp):

#include "GameObject.h" 

GameObject::GameObject() 
{ 
    x = 0; 
    y = 0; 

    velX = 0; 
    velY = 0; 

    dirX = 0; 
    dirY = 0; 

    boundX = 0; 
    boundY = 0; 

    maxFrame = 0; 
    curFrame = 0; 
    frameCount = 0; 
    frameDelay = 0; 
    frameWidth = 0; 
    frameHeight = 0; 
    animationColumns = 0; 
    animationDirection = 0; 

    image = NULL; 

    alive = true; 
    collidable = true; 

} 

void GameObject::destroy(ALLEGRO_BITMAP *image) 
{ 
    if(image != NULL) 
     al_destroy_bitmap(image); 

} 
void GameObject::init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY) 
{ 
    GameObject::x = x; 
    GameObject::y = y; 

    GameObject::velX = velX; 
    GameObject::velY = velY; 

    GameObject::dirX = dirX; 
    GameObject::dirY = dirY; 

    GameObject::boundX = boundX; 
    GameObject::boundY = boundY; 

} 

void GameObject::update() 
{ 
    x += velX*dirX; 
    y += velY*dirY; 
} 

void GameObject::render() 
{ 

} 

bool GameObject::checkCollisions(GameObject *otherObject) 
{ 
    float oX = otherObject->getX(); 
    float oY = otherObject->getY(); 

    int obX = otherObject->getBoundX(); 
    int obY = otherObject->getBoundY(); 

    if(x + boundX > oX - obX && 
     x - boundX < oX + obX && 
     y + boundY > oY - obY && 
     y - boundY < oY + obY 
     ) 
     return true; 
    else 
     return false; 
} 

void GameObject::collided(int objectID) 
{ 

} 
bool GameObject::collidableCheck() 
{ 
    return alive && collidable; 
} 

(SpaceShip.h):

#pragma once 

#include "GameObject.h" 

class Spaceship : public GameObject 
{ 
private : 
    int lives; 
    int score; 
    int animationRow; 

public : 
    Spaceship(); 

    void destroy(ALLEGRO_BITMAP *image); 

    void init(ALLEGRO_BITMAP *image = NULL); 

    void update(); 
    void render(); 

    void moveUp(); 
    void moveDown(); 
    void moveLeft(); 
    void moveRight(); 

    void resetAnim(int pos); 

    int getLives(){return lives;} 

    int getScore() {return score;} 

    void looseLife() {lives--;} 
    void addPoint() {score++;} 

    void collide(int objectID); 



}; 

(SpaceShip.cpp):

#include "Spaceship.h" 

    Spaceship::Spaceship() 
    {} 

    void Spaceship::destroy(ALLEGRO_BITMAP *image) 
    { 
     GameObject::destroy(image); 
    } 
    void Spaceship::init(ALLEGRO_BITMAP *image) 
    { 
     GameObject::init(20, 200, 6, 6, 0, 0, 10, 12); 

     setID(PLAYER); 
     setAlive(true); 

     lives = 3; 
     score = 0; 

     maxFrame = 3; 
     curFrame = 0; 
     frameWidth = 46; 
     frameHeight = 41; 
     animationColumns = 3; 
     animationDirection = 1; 

     animationRow = 1; 

     if(image != NULL) 
     { 
      Spaceship::image = image; 
     } 
    } 

    void Spaceship::update() 
    { 
     GameObject::update(); 
     if(x < 0) 
      x=0; 
     else if (x > WIDTH) 
      x = WIDTH; 
     if(y < 0) 
      y = 0; 
     else if (y > HEIGHT) 
      y = HEIGHT; 
    } 
    void Spaceship::render() 
    { 
     GameObject::render(); 

     int fx = (curFrame % animationColumns) *frameWidth; 
     int fy = animationRow *frameHeight; 

     al_draw_bitmap_region(image, fx, fy, frameWidth, frameHeight, 
      x - frameWidth /2, y - frameHeight /2, 0); 

    } 

    void Spaceship::moveUp() 
    { 
     animationRow = 0; 
     dirY = -1; 

    } 
    void Spaceship::moveDown() 
    { 
     animationRow = 2; 
     dirY = 1; 
    } 
    void Spaceship::moveLeft() 
    { 
     curFrame = 2; 
     dirX = -1; 
    } 
    void Spaceship::moveRight() 
    { 
     curFrame = 1; 
     dirX = 1; 
    } 

    void Spaceship::resetAnim(int pos) 
    { 
     if(pos == 1) 
     { 
      animationRow = 1; 
      dirY = 0; 
     } 
     else 
     { 
      curFrame = 0; 
      dirX = 0; 
     } 
    } 

    void Spaceship::collide(int objectID) 
    { 
     if(objectID == ENEMY) 
      lives--; 

    } 
+0

possibile duplicato [errore LNK1169 su global const char \ *] (http://stackoverflow.com/questions/13772206/error-lnk1169-on-global-const-char) –

risposta

40

Le due int variabili sono definite nel file di intestazione. Ciò significa che ogni file sorgente che include l'intestazione conterrà la loro definizione (l'inclusione dell'intestazione è puramente testuale). Ovviamente porta a errori di definizione multipli.

Hai diverse opzioni per risolvere questo problema.

  1. Effettuare le variabili static (static int WIDTH = 1024;). Esisteranno ancora in ogni file sorgente, ma le loro definizioni non saranno visibili al di fuori del file sorgente.

  2. trasformare le loro definizioni in dichiarazioni utilizzando extern (extern int WIDTH;) e mettere la definizione in uno file sorgente: int WIDTH = 1024;.

  3. Probabilmente la migliore opzione: rendere le variabili const (const int WIDTH = 1024;). Questo li rende static implicitamente, e permette loro di essere utilizzati come costanti in fase di compilazione, consentendo al compilatore di usare il loro valore direttamente invece di rilasciare codice per leggere dalla variabile ecc

+3

+1 per dare più soluzioni. –

+0

ringrazio molto, ma ora ho un nuovo errore, io continuo a ricevere 'fullSpace.exe': Loaded 'C: \ Windows \ SysWOW64 \ dwmapi.dll', Impossibile trovare o aprire il file PDB per centinaia di file .dll, può mi aiuti ancora? – Ted

+0

@ user2189708 Questa è una domanda diversa. Fai prima una ricerca. –

5

Non si può mettere definizioni di variabili nei file di intestazione, in quanto questi saranno quindi una parte di tutto il file sorgente in cui inserisci l'intestazione.

Il #pragma once è solo per proteggere da inclusioni multiple nello stesso file sorgente, non contro inclusioni multiple in più file sorgente.

Si potrebbe dichiarare le variabili come extern nel file di intestazione, e quindi definire loro in un singolo file di origine. Oppure è possibile dichiarare le variabili come const nel file di intestazione e quindi il compilatore e il linker lo gestiranno.

0
const int WIDTH = 1024; 
const int HEIGHT = 800; 
+1

Sì, questo è il problema, ma perché? –

+0

provare a cercare 'una regola di definizione' – AnatolyS

+0

corretto., Funziona., Grazie – Ted

Problemi correlati