Why are my two classes sharing variables? C++

Started by
24 comments, last by BHXSpecter 10 years ago

well I am trying to solve it. Heres what Im doing now. I scrapped the swordbeam and all projectiles from my game. Now im reimplementing the octorock class with better incapsulated code:


class OCTOROCK
{

private:
	SPRITE sprite;
public:

	//Constructor
	OCTOROCK()
	{
	}

	//Destructor
	~OCTOROCK()
	{
	}


	//Set the position of the octorock
	void setPosition(int x, int y)
	{
		sprite.x = x;
		sprite.y = y;
	}

	//Set the dimensions
	void setDimensions(int width, int height)
	{
		sprite.width = width;
		sprite.height = height;
	}

	//Set the frames
	void setFrames(int curframe, int maxframe, int framecount, int framedelay)
	{
		sprite.curframe = curframe;
		sprite.maxframe = maxframe;
		sprite.framecount = framecount;
		sprite.framedelay = framedelay;
	}

	//Set the speed of the octorock
	void setSpeed(int speed)
	{
		sprite.xspeed = speed;
		sprite.yspeed = speed;
	}

	//set the direction of the octorock
	void setDirection(int dir)
	{
		sprite.dir = dir;
	}

	//is it alive?
	void isAlive(int alive)
	{
		sprite.alive = alive;
	}

	//moves the octorock
	void moveOctorock()
	{
		if(sprite.dir == RIGHT)
		{
			sprite.x += sprite.xspeed;
			sprite.y += 0;
			sprite.curframe = 4;
		}
		else if(sprite.dir == LEFT)
		{
			sprite.x -= sprite.xspeed;
			sprite.y += 0;
			sprite.curframe = 6;
		}
		else if(sprite.dir == UP)
		{
			sprite.x += 0;
			sprite.y -= sprite.yspeed;
			sprite.curframe = 2;
		}
		else if(sprite.dir == DOWN)
		{
			sprite.x += 0;
			sprite.y += sprite.yspeed;
			sprite.curframe = 0;
		}
	}


	//Draw the octorock
	void drawOctorock()
	{
		al_draw_bitmap(octorock_images[sprite.curframe],
			           sprite.x - mapxoff, sprite.y - mapyoff, NULL);
	}
};
Advertisement

Your original code looked fine. It may not have even been the classes that was causing the problem. Without seeing the full code, as Vortez pointed out, it may have just been an issue with variables outside the classes. Depending on what you passed the objects, you may have inadvertently been giving the same data to both so it was doing the glitch of drawing the enemy at the player's location and moving it forward.

You know, your problem can be somewhere else.

I noticed that on all classes the first variables are int x, y.

This can create really weird behaviours in case of bad pointer management, but one that can easily be mistaken for something else, since the accesses to x and y will all seem to be valid!

For the code snippet:
http://codepad.org/MNao3Q2P

