• Advertisement
Sign in to follow this  

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

This topic is 3000 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 25

enum 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 4

class 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

Share this post


Link to post
Share on other sites
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)?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement