|
multiple definition of `_currentLevel' |
AmnesiA
Member #15,195
June 2013
|
I am still working on my first game and I created a globals.h file that keeps all of the globals for the game. This has worked flawlessly for all of my constants but now I tried to add a variable (int currentLevel) and now I get an error in every file that includes "globals.h" that looks like this: obj\Debug\sprite.o:sprite.cpp:(.data+0x0): multiple definition of `_currentLevel' I don't know why this is causing problems for a variable but not for constants. globals.h 1#ifndef GLOBALS_H
2#define GLOBALS_H
3
4const int DISPLAY_W = 640;
5const int DISPLAY_H = 640;
6const int FPS = 60;
7const double PI = 3.14159265359;
8
9enum MYKEYS{
10 UP, DOWN, LEFT, RIGHT
11};
12enum ROOMS{
13 RM_LOAD, RM_MENU, RM_GAME, RM_CREDITS
14};
15enum BG_TYPES{
16 BG_TILED, BG_STRETCH, BG_CENTER
17};
18
19int currentLevel = RM_GAME;
20
21#endif //GLOBALS_H
main.cpp 1#include<stdio.h>
2#include<allegro5/allegro.h>
3#include<allegro5/allegro_image.h>
4#include<allegro5/allegro_primitives.h>
5#include<allegro5/allegro_font.h>
6#include<allegro5/allegro_ttf.h>
7#include<allegro5/allegro_audio.h>
8#include<allegro5/allegro_acodec.h>
9
10#include "globals.h"
11#include "sprite_library.h"
12
13ALLEGRO_DISPLAY* display;
14ALLEGRO_EVENT_QUEUE* eventQueue;
15ALLEGRO_TIMER* timer;
16
17SPRITE_LIBRARY spriteLib;
18//Create OBJECT_LIBRARY > OBJECT
19//Create ROOM > BG_CTRL
20
21extern const int DISPLAY_W;
22extern const int DISPLAY_H;
23extern const int FPS;
24
25extern int currentLevel;
26
27bool key[4];
28bool done;
29
30void shutdown(){
31 if(timer)
32 al_destroy_timer(timer);
33 if(display)
34 al_destroy_display(display);
35 if(eventQueue)
36 al_destroy_event_queue(eventQueue);
37}
38
39void abort_game( const char* message){
40 printf("%s \n", message);
41 shutdown();
42 exit(1);
43}
44
45void init(){
46 //Standard Allegro initialization
47 if(!al_init())
48 abort_game( "Failed to initialize Allegro!");
49 if(!al_init_image_addon())
50 abort_game( "Failed to initialize Image Addon!");
51 if(!al_install_keyboard())
52 abort_game( "Failed to access keyboard!");
53 for( int i = 0; i < 4; ++i)
54 key[i] = false;
55 timer = al_create_timer(1.0 / 60);
56 if(!timer)
57 abort_game( "Failed to create timer!");
58 al_set_new_display_flags(ALLEGRO_WINDOWED);
59 display = al_create_display( DISPLAY_W, DISPLAY_H);
60 if(!display)
61 abort_game( "Failed to create display!");
62 eventQueue = al_create_event_queue();
63 if(!eventQueue)
64 abort_game( "Failed to create Event Queue!");
65 al_register_event_source( eventQueue, al_get_keyboard_event_source());
66 al_register_event_source( eventQueue, al_get_timer_event_source(timer));
67 al_register_event_source( eventQueue, al_get_display_event_source(display));
68
69 //Object initialization
70 spriteLib.init();
71
72 //Define variables
73 done = false;
74}
75
76void game_loop(){
77 //Use rooms for game loop, pass which keys are being pressed
78 //while(!done){
79 //get input
80 //handle anything like escaping out of the game, pausing, etc
81 //ROOM[currentLevel]::step(key[]);
82 //ROOM[currentLevel]::draw();
83 //}
84}
85
86int main( int argc, char** argv){
87 init();
88 game_loop();
89 shutdown();
90
91 return 0;
92}
And then just for reference: 1#ifndef SPRITE_H
2#define SPRITE_H
3
4#include<vector>
5#include<allegro5/allegro.h>
6#include<allegro5/allegro_image.h>
7#include<allegro5/allegro_primitives.h>
8#include "globals.h"
9
10using std::vector;
11
12class SPRITE{
13
14public:
15 SPRITE();
16 ~SPRITE();
17
18 SPRITE& operator=( SPRITE &rhs);
19
20 int load_from_file( const char* file_name, int sx, int sy, int sw, int sh,
21 int image_count, bool visible = true, int speed = 1, int offset = 1
22 );
23 int load_from_bitmap( ALLEGRO_BITMAP* temp_bitmap, int sx, int sy, int sw, int sh,
24 int image_count, bool visible = true, int speed = 1, int offset = 1
25 );
26 void set_image_index( int image_index);
27 void set_speed( int speed);
28 void set_visibility( bool visibile);
29 int get_frame();
30 int get_image_count();
31 int get_image_width();
32 int get_image_height();
33 int get_current_image();
34 int get_speed();
35 bool get_visibility();
36 vector<ALLEGRO_BITMAP*> get_image_index();
37
38 void step();
39 void draw( int x, int y);
40
41protected:
42 int errorSprite();
43 ALLEGRO_BITMAP* errorBitmap();
44
45 vector<ALLEGRO_BITMAP*> imageIndex;
46 bool isVisible;
47 int imageCount;
48 int IMAGE_WIDTH, IMAGE_HEIGHT;
49 ALLEGRO_COLOR alphaColor;
50 int frame, spf; //steps per frame
51 int stepCount;
52
53};
54
55#endif //SPRITE_H
sprite.cpp 1#include "sprite.h"
2
3SPRITE::SPRITE(){}
4SPRITE::~SPRITE(){}
5
6SPRITE& SPRITE::operator=( SPRITE &rhs){ //Copy all elements from right hand to left hand
7 imageIndex = rhs.get_image_index();
8 isVisible = rhs.get_visibility();
9 imageCount = rhs.get_image_count();
10 IMAGE_WIDTH = rhs.get_image_width();
11 IMAGE_HEIGHT = rhs.get_image_height();
12 frame = rhs.get_frame();
13 spf = rhs.get_speed();
14
15 return *this;
16}
17
18int SPRITE::load_from_file( const char* file_name, int sx, int sy, int sw, int sh,
19 int image_count, bool visible, int speed, int offset
20 ){ //load specific sprite from file
21 ALLEGRO_BITMAP* targetBitmap = al_get_target_bitmap();
22 //Set variables
23 imageCount = image_count;
24 IMAGE_WIDTH = sw;
25 IMAGE_HEIGHT = sh;
26 isVisible = visible;
27 spf = speed;
28 ALLEGRO_BITMAP* tempBitmap = al_load_bitmap( file_name);
29 if(!tempBitmap){ //if it didn't load, try to create an error sprite
30 if( !errorSprite())
31 return -1;
32 }else{
33 //Load series of images into imageIndex
34 al_convert_mask_to_alpha( tempBitmap, al_get_pixel( tempBitmap, sx, sy)); //set top left pixel as transparent color
35 for( int i = 0; i < imageCount; ++i){
36 imageIndex.push_back( al_create_bitmap( IMAGE_WIDTH, IMAGE_HEIGHT));
37 if(!imageIndex[i]){ //if the bitmap couldn't be created, try to create a missing image bitmap
38 imageIndex[i] = errorBitmap();
39 if(!imageIndex[i]) //If that still can't be craeted, create an error
40 return -1;
41 }
42 al_set_target_bitmap(imageIndex[i]);
43 al_draw_bitmap_region( tempBitmap,
44 sx + (IMAGE_WIDTH + offset) * i, sy,
45 IMAGE_WIDTH, IMAGE_HEIGHT, 0, 0, 0
46 );
47 }
48 }
49 al_set_target_bitmap(targetBitmap);
50 frame = 0;
51 stepCount = 0;
52 return 1;
53}
54
55int SPRITE::load_from_bitmap( ALLEGRO_BITMAP* temp_bitmap, int sx, int sy, int sw, int sh,
56 int image_count, bool visible, int speed, int offset
57 ){
58 ALLEGRO_BITMAP* targetBitmap = al_get_target_bitmap();
59 imageCount = image_count;
60 IMAGE_WIDTH = sw;
61 IMAGE_HEIGHT = sh;
62 isVisible = visible;
63 spf = speed;
64 al_convert_mask_to_alpha( temp_bitmap, al_get_pixel( temp_bitmap, sx, sy));
65 for( int i = 0; i < imageCount; ++i){
66 imageIndex.push_back( al_create_bitmap( IMAGE_WIDTH, IMAGE_HEIGHT));
67 if(!imageIndex[i]){
68 imageIndex[i] = errorBitmap();
69 if(!imageIndex[i])
70 return -1;
71 }
72 al_set_target_bitmap(imageIndex[i]);
73 al_draw_bitmap_region( temp_bitmap,
74 sx + (IMAGE_WIDTH + offset) * i, sy,
75 IMAGE_WIDTH, IMAGE_HEIGHT, 0, 0, 0
76 );
77 }
78 al_set_target_bitmap(targetBitmap);
79 frame = 0;
80 stepCount = 0;
81 return 1;
82}
83
84void SPRITE::set_image_index( int image_index){
85 frame = image_index;
86}
87
88void SPRITE::set_speed( int speed){
89 spf = speed;
90}
91
92void SPRITE::set_visibility( bool visible){
93 isVisible = visible;
94}
95
96int SPRITE::get_frame(){
97 return frame;
98}
99
100int SPRITE::get_image_count(){
101 return imageCount;
102}
103
104int SPRITE::get_image_width(){
105 return IMAGE_WIDTH;
106}
107
108int SPRITE::get_image_height(){
109 return IMAGE_HEIGHT;
110}
111
112int SPRITE::get_current_image(){
113 return frame;
114}
115
116int SPRITE::get_speed(){
117 return spf;
118}
119
120bool SPRITE::get_visibility(){
121 return isVisible;
122}
123
124vector<ALLEGRO_BITMAP*> SPRITE::get_image_index(){
125 return imageIndex;
126}
127
128void SPRITE::step(){
129 if( ++stepCount >= spf){
130 stepCount = 0;
131 if( ++frame >= imageCount){
132 frame = 0;
133 }
134 }
135}
136
137void SPRITE::draw( int x, int y){
138 al_draw_bitmap( imageIndex[frame], x, y, 0);
139}
140
141int SPRITE::errorSprite(){
142 ALLEGRO_BITMAP* targetBitmap = al_get_target_bitmap();
143 for( int i = 0; i < imageCount; ++i){
144 imageIndex.push_back(errorBitmap());
145 if(!imageIndex[i])
146 return -1;
147 }
148 al_set_target_bitmap( targetBitmap);
149 return 1;
150}
151
152ALLEGRO_BITMAP* SPRITE::errorBitmap(){
153 ALLEGRO_BITMAP* targetBitmap = al_get_target_bitmap();
154 ALLEGRO_BITMAP* tempBitmap = al_create_bitmap( IMAGE_WIDTH, IMAGE_HEIGHT);
155 if(!tempBitmap)
156 return tempBitmap;
157 al_set_target_bitmap(tempBitmap);
158 al_clear_to_color( al_map_rgb(0,0,160));
159 al_draw_line( 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, al_map_rgb(255,0,0), 1);
160 al_draw_line( IMAGE_WIDTH, 0, 0, IMAGE_HEIGHT, al_map_rgb(255,0,0), 1);
161 al_set_target_bitmap( targetBitmap);
162 return tempBitmap;
163}
My game loop does nothing yet, obviously, I'm just using the comments to brainstorm how I'm going to implement different parts. EDIT: I forgot to mention, doing a search off all of the project files for "currentLevel" yields: File Line Text globals.h 19 int currentLevel = RM_GAME; main.cpp 25 extern int currentLevel; main.cpp 81 //ROOM[currentLevel]::step(key[]); main.cpp 82 //ROOM[currentLevel]::draw(); Which shows that the only time the compiler would read "currentLevel is on line 19 of globals.h and line 25 of main.cpp which tells me that the problem must lie in linking the globals.h file BUT it shouldn't be an issue (if I understand this correctly) because of the #ifndef at the start. ======================= |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your problem is with the globals.h file. Objects that need to be accessible to other modules should be declared in a header preceeded by the keyword 'extern'. globals.hpp #ifndef HEADER #define HEADER extern int global_integer; #endif // #ifndef HEADER After that, you define them (ONCE) in a source module. globals.cpp #include "globals.hpp" int global_integer = 0; The reason you are getting that error is that each of your source file included code that defines an integer named current_level. But the compiler doesn't know or care about that. The linker does though, and when it tries to link everything it sees that more than one module defines current_level. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
AmnesiA
Member #15,195
June 2013
|
Thank you, I changed the declaration in globals.h to extern int currentLevel; and declared int currentLevel; in main.cpp and defined it in the init() function of main.cpp and it works beautifully. Thanks again! ======================= |
|