Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Class Problem

Credits go to gnolam, Jonatan Hedborg, and Matthew Dalrymple for helping out!
This thread is locked; no one can reply to it. rss feed Print
Class Problem
moon_rabbits
Member #8,469
March 2007
avatar

I am making a game similar to missile defence so that I can become used to Allegro and whatnot.

I wrote something up that generates a background and saves it to a bitmap, everything was going good until I added a class in a separate .cpp file.

1/********************
2 * Tank Class Header*
3 ********************/
4
5#ifndef _TANK_H
6#define _TANK_H
7 
8#define MAX_BULLETS 10
9#define MOVE_LEFT 0
10#define MOVE_RIGHT 1
11 
12#define TANK_W 100
13#define TANK_H 35
14 
15#define CANNON_W 25
16#define CANNON_H 50
17 
18class CTank
19{
20public:
21 CTank();
22 ~CTank();
23
24 int x, y; // x and y coordinate of the player
25 int health; // health of the player
26 int reload; // reload time of the player
27
28 int score;
29
30 BITMAP *tank, *cannon; //bitmaps to hold the tank and cannon
31
32 void MoveTank(int dir);
33 void FireBullet();
34};
35 
36#endif

1/********************
2 * Tank Source File *
3 ********************/
4
5#include <allegro.h>
6#include "tank.h"
7 
8CTank::CTank()
9/* Sets up tank object */
10{
11 x = (SCREEN_W/2); // init player
12 y = (SCREEN_H/4);
13 health = 100;
14 reload = 0;
15 score = 0;
16 tank = create_bitmap(TANK_W, TANK_H);
17 cannon = create_bitmap(CANNON_W, CANNON_H);
18
19 rectfill(tank, 10, 0, (TANK_W-10), TANK_H, makecol(45, 200, 60));
20 rect(tank, 10, 0, (TANK_W-10), TANK_H, makecol(60, 230, 70));
21}
22//--------------------------------------------
23 
24CTank::~CTank()
25/* Deletes tank bmps */
26{
27 destroy_bitmap(tank);
28 destroy_bitmap(cannon);
29}
30//--------------------------------------------
31 
32void CTank::MoveTank(int dir)
33/* Moves tank */
34{
35 if((dir == MOVE_LEFT) && (x < 0))
36 x -= 1;
37 else if((dir == MOVE_RIGHT) && ((x+TANK_W) > (SCREEN_W))
38 x += 1;
39
40 return;
41}
42//--------------------------------------------
43 
44void CTank::FireBullet()
45{}
46//--------------------------------------------

That's the tank class header and .cpp file. The program compiles fine, but this error is given when it runs:

The instruction at "0x10020efc" referenced memory at "0x00000038". The memory could not be "read".

Click on OK to terminate the program
Click on CANCEL to debug the problem.

Help, please?

Jonatan Hedborg
Member #4,886
July 2004
avatar

How do you use the class? Make sure you don't create it until you have initiated allegro. Post some more code.

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

moon_rabbits
Member #8,469
March 2007
avatar

Here is the only other code I have written so far, the main.cpp file:

1/******************************
2 * Tank Defense v.0.1 *
3 * March 25 2007 *
4 * Kelly Crawford *
5 ******************************/
6
7#include <allegro.h>
8#include <time.h>
9#include "tank.h"
10 
11#define WINDOW_W 640
12#define WINDOW_H 480
13 
14#define MAX_CLOUDS 14
15#define MIN_CLOUDS 7
16 
17int SetUp()
18/* Initializes allegro and screen */
19{
20 allegro_init();
21
22 install_keyboard();
23 install_mouse();
24
25 set_color_depth(16);
26
27 if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, WINDOW_W, WINDOW_H, 0, 0) != 0)
28 return 1;
29
30 srand(time(0));
31
32 return 0;
33}
34//--------------------------------------------
35 
36void cloud_line(BITMAP *bmp, int x, int y, int color)
37/* Function called by DoLine() */
38{
39 putpixel(bmp, x, y, color);
40
41 return;
42}
43//--------------------------------------------
44 
45void MakeCloud(BITMAP *bmp)
46/* Draws a cloud to bmp */
47{
48 int height = 1 + (rand()%50); // height of cloud
49 int width = 100 + (rand()%50); // general width of cloud
50
51 int x1 = (-30) + rand()%(SCREEN_W-30);
52 int x2 = x1 + width;
53 int y = 10 + rand()%(SCREEN_H-100); // cloud coordinates
54
55 int col = makecol(255,255,255); // cloud color information
56
57 for(int i = 0; i < height; i++) // loops until entire cloud is drawn
58 {
59 do_line(bmp, x1, y, x2, y, col, *cloud_line); // draw line of cloud
60 y += 1;
61
62 if(i < (height/2)){
63 x1 -= 3 + rand()%5;
64 x2 += 3 + rand()%5;}
65 else{
66 x1 += 3 + rand()%5;
67 x2 -= 3 + rand()%5;}
68 }
69
70 return;
71}
72//--------------------------------------------
73 
74BITMAP* GenerateSky(BITMAP *bmp)
75/* Generates a sky on bitmap pointed
76 to by bmp */
77{
78 int r = 140, g = 150, b = 225;
79 int col = makecol(r, g, b);
80
81
82 floodfill(bmp, SCREEN_W/2, SCREEN_H/2, col); // fill screen w/ blue
83
84 int clouds = (rand()%(MAX_CLOUDS-MIN_CLOUDS) + MIN_CLOUDS);
85
86 for(int c = 0; c < clouds; c++)
87 MakeCloud(bmp);
88
89 return bmp;
90}
91//--------------------------------------------
92 
93int main()
94{
95 CTank player;
96
97 if(SetUp() != 0) return 1; // setup + error checking for allegro
98
99 BITMAP *bg_sky = create_bitmap(SCREEN_W, SCREEN_H); // create sky bitmap
100 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H); // create double buffer
101
102 bg_sky = GenerateSky(bg_sky); // colour sky bitmap
103
104 while(!key[KEY_ESC]){
105
106 blit(bg_sky, buffer, 0, 0, 0, 0, bg_sky->w, bg_sky->h);
107
108 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
109 };
110
111 destroy_bitmap(bg_sky);
112 destroy_bitmap(buffer);
113 
114 return(0);
115}END_OF_MAIN();