You really should take a look at this snippet to understand what I'm talking about!
The output is just under the code itself (you won't even need to compile it).


So, before going around doing architecture breaking changes, make this (extremely simple) test:
class OCTOROCK
{
private:

    int width, height; //SWAP
    int x, y; // SWAP
    int curframe, maxframe;
    int framecount, framedelay;
    int dir;
    int alive;
    int pathx1, pathx2;
    int pathy1, pathy2;
    int speed;
If your monster's glitch changes (if it start to glitch differently), there you are! Bad pointer management is probably the culprit!
If you still can't find the problem, put a break point in the code that fires the projectile and step through the code one line at a time keeping the variables in a watch window. I agree that it's either bad pointer management or you put an assignment somewhere and didn't notice.

Learn all about my current projects and watch some of the game development videos that I've made.

Squared Programming Home

New Personal Journal

Swapping the variables is a good idea to get a better idea if the variables are overwritten "by name" or "by address".

Anyway, if you already know which variable changes, any decent debugger lets you set a breakpoint to when this variable changes and have a condition for the new value. It's a lot less painful than stepping through code that might run dozens of frames before the bug happens while manually staring at the watch window.

f@dzhttp://festini.device-zero.de

I tried finding the bug and just couldn't, also I wasn't happy with the overall implementation of it, so I decided to nuke it and code it much cleaner this time.

For those of you still wondering, heres what the new octorock class looks like now:


class OCTOROCK
{

public:

	SPRITE sprite;
	int pathx1, pathx2;
	int pathy1, pathy2;
	bool isExplode;

	//Constructor
	OCTOROCK()
	{
	}

	//Destructor
	~OCTOROCK()
	{
	}

	//moves the octorock
	void moveOctorock()
	{
		if(sprite.alive)
		{
			//Make sure the octorock does not leave its specified path
			if(sprite.x > pathx2)
			{
				sprite.dir = LEFT;
				sprite.curframe = 6;
			}
			else if(sprite.x < pathx1)
			{
				sprite.dir = RIGHT;
				sprite.curframe = 4;
			}
			if(sprite.y > pathy2)
			{
				sprite.dir = UP;
				sprite.curframe = 2;
			}
			else if(sprite.y < pathy1)
			{
				sprite.dir = DOWN;
				sprite.curframe = 0;
			}


			//Move the octorock according to its direction.
			if(sprite.dir == RIGHT)
			{
				sprite.x += sprite.xspeed;
				sprite.y += 0;
				//sprite.curframe = 4;
			}
			else if(sprite.dir == LEFT)
			{
				sprite.x -= sprite.xspeed;
				sprite.y += 0;
				//sprite.curframe = 6;
			}
			else if(sprite.dir == UP)
			{
				sprite.x += 0;
				sprite.y -= sprite.yspeed;
				//sprite.curframe = 2;
			}
			else if(sprite.dir == DOWN)
			{
				sprite.x += 0;
				sprite.y += sprite.yspeed;
				//sprite.curframe = 0;
			}
		}
	}

	//Detects if the player collides with the octorock
	void detectCollision(SPRITE *spr)
	{
		//Variables to record everyones bound box dimensions
		int playerx, playery, playerw, playerh;
		int top, bottom, left, right;

		int heartcount = 0;
		int heartdelay = 200;

		if(sprite.alive)
		{
			//record players box
			playerx = spr->x; 
			playery = spr->y;
			playerw = playerx + spr->width;
			playerh = playery + spr->height;
			

			//record the octorocks box
			top = sprite.y;
			left = sprite.x;
			bottom = top + sprite.height;
			right = left + sprite.width;

			//Check if they collide
			if(accurateInside(playerx, playery, playerw, playerh, left, top, right, bottom))
			{

				//If the players attacking frame is active during collision
				if(spr->curframe == 8 ||
                   spr->curframe == 9 ||
				   spr->curframe == 10 ||
				   spr->curframe == 11)
				{
					//Kill the octorock
					sprite.alive = 0;
					cout << "octorock killed" << endl;
					al_play_sample_instance(killInstance);
					isExplode = true;
					
				}
				else
				{
					//flinch a bit and lose 1 heart
					if(++heartcount > heartdelay)
					{
						hearts -= 1;
						heartcount = 0;
						//al_play_sample_instance(hurtInstance);
					}
					
					if(spr->dir == RIGHT)
					{
						spr->x -= 15;//8;
						hearts -= 1;
						al_play_sample_instance(hurtInstance);
					}
					else if(spr->dir == LEFT)
					{
						spr->x += 15;//8;
						hearts -= 1;
						al_play_sample_instance(hurtInstance);
					}
					else if(spr->dir == DOWN)
					{
						spr->y -= 15;//8;
						hearts -= 1;
						al_play_sample_instance(hurtInstance);
					}
					else if(spr->dir == UP)
					{
						spr->y += 15;//8;
						hearts -= 1;
						al_play_sample_instance(hurtInstance);
					}
					
					

					
				}
			}
		}
	}


	//Draw the octorock
	void drawOctorock()
	{
		if(sprite.alive)
		{
			if(sprite.dir == RIGHT)
			{
				if(++sprite.framecount > sprite.framedelay)
				{
					sprite.framecount = 0;

					if(++sprite.curframe > 5)
					{
						sprite.curframe = 4;
					}
				}
			}

			if(sprite.dir == LEFT)
			{
				if(++sprite.framecount > sprite.framedelay)
				{
					sprite.framecount = 0;

					if(++sprite.curframe > 7)
					{
						sprite.curframe = 6;
					}
				}
			}

			if(sprite.dir == UP)
			{
				if(++sprite.framecount > sprite.framedelay)
				{
					sprite.framecount = 0;

					if(++sprite.curframe > 3)
					{
						sprite.curframe = 2;
					}
				}
			}

			if(sprite.dir == DOWN)
			{
				if(++sprite.framecount > sprite.framedelay)
				{
					sprite.framecount = 0;

					if(++sprite.curframe > 1)
					{
						sprite.curframe = 0;
					}
				}
			}

			//Finally draw the octorock
			al_draw_bitmap(octorock_images[sprite.curframe],
						   sprite.x - mapxoff, sprite.y - mapyoff, NULL);
		}
	}
	
};

It works perfectly, I have multiple enemies on the map and no problem. Collision is a bit amateurish but so am I tongue.png

If anybody cares to see:

Just curious. You set a lot of class variables as private. Any reason why you do that?

wat

"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
I think i found out the bug today guys. Basically what happened was that i declared an array of octorocks:
OCTOROCK octorocks[4];

But what i did wrong was that initialized it like this
octorock[1].x =......
octorock[2].x =......
octorock[3].x =......
octorock[4].x =......

What i did wrong is that i didnt access octorock[0] and did a memory violation by going out of bounds in tbe array with octorock[4].

Just curious. You set a lot of class variables as private. Any reason why you do that?

wat

In a simple answer, data hiding. It is usually common practice to make class members (variables) private and only allow access by way of constructors(mainly for initializing the class object) and class methods (functions).

I think i found out the bug today guys.

I'm glad to hear you may have found it. It is looking good so far, IMO.

This topic is closed to new replies.

Advertisement