分类: LINUX
2006-05-26 10:34:41
#include
#include
#include
#include "font.h"
#define TICK_INTERVAL 40
#define TIME_LEFT 1
#define START 1
#define SETUP 2
#define EXIT 3
void wblx();
void game_init();
void game_over();
void draw_box(SDL_Surface *surface,int x,int y,int w,int h,Uint32 color);
int main_menu();
void setup_menu();
void data_init();
void game_main_loop();
void disp_result(int);
SDL_Surface *screen;
SDL_Surface *background;
Uint8 game_runing;
int Sound=1;
Mix_Chunk *beep;
int SVolume=128;
Uint8 keys[4];
Uint8 hits;
Uint32 lastTick,curTick;
int tick_interval=40;
int time_slice=1;
int time_left;
int count;
struct hz_info{
unsigned char word[2];
unsigned char code[4];
int index;
int x,y;
int time;
int kill;
SDL_Surface *Sprite;
SDL_Rect SrcMap;
SDL_Rect DesMap;
}hz[4];
/* ------------------------------ */
int main()
{
wblx();
}
/* ------------------------------ */
void wblx()
{
int chose;
game_init();
for(;;){
chose=main_menu();
if(chose==START){game_runing=1;game_main_loop();}
else if(chose==SETUP)setup_menu();
else if(chose==EXIT)break;
}
game_over();
}
/* --------------------------- */
int is_same(Uint8 *str1,Uint8 *str2,int length)
{
int i;
for(i=0;i
}
/* --------------------------- */
void ClearSurface(SDL_Surface *surface)
{
Uint32 color;
SDL_Rect clip;
clip.x=0;
clip.y=0;
clip.w=surface->w;
clip.h=surface->h;
color=SDL_MapRGB(surface->format,0,0,0);
SDL_FillRect(surface,&clip,color);
}
/* --------------------------- */
void Create_hzSprite(int i)
{
int j;
int LL=20;
float RR=100.0;
int WW=136;
int Range=3333;
int color;
hz[i].time=0;
hz[i].x=LL+1+(int)(RR*rand()/(RAND_MAX+1.0))+i*WW;
hz[i].y=(1+(int)(100.0*rand()/(RAND_MAX+1.0)));
hz[i].index=1+(int)((float)Range*rand()/(RAND_MAX+1.0))-1;
hz[i].word[0]=wbTAB[hz[i].index*6+0];
hz[i].word[1]=wbTAB[hz[i].index*6+1];
for(j=0;j<4;j++)hz[i].code[j]=wbTAB[hz[i].index*6+2+j];
hz[i].kill=0;
if(hz[i].Sprite==NULL){
printf("Error!\n");
exit(-1);
}
hz[i].Sprite=SDL_DisplayFormat(hz[i].Sprite);
ClearSurface(hz[i].Sprite);
SDL_SetColorKey(hz[i].Sprite,SDL_SRCCOLORKEY,
SDL_MapRGB(hz[i].Sprite->format,0,0,0));
color=SDL_MapRGB(screen->format,255,255,255);
cputchar2x(hz[i].Sprite,0,0,color,hz[i].word);
hz[i].SrcMap.x=hz[i].DesMap.x=hz[i].x;
hz[i].SrcMap.y=hz[i].DesMap.y=hz[i].y;
hz[i].SrcMap.w=hz[i].DesMap.w=32;
hz[i].SrcMap.h=hz[i].DesMap.h=32;
hz[i].DesMap.y=0;
hz[i].SrcMap.y=0;
}
/* ------------------------------ */
void PlaySound(Mix_Chunk *Snd)
{
int channel;
if(Sound){
Mix_Volume(1,SVolume);
Mix_PlayChannel(1,Snd,0);
}
}
/* ------------------------------ */
void game_init()
{
int i;
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)<0){
fprintf(stderr,"Can't init SDL:%s\n",SDL_GetError());
exit(1);
}
screen=SDL_SetVideoMode(640,480,16,SDL_SWSURFACE);
if(screen==NULL){
fprintf(stderr,"Can't set mode 640x480:%s\n",SDL_GetError());
exit(1);
}
SDL_ShowCursor(0);
// Create backgroud surface
background=SDL_CreateRGBSurface(SDL_SRCALPHA,640,480,16,
screen->format->Rmask,screen->format->Gmask,
screen->format->Bmask,screen->format->Amask);
if(background==NULL){
printf("Out of memory!\n");
exit(1);
}
background=SDL_DisplayFormat(background);
// Font init
font_init();
// Hz sprite init
for(i=0;i<4;i++){
hz[i].Sprite=SDL_CreateRGBSurface(SDL_SRCALPHA,32,32,16,
screen->format->Rmask,screen->format->Gmask,
screen->format->Bmask,screen->format->Amask);
if(hz[i].Sprite==NULL){
printf("Out of memory!\n");
exit(1);
}
}
// Init sound
if(Sound){
if(Mix_OpenAudio(22050,AUDIO_S16,1,1024)<0){
fprintf(stderr,"Warning:Couldn't set 22050 Hz 16-bit audio\n-Redson:%s\n",
SDL_GetError());
Sound=0;
}
beep=Mix_LoadWAV("./wav/kill.wav");
}
}
/* ------------------------------ */
void game_over()
{
int i;
font_free();
if(background!=NULL)SDL_FreeSurface(background);
for(i=0;i<4;i++)if(hz[i].Sprite!=NULL)SDL_FreeSurface(hz[i].Sprite);
atexit(SDL_Quit);
printf("");
}
/* ------------------------------ */
void draw_box(SDL_Surface *surface,int x,int y,int w,int h,Uint32 color)
{
SDL_Rect box;
box.x=x;box.y=y;
box.w=w;box.h=h;
SDL_FillRect(surface,&box,color);
SDL_UpdateRect(screen,x,y,w,h);
}
/* ------------------------------ */
int get_key()
{
SDL_Event event;
for(;;){
SDL_WaitEvent(&event);
switch(event.type){
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_ESCAPE){
printf("ESC!\n");
return;
}
else if(event.key.keysym.sym==SDLK_RETURN){
game_runing=1;
data_init();
return;
}
break;
case SDL_QUIT:
printf("SDL QUIT.\n");
exit(0);
}
}
}
/* ------------------------------ */
int main_menu()
{
int key;
int select=0;
Uint32 color;
SDL_Surface *logo;
SDL_Event event;
SDL_Rect logoMap={0,0,32,32};
SDL_Rect Mask={190,200,32,320};
SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,0,0));
color=SDL_MapRGB(screen->format,0,40,130);
draw_box(screen,80,20,480,80,color);
color=SDL_MapRGB(screen->format,255,255,255);
draw_box(screen,90,30,460,60,color);
color=SDL_MapRGB(screen->format,0,40,130);
draw_box(screen,92,32,456,56,color);
color=SDL_MapRGB(screen->format,255,226,65);
ecprint2x(screen,60,22,color,"五笔练习 for Linux V0.6.8"),
/*color=SDL_MapRGB(screen->format,255,255,255);*/
ecprint2x(screen,120,100,color,"开 始 练 习");
ecprint2x(screen,120,130,color,"参 数 设 置");
ecprint2x(screen,120,160,color,"退 出 游 戏");
SDL_UpdateRect(screen,0,0,0,0);
logo=SDL_LoadBMP("bmp/logo.bmp");
if(logo==NULL)return EXIT;
SDL_SetColorKey(logo,SDL_SRCCOLORKEY,SDL_MapRGB(logo->format,255,0,255));
SDL_SetAlpha(logo,SDL_SRCALPHA,255);
logo=SDL_DisplayFormat(logo);
SDL_BlitSurface(logo,NULL,screen,&Mask);
SDL_UpdateRect(screen,Mask.x,Mask.y,Mask.w,Mask.h);
Mask.w=32;Mask.h=320;
for(;;){
SDL_WaitEvent(&event);
switch(event.type){
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_RETURN||event.key.keysym.sym==SDLK_SPACE){
return (select+1);
}
if(event.key.keysym.sym==SDLK_ESCAPE){
return EXIT;
}
if(event.key.keysym.sym==SDLK_UP){
select--;if(select<0)select=2;
logoMap.x=190;logoMap.y=200+select*60;
SDL_FillRect(screen,&Mask,SDL_MapRGB(screen->format,0,0,0));
SDL_BlitSurface(logo,NULL,screen,&logoMap);
SDL_UpdateRect(screen,Mask.x,Mask.y,Mask.w,Mask.h);
SDL_UpdateRect(screen,logoMap.x,logoMap.y,logoMap.w,logoMap.h);
}
if(event.key.keysym.sym==SDLK_DOWN){
select++;if(select>2)select=0;
logoMap.x=190;logoMap.y=200+select*60;
SDL_FillRect(screen,&Mask,SDL_MapRGB(screen->format,0,0,0));
SDL_BlitSurface(logo,NULL,screen,&logoMap);
SDL_UpdateRect(screen,Mask.x,Mask.y,Mask.w,Mask.h);
/*SDL_UpdateRect(screen,logoMap.x,logoMap.y,logoMap.w,logoMap.h);*/
}
break;
case SDL_QUIT:
return EXIT;
}
}
return EXIT;
}
/* ------------------------------ */
void setup_menu()
{
int i;
Uint32 color;
int select=0;
static int sub_select[3]={1,1,0};
char code[2];
char *menu_item[]={
"难 度: 低",
"难 度: 中",
"难 度: 高",
"速 度: 慢",
"速 度: 中",
"速 度: 快",
"时 间: 1 分钟",
"时 间: 5 分钟",
"时 间: 8 分钟"
};
SDL_Event event;
SDL_Rect Mask={190,200,32,320};
SDL_Rect Mask2={240,260,200,32};
// Show title
SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,0,0));
color=SDL_MapRGB(screen->format,0,40,130);
draw_box(screen,80,20,480,80,color);
color=SDL_MapRGB(screen->format,255,255,255);
draw_box(screen,90,30,460,60,color);
color=SDL_MapRGB(screen->format,0,40,130);
draw_box(screen,92,32,456,56,color);
color=SDL_MapRGB(screen->format,255,226,65);
ecprint2x(screen,60,22,color," 参 数 设 置 ");
SDL_UpdateRect(screen,0,0,0,0);
// Show menu
for(i=0;i<3;i++)ecprint2x(screen,120,100+i*30,color,
menu_item[i*3+sub_select[i]]);
code[0]=12+0xa0;code[1]=85+0xa0;
cputchar2x(screen,95,100,SDL_MapRGB(screen->format,255,255,255),code);
// Wait for key
for(;;){
SDL_WaitEvent(&event);
switch(event.type){
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_ESCAPE)return;
else if(event.key.keysym.sym==SDLK_RETURN)return;
else if(event.key.keysym.sym==SDLK_UP){
select--;if(select<0)select=2;
SDL_FillRect(screen,&Mask,SDL_MapRGB(screen->format,0,0,0));
color=SDL_MapRGB(screen->format,255,255,255);
cputchar2x(screen,95,100+select*30,color,code);
SDL_UpdateRect(screen,Mask.x,Mask.y,Mask.w,Mask.h);
}
else if(event.key.keysym.sym==SDLK_DOWN){
select++;if(select>2)select=0;
SDL_FillRect(screen,&Mask,SDL_MapRGB(screen->format,0,0,0));
color=SDL_MapRGB(screen->format,255,255,255);
cputchar2x(screen,95,100+select*30,color,code);
SDL_UpdateRect(screen,Mask.x,Mask.y,Mask.w,Mask.h);
}
if(event.key.keysym.sym==SDLK_SPACE){
sub_select[select]++;
if(sub_select[select]>2)sub_select[select]=0;
if(select==0){}
else if(select==1){
if(sub_select[select]==0)tick_interval=55;
else if(sub_select[select]==1)tick_interval=40;
else if(sub_select[select]==2)tick_interval=20;
}
else if(select==2){
if(sub_select[select]==0)time_slice=1;
else if(sub_select[select]==1)time_slice=5;
else if(sub_select[select]==2)time_slice=8;
}
color=SDL_MapRGB(screen->format,255,226,65);
Mask2.y=200+select*60;
SDL_FillRect(screen,&Mask2,SDL_MapRGB(screen->format,0,0,0));
ecprint2x(screen,120,100+select*30,color,
menu_item[select*3+sub_select[select]]);
SDL_UpdateRect(screen,Mask2.x,Mask2.y,Mask2.w,Mask2.h);
}
break;
case SDL_QUIT:
return;
}
}
}
/* ------------------------------ */
int str_cmp(Uint8 *str1,Uint8 *str2,int length)
{
int i;
for(i=0;i
}
/* ------------------------------ */
void check_keys()
{
int i;
int index;
unsigned char t_word[2];
unsigned char t_code[4];
for(index=0;index<3333;index++){
// Get all wb code from wbTAB
for(i=0;i<4;i++)t_code[i]=wbTAB[index*6+2+i];
if(!str_cmp(t_code,keys,4))continue;
// Get index hz's word
t_word[0]=wbTAB[index*6+0];
t_word[1]=wbTAB[index*6+1];
// Yes! Now see this wb code map to which hz
for(i=0;i<4;i++){
if(str_cmp(t_word,hz[i].word,2)){
PlaySound(beep);
count++;
disp_result(count);
hz[i].kill=1;
break;
}
}
}
}
/* ------------------------------ */
void anykey()
{
int i;
Uint32 color;
SDL_Event event;
SDL_Rect input_rec={140,439,100,40};
SDL_PollEvent(&event);
switch(event.type){
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_ESCAPE){
game_runing=0;
break;
}
if(event.key.keysym.sym>=SDLK_a && event.key.keysym.sym<=SDLK_z){
keys[hits]=event.key.keysym.sym;
hits++;
if(hits<4){
color=SDL_MapRGB(screen->format,255,226,65);
eputchar2x(screen,72+(hits-1)*8,222,color,keys[hits-1]);
}
else {
SDL_FillRect(screen,&input_rec,SDL_MapRGB(screen->format,8,40,130));
SDL_UpdateRect(screen,input_rec.x,input_rec.y,input_rec.w,input_rec.h); hits=0;
check_keys();
}
}
if(event.key.keysym.sym==SDLK_SPACE){
SDL_FillRect(screen,&input_rec,SDL_MapRGB(screen->format,8,40,130));
SDL_UpdateRect(screen,input_rec.x,input_rec.y,input_rec.w,input_rec.h);
for(i=hits;i<4;i++)keys[i]='-';
check_keys();
hits=0;
}
break;
case SDL_QUIT:
printf("SDL_QUIT\n");
exit(0);
}
}
/* ------------------------------ */
Uint32 TimeLeft()
{
static Uint32 next_time=0;
Uint32 now;
now=SDL_GetTicks();
if(next_time<=now){
next_time=now+tick_interval;
return(0);
}
return(next_time-now);
}
/* --------------------------- */
void disp_time(int seconds)
{
int minute,second;
Uint32 color;
minute=seconds/60;
second=seconds-minute*60;
SDL_Rect timeMap={560,36,78,28};
SDL_FillRect(screen,&timeMap,SDL_MapRGB(screen->format,25,70,155));
color=SDL_MapRGB(screen->format,255,226,65);
eputchar2x(screen,280,16,color,minute+'0');
eputchar2x(screen,290,16,color,':');
eputchar2x(screen,300,16,color,(second/10+'0'));
eputchar2x(screen,310,16,color,second-second/10*10+'0');
SDL_UpdateRect(screen,timeMap.x,timeMap.y,timeMap.w,timeMap.h);
}
/* ------------------------------ */
void disp_result(int result)
{
Uint32 color;
SDL_Rect timeMap={560,96,78,28};
SDL_FillRect(screen,&timeMap,SDL_MapRGB(screen->format,25,70,155));
color=SDL_MapRGB(screen->format,255,226,65);
eputchar2x(screen,280,48,color,(result/1000+'0'));
result=result-result/1000*1000;
eputchar2x(screen,290,48,color,(result/100+'0'));
result=result-result/100*100;
eputchar2x(screen,300,48,color,result/10+'0');
eputchar2x(screen,310,48,color,result-result/10*10+'0');
SDL_UpdateRect(screen,timeMap.x,timeMap.y,timeMap.w,timeMap.h);
}
/* ------------------------------ */
void score(int count)
{
int speed;
Uint32 color;
/*SDL_Rect bMap={180,130,280,160};*/
SDL_Rect bMap={170,120,300,180};
SDL_Surface *board;
board=SDL_CreateRGBSurface(SDL_SRCALPHA,300,180,16,
screen->format->Rmask,screen->format->Gmask,
screen->format->Bmask,screen->format->Amask);
if(board==NULL)return;
board=SDL_DisplayFormat(board);
SDL_SetAlpha(board,SDL_SRCALPHA,220);
SDL_FillRect(board,NULL,SDL_MapRGB(screen->format,0,40,130));
draw_box(board,10,10,280,160,SDL_MapRGB(board->format,255,255,255));
draw_box(board,12,12,276,156,SDL_MapRGB(board->format,0,40,130));
//SDL_FillRect(board,&bMap,SDL_MapRGB(screen->format,255,255,255));
//color=SDL_MapRGB(board->format,255,255,255);
color=SDL_MapRGB(board->format,255,226,65);
ecprint2x(board,10,20,color,"速度: 字/分");
speed=count/time_slice;
eputchar2x(board,58,22,color,speed/10+'0');
eputchar2x(board,66,22,color,speed-speed/10*10+'0');
if(speed<30)ecprint2x(board,12,52,color,"继续加油啊!");
else if(speed<40)ecprint2x(board,10,52,color,"不错!请再接再励。");
else if(speed<50)ecprint2x(board,12,52,color,"果然厉害!继续吗?");
else if(speed<60)ecprint2x(board,10,52,color,"有两下子!再试试?");
else if(speed<70)ecprint2x(board,12,52,color,"啊?!真看不出来!");
else if(speed<80)ecprint2x(board,10,52,color,"恭喜你!打字高手!");
else if(speed<90)ecprint2x(board,10,52,color,"键盘被你敲坏了!!");
else if(speed>90)ecprint2x(board,10,52,color,"我的天!真是神了!");
//ecprint(board,64,144,color,"按回车键继续,ESC退出。");
ecprint(screen,234,412,color,"按回车键继续,ESC退出。");
SDL_BlitSurface(board,NULL,screen,&bMap);
SDL_UpdateRect(screen,0,0,0,0);
//get_key();
if(board!=NULL)SDL_FreeSurface(board);
}
/* ------------------------------ */
void UpdateGameState()
{
int i=0;
Uint32 color;
SDL_Rect hzMap={0,0,32,32};
curTick=SDL_GetTicks();
disp_time(time_left);
if((curTick-lastTick)>=1000){
time_left--;
if(time_left<0){
score(count);
game_runing=0;
get_key();
/*
game_runing=0;
time_left=TIME_LEFT*60;
score(count);
hits=0;
*/
}
lastTick=curTick;
}
for(i=0;i<4;i++){
hz[i].DesMap.y++;
if(hz[i].DesMap.y>400){
SDL_BlitSurface(background,&hz[i].SrcMap,screen,&hz[i].SrcMap);
SDL_UpdateRect(screen,0,0,0,0);
Create_hzSprite(i);
continue;
}
if(hz[i].kill==1){
SDL_BlitSurface(background,&hz[i].SrcMap,screen,&hz[i].SrcMap);
SDL_UpdateRect(screen,0,0,0,0);
Create_hzSprite(i);
continue;
}
SDL_BlitSurface(background,&hz[i].SrcMap,screen,&hz[i].SrcMap);
// ReDraw dirty rectgle only , quikly
// SDL_BlitSurface(backBmp,&hz[i].DesMap,screen,&hz[i].DesMap);
SDL_BlitSurface(hz[i].Sprite,&hzMap,screen,&hz[i].DesMap);
// Update dirty rectgle only
SDL_UpdateRect(screen,hz[i].SrcMap.x,hz[i].SrcMap.y,
hz[i].SrcMap.w,hz[i].SrcMap.h);
SDL_UpdateRect(screen,hz[i].DesMap.x,hz[i].DesMap.y,
hz[i].DesMap.w,hz[i].DesMap.h);
hz[i].SrcMap.y=hz[i].DesMap.y;
}
}
/* ------------------------------ */
void data_init()
{
int i;
Uint32 color;
SDL_Surface *Clock;
SDL_Surface *Tip;
SDL_Rect input_bar={0,439,640,40};
SDL_Rect clockMap={556,4,24,24};
SDL_Rect tipMap={556,66,24,24};
// Show background
SDL_FillRect(background,NULL,SDL_MapRGB(background->format,25,70,155));
SDL_FillRect(background,&input_bar,SDL_MapRGB(background->format,8,40,130));
color=SDL_MapRGB(background->format,65,107,184);
ecprint2x(background,5,3,color,"五笔练习 for Linux V0.6.8");
color=SDL_MapRGB(background->format,16,55,145);
ecprint2x(background,6,2,color,"五笔练习 for Linux V0.6.8");
color=SDL_MapRGB(background->format,255,226,65);
ecprint2x(background,2,222,color,"〖五笔〗");
ecprint2x(background,250,222,color,"退出:ESC");
Clock=SDL_LoadBMP("./bmp/clock.bmp");
Tip=SDL_LoadBMP("./bmp/tip.bmp");
if(Clock==NULL||Tip==NULL){printf("Clock error.\n");exit(-1);}
SDL_SetColorKey(Clock,SDL_SRCCOLORKEY,SDL_MapRGB(Clock->format,255,0,255));
SDL_SetColorKey(Tip,SDL_SRCCOLORKEY,SDL_MapRGB(Clock->format,255,0,255));
SDL_SetAlpha(Clock,SDL_SRCALPHA,180);
SDL_SetAlpha(Tip,SDL_SRCALPHA,180);
Clock=SDL_DisplayFormat(Clock);
Tip=SDL_DisplayFormat(Tip);
SDL_BlitSurface(Tip,NULL,background,&tipMap);
SDL_BlitSurface(Clock,NULL,background,&clockMap);
if(Clock!=NULL)SDL_FreeSurface(Clock);
if(Tip!=NULL)SDL_FreeSurface(Tip);
color=SDL_MapRGB(screen->format,255,226,65);
eputchar2x(background,280,48,color,'0');
eputchar2x(background,290,48,color,'0');
eputchar2x(background,300,48,color,'0');
eputchar2x(background,310,48,color,'0');
SDL_BlitSurface(background,NULL,screen,NULL);
SDL_UpdateRect(screen,0,0,0,0);
srand(time(NULL));
for(i=0;i<4;i++)Create_hzSprite(i);
lastTick=SDL_GetTicks();
time_left=time_slice*60;
count=0;
hits=0;
}
/* ------------------------------ */
void game_main_loop()
{
data_init();
while(game_runing){
anykey();
UpdateGameState();
SDL_Delay(TimeLeft());
}
}
/* ------------------------------ */