1、版权所有,违者必究哈尔滨工业大学哈尔滨工业大学计算机科学与技术学院计算机科学与技术学院苏小红苏小红第14章 简单的游戏设计C语言程序设计第13章 简单的游戏设计第14章 学习内容n设计动画的一般步骤n常用的动画函数n动画设计实例:走迷宫,flippybird2/65C语言程序设计第13章 简单的游戏设计n屏幕上的每个点,称为一个像素(Pixel),它是构成图形的基本元素。14.1动画的基本原理3/65C语言程序设计第13章 简单的游戏设计n设计动画的一般化实现步骤如下:while(1)/循环播放,即循环显示不断更新的图形 清屏 /system(“cls”)向dos发送清屏指令,需包含stdli
2、b.h 显示图形 延时 /使用Sleep()函数,需包含windows.h 更新图形14.1动画的基本原理4/65C语言程序设计第13章 简单的游戏设计14.2 迷宫游戏int main(void)char strNM=*,*o *,*,*,*,*,*,*,*,*,*,*;/保存迷宫地图数据保存迷宫地图数据 int n=12;Show(str,n);/显示迷宫显示迷宫 UpdateWithInput(str,n);/与用户输入有关的更新与用户输入有关的更新 return 0;C语言程序设计第13章 简单的游戏设计14.2 迷宫游戏x-1,y-1x-1,yx-1,y+1x,y-1x,yx,y+1
3、x+1,y-1x+1,yx+1,y+1int main(void)char strNM=*,*o *,*,*,*,*,*,*,*,*,*,*;/保存迷宫地图数据保存迷宫地图数据 int n=12;Show(str,n);/显示迷宫显示迷宫 UpdateWithInput(str,n);/与用户输入有关的更新与用户输入有关的更新 return 0;/函数功能:显示迷宫地图函数功能:显示迷宫地图void Show(char strM,int n)int i;for(i=0;in;i+)/显示显示n行迷宫地图数据行迷宫地图数据 puts(stri);C语言程序设计第13章 简单的游戏设计如何走迷宫?
4、void UpdateWithInput(char strM,int n)/函数功能:完成与用户输入有关的迷宫更新函数功能:完成与用户输入有关的迷宫更新 int x=1,y=1;/初始位置初始位置 int exitX=10,exitY=10;/迷宫出口迷宫出口 char input;while(x!=exitX|y!=exitY)/判断是否到达迷宫出口判断是否到达迷宫出口 if(kbhit()/检测是否有键盘输入,没有就继续循环检测是否有键盘输入,没有就继续循环 input=getch();/从键盘获取输入从键盘获取输入 if(input=a&strxy-1!=*)/左移左移 strxy=;y
5、-;strxy=o;if(input=d&strxy+1!=*)/右移右移 strxy=;y+;strxy=o;if(input=w&strx-1y!=*)/上移上移 strxy=;x-;strxy=o;if(input=s&strx+1y!=*)/下移下移 strxy=;x+;strxy=o;system(cls);/清屏清屏 Show(str,n);/显示更新后的迷宫地图显示更新后的迷宫地图 Sleep(200);/延时延时200ms printf(You win!n);system(PAUSE);C语言程序设计第13章 简单的游戏设计如何自动走迷宫?#define N 50#define
6、 M 50int flag=0;/flag用来标记是否路径全部走完用来标记是否路径全部走完int aNN=1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,1,0,0,0
7、,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1;int main(void)int x1,y1,x2,y2;int n=12,m=12;Show(a,n,m);/显示初始迷宫显示初始迷宫 printf(Input x1,y1,x2,y2:);/输入入口和出口输入入口和出口 scanf(%d,%d,%d,%d,&x1,&y1,&x2,&y2);if(Go(x1,y1,x2,y2)=0)/设置起始点为设置起始点为1,1 printf(没有路径!没有路径!n);else printf(You win!n);system(PAUSE);return 0;C语言程序设计
8、第13章 简单的游戏设计如何自动走迷宫?/函数功能:显示迷宫地图函数功能:显示迷宫地图void Show(int aM,int n,int m)int i,j;for(i=0;in;+i)/显示显示n行行m列迷宫地图数据列迷宫地图数据 for(j=0;jm;+j)if(aij=0)printf();else if(aij=1)printf(*);else if(aij=2)printf(o);printf(n);C语言程序设计第13章 简单的游戏设计如何自动走迷宫?/函数功能:自动走迷宫函数功能:自动走迷宫int Go(int x1,int y1,int x2,int y2)ax1y1=2;/
9、迷宫入口迷宫入口 system(cls);/清屏清屏 Show(a,12,12);/显示更新后的迷宫地图显示更新后的迷宫地图 Sleep(200);/延时延时200ms if(x1=x2&y1=y2)/迷宫出口设置为迷宫出口设置为x2,y2 flag=1;if(flag!=1&ax1-1y1=0)/判断向上是否有路判断向上是否有路 Go(x1-1,y1,x2,y2);if(flag!=1&ax1+1y1=0)/判断向下是否有路判断向下是否有路 Go(x1+1,y1,x2,y2);if(flag!=1&ax1y1+1=0)/判断向右是否有路判断向右是否有路 Go(x1,y1+1,x2,y2);i
10、f(flag!=1&ax1y1-1=0)/判断向左是否有路判断向左是否有路 Go(x1,y1-1,x2,y2);if(flag!=1)ax1y1=0;return flag;C语言程序设计第13章 简单的游戏设计n游戏设计要求如下:1)在游戏窗口中显示从右向左运动的障碍物,显示三根柱子墙;2)用户使用空格键控制小鸟向上移动,以不碰到障碍物为准,即需要从柱子墙的缝隙中穿行,确保随机产生的障碍物之间的缝隙大小可以足够小鸟通过;3)在没有用户按键操作情况下,小鸟受重力影响会自行下落,为了不让小鸟掉下来,需要用户间歇性地点击空格键让小鸟往上飞,并躲避途中可能遇到的高低不平的障碍物;4)进行小鸟与障碍物
11、的碰撞检测,如果没有碰到,则给游戏者加1分。5)如果小鸟碰到障碍物或者超出游戏画面的上下边界,则游戏结束。14.3 Flagppybird游戏11/65C语言程序设计第13章 简单的游戏设计n游戏的第一个难点:如何让小鸟不会飞出屏幕?让小鸟从左向右运动的问题就转化为让柱子从右向左运动的问题首先使用Windows API中定义的结构体类型COORD来表示字符在控制台屏幕上的坐标。14.3 Flagppybird游戏12/65nWindows API中定义的一种结构类型表示一个字符在控制台屏幕上的坐标#include typedef struct _COORD short X;/horizonta
12、l coordinateshort Y;/vertical coordinateCOORD;/在在windows.h中定义中定义C语言程序设计第13章 简单的游戏设计#include void Gotoxy(int x,int y)/定位光标位置 COORD pos=x,y;/获取标准输出设备的获取标准输出设备的句柄(HANDLE),即即资源的标识 /操作系统通过句柄找到要管理和操作的资源操作系统通过句柄找到要管理和操作的资源 HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);/光标位置定位到光标位置定位到pos SetConsoleCursorPo
13、sition(hOutput,pos);typedef struct _COORD short X;short Y;COORD;COORD pos=x,y;/等价于等价于COORD pos;pos.X=x;pos.Y=y;n利用利用COORD类型定位光标位置类型定位光标位置使用使用Windows API函数函数GetStdHandle(),从一个特定的标准设备(例如标准输出)获取标识设,从一个特定的标准设备(例如标准输出)获取标识设备的句柄(用来标识不同设备的一个数值)备的句柄(用来标识不同设备的一个数值)使用使用Windows API函数函数SetConsoleCursorPosition(
14、)定位光标的位置。定位光标的位置。14.3 Flagppybird游戏C语言程序设计第13章 简单的游戏设计void HideCursor()HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle,&CursorInfo);/获取控制台光标信息获取控制台光标信息 CursorInfo.bVisible=0;/隐藏控制台光标隐藏控制台光标 SetConsoleCursorInfo(handle,&CursorInfo);/设置控制台光标状态设置
15、控制台光标状态n避免清屏和反复刷新屏幕带来的闪烁效应避免清屏和反复刷新屏幕带来的闪烁效应14.3 Flagppybird游戏C语言程序设计第13章 简单的游戏设计n游戏的第二个难点问题:小鸟与柱子的碰撞检测问题游戏的第二个难点问题:小鸟与柱子的碰撞检测问题n解决思路是:解决思路是:记录每根柱子的横纵坐标范围记录每根柱子的横纵坐标范围检测小鸟当前所在位置的横纵坐标是否落入柱子的横纵坐标范围检测小鸟当前所在位置的横纵坐标是否落入柱子的横纵坐标范围如果落入,则表示小鸟碰到了墙体如果落入,则表示小鸟碰到了墙体14.3 Flagppybird游戏C语言程序设计第13章 简单的游戏设计14.3 Flagp
16、pybird游戏typedef struct bird COORD pos;int score;BIRD;/小鸟的初始位置和分数小鸟的初始位置和分数BIRD bird=22,10,0;Flappybird/3个柱子的初始位置和高度个柱子的初始位置和高度COORD wall3=40,10,60,6,80,8;C语言程序设计第13章 简单的游戏设计flappybirdint main(void)BIRD bird=22,10,0;/小鸟的初始位置小鸟的初始位置 COORD wall3=40,10,60,6,80,8;/柱子的初始位置和高度柱子的初始位置和高度 int i;char ch;while
17、(CheckWin(wall,&bird)/未发生碰撞未发生碰撞 Begin(&bird);/清屏并显示上下边界和分数清屏并显示上下边界和分数 CheckWall(wall);/显示柱子显示柱子 PrtBird(&bird);/显示小鸟显示小鸟 Sleep(200);if(kbhit()/检测到有键盘输入检测到有键盘输入 ch=getch();/输入的字符存入输入的字符存入ch if(ch=)/输入的是空格输入的是空格 bird.pos.Y-=1;/小鸟向上移动一格小鸟向上移动一格 else/未检测到键盘输入未检测到键盘输入 bird.pos.Y+=1;/小鸟向下移动一格小鸟向下移动一格 fo
18、r(i=0;i3;i+)walli.X-;/柱子向左移动一格柱子向左移动一格 return 0;C语言程序设计第13章 简单的游戏设计flappybirdvoid CheckWall(COORD wall)/显示柱子显示柱子 int i;srand(time(NULL);COORD temp=wall2.X+DIS,rand()%13+5;/随机产生一个新柱子随机产生一个新柱子 if(wall0.X 10)/超出预设的左边界超出预设的左边界 wall0=wall1;/最左侧的柱子消失,第二个柱子变成第一个最左侧的柱子消失,第二个柱子变成第一个 wall1=wall2;/第三个柱子变成第二个第三
19、个柱子变成第二个 wall2=temp;/新产生的柱子变成第三个新产生的柱子变成第三个 C语言程序设计第13章 简单的游戏设计flappybird for(i=0;i3;i+)/循环显示三个柱子循环显示三个柱子 /显示上半部分柱子显示上半部分柱子 temp.X=walli.X+1;/向右缩进一格显示图案向右缩进一格显示图案 SetConsoleColor(0 x0C);/黑背景红色前景黑背景红色前景 for(temp.Y=2;temp.Ywalli.Y;temp.Y+)/从第从第2行开始显示行开始显示 Gotoxy(temp.X,temp.Y);printf();temp.X-;/向左移动一格
20、显示图案向左移动一格显示图案 Gotoxy(temp.X,temp.Y);printf();/显示下半部分柱子显示下半部分柱子 temp.Y+=BLAN;Gotoxy(temp.X,temp.Y);printf();temp.X+;/向右缩进一格显示图案向右缩进一格显示图案 temp.Y+;/在下一行显示下面的图案在下一行显示下面的图案 for(;(temp.Y)26;temp.Y+)/一直显示到第一直显示到第25行行 Gotoxy(temp.X,temp.Y);printf();C语言程序设计第13章 简单的游戏设计本章知识点小结20/65C语言程序设计第13章 简单的游戏设计SuXiaoHongSuXiaoHongnQ&A21/65