Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
So I'm nearly done writing my first tic tac toe in C++ and SDL, ad I've run into a slight problem. I use a state machine to switch from title screen to shape choice screen, to player one or two to winning screen and back to the choice screen etc etc. On the choice screen I have two SDL_Rect arrays that act as buttons and the buttons are the X and O sprites I use from my sprite sheet. When the mouse hovers over them, they change colors. Everything is fine and dandy until the game resets to the choice screen after a win lose or tie. When it goes back to the choice screen and the mouse hovers over the button, it does not show the highlighted or mouse hovered sprite it clipped before. I pin pointed this problem to the initialization of my "set_grid_regions()" function. But this array doesn't even interact with the choice screen class in any way. How can this be affecting my hover sprites?
Just so anyone can see, here is the whole of the program:
#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include <string>
#include <iostream>
//constants
const int SCREEN_HEIGHT = 300;
const int SCREEN_WIDTH = 300;
const int SCREEN_BPP = 32;
const int GRID_WIDTH = 96;
const int GRID_HEIGHT = 96;
//game states
enum States
{
S_NULL,
INTRO,
CHOICE,
START_O,
START_X,
PLAYER_ONE,
PLAYER_TWO,
O_win,
X_win,
Tie,
EXIT,
};
// CLASSES //
class GameState
{
public:
virtual void events() = 0;
virtual void logic() = 0;
virtual void render() = 0;
virtual ~GameState(){};
};
class intro : public GameState
{
private:
//hover variable
bool button_hover = NULL;
//rects and surfaces
SDL_Rect button;
SDL_Surface *title_message = NULL;
public:
void events();
void logic();
void render();
intro();
~intro();
};
class choice : public GameState
{
private:
bool O_hover = NULL;
bool X_hover = NULL;
SDL_Rect shape_O_button;
SDL_Rect shape_X_button;
SDL_Surface *choice_text = NULL;
public:
void events();
void logic();
void render();
choice();
~choice();
};
class playerOne : public GameState
{
public:
void events();
void logic();
void render();
playerOne();
~playerOne();
};
class playerTwo : public GameState
{
public:
void events();
void logic();
void render();
playerTwo();
~playerTwo();
};
class win : public GameState
{
private:
int winner = NULL;
SDL_Surface *Tie = NULL;
SDL_Surface *X_win = NULL;
SDL_Surface *O_win = NULL;
public:
void events();
void logic();
void render();
win(int winner);
~win();
};
class Exit : public GameState
{
public:
void events();
void logic();
void render();
Exit();
~Exit();
};
// GLOBALS //
GameState *currentState = NULL;
int stateID = S_NULL;
int nextState = S_NULL;
//event
SDL_Event event;
//surfaces
SDL_Surface *screen = NULL;
SDL_Surface *sprites = NULL;
//ttf
TTF_Font *font = NULL;
SDL_Color color = { 0, 0, 0 };
SDL_Color win_Color = { 0, 100, 0 };
//arrays
int grid_array[9];
//rects
SDL_Rect sprite_clip[10];
SDL_Rect grid_region[9];
int number_elements = sizeof(grid_region) / sizeof(grid_region[0]);
//bools
bool shape = NULL;
bool invalid = NULL;
bool winner = NULL;
//ints
int highlight = NULL;
int shape_winner = NULL;
// FUCNTIONS //
//load image
SDL_Surface *load_image(std::string filename)
{
//loaded image
SDL_Surface* loadedImage = NULL;
//optimized surface
SDL_Surface* optimizedImage = NULL;
//load image
loadedImage = IMG_Load(filename.c_str());
//if image loaded
if (loadedImage != NULL)
{
//Create optimized image
optimizedImage = SDL_DisplayFormat(loadedImage);
//free old image
SDL_FreeSurface(loadedImage);
//if optimized
if (optimizedImage != NULL)
{
//map color key
Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 255, 255, 0);
//set all pixles of color 0,0,0 to be transparent
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
}
}
return optimizedImage;
}
//apply image
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//temp rect
SDL_Rect offset;
//offsets
offset.x = x;
offset.y = y;
//blit
SDL_BlitSurface(source, clip, destination, &offset);
}
//initiate SDL etc
bool init()
{
//initialize all SDL subsystems
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
return false;
}
//set up screen
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if (screen == NULL)
{
return false;
}
//check screen
if (screen == NULL)
{
return false;
}
//init TTF
if (TTF_Init() == -1)
{
return false;
}
//set window caption
SDL_WM_SetCaption("Tic-Tac-Toe", NULL);
//if evetything worked
return true;
}
//load files
bool load_files()
{
//sprite sheet
sprites = load_image("Sprites.png");
if (sprites == NULL)
{
return false;
}
font = TTF_OpenFont("font.ttf", 45);
if (font == NULL)
{
return false;
}
return true;
}
//quit
void clean_up()
{
//delete game state
delete currentState;
//free image
SDL_FreeSurface(sprites);
//quit ttf
TTF_CloseFont(font);
TTF_Quit();
//quit SDL
SDL_Quit();
}
void set_clip_regions()
{
//init clip array
//O
sprite_clip[0].x = 300;
sprite_clip[0].y = 0;
sprite_clip[0].w = 80;
sprite_clip[0].h = 82;
//X
sprite_clip[1].x = 300;
sprite_clip[1].y = 176;
sprite_clip[1].w = 80;
sprite_clip[1].h = 82;
//grid
sprite_clip[2].x = 0;
sprite_clip[2].y = 0;
sprite_clip[2].w = 300;
sprite_clip[2].h = 300;
//highlight
sprite_clip[3].x = 300;
sprite_clip[3].y = 82;
sprite_clip[3].w = 94;
sprite_clip[3].h = 94;
//left to right line
sprite_clip[4].x = 398;
sprite_clip[4].y = 188;
sprite_clip[4].w = 234;
sprite_clip[4].h = 12;
//diag up
sprite_clip[5].x = 393;
sprite_clip[5].y = 0;
sprite_clip[5].w = 188;
sprite_clip[5].h = 186;
//up down line
sprite_clip[6].x = 591;
sprite_clip[6].y = 0;
sprite_clip[6].w = 11;
sprite_clip[6].h = 208;
//Diag down line
sprite_clip[7].x = 0;
sprite_clip[7].y = 300;
sprite_clip[7].w = 188;
sprite_clip[7].h = 186;
//start button
sprite_clip[8].x = 202;
sprite_clip[8].y = 300;
sprite_clip[8].w = 94;
sprite_clip[8].h = 32;
//intro and choice background
sprite_clip[9].x = 300;
sprite_clip[9].y = 300;
sprite_clip[9].w = 300;
sprite_clip[9].h = 300;
//start hover
sprite_clip[10].x = 202;
sprite_clip[10].y = 332;
sprite_clip[10].w = 94;
sprite_clip[10].h = 32;
//X hover
sprite_clip[11].x = 202;
sprite_clip[11].y = 446;
sprite_clip[11].w = 80;
sprite_clip[11].h = 82;
//o hover
sprite_clip[12].x = 202;
sprite_clip[12].y = 364;
sprite_clip[12].w = 80;
sprite_clip[12].h = 82;
}
void set_grid_regions()
{
//set regions for images to be applied to
grid_region[0].x = 3;
grid_region[0].y = 3;
grid_region[1].x = 103;
grid_region[1].y = 3;
grid_region[2].x = 203;
grid_region[2].y = 3;
grid_region[3].x = 3;
grid_region[3].y = 103;
grid_region[4].x = 103;
grid_region[4].y = 103;
grid_region[5].x = 203;
grid_region[5].y = 103;
grid_region[6].x = 3;
grid_region[6].y = 203;
grid_region[7].x = 103;
grid_region[7].y = 203;
grid_region[8].x = 203;
grid_region[8].y = 203;
}
void init_grid()
{
//from left to right top to bottom
grid_array[0] = 0;
grid_array[1] = 0;
grid_array[2] = 0;
grid_array[3] = 0;
grid_array[4] = 0;
grid_array[5] = 0;
grid_array[6] = 0;
grid_array[7] = 0;
grid_array[8] = 0;
}
// STATE MACHINE FUNCTIONS //
void set_next_state(int newState)
{
if (nextState != EXIT)
{
nextState = newState;
}
}
void change_state()
{
if (nextState != S_NULL)
{
//change state
switch (nextState)
{
case CHOICE:
currentState = new choice();
break;
case PLAYER_ONE:
currentState = new playerOne();
break;
case PLAYER_TWO:
currentState = new playerTwo();
break;
case O_win:
currentState = new win(0);
break;
case X_win:
currentState = new win(1);
break;
case Tie:
currentState = new win(2);
break;
case EXIT:
currentState = new Exit();
break;
}
//change state
stateID = nextState;
//null nextState
nextState = S_NULL;
}
}
// CLASS DEFINITIONS //
intro::intro()
{
//button
button_hover = false;
//title
title_message = TTF_RenderText_Solid(font, "TIC TAC TOE", color);
//button bounds
button.x = 102;
button.y = 180;
button.w = 94;
button.h = 32;
}
intro::~intro()
{
SDL_FreeSurface(title_message);
}
void intro::events()
{
int x, y;
//mouse events
while (SDL_PollEvent(&event))
{
if (event.type == SDL_MOUSEMOTION)
{
x = event.motion.x;
y = event.motion.y;
if ((x > button.x) && (x < button.x + button.w) && (y > button.y) && (y < button.y + button.h))
{
button_hover = true;
}
else
{
button_hover = false;
}
}
if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button == SDL_BUTTON_LEFT)
{
x = event.motion.x;
y = event.motion.y;
if ((x > button.x) && (x < button.x + button.w) && (y > button.y) && (y < button.y + button.h))
{
set_next_state(CHOICE);
}
}
}
if (event.type == SDL_QUIT)
{
set_next_state(EXIT);
}
}
}
void intro::logic()
{
}
void intro::render()
{
apply_surface(0, 0, sprites, screen, &sprite_clip[9]);
apply_surface((SCREEN_WIDTH - title_message->w) / 2, 100, title_message, screen);
if (button_hover == true)
{
apply_surface(102, 180, sprites, screen, &sprite_clip[10]);
}
else
{
apply_surface(102, 180, sprites, screen, &sprite_clip[8]);
}
}
choice::choice()
{
O_hover = false;
X_hover = false;
shape_O_button.x = 0;
shape_O_button.y = 130;
shape_O_button.w = 80;
shape_O_button.h = 82;
shape_X_button.x = 220;
shape_X_button.y = 130;
shape_X_button.w = 80;
shape_X_button.h = 82;
font = TTF_OpenFont("font.ttf", 34);
choice_text = TTF_RenderText_Solid(font, "CHOOSE YOUR SHAPE", color);
}
choice::~choice()
{
SDL_FreeSurface(choice_text);
O_hover = NULL;
X_hover = NULL;
}
void choice::events()
{
int x, y;
//mouse events
while (SDL_PollEvent(&event))
{
if (event.type == SDL_MOUSEMOTION)
{
x = event.motion.x;
y = event.motion.y;
if ((x > shape_O_button.x) && (x < shape_O_button.x + shape_O_button.w) && (y > shape_O_button.y) && (y < shape_O_button.y + shape_O_button.h))
{
O_hover = true;
}
else
{
O_hover = false;
}
if ((x > shape_X_button.x) && (x < shape_X_button.x + shape_X_button.w) && (y > shape_X_button.y) && (y < shape_X_button.y + shape_X_button.h))
{
X_hover = true;
}
else
{
X_hover = false;
}
}
if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button == SDL_BUTTON_LEFT)
{
x = event.motion.x;
y = event.motion.y;
if ((x > shape_O_button.x) && (x < shape_O_button.x + shape_O_button.w) && (y > shape_O_button.y) && (y < shape_O_button.y + shape_O_button.h))
{
shape = false;
init_grid();
set_next_state(PLAYER_ONE);
}
if ((x > shape_X_button.x) && (x < shape_X_button.x + shape_X_button.w) && (y > shape_X_button.y) && (y < shape_X_button.y + shape_X_button.h))
{
shape = true;
init_grid();
set_next_state(PLAYER_TWO);
}
}
}
if (event.type == SDL_QUIT)
{
set_next_state(EXIT);
}
}
}
void choice::logic()
{
}
void choice::render()
{
apply_surface( 0, 0, sprites, screen, &sprite_clip[9]);
if (O_hover == false)
{
apply_surface(shape_O_button.x, shape_O_button.y, sprites, screen, &sprite_clip[0]);
}
else
{
apply_surface(shape_O_button.x, shape_O_button.y, sprites, screen, &sprite_clip[12]);
}
if (X_hover == false)
{
apply_surface(shape_X_button.x, shape_X_button.y, sprites, screen, &sprite_clip[1]);
}
else
{
apply_surface(shape_X_button.x, shape_X_button.y, sprites, screen, &sprite_clip[11]);
}
apply_surface((SCREEN_WIDTH - choice_text->w) / 2, 60, choice_text, screen);
}
//plyer O
playerOne::playerOne()
{
set_grid_regions();
}
playerOne::~playerOne()
{
}
void playerOne::events()
{
//mouse offsets
int x = 0, y = 0;
//if mouse moves
while (SDL_PollEvent(&event))
{
if (event.type == SDL_MOUSEMOTION)
{
//get the mouse co-ords
x = event.motion.x;
y = event.motion.y;
for (int grid = 0; grid < number_elements; grid++)
{
if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
{
//set highlight region
highlight = grid;
}
}
}
//when the player clicks on a grid_region
if (event.type == SDL_MOUSEBUTTONDOWN)
{
//mouse co-ordinates
x = event.motion.x;
y = event.motion.y;
if (event.button.button == SDL_BUTTON_LEFT)
{
//iterate
for (int grid = 0; grid < number_elements; grid++)
{
//if in region box
if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
{
//check region
//if O turn
if ((grid_array[grid] == 0) && (shape == 0))
{
//fill region
grid_array[grid] = 1;
shape = (!shape);
}
else if (grid_array[grid] != 0)
{
//raise "error"
invalid = true;
}
//if X turn
else if ((grid_array[grid] == 0) && (shape == 1))
{
if ((grid_array[grid] == 0))
{
//fill region
grid_array[grid] = 2;
shape = (!shape);
}
else if (grid_array[grid] != 0)
{
//raise "error"
invalid = true;
}
}
}
}
}
}
if (event.type == SDL_QUIT)
{
set_next_state(EXIT);
}
}
}
void playerOne::logic()
{
//check O win
for (int win = 0; win <= 6; win += 3)
{
if ((grid_array[win] == 1) && (grid_array[win + 1] == 1) && (grid_array[win + 2] == 1))
{
winner = 0;
set_next_state(O_win);
}
}
for (int win = 0; win < 3; win++)
{
if ((grid_array[win] == 1) && (grid_array[win + 3] == 1) && (grid_array[win + 6] == 1))
{
winner = 0;
set_next_state(O_win);
}
}
if ((grid_array[0] == 1) && (grid_array[4] == 1) && (grid_array[8] == 1))
{
winner = 0;
set_next_state(O_win);
}
if ((grid_array[2] == 1) && (grid_array[4] == 1) && (grid_array[6] == 1))
{
winner = 0;
set_next_state(O_win);
}
//check X's
for (int win = 0; win <= 6; win += 3)
{
if ((grid_array[win] == 2) && (grid_array[win + 1] == 2) && (grid_array[win + 2] == 2))
{
winner = 1;
set_next_state(X_win);
}
}
for (int win = 0; win < 3; win++)
{
if ((grid_array[win] == 2) && (grid_array[win + 3] == 2) && (grid_array[win + 6] == 2))
{
winner = 1;
set_next_state(X_win);
}
}
if ((grid_array[0] == 2) && (grid_array[4] == 2) && (grid_array[8] == 2))
{
winner = 1;
set_next_state(X_win);
}
if ((grid_array[2] == 2) && (grid_array[4] == 2) && (grid_array[6] == 2))
{
winner = 1;
set_next_state(X_win);
}
//check TIE
if ((grid_array[0] != 0) && (grid_array[1] != 0) && (grid_array[2] != 0) && (grid_array[3] != 0) && (grid_array[4] != 0) && (grid_array[5] != 0) && (grid_array[6] != 0) && (grid_array[7] != 0) && (grid_array[8] != 0) && (winner == NULL))
{
set_next_state(Tie);
}
}
void playerOne::render()
{
//logic
//rendering
//background
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
//grid
apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
//highlight
if (highlight != -1)
{
apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
}
//APPLY PLAYER SHAPE
for (int grid = 0; grid < number_elements; grid++)
{
//O's
if ((grid_array[grid] == 1))
{
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
}
else if ((grid_array[grid] == 2))
{
//X's
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
}
}
}
playerTwo::playerTwo()
{
set_grid_regions();
}
playerTwo::~playerTwo()
{
}
void playerTwo::events()
{
//mouse offsets
int x = 0, y = 0;
//if mouse moves
while (SDL_PollEvent(&event))
{
if (event.type == SDL_MOUSEMOTION)
{
//get the mouse co-ords
x = event.motion.x;
y = event.motion.y;
for (int grid = 0; grid < number_elements; grid++)
{
if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
{
//set highlight region
highlight = grid;
}
}
}
//when the player clicks on a grid_region
if (event.type == SDL_MOUSEBUTTONDOWN)
{
//mouse co-ordinates
x = event.motion.x;
y = event.motion.y;
if (event.button.button == SDL_BUTTON_LEFT)
{
//iterate
for (int grid = 0; grid < number_elements; grid++)
{
//if in region box
if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
{
//check region
//if O turn
if ((grid_array[grid] == 0) && (shape == 0))
{
//fill region
grid_array[grid] = 1;
shape = (!shape);
}
else if (grid_array[grid] != 0)
{
//raise "error"
invalid = true;
}
//if X turn
else if ((grid_array[grid] == 0) && (shape == 1))
{
if ((grid_array[grid] == 0))
{
//fill region
grid_array[grid] = 2;
shape = (!shape);
}
else if (grid_array[grid] != 0)
{
//raise "error"
invalid = true;
}
}
}
}
}
}
if (event.type == SDL_QUIT)
{
set_next_state(EXIT);
}
}
}
void playerTwo::logic()
{
//check O win
for (int win = 0; win <= 6; win += 3)
{
if ((grid_array[win] == 1) && (grid_array[win + 1] == 1) && (grid_array[win + 2] == 1))
{
winner = 0;
set_next_state(O_win);
}
}
for (int win = 0; win < 3; win++)
{
if ((grid_array[win] == 1) && (grid_array[win + 3] == 1) && (grid_array[win + 6] == 1))
{
winner = 0;
set_next_state(O_win);
}
}
if ((grid_array[0] == 1) && (grid_array[4] == 1) && (grid_array[8] == 1))
{
winner = 0;
set_next_state(O_win);
}
if ((grid_array[2] == 1) && (grid_array[4] == 1) && (grid_array[6] == 1))
{
winner = 0;
set_next_state(O_win);
}
//check X's
for (int win = 0; win <= 6; win += 3)
{
if ((grid_array[win] == 2) && (grid_array[win + 1] == 2) && (grid_array[win + 2] == 2))
{
winner = 1;
set_next_state(X_win);
}
}
for (int win = 0; win < 3; win++)
{
if ((grid_array[win] == 2) && (grid_array[win + 3] == 2) && (grid_array[win + 6] == 2))
{
winner = 1;
set_next_state(X_win);
}
}
if ((grid_array[0] == 2) && (grid_array[4] == 2) && (grid_array[8] == 2))
{
winner = 1;
set_next_state(X_win);
}
if ((grid_array[2] == 2) && (grid_array[4] == 2) && (grid_array[6] == 2))
{
winner = 1;
set_next_state(X_win);
}
//check TIE
if ((grid_array[0] != 0) && (grid_array[1] != 0) && (grid_array[2] != 0) && (grid_array[3] != 0) && (grid_array[4] != 0) && (grid_array[5] != 0) && (grid_array[6] != 0) && (grid_array[7] != 0) && (grid_array[8] != 0) && (winner == NULL))
{
set_next_state(Tie);
}
}
void playerTwo::render()
{
//logic
//rendering
//background
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
//grid
apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
//highlight
if (highlight != -1)
{
apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
}
//APPLY PLAYER SHAPE
for (int grid = 0; grid < number_elements; grid++)
{
//O's
if ((grid_array[grid] == 1))
{
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
}
else if ((grid_array[grid] == 2))
{
//X's
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
}
}
}
win::win(int winner)
{
shape_winner = winner;
font = TTF_OpenFont("font.ttf", 45);
X_win = TTF_RenderText_Solid(font, "X WINS", win_Color);
O_win = TTF_RenderText_Solid(font, "O wins", win_Color);
Tie = TTF_RenderText_Solid(font, "Tie", win_Color);
}
win::~win()
{
TTF_CloseFont(font);
SDL_FreeSurface(X_win);
SDL_FreeSurface(O_win);
}
void win::events()
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
set_next_state(EXIT);
}
}
}
void win::logic()
{
if (shape_winner == 3)
{
SDL_Delay(2000);
set_next_state(CHOICE);
winner = NULL;
}
}
void win::render()
{
//background
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
//grid
apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
//highlight
if (highlight != -1)
{
apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
}
//APPLY PLAYER SHAPE
for (int grid = 0; grid < number_elements; grid++)
{
//O's
if ((grid_array[grid] == 1))
{
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
}
else if ((grid_array[grid] == 2))
{
//X's
apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
}
}
if (shape_winner == 1)
{
apply_surface((SCREEN_WIDTH - X_win->w) / 2, (SCREEN_HEIGHT - X_win->h) / 2, X_win, screen);
//enable delay and reset
shape_winner = 3;
}
if (shape_winner == 0)
{
apply_surface((SCREEN_WIDTH - O_win->w) / 2, (SCREEN_HEIGHT - O_win->h) / 2, O_win, screen);
//enable delay and reset
shape_winner = 3;
}
if (shape_winner == 2)
{
apply_surface((SCREEN_WIDTH - Tie->w) / 2, (SCREEN_HEIGHT - Tie->h) / 2, Tie, screen);
//enable delay and reset
shape_winner = 3;
}
}
Exit::Exit()
{
}
Exit::~Exit()
{
}
void Exit::events()
{
}
void Exit::logic()
{
}
void Exit::render()
{
}
//MAAAAAAAAAAAAAAAAAAIN//
int main(int argc, char* args[])
{
//init SDL
init();
//load files
load_files();
//set clips
set_clip_regions();
//set state
stateID = INTRO;
//set game object
currentState = new intro();
while (stateID != EXIT)
{
//handle state events
currentState->events();
// do state logic
currentState->logic();
//change state if needed
change_state();
//render state
currentState->render();
if (SDL_Flip(screen) == -1)
{
return 1;
}
}
clean_up();
return 0;
}
It's pretty strange. But I'm 99% sure that it's the "set_grid_regions()" that is effecting the rendering inside the choice::render() or choice::event() class fucntions. Can anyone help with this?
The error causing the clipping problem is an incorrect declaration for sprite_clip. You've declared it as sprite_clip[10], but you have 13 sprites. Change this to sprite_clip[13].
Other things I noticed:
You allocate all these state objects with new, but you never delete them. You need to delete them when you change states. Otherwise you will leak memory.
The font font.ttf seems to be a global resource but is haphazardly managed by a mixture of global and local methods. Load it once in load_files() and release it once in clean_up().
While your project may be complete, you might tinker around with it and work on improving the implementation now that you have something working. (If this was a homework, keep a copy of a working version to hand in. ;-) )
Consider packaging all of your global state (your fonts, sprites, clipping arrays, etc.) into a single class for the game. Your init_xxx and load_xxx functions move to its constructor. Your clean_up moves to its destructor.
Consider converting your dynamic state objects into statically allocated state objects. They could even be members of the same global state class I mentioned in the previous bullet. Now you've encapsulated the whole game in one class.
Consider merging playerOne and playerTwo into a single class. Distinguish them at construction time, just as you did with win(0), win(1), win(2).
I have just recently started working with allegro 5 and decided to start with a basic pong game. I found one and decided to add some extras to it. After adding two more paddles and the needed variables and controls, I copied and pasted the collision code from the original two and added the needed variables. However, if I move the new paddles from the originals, they no longer bounce off the ball. The code is huge I know, but I have no idea whats causing the problem.
`
#include <stdio.h>
#include <cstdlib>
#include <sstream>
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_color.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
/* constants and definitions */
const int SCREEN_W = 960;
const int SCREEN_H = 720;
const float FPS = 60;
const int paddle_height = 96;
const int paddle_width = 16;
const int bouncer_size = 16;
enum MYKEYS{
KEY_UP,KEY_DOWN,KEY_W,KEY_S,KEY_E,KEY_D,KEY_O,KEY_L
};
/* functions */
void draw_paddle(float x,float y){
// fill
al_draw_filled_rounded_rectangle(x,y,x+paddle_width,y+paddle_height,3,3,al_color_html("729fcf"));
// outline
al_draw_rounded_rectangle(x,y,x+paddle_width,y+paddle_height,3,3,al_color_html("b5edff"),1.0);
// shine
al_draw_filled_rounded_rectangle(x,y,x+paddle_width/2,y+paddle_height-10,3,3,al_color_html("8abbef"));
}
void draw_ball(float x,float y){
// fill
al_draw_filled_circle(x,y,bouncer_size,al_color_html("6be97d"));
// shadow
al_draw_filled_circle(x+bouncer_size/4,y+bouncer_size/4,bouncer_size/3*2,al_color_html("59ce76"));
// shine
al_draw_filled_circle(x-bouncer_size/3,y-bouncer_size/3,bouncer_size/4,al_color_html("9bffaa"));
}
void draw_score(int l,int r){
std::ostringstream ostr;
ostr << l;
std::ostringstream ostr1;
ostr1 << r;
ALLEGRO_FONT *font = al_load_font("arial.ttf",72,0);
al_draw_filled_rectangle(SCREEN_W/2-5,SCREEN_H,SCREEN_W/2+5,-SCREEN_H,al_color_html("ffffff"));
al_draw_text(font,al_color_html("ffffff"),SCREEN_W/2-50,0,ALLEGRO_ALIGN_CENTRE,ostr.str().c_str());
al_draw_text(font,al_color_html("ffffff"),SCREEN_W/2+50,0,ALLEGRO_ALIGN_CENTER,ostr1.str().c_str());
al_destroy_font(font);
}
int main(){
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
ALLEGRO_BITMAP *right_paddle = NULL;
ALLEGRO_BITMAP *left_paddle = NULL;
ALLEGRO_BITMAP *right_sub_paddle = NULL;
ALLEGRO_BITMAP *left_sub_paddle = NULL;
ALLEGRO_BITMAP *bouncer = NULL;
float right_paddle_x =(SCREEN_W*4/5)-(paddle_width/2.0);
float right_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
float left_paddle_x =(SCREEN_W*1/5)-(paddle_width/2.0);
float left_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
float right_sub_paddle_x = (SCREEN_W*4/5)-(paddle_width/2.0)-100;
float right_sub_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
float left_sub_paddle_x = (SCREEN_W*1/5)-(paddle_width/2.0)+100;
float left_sub_paddle_y = (SCREEN_H/2.0)-(paddle_height/2.0);
float bouncer_x = SCREEN_W/2.0-bouncer_size/2.0;
float bouncer_y = SCREEN_H/2.0-bouncer_size/2.0;
float bouncer_dx = 8.0,bouncer_dy = -8.0;
float paddle_speed = 8.0;
bool key[8] = {false,false,false,false,false,false,false,false};
bool redraw = true;
bool doexit = false;
bool pause = false;
int left_score = 0;
int right_score = 0;
if(!al_init()){
fprintf(stderr,"failed to initialized allegro\n");
return -1;
}
if(!al_install_keyboard()){
fprintf(stderr,"failed to install keyboard\n");
return -1;
}
al_init_primitives_addon();
al_init_font_addon();
al_init_ttf_addon();
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS,1,ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES,4,ALLEGRO_SUGGEST);
//initialize display(w,h)
display = al_create_display(SCREEN_W,SCREEN_H);
if(!display){
fprintf(stderr,"failed to create display\n");
return -1;
}
timer = al_create_timer(1.0/FPS);
if(!timer){
fprintf(stderr,"failed to create timer\n");
return -1;
}
right_paddle = al_create_bitmap(paddle_width,paddle_height);
if(!right_paddle){
fprintf(stderr,"failed to create right paddle bitmap\n");
return -1;
}
left_paddle = al_create_bitmap(paddle_width,paddle_height);
if(!left_paddle){
fprintf(stderr,"failed to create left paddle bitmap\n");
return -1;
}
right_sub_paddle = al_create_bitmap(paddle_width,paddle_height);
if(!right_sub_paddle){
fprintf(stderr,"failed to create right sub paddle bitmap\n");
return -1;
}
left_sub_paddle = al_create_bitmap(paddle_width,paddle_height);
if(!left_sub_paddle){
fprintf(stderr,"failed to create left sub paddle bitmap\n");
return -1;
}
bouncer = al_create_bitmap(bouncer_size,bouncer_size);
if(!bouncer){
fprintf(stderr,"failed to create bouncer bitmap\n");
return -1;
}
al_set_target_bitmap(left_paddle);
al_clear_to_color(al_map_rgb(0,255,0));
al_set_target_bitmap(right_paddle);
al_clear_to_color(al_map_rgb(0,255,0));
al_set_target_bitmap(left_sub_paddle);
al_clear_to_color(al_map_rgb(0,255,0));
al_set_target_bitmap(right_sub_paddle);
al_clear_to_color(al_map_rgb(0,255,0));
al_set_target_bitmap(bouncer);
al_clear_to_color(al_map_rgb(0,0,255));
al_set_target_bitmap(al_get_backbuffer(display));
event_queue = al_create_event_queue();
if(!event_queue){
fprintf(stderr,"failed to create event queue\n");
return -1;
}
al_register_event_source(event_queue,al_get_display_event_source(display));
al_register_event_source(event_queue,al_get_timer_event_source(timer));
al_register_event_source(event_queue,al_get_keyboard_event_source());
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_start_timer(timer);
while(!doexit){
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue,&ev);
if(ev.type == ALLEGRO_EVENT_TIMER && !pause){
//logic for moving the paddles on input
if(key[KEY_UP] && right_paddle_y >= 4.0){
right_paddle_y -= paddle_speed;
}
if(key[KEY_DOWN] && right_paddle_y <= SCREEN_H-paddle_height-4.0){
right_paddle_y += paddle_speed;
}
if(key[KEY_W] && left_paddle_y >= 4.0){
left_paddle_y -= paddle_speed;
}
if(key[KEY_S] && left_paddle_y <= SCREEN_H-paddle_height-4.0){
left_paddle_y += paddle_speed;
}
if(key[KEY_E] && left_sub_paddle_y >= 4.0){
left_sub_paddle_y -= paddle_speed;
}
if(key[KEY_D] && left_sub_paddle_y <= SCREEN_H-paddle_height-4.0){
left_sub_paddle_y += paddle_speed;
}
if(key[KEY_O] && right_sub_paddle_y >= 4.0){
right_sub_paddle_y -= paddle_speed;
}
if(key[KEY_L] && right_sub_paddle_y <= SCREEN_H-paddle_height-4.0){
right_sub_paddle_y += paddle_speed;
}
//logic for the bouncer
if(bouncer_x < 0 || bouncer_x > SCREEN_W-bouncer_size){
if(bouncer_x < 0){
left_score += 1;
}else if(bouncer_x > SCREEN_W-bouncer_size){
right_score += 1;
}
paddle_speed = 8.0;
bouncer_x = SCREEN_W/2.0-bouncer_size/2.0;
bouncer_y = SCREEN_H/2.0-bouncer_size/2.0;
bouncer_dx = -bouncer_dx;
bouncer_dy = -bouncer_dx;
}
if(bouncer_y < 0 || bouncer_y > SCREEN_H-bouncer_size){
bouncer_dy = -bouncer_dy;
}
if(bouncer_x == left_paddle_x+(paddle_width/1.0)){
if(bouncer_y >= left_paddle_y+paddle_height || bouncer_y+bouncer_size < left_paddle_y){
}else{
paddle_speed += 1;
bouncer_dx = -bouncer_dx;
}
}
if(bouncer_x == right_paddle_x-(paddle_width/2.0)){
if(bouncer_y >= right_paddle_y+paddle_height || bouncer_y+bouncer_size < right_paddle_y){
}else{
paddle_speed += 1;
bouncer_dx = -bouncer_dx;
}
}
if(bouncer_x == left_sub_paddle_x+(paddle_width/1.0)){
if(bouncer_y >= left_sub_paddle_y+paddle_height || bouncer_y+bouncer_size < left_sub_paddle_y){
}else{
paddle_speed +=1;
bouncer_dx = -bouncer_dx;
}
}
if(bouncer_x == right_sub_paddle_x+(paddle_width/1.0)){
if(bouncer_y >= right_sub_paddle_y+paddle_height || bouncer_y+bouncer_size < right_sub_paddle_y){
}else{
paddle_speed +=1;
bouncer_dx = -bouncer_dx;
}
}
bouncer_x += bouncer_dx;
bouncer_y += bouncer_dy;
redraw = true;
}else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE){
break;
}else if(ev.type == ALLEGRO_EVENT_KEY_DOWN){
switch(ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
key[KEY_UP] = true;
break;
case ALLEGRO_KEY_DOWN:
key[KEY_DOWN] = true;
break;
case ALLEGRO_KEY_W:
key[KEY_W] = true;
break;
case ALLEGRO_KEY_S:
key[KEY_S] = true;
break;
case ALLEGRO_KEY_E:
key[KEY_E] = true;
break;
case ALLEGRO_KEY_D:
key[KEY_D] = true;
break;
case ALLEGRO_KEY_O:
key[KEY_O] = true;
break;
case ALLEGRO_KEY_L:
key[KEY_L] = true;
break;
}
}else if(ev.type == ALLEGRO_EVENT_KEY_UP){
switch(ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
key[KEY_UP] = false;
break;
case ALLEGRO_KEY_DOWN:
key[KEY_DOWN] = false;
break;
case ALLEGRO_KEY_W:
key[KEY_W] = false;
break;
case ALLEGRO_KEY_S:
key[KEY_S] = false;
break;
case ALLEGRO_KEY_E:
key[KEY_E] = false;
break;
case ALLEGRO_KEY_D:
key[KEY_D] = false;
break;
case ALLEGRO_KEY_O:
key[KEY_O] = false;
break;
case ALLEGRO_KEY_L:
key[KEY_L] = false;
break;
case ALLEGRO_KEY_ESCAPE:
doexit = true;
break;
case ALLEGRO_KEY_P:
if(pause){
pause = false;
}else{
pause = true;
}
break;
}
}
if(redraw && al_is_event_queue_empty(event_queue)){
redraw = false;
al_clear_to_color(al_map_rgb(0,0,0));
draw_score(right_score,left_score);
draw_paddle(right_sub_paddle_x,right_sub_paddle_y);
draw_paddle(left_sub_paddle_x,left_sub_paddle_y);
draw_paddle(right_paddle_x,right_paddle_y);
draw_paddle(left_paddle_x,left_paddle_y);
draw_ball(bouncer_x,bouncer_y);
//al_draw_bitmap(right_paddle,right_paddle_x,right_paddle_y,0);
//al_draw_bitmap(left_paddle,left_paddle_x,left_paddle_y,0);
//al_draw_bitmap(right_sub_paddle,right_sub_paddle_x,right_sub_paddle_y,0);
//al_draw_bitmap(left_sub_paddle,left_sub_paddle_x,left_sub_paddle_y,0);
//al_draw_bitmap(bouncer,bouncer_x,bouncer_y,0);
al_flip_display();
}
}
al_destroy_bitmap(bouncer);
al_destroy_bitmap(right_paddle);
al_destroy_bitmap(left_paddle);
al_destroy_bitmap(right_sub_paddle);
al_destroy_bitmap(left_sub_paddle);
al_destroy_timer(timer);
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}`
Any help is greatly appreciated.
I'm pretty sure this is your problem:
float bouncer_dx = 8.0,bouncer_dy = -8.0;
^ notice it's always moving at 8px per game tick...
Further down in the code, you are checking if bouncer_x (and bouncer_y) is landing on a pixel that is exactly divisible by 8, and while it seems to work for the two original paddles, i'm willing to bet the bouncer_x value never equals the value to trigger this 'if' statement:
if(bouncer_x == left_sub_paddle_x+(paddle_width/1.0)) { ... }
because your new sub paddles have different width and math (divided by 1.0 and not 2.0)
Check it and see... this is just from looking over the code for a minute so i dunno for sure :)
Good luck!
I am currently making a particle system, a basic one, also using Allegro 5 library.
Here is what i came up with:
int main()
{
int mouseX = 0, mouseY = 0;
int randNum = 0;
std::vector <Particle *> Particles;
bool running = false, redraw = false, mouseHold = false;
int particleCount = 0;
al_init();
al_init_image_addon();
al_install_mouse();
al_init_font_addon();
al_init_ttf_addon();
ALLEGRO_DISPLAY* display = al_create_display(800, 600);
ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue();
ALLEGRO_TIMER* myTimer = al_create_timer(1.0 / 60);
ALLEGRO_TIMER* pTimer = al_create_timer(1.0 / 120);
ALLEGRO_FONT* myFont = al_load_ttf_font("MyFont.ttf", 20, NULL);
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(myTimer));
al_register_event_source(event_queue, al_get_timer_event_source(pTimer));
al_register_event_source(event_queue, al_get_mouse_event_source());
running = true;
al_start_timer(myTimer);
while(running)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
running = false;
if(ev.type == ALLEGRO_EVENT_MOUSE_AXES)
{
mouseX = ev.mouse.x;
mouseY = ev.mouse.y;
}
if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
{
if(ev.mouse.button == 1)
mouseHold = true;
}
if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
{
if(ev.mouse.button == 1)
mouseHold = false;
}
if(ev.type == ALLEGRO_EVENT_TIMER)
{
randNum = (std::rand()+1 * ev.timer.count) % 50;
std::cout << randNum << std::endl;
if(mouseHold)
{
Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
Particles.push_back(particle);
}
particleCount = Particles.size();
for(auto i : Particles)
i->Update();
redraw = true;
}
for(auto iter = Particles.begin(); iter != Particles.end(); )
{
if(!(*iter)->GetAlive())
{
delete (*iter);
iter = Particles.erase(iter);
}
else
iter++;
}
if(redraw && al_event_queue_is_empty(event_queue))
{
for(auto i : Particles)
i->Draw();
al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 10, NULL, "Mouse X: %i", mouseX);
al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 30, NULL, "Mouse Y: %i", mouseY);
al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 60, NULL, "Particle Count: %i", particleCount);
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
redraw = false;
}
}
al_destroy_display(display);
al_destroy_event_queue(event_queue);
al_destroy_timer(myTimer);
for(auto i : Particles)
delete i;
Particles.clear();
return 0;
}
Yes, the code is quite bad. It seems i know more about theory behind c++ than actually implementing it.. but im guess im learning.
The problems:
Someone said I couldn't be calling 'new' and 'delete' so many times as this is very bad.
The particle creation is limited by the timer- I can't/don't know how to make it so I can control the speed of particle creation.
I'm not expecting for someone to create on for me, it would be of great use if I could read something to help me understand or someone post some code to learn from/get me thinking?
Your particle generation as you have it layed it is indeed, limited by your timer. You are telling Allegro that if you have the mouse button down when a timer event is fired, generate one particle. You could increase the rate of particle creation by creating multiple particles each timer tick.
for(int i = 0; i < rate; rate++)
{
randNum = (std::rand()+1 * ev.timer.count) % 50;
std::cout << randNum << std::endl;
if(mouseHold)
{
Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
Particles.push_back(particle);
}
}
Then just use the variable rate to control how "fast" you are generating particles. This has the drawback of drawing multiple particles with the same original X and Y positions, but since you're also using the randNum, it should be ok.
Another option, which may be more suited for your needs depending on what these particles are doing, is to use a timer ticking at a faster rate to generate your particles. When you are checking for ALLEGRO_EVENT_TIMER do
if(ev.timer.source == timer)
{
redraw = true;
}
if (ev.timer.source == fasterTimer)
{
randNum = (std::rand()+1 * ev.timer.count) % 50;
std::cout << randNum << std::endl;
if(mouseHold)
{
Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
Particles.push_back(particle);
}
}
after running my asteroids game for several minutes the SDL_Surface representing my ship disappears. Somehow the surface that holds the rotated image (rot) of the ship is getting set to NULL. I can't figure out why! Before I added the line if(rot != NULL && image != NULL) the program would crash after running for a about a minute an thirty seconds, but now the image just disappears. I can't seem to figure out whats wrong! Thanks in advance!
Sprite Class functions involving rotation and rendering.
void Sprite::Rotate(double angleAdd)
{
rotated = true;
double temp = 0;
angle += angleAdd;
temp = angleAdd + angle;
if (temp >= 360)
angleAdd = temp - 360;
if (temp <= 360)
angleAdd = temp + 360;
rot = rotozoomSurface(image, angle , 1.0, 1);
}
void Sprite::Draw(SDL_Surface* screen)
{
if(image == NULL)
SDL_FillRect(screen, &rect, color);
else
{
if (rotated)
{
rotRect.x = x;
rotRect.y = y;
//Center the image
if(rot != NULL && image != NULL){
rotRect.x -= ((rot->w/2) - (image->w/2));
rotRect.y -= ((rot->h/2) - (image->h/2));
}
SDL_BlitSurface(rot, NULL, screen, &rotRect);
}
else
SDL_BlitSurface(image, NULL, screen, &rect);
}
}
bool Sprite::SetImage(std::string fileName)
{
imageFileName = fileName;
SDL_Surface* loadedImage = NULL;
loadedImage = SDL_LoadBMP(fileName.c_str());
if(loadedImage == NULL)
{
if (debugEnabled)
printf("Failed to load image: %s\n", fileName.c_str());
SDL_FreeSurface(loadedImage);
return false;
}
else
{
image = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
return true;
}
}
Main:
if (arrowPressed[0])
{
ship.SetImage(shipFor.GetImage());
if(!phase)
ship.Accel(-moveSpeed);
else
ship.Accel(-moveSpeed * 2);
}
if (arrowPressed[1])
{
ship.Rotate(turnSpeed);
ship.SetImage(shipRig.GetImage());
}
if (arrowPressed[3])
{
ship.Rotate(-turnSpeed);
ship.SetImage(shipLef.GetImage());
}
if (arrowPressed[0] && arrowPressed[1])
ship.SetImage(shipForRig.GetImage());
if (arrowPressed[0] && arrowPressed[3])
ship.SetImage(shipForLef.GetImage());
if (!arrowPressed[0] && !arrowPressed[1] && !arrowPressed[3])
ship.SetImage(shipNor.GetImage());
if (ship.GetCenterX() >= RESX - 40)
ship.SetPosCentered(50, ship.GetCenterY());
if (ship.GetCenterX() <= 40)
ship.SetPosCentered(RESX - 50, ship.GetCenterY());
if (ship.GetCenterY() >= RESY - 40)
ship.SetPosCentered(ship.GetCenterX(), 50);
if (ship.GetCenterY() <= 40)
ship.SetPosCentered(ship.GetCenterX(), RESY - 150);
It seems that you are not freeing the last rotated image. Check for null, and free the surface before creating a new one:
void Sprite::Rotate(double angleAdd)
{
if(rot != NULL)
SDL_FreeSurface(rot);
rotated = true;
double temp = 0;
angle += angleAdd;
temp = angleAdd + angle;
if (temp >= 360)
angleAdd = temp - 360;
if (temp <= 360)
angleAdd = temp + 360;
rot = rotozoomSurface(image, angle , 1.0, 1);
}
This is my code.In this my application is crashing at "CheckIntersectOrNot" method.In this method it is crashing at the line is "[self DifferentColorBalls:loBall];". In this i am also using exceptions it is not working .
-(void)CheckIntersectOrNot:(BallImage *)loBall{
BallImage *loTar = (BallImage *)[self getChildByTag:200];
if (CGRectIntersectsRect([loTar boundingBox], [loBall boundingBox])) {
[loTar stopAllActions];
checkCollsionEnable = YES;
if (loTar.BallColor == loBall.BallColor) {
//same color
[self SameColorBall:loBall TargetBall:loTar];
}
else{
//different color balls
#try {
if (loBall != nil ) {
[loBall retain];
if (GameOverCompleted == 2) {
return;
}
[self DifferentColorBalls:loBall];
}
}
#catch (NSException *exception) {
NSLog(#"exception:%#",exception);
}
}
checkCollsionEnable = NO;
}
}
-(void)DifferentColorBalls:(BallImage *)loBall{
if (GameOverCompleted == 2 ) {
return;
}
[[SimpleAudioEngine sharedEngine] playEffect:#"BallSound2.wav"];
#try {
CGPoint tarPoint;
BallImage *loTar = (BallImage *)[self getChildByTag:200];
int index = [self.mBallImageArray indexOfObject:loBall];
tarPoint = loBall.position;
int ballangle = loBall.ballAngle;
int ballDirection = loBall.BallDirection;
for (int i = index; i>= 0; i--) {
BallImage *loba = [self.mBallImageArray objectAtIndex:i];
[self Movenext:loba];
}
[loTar setTag:-1];
loTar.BallAnimationEnable = 1;
loTar.position = tarPoint;
loTar.ballAngle = ballangle;
loTar.BallDirection = ballDirection;
#try {
if (loTar != nil) {
[self.mBallImageArray insertObject:loTar atIndex:++index];
}
}
#catch (NSException *exception) {
NSLog(#"differnet loTar ball :%#",exception);
}
[self CreteTargetBallImage];
}
#catch (NSException *exception) {
NSLog(#"exception DifferentColorBalls :%#",exception);
}
#finally {
}
}
-(void)Movenext:(BallImage *)loBall{
int loop = loBall.contentSize.width/AnimationMoveLength;
for (int i = 0; i<loop; i++) {
#try {
[self BallNextposition:loBall];
}
#catch (NSException *exception) {
NSLog(#"Movenext exception :%#",exception);
}
}
}
-(void)BallNextposition:(BallImage *)loBall{
[self DisableForBallAnimation:loBall];
if (!loBall.BallAnimationEnable) {
return;
}
if (loBall.BallForwardEnable == 0) {
[self MoveBackPosition:loBall];
return;
}
CGPoint point1, point2, point3;
CGPoint ballPosition = loBall.position;
CGRect BoxRect = CGRectMake(40, 40, 22, 244);
CGRect BoxRect2 = CGRectMake(40, 0, 100, 40);
CGRect BoxRect3 = CGRectMake(94, 40, 22, 207);
CGRect BoxRect4 = CGRectMake(94, 245, 100, 44);
CGRect BoxRect12 = CGRectMake(363, 10, 80, 34);
CGRect BoxRect13 = CGRectMake(418, 40, 24, 233);
CGRect BoxRect14 = CGRectMake(405, 272, 50, 50);
if (CGRectContainsPoint(BoxRect, ballPosition) && loBall.BallDirection == 0) {
point1 = CGPointMake(50, 283);
point2 = CGPointMake(50, 40);
loBall.position = [self DrawStrightLine:point1 SecondPoint:point2 BallMovementlength:AnimationMoveLength t:loBall.ballAngle];
loBall.ballAngle++;
if (CGRectContainsPoint(BoxRect2, loBall.position)) {
loBall.ballAngle = 1;
loBall.BallDirection = 1;
}
}
else if (CGRectContainsPoint(BoxRect2, ballPosition) && loBall.BallDirection == 1) {
point1 = CGPointMake(50, 40);
point2 = CGPointMake(77, 10);
point3 = CGPointMake(104, 40);
loBall.position = [self DrawCurve:point1 secondPoint:point2 thirdPoint:point3 BallMovementlength:AnimationMoveLength t:loBall.ballAngle];
loBall.ballAngle++;
if (CGRectContainsPoint(BoxRect3, loBall.position)) {
loBall.ballAngle = 1;
loBall.BallDirection = 2;
}
}
else if (CGRectContainsPoint(BoxRect13, ballPosition) && loBall.BallDirection == 13){
// AnimationMoveLength = 4;
// loBall.BallForwardEnable = 0;
GameOverCompleted = 2;
[self GameOver];
[self RemoveBallsFromBG:loBall];
}
else{
NSLog(#"loBall.position:%#",NSStringFromCGPoint(loBall.position));
}
}
-(void)RemoveBallsFromBG:(BallImage *)loBall{
[loBall runAction:[CCScaleTo actionWithDuration:0.1 scale:.1]];
[self.mBallImageArray removeObject:loBall];
[self removeChild:loBall cleanup:YES];
loBall = nil;
BallImage *loTarSpr = (BallImage *)[self getChildByTag:200];
[self removeChild:loTarSpr cleanup:YES];
loTarSpr = nil;
if ([self.mBallImageArray count] == 0) {
[self unscheduleAllSelectors];
[self LossGame];
}
}
-(void)GameOver{
static int i = 0;
if (i == 0) {
i++;
for (int loop = 0; loop < [self.mBallImageArray count]; loop++) {
BallImage *loBall = [self.mBallImageArray objectAtIndex:loop];
loBall.BallAnimationEnable = 1;
}
[self unscheduleAllSelectors];
[self schedule:#selector(MoveBall:)];
}
if ([self.mBallImageArray count] == 0) {
[self LossGame];
[self unscheduleAllSelectors];
i = 0;
}
}
-(void)WinGame{
GameOverCompleted = 2;
NSLog(#"WinGame");
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[CommonUserDetails sharedUserDetails].GameWinOrNot = 1;
[CommonUserDetails sharedUserDetails].GameScore = TotalScore;
[[CommonUserDetails sharedUserDetails].HighScoreArray addObject:[NSString stringWithFormat:#"%d",TotalScore]];
if ([[CommonUserDetails sharedUserDetails].HighScoreArray count] > 50) {
[[CommonUserDetails sharedUserDetails].HighScoreArray removeObjectAtIndex:0];
}
[[CommonUserDetails sharedUserDetails] saveToUserDefaults];
[self unscheduleAllSelectors];
[[CCDirector sharedDirector] replaceScene:[GameOverScene node]];
}
-(void)LossGame{
GameOverCompleted = 2;
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[CommonUserDetails sharedUserDetails].GameWinOrNot = 0;
[CommonUserDetails sharedUserDetails].GameScore = TotalScore;
[[CommonUserDetails sharedUserDetails].HighScoreArray addObject:[NSString stringWithFormat:#"%d",TotalScore]];
if ([[CommonUserDetails sharedUserDetails].HighScoreArray count] > 50) {
[[CommonUserDetails sharedUserDetails].HighScoreArray removeObjectAtIndex:0];
}
[[CommonUserDetails sharedUserDetails] saveToUserDefaults];
[self unscheduleAllSelectors];
[[CCDirector sharedDirector] replaceScene:[GameOverScene node]];
NSLog(#"Loss Game");
}
any one please help me for this .why it is crashing and give any suggestion for this issue
Thank you very much