📄 snake.c
字号:
IMENUCTL_SetActive(pMe->pIMenuCtl, TRUE); // 激活菜单控件对象
pMe->Mode = MODE_MENU; // 切换到主菜单状态
return TRUE;
}
return FALSE;
}
static void main_Display(snake* pMe)
{
int i;
AEERect rc[SNAKE_MAX_LENGTH+1]; /* 设置局部变量保存蛇的身体,最后一位“+1”是用来保存食物的 */
IDISPLAY_FillRect(pMe->a.m_pIDisplay, &(pMe->ScreenRect), MAKE_RGB(0, 0, 0)); /*用纯黑背景刷新屏幕 */
switch (pMe->Mode){
case MODE_MENU:
IMENUCTL_Redraw(pMe->pIMenuCtl); //刷新菜单控件显示
break;
case MODE_GAME://游戏状态
if (pMe->life==1){//失败
draw_Lost(pMe);
return;
}
IDISPLAY_ClearScreen(pMe->a.m_pIDisplay);
IDISPLAY_DrawRect(pMe->a.m_pIDisplay, &(pMe->ScreenRect), BLUE, BLACK, IDF_RECT_FILL|IDF_RECT_FRAME);/* 绘制背景和墙壁 */
if (pMe->yes == 1){
/* 需出现新食物 */
new_Food(pMe);
/* 生成新的食物 */
pMe->yes = 0;
/* 新食物已经出现 */
}
for (i = pMe->length; i > 0; i--){ /* 蛇身体向前移动 */
pMe->x[i] = pMe->x[i-1];
pMe->y[i] = pMe->y[i-1];
}
switch (pMe->direction){ /* 蛇头移动 */
case RIGHT: pMe->x[0] += 8; break;
case LEFT: pMe->x[0] -= 8; break;
case UP: pMe->y[0] -= 8; break;
case DOWN: pMe->y[0] += 8; break;
}
pMe->bDirectionChg = TRUE;
/*设置蛇可穿墙 */
if (pMe->x[0] > pMe->DeviceInfo.cxScreen - 8) pMe->x[0] = 0;
if (pMe->x[0] < 0) pMe-> x[0] = pMe->DeviceInfo.cxScreen - 8;
if (pMe->y[0] > pMe->DeviceInfo.cyScreen - 8) pMe->y[0] = 0;
if (pMe->y[0] < 0) pMe-> y[0] = pMe->DeviceInfo.cyScreen - 8;
if (pMe->yes == 0){
/*
显示已有的食物 */
SETAEERECT(&rc[SNAKE_MAX_LENGTH],pMe->foodx,pMe->foody, 8, 8);
IDISPLAY_DrawRect(pMe->a.m_pIDisplay,&rc[SNAKE_MAX_LENGTH], BLUE, RED, IDF_RECT_FILL|IDF_RECT_FRAME);
}
if ((pMe->x[0] == pMe->foodx) && (pMe->y[0] == pMe->foody)){ /* 食到食物*/
pMe->length++; /* 蛇身长一节 */
pMe->yes = 1; /* 画面上需出现新的食物 */
pMe->scores += 10; /* 更新得分 */
}
for (i = 0; i < pMe->length; i++)
{
SETAEERECT(&rc[i],pMe->x[i],pMe->y[i],8,8);
}
for (i = 0; i < pMe->length; i++)
IDISPLAY_DrawRect(pMe->a.m_pIDisplay,&rc[i], BLUE, GREEN, IDF_RECT_FRAME|IDF_RECT_FILL);//绘制矩形,蛇的身体
for (i = 3; i < pMe->length; i ++){ /* 从蛇的第四节开始判断是否撞到自己了 */
if ((pMe->x[i] == pMe->x[0]) && (pMe->y[i] == pMe->y[0])){
pMe->life = 1; /* 设置蛇的生命,游戏失败 */
stopSound(pMe);
saveScore(pMe);
}
}
if ((pMe->x[0] == pMe->foodx) && (pMe->y[0] == pMe->foody)){
playTone(pMe);//播放音效
}
IDISPLAY_Update(pMe->a.m_pIDisplay);
break;
default:
break;
}
}
static void release_Menuctl(snake* pMe)
{
if ( pMe->pIMenuCtl != NULL )
{
IMENUCTL_Release(pMe->pIMenuCtl);
pMe->pIMenuCtl = NULL;
}
}
static void draw_Lost(snake* pMe)
{
ISHELL_CancelTimer(pMe->a.m_pIShell,(PFNNOTIFY)main_Loop,pMe);
load_Draw_PNG(pMe); //显示55.png
draw_Ellipse(pMe); //画椭圆
load_Draw_BMP(pMe); //椭圆里面显示lost.bmp
IDISPLAY_Update(pMe->a.m_pIDisplay);
}
/* load_Draw_PNG 函数功能:载入并显示PNG图片 */
static void load_Draw_PNG(snake* pMe)
{
IImage* pimg = NULL; //PNG图片指针
AEEImageInfo imginfo; //PNG图片信息
pimg = ISHELL_LoadImage(pMe->a.m_pIShell, "55.png"); /* 载入PNG图片文件 */
if (pimg)
{ //如果图片载入成功
IIMAGE_GetInfo(pimg, &imginfo); /* 得到图片大小等信息 */
IIMAGE_Draw(pimg, (pMe->DeviceInfo.cxScreen - imginfo.cx)/2, pMe->DeviceInfo.cyScreen - imginfo.cy); /* 图片画在手机屏幕的底部中央 */
IIMAGE_Release(pimg); /* 用完释放图片 */
}
}
/* draw_Ellipse 函数功能:创建IGraphics接口实例并且描绘矩形 */
static void draw_Ellipse(snake* pMe)
{
IGraphics* pgraphic = NULL;
AEEEllipse pellipse;
pellipse.cx = pMe->DeviceInfo.cxScreen/2; /* 椭圆中心点X, Y坐标 */
pellipse.cy = 30;
pellipse.wx = 40; /* 椭圆X,Y方向半轴长度 */
pellipse.wy = 20;
if(SUCCESS == ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_GRAPHICS, (void **)&pgraphic))
{
IGRAPHICS_SetFillColor(pgraphic, 255, 0, 0, NULL);
/* 设置填充红色 */
IGRAPHICS_SetFillMode(pgraphic, TRUE); /* 设置填充模式 */
IGRAPHICS_DrawEllipse(pgraphic, &pellipse); /* 根据前面得设置描绘椭圆*/
IGRAPHICS_Release(pgraphic); /* 释放接口 */
}
}
/* load_Draw_BMP 函数功能:载入并显示BMP图片 */
static void load_Draw_BMP(snake* pMe)
{
IBitmap* pbmp = NULL; //BMP图片指针
AEEBitmapInfo bmpinfo; //BMP图片信息
pbmp = ISHELL_LoadBitmap(pMe->a.m_pIShell, "lost.bmp"); /* 载入BMP图片文件 */
if (pbmp)
{ //如果图片载入成功
IBITMAP_GetInfo(pbmp, &bmpinfo, sizeof(AEEBitmapInfo)); /* 得到图片大小等信息 */
IDISPLAY_BitBlt ( pMe->a.m_pIDisplay, (pMe->DeviceInfo.cxScreen - bmpinfo.cx)/2, 20,
bmpinfo.cx, bmpinfo.cy, (const void*) pbmp, 0, 0, NULL,);
IBITMAP_Release(pbmp); /* 用完释放图片 */
}
}
/*播放背景音乐 */
static void playSound(snake* pMe)
{
AEEMediaData pinfo; /* 音频源信息 */
pinfo.clsData = MMD_FILE_NAME; /* 指定文件 */
pinfo.pData = (void *)"test.mp3"; /* 指向文件名的指针 */
pinfo.dwSize = NULL; /* 缓冲区地址,指向文件时无效 */
ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_MEDIAMP3, (void **)&(pMe->pimedia)); /* 创建pimedia对象,指定使用MP3文件 */
IMEDIA_SetMediaData(pMe->pimedia, &pinfo); /* 设置音频信息 */
IMEDIA_Play(pMe->pimedia); /* 播放声音 */
}
/*播放特殊音效*/
static void playTone(snake* pMe)
{
ISound *pisound;
AEESoundToneData tonedata; /* 音调数据 */
tonedata.eTone = AEE_TONE_ANSWER_TONE; /* 设置一种音调 */
tonedata.wDuration = 30; /* 音调持续时间 */
ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_SOUND, (void **)&pisound);
ISOUND_PlayTone(pisound,tonedata); /* 播放音调 */
ISOUND_Release(pisound); /* 释放接口 */
}
/* 游戏结束时,停止声音效果和释放接口 */
static void stopSound(snake* pMe)
{
if (pMe->pimedia)
{
IMEDIA_Stop (pMe->pimedia); /* 停止播放 */
IMEDIA_Release(pMe->pimedia); /* 释放接口 */
pMe->pimedia = NULL; /* 清空,防止重复释放 */
}
}
/* loadScore 函数功能:排行榜从文件中读取排行榜中的高分纪录,如果纪录文件不存在,则分数全初始化为0 */
static void loadScore(snake* pMe){
IFileMgr *pIFileMgr = NULL;
IFile *pIFile = NULL;
int i;
for (i = 0; i < 5; i++){ /* 初始化分数全为0 */
pMe->HighScore[i] = 0;
}
/* 创建文件接口实例 */
if (SUCCESS == ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_FILEMGR, (void**)&pIFileMgr)){
if (pIFileMgr){
pIFile = IFILEMGR_OpenFile(pIFileMgr, SAVE_FILE, _OFM_READ); /* 打开纪录文件 */
if (pIFile){ /* 排行榜纪录文件存在 */
if (IFILE_Read(pIFile, (void*)pMe->HighScore, sizeof(pMe->HighScore)) == sizeof(pMe->HighScore)){/* 从文件中读取排行榜分数 */
}else{
DBGPRINTF("---Load file error!---"); /* 打印信息提示文件读取出错 */
}
IFILE_Release(pIFile);
}
IFILEMGR_Release(pIFileMgr); /* 释放相关文件接口 */
}
}
}
/* saveScore 函数功能:游戏结束后得分如果破纪录,则更新排行榜并存储到文件中 */
static void saveScore(snake* pMe){
IFileMgr *pIFileMgr = NULL;
IFile *pIFile = NULL;
int ret, i, j;
/* 创建文件接口实例 */
if (SUCCESS == ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_FILEMGR, (void**)&pIFileMgr)){
if (pIFileMgr){ /* 创建接口成功 */
ret = IFILEMGR_GetFreeSpace(pIFileMgr, NULL); /*得到剩余的文件空间*/
if(ret < sizeof(pMe->HighScore)){ /* 空间不够则不再进行存储 */
IFILEMGR_Release(pIFileMgr);
return;
}
if (SUCCESS == IFILEMGR_Test(pIFileMgr, SAVE_FILE)){/* 如果已经存在最高分记录文件 */
pIFile = IFILEMGR_OpenFile(pIFileMgr, SAVE_FILE, _OFM_READWRITE); /* 读写方式打开文件 */
}else{
pIFile = IFILEMGR_OpenFile(pIFileMgr, SAVE_FILE, _OFM_CREATE); /* 新建文件来存储最高分 */
}
if (pIFile){ /* 文件打开或者新建成功 */
for (i = 0; i < 5; i++){
if (pMe->scores > pMe->HighScore[i]){ /* 如果得分上榜 */
for (j = 4; j > i; j--){/* 重新排列排行榜 */
pMe->HighScore[j] = pMe->HighScore[j-1];
}
pMe->HighScore[i] = pMe->scores; /* 新纪录上榜 */
break;
}
}
if (IFILE_Write(pIFile, (PACKED const void*)pMe->HighScore,sizeof(pMe->HighScore)) == sizeof(pMe->HighScore)){ /* 保存排行榜分数到文件 */
}else{
DBGPRINTF("---Save file error!---"); /* 打印信息提示文件存储出错 */
}
IFILE_Release(pIFile);
}
IFILEMGR_Release(pIFileMgr); /* 释放相关文件接口 */
}
}
}
/* show_HighScore 函数功能:排行榜画面显示历史前五名最高得分 */
static void show_HighScore(snake* pMe){
AECHAR wstr[100];
char str[100];
int i;
int res = 0;
IDISPLAY_ClearScreen(pMe->a.m_pIDisplay);
IDISPLAY_SetColor(pMe->a.m_pIDisplay, CLR_USER_TEXT, BLUE); /* 设置标题蓝色 */
IDISPLAY_DrawText(pMe->a.m_pIDisplay, AEE_FONT_BOLD, L"HighScores", -1,0, 10, NULL, IDF_ALIGN_CENTER|IDF_TEXT_UNDERLINE|IDF_TEXT_TRANSPARENT); /* 标题加粗、居中并加下划线 */
IDISPLAY_SetColor(pMe->a.m_pIDisplay, CLR_USER_TEXT, RED); /* 设置分数白色 */
for(i = 0; i < 5; i ++)
{
SPRINTF(str, "%d.%d", i+1, pMe->HighScore[i]); /* 转换分数到字符串 */
STRTOWSTR(str, wstr, sizeof(str)+1); /* 转换成BREW用来显示的宽字节字符串 */
res = IDISPLAY_DrawText(pMe->a.m_pIDisplay, AEE_FONT_NORMAL, wstr, -1,20, 40 + i*20, NULL, IDF_TEXT_TRANSPARENT); /* 显示排行榜上各分数*/
}
IDISPLAY_Update(pMe->a.m_pIDisplay);
}
static void main_Loop(snake* pMe)
{
main_Display(pMe);
ISHELL_SetTimer(pMe->a.m_pIShell,200,(PFNNOTIFY)(main_Loop),(void*)pMe);
}
static void new_Food(snake* pMe)
{
pMe->foodx = 50;
pMe->foody = 34;
}
static void init_GameData(snake* pMe)
{
new_Food(pMe);
pMe->life = 0;
pMe->length = 3;
pMe->yes = 0;
pMe->x[0] = 50;
pMe->y[0] = 50;
pMe->x[1] = 58;
pMe->y[1] = 50;
pMe->x[2] = 64;
pMe->y[2] = 50;
pMe->direction = RIGHT;
pMe->bDirectionChg = FALSE;
pMe->scores = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -