Hello forum. I’ve decided to do a simple game of tic tac toe but I came across problems after fixing problems. It gotten me to the point where I’m questioning my way of doing this. I’m going to reveal what my goals were. I wanted to create 9 buttons and set them to a constant value when they were clicked. I would neatly arrange everything including the detection boxes of the button and check certain button combinations to determine a winner.
Anyways my problems are
*the image isn’t being clipped correctly.
*multiple buttons appear activated by one.
*No idea how to deal with AI/computer/cpu/ect
I have a gut feeling my code is wonky with my event handling function at the bottom but I can’t figure why.
void OX::handle_events()
{
//The mouse offsets
int x = 0, y = 0;
//If a mouse button was pressed
if( event.type == SDL_MOUSEBUTTONDOWN )
{
//If the left mouse button was pressed
if( event.button.button == SDL_BUTTON_LEFT )
{
//Get the mouse offsets
x = event.button.x;
y = event.button.y;
//If the mouse is over the button
if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
{
clip = &clips[CLIP_O];
}
}
}
}
void OX::show()
{
//Show the button
apply_surface( box.x, box.y, TTTox, screen, clip );
}
int main( int argc, char* args[] )
{
//Make sure the program waits for a quit
bool quit = false;
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Apply the surface to the screen
apply_surface( 0, 0, TTTfield, screen );
//Clip the sprite sheet
set_clips();
//Make the buttons
OX myButton(1, 0, 26, 31);
OX myButton1 (28, 0, 54, 31);
OX myButton2 (56, 0, 82, 31);
OX myButton3 (1, 33, 26, 64);
OX myButton4 (28, 33, 54, 64);
OX myButton5 (56, 33, 82, 64);
OX myButton6 (1, 66, 26, 97);
OX myButton7 (28, 66, 54, 97);
OX myButton8 (56, 66, 82, 97);
//While the user hasn't quit
while( quit == false )
{
//If there's events to handle
if( SDL_PollEvent( &event ) )
{
//Handle button events
myButton.handle_events();
myButton1.handle_events();
myButton2.handle_events();
myButton3.handle_events();
myButton4.handle_events();
myButton5.handle_events();
myButton6.handle_events();
myButton7.handle_events();
myButton8.handle_events();
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
//Show the button
myButton.show();
myButton1.show();
myButton2.show();
myButton3.show();
myButton4.show();
myButton5.show();
myButton6.show();
myButton7.show();
myButton8.show();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
//Free the surface and quit SDL
clean_up();
return 0;
}
Here is all my code if you suspect I’m looking in the wrong areas
//The headers
#include “SDL.h”
#include “SDL_image.h”
#include
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
//The button states in the sprite sheet
const int CLIP_X = 0;
const int CLIP_O = 1;
const int CLIP_BLINK = 2;
//The surfaces
SDL_Surface *TTTox = NULL;
SDL_Surface *TTTfield = NULL;
SDL_Surface *screen = NULL;
//The event structure that will be used
SDL_Event event;
//Portions of the TTTox file
SDL_Rect clips[3];
//The buttons
class OX
{
private:
//The attributes of the button
SDL_Rect box;
//The part of the button sprite sheet that will be shown
SDL_Rect* clip;
public:
//Initialize the variables
OX( int x, int y, int w, int h );
//Handles events and set the button's sprite region
void handle_events();
//Shows the button on the screen
void show();
};
SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load( filename.c_str() );
//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized surface
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old surface
SDL_FreeSurface( loadedImage );
//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}
//Return the optimized surface
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Temporary rectangle to hold the offsets
SDL_Rect offset;
//Get the offsets
offset.x = x;
offset.y = y;
//Blit the surface
SDL_BlitSurface( source, clip, destination, &offset );
}
bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "Tic tac toe", NULL );
//If everything initialized fine
return true;
}
bool load_files()
{
//Load the image
TTTfield = load_image( "TTTfield.png" );
//If there was an error in loading the image
if( TTTfield == NULL )
{
return false;
}
TTTox = load_image( "TTTox.png" );
if( TTTox == NULL )
{
return false;
}
//If everything loaded fine
return true;
}
void clean_up()
{
//Free the surface
SDL_FreeSurface( TTTfield );
SDL_FreeSurface( TTTox );
//Quit SDL
SDL_Quit();
}
void set_clips()
{
//Clip range for the top left
clips[ CLIP_O ].x = 0;
clips[ CLIP_O ].y = 0;
clips[ CLIP_O ].w = 26;
clips[ CLIP_O ].h = 31;
//Clip range for the top right
clips[ CLIP_X ].x = 27;
clips[ CLIP_X ].y = 0;
clips[ CLIP_X ].w = 50;
clips[ CLIP_X ].h = 31;
//Clip range for white space
clips[ CLIP_BLINK ].x = 54;
clips[ CLIP_BLINK ].y = 0;
clips[ CLIP_BLINK ].w = 79;
clips[ CLIP_BLINK ].h = 31;
}
OX::OX( int x, int y, int w, int h )
{
//Set the button's attributes
box.x = x;
box.y = y;
box.w = w;
box.h = h;
//Set the default sprite
clip = &clips[ CLIP_BLINK ];
}
void OX::handle_events()
{
//The mouse offsets
int x = 0, y = 0;
//If a mouse button was pressed
if( event.type == SDL_MOUSEBUTTONDOWN )
{
//If the left mouse button was pressed
if( event.button.button == SDL_BUTTON_LEFT )
{
//Get the mouse offsets
x = event.button.x;
y = event.button.y;
//If the mouse is over the button
if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
{
clip = &clips[CLIP_O];
}
}
}
}
void OX::show()
{
//Show the button
apply_surface( box.x, box.y, TTTox, screen, clip );
}
int main( int argc, char* args[] )
{
//Make sure the program waits for a quit
bool quit = false;
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Apply the surface to the screen
apply_surface( 0, 0, TTTfield, screen );
//Clip the sprite sheet
set_clips();
//Make the buttons
OX myButton(1, 0, 26, 31);
OX myButton1 (28, 0, 54, 31);
OX myButton2 (56, 0, 82, 31);
OX myButton3 (1, 33, 26, 64);
OX myButton4 (28, 33, 54, 64);
OX myButton5 (56, 33, 82, 64);
OX myButton6 (1, 66, 26, 97);
OX myButton7 (28, 66, 54, 97);
OX myButton8 (56, 66, 82, 97);
//While the user hasn't quit
while( quit == false )
{
//If there's events to handle
if( SDL_PollEvent( &event ) )
{
//Handle button events
myButton.handle_events();
myButton1.handle_events();
myButton2.handle_events();
myButton3.handle_events();
myButton4.handle_events();
myButton5.handle_events();
myButton6.handle_events();
myButton7.handle_events();
myButton8.handle_events();
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
//Show the button
myButton.show();
myButton1.show();
myButton2.show();
myButton3.show();
myButton4.show();
myButton5.show();
myButton6.show();
myButton7.show();
myButton8.show();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
//Free the surface and quit SDL
clean_up();
return 0;
}