致命错误LNK1169:在游戏编程中发现一个或多个乘法定义的符号 [英] fatal error LNK1169: one or more multiply defined symbols found in game programming

查看:50
本文介绍了致命错误LNK1169:在游戏编程中发现一个或多个乘法定义的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在训练如何在c ++中使用面向对象的编程,但是我不断收到此错误:

I've been training to use object orientated programming in c++ but I keep getting this error:

1>main.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>main.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@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

但是,对我来说,似乎完整的代码编写正确,并且两个int仅在Global标头中提及,并且所有对象似乎都在正确继承.但是,就像我刚才说的那样,我是OOP的初学者,所以我真的需要一个意见:值得一提的是,我正在使用Allegro 5创建侧射手.

However to me, it seems that the entire code is written properly and the two ints are only mentioned in the Global header and all objects seem to be inheriting properly. However, like I just said, I'm a beginner in OOP so I really need an opinion : It is also worth mentioning that I am using allegro 5 to create a side shooter.

这是代码:

(主):

#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):

(Globals.h):

#pragma once

int WIDTH = 1024;
int HEIGHT = 800;

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

(GameObject.h):

(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):

(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):

(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):

(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--;

    }

推荐答案

两个 int 变量是在头文件中定义的.这意味着每个包含标头的源文件都将包含其定义(标头包含的内容纯粹是文本的).当然会导致多个定义错误.

The two int variables are defined in the header file. This means that every source file which includes the header will contain their definition (header inclusion is purely textual). The of course leads to multiple definition errors.

您有几种方法可以解决此问题.

You have several options to fix this.

  1. 使变量 static ( static int WIDTH = 1024; ).它们仍将存在于每个源文件中,但是它们的定义在源文件之外将不可见.

  1. Make the variables static (static int WIDTH = 1024;). They will still exist in each source file, but their definitions will not be visible outside of the source file.

使用 extern ( extern int WIDTH; )将其定义转换为声明,并将定义放入一个源文件中: int WIDTH = 1024; .

Turn their definitions into declarations by using extern (extern int WIDTH;) and put the definition into one source file: int WIDTH = 1024;.

可能是最好的选择:使变量 const ( const int WIDTH = 1024; ).这使它们隐式地为 static ,并且还允许将它们用作编译时常量,从而允许编译器直接使用其值,而不是发出代码从变量等中读取它.

Probably the best option: make the variables const (const int WIDTH = 1024;). This makes them static implicitly, and also allows them to be used as compile-time constants, allowing the compiler to use their value directly instead of issuing code to read it from the variable etc.

这篇关于致命错误LNK1169:在游戏编程中发现一个或多个乘法定义的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