Pointer Problem - Values are changing when I create a new SDL_EVENT

Started by
3 comments, last by Kaldris 14 years, 4 months ago
Hello gamedev :) I'm new to C++ and Game Developing and I got a problem I can't solve on my own. (I doesn't even know why this is happening) I got a _currentFigure in my class Game that holds the current Figure which is moving in my Gamefield.
Figure*	_currentFigure;
This Figure has 2 memberfields:
Block**	_blocks; //Usually 4 Blocks
Block* _middleBlock;
And a Block has the Coordinates, Color, and a bool:
int _x;
int _y;
Color _color;
bool _isMoving;
so far so good, but when the gameloop enters the method processEvents(), after this line of code
SDL_Event* act = new SDL_Event;
the _currentFigure._blocks's memberfield are no longer 50, or 100 or whatever, but instead they are a very big value(looks like they changed to a address or something like that). For me this makes no sense because creating a new SDL_Event doesn't change the _currentFigure._blocks, but in fact it does. So I hope you can help me with this problem. If you need more description, just tell me, but I hope i explained it well. regards, Kaldris
Advertisement
Can you post some code? (Ideally a minimal working example that demonstrates the behavior.) Be sure to use [ source ] tags to preserve formatting.

Meanwhile, I'm guessing the problem is related to your use of pointers. Do you by any chance have a background in some other language, such as C# or Java? If so, note that the new operator plays a different role in C++ than it does in those languages. A good rule of thumb in C++ is, don't create an object dynamically (e.g. by using new) unless there's a specific reason for doing so. Maybe I'm just suffering from a lack of imagination, but I can't imagine why you would ever need to create an object of type SDL_Event using new. In other words, in C++ we would usually write:
SDL_Event event;
Not:
SDL_Event* event = new SDL_Event;
Misuse of pointers in C++ can cause all kinds of problems, including the kind you're describing. However, to tell you specifically what's wrong, we'd probably have to see some code.
Thank you for your answer.
Bevor I started with C++ and Game Programming I learned C# and Java (also a bit of plain C).
Thanks for the hint with new, I will consider it in future projects.
The SDL_Event* act was a kind of desperate try to solve the problem ;)

Here is some Code where I tried to reproduce the error, but failed:

Block* tempGameField[10][20];	for (int i = 0; i < 10; i++)		for (int j = 0; j < 20; j++)			tempGameField[j] = new Block(i, j);	Block* blocks[4];	blocks[0] = tempGameField[0][0];	blocks[1] = tempGameField[1][0];	blocks[2] = tempGameField[0][1];	blocks[3] = tempGameField[1][1];	Figure* figure = new Figure(blocks, GREEN, blocks[1]);	SDL_Event act;	SDL_PollEvent(&act);


It is the same scenario like in my real gamecode, but the figure._blocks remain unchanged.
I cant reproduce the error so I just post the whole code (the error occures in game.cpp in the method processEvents):

Block.hpp:
#ifndef BLOCK_HPP#define BLOCK_HPP#define BLOCKSIZE	25enum Color{	NONE, BLUE, YELLOW, RED, GREEN, ORANGE, TEAL, PINK	};class Block{	public:					Block(int x, int y);			int		GetX();			int		GetY();			Color	GetColor();			void	SetX(int x);			void	SetY(int y);			bool	IsMoving();			void	SetMoving(bool isMoving);			void	SetColor(Color color);			void	MoveDown();			void	MoveLeft();			void	MoveRight();	private:		int			_x;		int			_y;		Color		_color;		bool		_isMoving;};#endif


Block.cpp:
#include "Block.hpp"Block::Block(int x, int y){	_x = x;	_y = y;	_color = NONE;	_isMoving = false;}int Block::GetX(){	return _x;}int Block::GetY(){	return _y;}bool Block::IsMoving(){	return _isMoving;}void Block::SetMoving(bool isMoving){	_isMoving = isMoving;}void Block::SetColor(Color color){	_color = color;}void Block::MoveRight(){	_x += BLOCKSIZE;}void Block::MoveLeft(){	_x -= BLOCKSIZE;}void Block::MoveDown(){	_y += BLOCKSIZE;}void Block::SetX(int x){	_x = x;}void Block::SetY(int y){	_y = y;}Color Block::GetColor(){	return _color;}


Figure.hpp:
#include "Block.hpp"#ifndef FIGURE_HPP#define FIGURE_HPP#define BLOCKCOUNT	4class Figure{	public:				Figure(Block* blocks[BLOCKCOUNT], Color color, Block* MiddleBlock);		void	MoveDown();		void	MoveLeft();		void	MoveRight();		void	RotateCW();		void	Stop();		Block*	GetMiddleBlock();		Block**	GetBlocks();	private:		Block**	_blocks;		Block* _middleBlock;};#endif