EDIT: The CTank class is used in the main() function only.

Matthew Dalrymple
Member #7,922
October 2006
avatar

There is no semi-colon after END_OF_MAIN()

=-----===-----===-----=
I like signatures that only the signer would understand. Inside jokes are always the best, because they exclude everyone else.

moon_rabbits
Member #8,469
March 2007
avatar

I removed the semi-colon, the problem persists.

gnolam
Member #2,030
March 2002
avatar

Jonatan nailed it. The class's constructor (and thus create_bitmap() etc) is called before Allegro is initialized.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Matthew Dalrymple
Member #7,922
October 2006
avatar

CTank is declared before Allegro is initialized. The constructor of CTank uses allegro definitions.

edit:
Darn I was ...
http://www.mmmchicago.com/Transparent%20Red%20Beet%20by%20dick.gif

=-----===-----===-----=
I like signatures that only the signer would understand. Inside jokes are always the best, because they exclude everyone else.

moon_rabbits
Member #8,469
March 2007
avatar

Ah! It all makes sense now. Everything is working now, thanks everyone~

bamccaig
Member #7,536
July 2006
avatar

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

/********************
* Tank Class Header*
********************/

#ifndef _TANK_H
#define _TANK_H

An underscore followed by an uppercase letter is undefined behavior. Adopt a new naming scheme.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

An underscore followed by an uppercase letter is undefined behavior.

Actually, symbols and macros starting with an underscore are reserved for compiler/system use.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Dustin Dettmer
Member #3,935
October 2003
avatar

But the resulting behavior is undefined :D

Thomas Fjellstrom
Member #476
June 2000
avatar

Its perfectly defined. :) Expect problems when the symbol you chose happens to be used in the compiler or system headers sometime in the future.

edit:

I used to use _FILENAMEHERE_H_

I now use FileNameHere_H_GUARD

:)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

An underscore followed by an uppercase letter is undefined behavior.

No, it's definitely not. An identifier in C can start with any letter (upper- or lowercase), or an underscore, and after that, it can contain letters, underscores, and numeric digits.

Quote:

Actually, symbols and macros starting with an underscore are reserved for compiler/system use.

Double underscores. Single underscores should be fine.

Quote:

But the resulting behavior is undefined

Not at all.
If you happen to use a compiler-defined identifier for your own #defines, you will either prevent certain code from being read by the compiler, as in this example:

#ifndef __FILE__
#define __FILE__

// anything here will be ignored, because __FILE__ is always defined

#endif

...or it will produce compiler errors due to incompatible definitions for the identifier.

Neither of these constitute undefined behaviour.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Onewing
Member #6,152
August 2005
avatar

Quote:

I used to use _FILENAMEHERE_H_

I now use FileNameHere_H_GUARD

Interesting... I've been using the top method since the beginning as that was the way I was taught. Never seen a problem...

------------
Solo-Games.org | My Tech Blog: The Digital Helm

bamccaig
Member #7,536
July 2006
avatar

I could be wrong, but I assumed it wasn't a compiler rule, but a good practice. Like root declaring environment variables in all CAPS (or was it the other way around) in a *nix environment. I think it's only a problem if that identifier is already defined, such as _FILE_.

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

Double underscores. Single underscores should be fine.

Single underscores followed by an uppercase letter are reserved for compiler usage.

Quote:

Its perfectly defined. :) Expect problems when the symbol you chose happens to be used in the compiler or system headers sometime in the future.

Technically the C++ spec does not define if you will collide or not, and when that collision occurs the results are compiler specific and therefore undefined.

I agree with you :), I was just saying undefined to make my sentence more english and less codelish.

Go to: