Linux基于SDL图形库程序,基于Linux系统的SDL图形库记忆翻牌小游戏

步骤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;

}

运行效果图片,请读者自行运行。

a8ff6f1907984d20e547438a7bb9c28e.png

下载图片地址:http://download.csdn.net/detail/shiren_bod/4409888

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XO_OX 0.0 这些是“XO_OX"的注解。它们会让你全面了解这个游戏,并会说明如何安装它。 什么是“XO_OX"? “XO_OX"又名“五子棋”,五子棋则咸信是流传于古中国的传统棋种之一,至今仍在民间广泛流传,规则相当简单。或许因没有形成一套独立完整的棋种理论及文化内涵,更无制定公平完善的规则来解决黑白平衡问题,一直没有得到发展,所以没有像六博、格五、弹棋等传统棋类流传广泛,导致缺少可考古的棋具或文献,直到流传到外国才规则改革。 不管是哪种五子棋,棋手在先后手的观念、空间的思维及对棋形的理解都十分重要。 游戏规则: * 行棋:一人流轮一著下于棋盘空点处,下后不得移动。 * 胜负:先把五枚或以上己棋相连成任何横纵斜方向为胜。 * 和棋: o 行棋中一方提出和棋,另一方同意则判和棋。 o 棋子落满整张棋盘仍未分出胜负为和棋。 o 一方PASS后另一方下一手也PASS为和棋。 技术规格说明: 1、用C语言调用SDL实现; 2、基于LGPL协议。 3、程序中用到了SDL_image扩展包 如何安装: 1、在终端中运行make 2、在终端中运行make install 如何卸载: make uninstall 历史: 一、2011年8月15日 项目开始,谢红负责图形模块,赵梓辰负责游戏逻辑,吕玉飞负责事件响应,范人豪负责整体架构。 二、2011年8月17日 为了增加游戏的可玩性,项目由圈叉棋升级为五子棋。
SDL(Simple DirectMedia Layer)是一个跨平台的、开源的、C语言编写的图形库,用于游戏和多媒体应用程序的开发。下面是一个简单的SDL程序示例: 1. 导入SDL头文件: ``` #include <SDL2/SDL.h> ``` 2. 初始化SDL: ``` if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL_Init Error: %s\n", SDL_GetError()); return 1; } ``` 3. 创建窗口: ``` SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN); if (win == NULL) { printf("SDL_CreateWindow Error: %s\n", SDL_GetError()); return 1; } ``` 4. 创建渲染器: ``` SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { SDL_DestroyWindow(win); printf("SDL_CreateRenderer Error: %s\n", SDL_GetError()); SDL_Quit(); return 1; } ``` 5. 加载图片: ``` SDL_Surface *bmp = SDL_LoadBMP("hello.bmp"); if (bmp == NULL) { SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); printf("SDL_LoadBMP Error: %s\n", SDL_GetError()); SDL_Quit(); return 1; } ``` 6. 创建纹理: ``` SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp); SDL_FreeSurface(bmp); if (tex == NULL) { SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); printf("SDL_CreateTextureFromSurface Error: %s\n", SDL_GetError()); SDL_Quit(); return 1; } ``` 7. 渲染纹理: ``` SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); ``` 8. 等待退出: ``` SDL_Delay(2000); ``` 9. 释放资源: ``` SDL_DestroyTexture(tex); SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit(); ``` 这是一个非常简单的SDL程序示例,但是它演示了如何使用SDL创建一个窗口、渲染图片和退出程序。更多高级的功能,如音频、输入、事件处理等,需要查阅SDL的文档和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值