Figure.cpp:
#include "Figure.hpp"Figure::Figure(Block* blocks[], Color color, Block* middleBlock){	_blocks = blocks;	_middleBlock = middleBlock;	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->SetColor(color);		_blocks->SetMoving(true);	}}void Figure::MoveDown(){	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->MoveDown();	}}void Figure::MoveRight(){	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->MoveRight();	}}void Figure::MoveLeft(){	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->MoveLeft();	}}void Figure::Stop(){	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->SetMoving(false);	}}void Figure::RotateCW(){	for (int i = 0; i < BLOCKCOUNT; i++)	{		_blocks->SetX(-1 * (_blocks->GetY() - _middleBlock->GetY()) + _middleBlock->GetY());		_blocks->SetY((_blocks->GetX() - _middleBlock->GetX()) + _middleBlock->GetY());	}}Block* Figure::GetMiddleBlock(){	return _middleBlock;}Block** Figure::GetBlocks(){	return _blocks;}


game.hpp:
#ifndef GAME_HPP#define GAME_HPP#include "Figure.hpp"#include "Block.hpp"#include "Sprite.hpp"#include <time.h>#include <iostream>#include <sstream>#include <cstdlib> class Game{	public:			Game		();		void Run		();		void Quit		();		void Reset		();	private:		void processEvents	();		void renderField	();		bool checkCollision	(bool checkSideBounds);		bool createNewFigure();		void checkForFullRow();		void swapRows(int first, int second);				Sprite* _spriteBackground;		Sprite* _spriteBlocks[8];		bool	_gameRunning;		Block*	_gameField[10][20];		Figure*	_currentFigure;};#endif


