步骤1:显示图片
用二维数组来显示8张90×90的配对图片,用来翻转的;首先显示的是背景图片。定义一个二维数组pic[4][4] 来表示每张小图片存放的位置,数组里面存放0~7的数字,当前位置存放是0,就表示该位置要显示image0小图片。这样就可以显示所有小图片了。
步骤2: 实现可以翻转
根据鼠标点击的位置,翻转指定的小图片,而且要自动的翻转回来,主要是鼠标的获取和定位;定义一个二维数组flag[mouse_y/90][mouse_x/90] 来标志有没有翻转,鼠标点击的坐标位置除以90就可以确定点击的是哪张小图片。
步骤3: 游戏逻辑翻转
所谓逻辑翻转就是根据游戏的规则翻转和不翻转图片,就是当鼠标点击次数为偶数时,判断前面的一张图片和当前这张图片是否相同,如果是相同的,这两张图片就不要翻转回背面,否则,就把这两张图片都翻转回背面。主要还是怎样判断两张图片是否相同,解决方法是根据一开始的二维数组pic[4][4]里面存放的数字是否是相同的来判断两张图片是否是相同的。直到所有的小图片都被翻转了游戏就结束。最后利用了SDL的强大功能弄了一个动画的界面来结束游戏。
下面是完整的代码:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include
#include
#include
const int SCREEN_WIDTH = 360; //屏幕宽
const int SCREEN_HEIGHT = 360; //屏幕高
const int SCREEN_BPP = 32; //屏幕像素
const int FRAMES_PER_SECOND = 10;
const int FOO_WIDTH = 90; //小图片90*90
const int FOO_HEIGHT = 90;
SDL_Surface * foo = NULL;
SDL_Surface * screen = NULL;
SDL_Surface *image0 = NULL;
SDL_Surface *image1 = NULL;
SDL_Surface *image2 = NULL;
SDL_Surface *image3 = NULL;
SDL_Surface *image4 = NULL;
SDL_Surface *image5 = NULL;
SDL_Surface *image6 = NULL;
SDL_Surface *image7 = NULL;
SDL_Surface *Menu = NULL;
SDL_Surface *beginBg = NULL;
SDL_Surface * endBg = NULL;
SDL_Event event;
//定义一个二维数组,用来保存图片索引
int pic[4][4];
bool flag[4][4]; //标记图像是否翻开
bool mousecheck; //记录鼠标点击状态
int pic_x, pic_y; //图片索引
int mouse_x;
int mouse_y; //鼠标点击位置
bool quit = false;
bool lock;
int GameState;//游戏当前状态
const int BEGIN = 0;//开始状态
const int RUN = 1;//运行状态
const int END = 2;//结束状态
SDL_Rect MenuRect[2];
SDL_Rect EndRect[2];
int end_y;
class Foo
{
private:
int offSet;
int velocity;
int frame;
public:
Foo();
int handle_events();
void show();
};
Foo Show;
Foo::Foo()
{
offSet = 0;
velocity = 0;
}
//读入图片
SDL_Surface *load_image(std::string filename)
{
SDL_Surface * loadedImage = NULL;
SDL_Surface * optimizedImage = NULL;
loadedImage = IMG_Load(filename.c_str());
if(loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
if(optimizedImage != NULL)
{
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, \
SDL_MapRGB(optimizedImage->format, 0, 0xF8, 0xF8));
}
}
return optimizedImage;
}
//显示图片
void apply_surface(int x, int y, SDL_Surface *source, \
SDL_Surface * destination, SDL_Rect *clip = NULL)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
//初始化图片索引的函数
void initIndex()
{
srand(time(NULL));
int k=0;
//初始化
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
pic[i][j] = k++;
k %= 8;
}
}
//随机
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
int x = rand()%4;
int y = rand()%4;
int temp = pic[i][j];
pic[i][j] = pic[x][y];
pic[x][y] = temp;
}
}
//初始化为背面
memset(flag, 0, sizeof(flag));
mousecheck = true;
pic_x = -1;
lock = false;
quit = false;
end_y = 30;
GameState = BEGIN;
MenuRect[0].x = 0;
MenuRect[0].y = 0;
MenuRect[0].w= 125;
MenuRect[0].h = 30;
MenuRect[1].x = 0;
MenuRect[1].y = 60;
MenuRect[1].w= 125;
MenuRect[1].h = 30;
EndRect[0].x = 0;
EndRect[0].y = 150;
EndRect[0].w = 360;
EndRect[0].h = 30;
EndRect[1].x = 0;
EndRect[1].y = 180;
EndRect[1].w = 360;
EndRect[1].h = 30;
}
bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
return false;
}
screen = SDL_SetVideoMode( SCREEN_WIDTH, \
SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if( screen == NULL)
{
return false;
}
SDL_WM_SetCaption("Memory Game", NULL);
return true;
}
bool load_files()
{
beginBg = load_image("pic/begin.bmp");
endBg = load_image("pic/end.bmp");
Menu = load_image("pic/menu.bmp");
foo = load_image("pic/bgimage.bmp");
image0 = load_image("pic/image0.bmp");
image1 = load_image("pic/image1.bmp");
image2 = load_image("pic/image2.bmp");
image3 = load_image("pic/image3.bmp");
image4 = load_image("pic/image4.bmp");
image5 = load_image("pic/image5.bmp");
image6 = load_image("pic/image6.bmp");
image7 = load_image("pic/image7.bmp");
if( NULL == foo || NULL == endBg || NULL == Menu || NULL == beginBg || NULL == image0 \
|| NULL == image1 || NULL == image2 || NULL == image3 || NULL == image4 \
|| NULL == image5 || NULL == image6 || NULL == image7 )
{
return false;
}
return true;
}
void clean_up()
{
SDL_FreeSurface(foo);
SDL_FreeSurface(endBg);
SDL_FreeSurface(image0);
SDL_FreeSurface(image1);
SDL_FreeSurface(image2);
SDL_FreeSurface(image3);
SDL_FreeSurface(image4);
SDL_FreeSurface(image5);
SDL_FreeSurface(image6);
SDL_FreeSurface(image7);
SDL_FreeSurface(Menu);
SDL_FreeSurface(beginBg);
SDL_Quit();
}
int Foo::handle_events()
{
int x =0, y = 0;
if(event.type == SDL_MOUSEMOTION)
{
//获取新鼠标偏移位置
x = event.motion.x;
y = event.motion.y;
if(y>=250 && y<=280 && x>= 230 && x<355)
{
//第一项
MenuRect[0].y = 30;
}
else if(y>=290 && y<=320 && x>= 230 && x<355)
{
//第二项
MenuRect[1].y = 90;
}
else
{
MenuRect[0].y = 0;
MenuRect[1].y = 60;
}
}
//鼠标按键按下
if( event.type == SDL_MOUSEBUTTONUP)
{
//如果鼠标左键已经放开
if( event.button.button == SDL_BUTTON_LEFT)
{
//获取鼠标的偏移位置
x = event.button.x;
y = event.button.y;
//如果鼠标在图片上
if(GameState == BEGIN)
{
if(y>=250 && y<=280 && x>= 230 && x<355)
{
//第一项
GameState = RUN;
}
else if(y>=290 && y<=320 && x>= 230 && x<355)
{
//第二项
quit = true;
}
}
else if(GameState == RUN)
{
if(lock && !flag[y/90][x/90]) //如果没翻开,那就翻开
{
flag[y/90][x/90] = true;
mousecheck = !mousecheck; //变换当前状态
mouse_x = x;
mouse_y = y;
lock = false;
}
}
}
}
}
void logic()
{
if(GameState == RUN && lock == false)
{
//判断是否翻开一对
if(mousecheck) //双
{
if((pic_x != -1)&&(pic[pic_x][pic_y] != pic[mouse_y/90][mouse_x/90]) )
{
//取反?
flag[pic_x][pic_y] = false;
flag[mouse_y/90][mouse_x/90] = false;
}
}
else//单数,记录位置
{
pic_x = mouse_y/90;
pic_y = mouse_x/90;
}
lock = true;
//判断是否全部翻开
bool isopen = true;
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
if(flag[i][j] == false) //有没有翻开的
{
isopen = false;
}
}
}
if(isopen)
{
GameState = END;
}
}
else if(GameState == END)
{
end_y += 30;
if(end_y > 180)
{
end_y = 180;
//quit = true;
}
EndRect[0].y = 180-end_y;
EndRect[0].h = end_y;
EndRect[1].h = end_y;
}
}
void Foo::show()
{
if(GameState == BEGIN)//如果开始状态,显示开始图片
{
apply_surface(0, 0, beginBg, screen);
for(int i=0; i<2; i++)
{
apply_surface(230, 250+i*40, Menu, screen, &MenuRect[i]);
}
}
else if(GameState == RUN)
{
//遍历图像索引,在相应位置显示图像
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
if(flag[i][j]) //翻开
{
switch(pic[i][j])
{
case 0: apply_surface(90*j,90*i, image0, screen); break;
case 1: apply_surface(90*j,90*i, image1, screen); break;
case 2: apply_surface(90*j,90*i, image2, screen); break;
case 3: apply_surface(90*j,90*i, image3, screen); break;
case 4: apply_surface(90*j,90*i, image4, screen); break;
case 5: apply_surface(90*j,90*i, image5, screen); break;
case 6: apply_surface(90*j,90*i, image6, screen); break;
case 7: apply_surface(90*j,90*i, image7, screen); break;
}
}
else//没翻开
{
apply_surface(90*j,90*i, foo, screen);
}
}
}
}
else if(GameState == END)
{
//apply_surface(0, 0, endBg, screen);
apply_surface(0, 0, endBg, screen, &EndRect[0]);
apply_surface(0, 360-end_y, endBg, screen, &EndRect[1]);
}
}
int main(int argc, char *args[])
{
if( init() == false)
{
printf("init error...\n");
return 1;
}
if( load_files() == false)
{
printf("load_files error...\n");
return 1;
}
initIndex(); //初始化二维数组
while( quit == false )
{
logic();
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
Show.handle_events();
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
{
printf("escape button is pressed\n");
quit = true;
break;
}
}
}
}
Show.show();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
if(GameState == RUN)
SDL_Delay(500);
if(GameState == END)
SDL_Delay(150);
}
//Clean up
clean_up();
return 0;
}
运行效果图片,请读者自行运行。
下载图片地址:http://download.csdn.net/detail/shiren_bod/4409888