game.cpp:
#include "Game.hpp"Game::Game(){	for (int i = 0; i < 10; i++)		for (int j = 0; j < 20; j++)			_gameField[j] = 0;	_spriteBackground = new Sprite;	_spriteBackground->Load("BMPs/Background.bmp");	for (int i = 1; i < 8; i++)	{		stringstream ss; (stringstream::in, stringstream::out);		ss << "BMPs/Block";		ss << i;		ss << ".bmp";		_spriteBlocks = new Sprite();		_spriteBlocks->Load(ss.str());	}	_gameRunning = true;	Reset();}void Game::Quit(){	delete (_spriteBackground);	_spriteBackground = 0;	for (int i = 1; i < 8; i++)	{		delete (_spriteBlocks);		_spriteBlocks = 0;	} }void Game::Reset(){	for (int i = 0; i < 10; i++)	{		for (int j = 0; j < 20; j++)		{			if (_gameField[j] != 0)			{				delete (_gameField[j]);				_gameField[j] = 0;			}			_gameField[j] = new Block(i * 25, j * 25);		}	}	createNewFigure();}void Game::Run(){	while (_gameRunning)	{		SINGLETONINSTANCE(Framework)->Update();		SINGLETONINSTANCE(Framework)->Clear();		processEvents();				if (checkCollision(false))		{			_currentFigure->Stop();			delete (_currentFigure);			if (!createNewFigure())			{				break;			}			checkForFullRow();		} else		{			_currentFigure->MoveDown();		}		_spriteBackground->Render();		renderField();		SINGLETONINSTANCE(Framework)->Flip();	}}void Game::processEvents(){	SDL_Event act;	if (SDL_PollEvent(&act))	{		switch (act.type)		{			case SDL_QUIT:			{				_gameRunning = false;			} break;			case SDL_KEYDOWN:			{				switch (act.key.keysym.sym)				{					case (SDLK_ESCAPE):					{						_gameRunning = false;					} break;					case (SDLK_DOWN):					{						SINGLETONINSTANCE(Timer)->SetTickInterval(25);					} break;					case (SDLK_UP):					{						_currentFigure->RotateCW();					} break;					case (SDLK_RIGHT):					{						if(!checkCollision(true))						{							_currentFigure->MoveRight();						}					} break;					case (SDLK_LEFT):					{						if(!checkCollision(true))						{							_currentFigure->MoveLeft();						}					} break;				}			} break;			case SDL_KEYUP:			{				switch (act.key.keysym.sym)				{					case (SDLK_DOWN):					{						SINGLETONINSTANCE(Timer)->SetTickInterval(50);					} break;				}			} break;		}	}}void Game::renderField(){	for (int i = 0; i < 10; i++)		for (int j = 0; j < 20; j++)		{			_spriteBlocks[_gameField[j]->GetColor()]->SetPosition(static_cast<float>(_gameField[j]->GetX()),																	 static_cast<float>(_gameField[j]->GetY()));			_spriteBlocks[_gameField[j]->GetColor()]->Render();		}}void Game::checkForFullRow(){	bool rowFound = true;	int lastRow = 0;	int rowsDeleted = 0;	for (int i = 0; i < 20; i++)	{		for (int j = 0; j < 10; j++)		{			if (_gameField[j]->GetColor() == NONE && !(_gameField[j]->IsMoving()))			{				rowFound = false;				lastRow = i;				rowsDeleted++;				break;			}		}		if (rowFound)		{			for (int k = 0; k < 10; k++)			{				_gameField[k]->SetColor(NONE);			}			_spriteBackground->Render();			renderField();			SINGLETONINSTANCE(Framework)->Flip();		}	}	SDL_Delay(250);	for (int i = 0; i < rowsDeleted; i++)	{		swapRows(i, lastRow - i);	}	for (int i = 0; i < 19; i++)	{		swapRows(i, i + 1);	}	}void Game::swapRows(int first, int second){	for (int i = 0; i < 10; i++)	{		Block* temp = _gameField[first];		_gameField[first]->SetColor(_gameField[second]->GetColor());		_gameField[second]->SetColor(temp->GetColor());	}}bool Game::createNewFigure(){	srand((unsigned) time(0));	int random = (rand() % 7) + 1;	switch (random)	{		Block* blocks[4];		case 1:		{			if (_gameField[5][0]->GetColor() != NONE || _gameField[5][1]->GetColor() != NONE ||				_gameField[5][2]->GetColor() != NONE || _gameField[5][3]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[5][0];			blocks[1] = _gameField[5][1];			blocks[2] = _gameField[5][2]; 			blocks[3] = _gameField[5][3];			_currentFigure = new Figure(blocks, (Color)random, _gameField[5][1]);		} break;				case 2:		{			if (_gameField[4][2]->GetColor() != NONE || _gameField[5][1]->GetColor() != NONE ||				_gameField[5][2]->GetColor() != NONE || _gameField[5][0]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[5][0];			blocks[1] = _gameField[5][1];			blocks[2] = _gameField[5][2]; 			blocks[3] = _gameField[4][2];			_currentFigure = new Figure(blocks, (Color)random, _gameField[5][1]);		} break;		case 3:		{			if (_gameField[4][0]->GetColor() != NONE || _gameField[4][1]->GetColor() != NONE ||				_gameField[4][2]->GetColor() != NONE || _gameField[5][2]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[4][0];			blocks[1] = _gameField[4][1];			blocks[2] = _gameField[4][2]; 			blocks[3] = _gameField[5][2];			_currentFigure = new Figure(blocks, (Color)random, _gameField[4][1]);		} break;		case 4:		{			if (_gameField[4][0]->GetColor() != NONE || _gameField[4][1]->GetColor() != NONE ||				_gameField[5][0]->GetColor() != NONE || _gameField[5][1]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[4][0];			blocks[1] = _gameField[4][1];			blocks[2] = _gameField[5][0]; 			blocks[3] = _gameField[5][1];			_currentFigure = new Figure(blocks, (Color)random, _gameField[4][0]);		} break;		case 5:		{			if (_gameField[4][1]->GetColor() != NONE || _gameField[5][0]->GetColor() != NONE ||				_gameField[5][1]->GetColor() != NONE || _gameField[6][0]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[5][0];			blocks[1] = _gameField[4][1];			blocks[2] = _gameField[5][1]; 			blocks[3] = _gameField[6][0];			_currentFigure = new Figure(blocks, (Color)random, _gameField[5][0]);		} break;		case 6:		{			if (_gameField[4][0]->GetColor() != NONE || _gameField[5][0]->GetColor() != NONE ||				_gameField[5][1]->GetColor() != NONE || _gameField[6][0]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[4][0];			blocks[1] = _gameField[5][0];			blocks[2] = _gameField[5][1]; 			blocks[3] = _gameField[6][0];			_currentFigure = new Figure(blocks, (Color)random, _gameField[5][0]);		} break;		case 7:		{			if (_gameField[4][0]->GetColor() != NONE || _gameField[5][0]->GetColor() != NONE ||				_gameField[5][1]->GetColor() != NONE || _gameField[6][1]->GetColor() != NONE	)				return false;			blocks[0] = _gameField[4][0];			blocks[1] = _gameField[6][1];			blocks[2] = _gameField[5][0]; 			blocks[3] = _gameField[5][1];			_currentFigure = new Figure(blocks, (Color)random, _gameField[5][0]);		} break;	}	return true;}bool Game::checkCollision(bool checkSideBounds){	if (checkSideBounds)	{		int i = 0;		int k = 0;		int x = _currentFigure->GetMiddleBlock()->GetX();		int y = _currentFigure->GetMiddleBlock()->GetY();		while (_gameField[x][y - i]->GetColor() != NONE && (y - 1) >= 0)		{			i++;		}		while (_gameField[x][y + i]->GetColor() != NONE && (y - 1) < 20)		{			k++;		}		return ((((x + i) > 10) || ((x - k) < 0)));	} else	{		Block** blocks = _currentFigure->GetBlocks();		for (int i = 0; i < 4; i++)		{			Block* block = blocks;			if (block->GetY() + 1 < 20)			{				if (_gameField[block->GetX()][block->GetY()]->GetColor() != NONE)					return false;			} else				return false;		}		return true;	}}


regards,
Kaldris
Are you sure that _blocks is being changed right after the line SDL_Event act; and not after one of the events has been called (such as the key-up event)?
Thank you for your answer.
I just tested it again, and the error occures after the SDL_PollEvents().

Before:
Image and video hosting by TinyPic

After:
Image and video hosting by TinyPic

regards,
Kaldris

This topic is closed to new replies.

Advertisement