从游戏编程的新角度看待编程教学

时间:2022-10-11 02:08:34

从游戏编程的新角度看待编程教学

摘要:从一个新的角度看待编程教学,从游戏的角度学习C语言。虽然C语言不是面向对象语言,但通过一个小游戏的设计过程学习用函数思考问题,在过程性语言中更多加入面向对象思路,那么当你真正的去学习一门面向对象语言时,就会有C语言的函数学习基础去对比。这会使学习面向对象编程更容易理解和更有乐趣。

关键词:编程;C语言;游戏编程;面向对象编程思路

中图分类号:TP311文献标识码:A文章编号:1009-3044(2008)11-20303-05

1 引言

程序设计是一门实践性很强的课程,只有理论没有实践是不行的,而且理论水平也要在分析对比不同实践的基础上才能积累和提高。如果教师认为只要讲解了语法就算教授了该门语言的程序设计,连理论的边恐怕都没沾上。在学生学习程序设计的时候,接触到的书本例题及课后习题多是就题解题,主要是演习一下语法。并且当前的程序设计教学多以教授语法为主,没有引导学生如何合理优美地使用语言。同时程序实现中的很多技巧被公认为是标准的实现方法,但学生很少在教学过程中接触到。而最重要的一点,学生往往没有学习到程序设计的一些原理,没有判断程序实现优劣的正确标准,这会妨碍他们今后不断提高程序设计水平。

我们在教学C语言程序设计时,更容易遇到上述的问题。学生基本上是学习控制台应用程序就题解题演习算法,而对C的实际应用却一无所知。那么本文就想通过以Turbo C为游戏编程平台,C作为编程语言,引导学生做一个生活中相关的项目。从游戏编程的角度学习C语言。虽然C语言不是面向对象语言,但通过一个小游戏的设计过程学习用函数思考问题,在过程性语言中更多加入面向对象思路,那么当你真正的去学习一门面向对象语言时,就会有C语言的函数学习基础去对比。同时在游戏对象结构定义的时候融入更多属性,事件函数指针和链表指针,在子画面处理和界面对象处理中更多采用了事件驱动的思路,从而也可以为今后转向C++游戏编程铺平道路。

2 游戏编程的几大要素

一个成功的游戏通常需要极高的美工水平、逼真的动画效果、精巧的构思、简便的操作。其中动画和用户操作是需要在编程中下苦功夫的。

游戏编程要注意五大要素:动画的效果一定要流畅,没有散动和尽量逼真,最好能够符合“物理”和“生物学”的运动规律;且游戏要易于操作,并且能够快速响应,必要的时候能够设计出适合游戏的输入设备和驱动程序;再则提高图像,动画,声音和操作的同步性和混合性;用于实现游戏的数据结构一定要经过规划,尽量简便,高效,以及适用面和扩充性强。最后引入面向对象的思路将对理清程序员思路,简化程序设计以及程序扩充等问题带来相当大的帮助。

这些编程要素事实上涉及了包括直接写屏,中断,多任务,内存技术,动画技术,显示技术和优化算法等各种编程技术;涉及到了内存,PC喇叭,声卡,键盘,鼠标,手柄,显卡等各种技术和优化算法等各种编程技术;也涉及了包括C语言程序设计,C++语言程序设计,汇编语言,数据结构,数据库,计算机硬件,接口技术,算法,高等数学,多媒体技术,人工智能等计算机专业课目;此外,还涉及到动画技术,三维游戏编程,加密,解密技术和病毒与病毒防治编程等一些当前流行的计算机专业技术。

3 游戏的设计步骤

软件工程课告诉我们任何一个软件的实现都有必要的几个步骤:先要对具体的内容规划,融入自己的创意;其次用简洁高效的数据结构来实现你的创意;再将你的数据结构用程序语言来表达出来;最后对程序的系统可用性,模块功能进行测试,检验程序中错误和边缘问题,同时修改程序不符人意的部分,使游戏更加好玩,更便于操作。

游戏设计事实上也是软件的设计,然而它又有自身的一些特点。比如,游戏强调有极其新颖的创意,要对游戏的每个细节都有准确,详尽的描述和表现等。游戏编程的步骤可以归纳为如下几点。

(1)创意阶段:对创意进行完善,设计出游戏的完整过程并画出流程图,并将游戏分解为若干层次;对每个层次进行详尽的描述,包括其中的人和物以及每个层次的实现目标;对每个层次设定规则,包括人和物的移动,操作者的权利,游戏的奖励和惩罚以及周边的一切环境,音效和帮助。

(2)规划阶段:使用的图形模式。比如BIOS中断10H的13H模式,即200*320像素256色;确定图形,动画的复杂程度。比如用二维实现还是三维。考虑使用游戏函数库中的哪些函数来实现游戏创意中的那些要求。

(3)周边准备:制作人物,环境的图像文件,声音文件以及建立地点,发展层次,人,物品,对话和奖励惩罚的数据库文件。

(4)细部实现:图像实现函数,图像动画函数,声音播放函数,输入装置驱动和功能函数以及存盘,读盘函数。

(5)模块实现:数据结构系统,图像,动画系统,输入、输出系统,人工智能系统,游戏循环系统,用户界面系统以及声音系统

(6)整体完善:游戏功能和完整性的扩展;游戏的文件大小的缩减。

这只是一个大的方向性原则,具体的内部设计步骤根据不同的游戏的情况和个人风格进行增减或调整。

4 游戏的流程

别看游戏有那么复杂的情节和玩法,从开始到发展再到结束的流程中,归根结底就只有四样东西:

动画:根据运算结果对屏幕中变化的对象进行重画,从而实现动画效果;

响应:对于来自键盘,鼠标等输入设备和计算机内部如时间等中断进行响应;

运算:根据各类具体响应通过计算和重新赋值来改变程序内变量数值;

循环:反复进行动画,响应和运算的操作来实现游戏的真正进程。

实现一个游戏的基本流程如图1所示。

下面以游戏俄罗斯方块为例,动画流程分为以下几个步骤:

(1)游戏开始,初始设置(这个过程设置了所有的变量初始值);

(2)进行一个方块下落或者消去的动画(这个过程只负责重画屏幕);

(3)然后查看是否有用户发出的旋转,下落,左右移动或退出游戏的指令(这个过程接收信息,同时存入输入变量);

(4)此后如果有用户指令根据其指令计算出块的下一个形状,位置,同时也按照游戏本身设置的下落速度进行叠加计算并且判断是否到达底部,如果到达底部再判断是否可以消去和是否死亡(这个过程改变各种变量的值);

(5)计算完毕后,根据结果进行下一次下落或消去的动画(回到步骤2),如此循环往复直到游戏结束(这个过程就是一个While语句之类的循环)。

对应上面5个步骤,再以一个简单的C语言伪程序为例:

# include…

#define…

Void main(void)

{

int a,b,c;//步骤1:相当于设置初始值

a=1;

b=2;

c=3;

while(a!=’q’)

{

printf(“%d”,c); // 步骤2:相当于重画屏幕

a=getch(); //步骤3:相当于响应输入设备

c=a*b; //步骤4:相当于重新运算变量值

}//步骤5:相当于如果a不等于q就继续循环步骤2--4

}

我们将上面给出的伪程序套用之后再一步一步改写,一个游戏程序就出来了。

# include

# include

# include

# include

# include

# include

/* 七种拼块的形状数据 */

char fk[7][4][2]={

1,1,1,2,1,3,1,4,

1,1,1,2,1,3,2,3,

2,1,2,2,1,3,2,3,

1,1,1,2,2,2,2,3,

2,1,2,2,1,3,2,3,

1,1,2,1,1,2,2,2,

1,1,1,2,1,3,2,2};

/* 存放组成拼块的四个小方块X和Y坐标 */

int kx[4],ky[4];

/* 桶 */

int tong[13][25];

/* 等待按键并延时的函数 */

char key(int s)

{

clock_t t1,t2;

char c;

t1=clock();

do

t2=clock();

while (((t2-t1)

if (kbhit())

c=getch();

else

c=0;

returnc;

}

/* 显示或清除方块的函数 */

void kuai(int x,int y,int c)

{

char cc[3];

if(c==1)

strcpy(cc,"[]");

else

strcpy(cc,"");

gotoxy(x*2,y);

puts(cc);

gotoxy(79,24);

}

/* 画出拼块 */

void hua()

{

int i;

for(i=0;i

kuai(kx[i],ky[i],1);

}

/* 清除拼块的函数 */

void ca()

{

int i;

for(i=0;i

kuai(kx[i],ky[i],0);

}

/* 拼块下落一行 */

int xialuo()

{

int t,i;

ca();

t=1;

for(i=0;i

if(ky[i]==24) {t=0; break;};

if(tong[kx[i]][ky[i]+1]==1) {t=0; break;};

}

if(t==1)

for(i=0;i

ky[i]=ky[i]+1;

else

for(i=0;i

tong[kx[i]][ky[i]]=1;

hua();

return t;

}

/* 拼块左右移动函数 */

void yidong(int p)

{

int t,i;

ca();

t=1;

i=0;

do{

if((kx[i]==1)&&(p==-1)) {t=0; break;};

if((kx[i]==12)&&(p==1)) {t=0; break;};

if (tong[kx[i]+p][ky[i]]==1) {t=0; break;};

i++;

} while (i

if(t==1)

for(i=0;i

kx[i]=kx[i]+p;

hua();

}

/* 旋转拼块的函数 */

void zhuan()

{

int i,t,x,y;

int kx1[4],ky1[4];

ca();

x=kx[1]; y=ky[1];

for(i=0;i

kx1[i]=x+y-ky[i]; ky1[i]=y-x+kx[i];

}

t=1;

for(i=0;i

if((kx1[i]12)||(ky1[i]24)) {t=0; break;};

if (tong[kx1[i]][ky1[i]]==1) {t=0; break;};

}

if(t==1)

for(i=0;i

kx[i]=kx1[i]; ky[i]=ky1[i];

};

hua();

}

/* 计算一行中的方块数 */

int fangkuaishu(int h)

{

int i,p=0;

for(i=1;i

p=p+tong[i][h];

if(p==12)

for(i=1000;i

sound(i);

delay(10);

}

nosound();

return p;

}

/* 桶中方块除去一行,在此行上面的方块下移一行 */

void yihang(int h)

{

int k,j,q;

for(k=h;k>0;k--){

q=0;

for(j=1;j

if(tong[j][k]!=tong[j][k-1]){

kuai(j,k,tong[j][k-1]);

tong[j][k]=tong[j][k-1];

}

q=q+tong[j][k];

}

if(q==0) break;

}

}

/* 检查有无完成的行,并处理之 */

void jiancha()

{

int i,n;

i=24;

do{

n=fangkuaishu(i);

if(n==12) yihang(i); else i--;

} while((i>0)&&(n>0));

}

/* 开始函数,初始化,画出空桶*/

void kaishi()

{

int i,j;

for(i=1;i

for(j=1;j

tong[j][i]=0;

clrscr();

for(i=0;i

puts("| |");

printf("`----------'");

randomize();

}

/* 主程序 */

main()

{

int i,j,k,s;

int m,t;

char kk;

kaishi();/* 屏幕初始化,显示空桶 */

for(;;){/* 开始一个循环,在此循环中不断检测按键并处理之 */

m=rand()%7; /* 随机产生一种拼块 */

for(i=0;i

kx[i]=fk[m][i][0]+5;

ky[i]=fk[m][i][1];

}

t=1;

for(i=0;i

if (tong[kx[i]][ky[i]]==1)

exit(0);

hua();/* 画出拼块 */

s=0; /* S是一个标志,指示是否按了空格键 */

for(;;){/* 此循环中处理一个拼块的下落过程 */

if(s==0) kk=key(9); else kk=key(0); /* 按过了空格键则不延时 */

if((kk>='a')&&(kk

switch (kk){/* 根据按键作相应处理 */

case ' ' : s=1; break;/* 按空格, 快速下落 */

case 'K': zhuan(); break; /* 按K,旋转拼块 */

case 'J': yidong(-1); break; /* 按J,左移拼块 */

case 'L': yidong(1); break; /* 按L,右移拼块 */

case 'S': while(kbhit()==0);break; /* 按S,暂停游戏 */

case 'E': exit(0); break; /* 按E,结束游戏 */

default : t=xialuo(); /* 没按上面的键,或未按任何键,拼块下落一格 */

}

if(t==0) break; /* 拼块落到桶底或不能再下落退出循环 */

}

jiancha();/* 检查是否有完成的行,并处理之 */

}

}

面向对象编程思路的融入是游戏编程流程的又一重点。再来看一下程序设计,原先的流程可以被理解成结构图如图2。

这和前面的游戏流程并不矛盾,只是换个角度看问题。如下表1是对象思路中的每个环节和游戏流程的四大部分进行对应关系。

一个是流程明晰,一个是流行的对象化思路,那么到底我们按照哪种思路来编写程序

(上接第307页)

呢?如果我们以TC为平台,那么思路就在流程化语言的基础上加入面向对象思路,这样的好处是能让流程化语言也拥有一定的面向对象思路容易扩充,维护的优点。

5 结束语

本文章就给了大家一套写游戏最简单的模板。无论你要写怎样的游戏,都可将它分为动画,响应,运算和循环四部分,外加一个初始设置。教师在教授学生基础语法知识同时可以引导学生做些类似游戏的,学生比较感兴趣的小程序,逐步培养算法思维,培养用程序设计语言思考和表达的能力。最后在学完一种语言的语法知识以后,让学生自己选题完成一个项目,项目不论大小,关键是寻找最佳的解决方案,用最好的设计和代码实现。在这一过程中,程序设计水平就逐渐提升了。

参考文献:

[1] Tom Meigs,著,陈贵敏,杜敬利,韩琪,译.顶级游戏设计[M].北京:电子工业出版社,2004:1-57.

[2] Andre LaMothe著, 李祥瑞,陈武译. 3D游戏编程大师技巧[M].北京:人民邮电出版社,2005:1-139.

[3] 浦滨.C游戏编程从入门到精通[M].北京:北京希望电子出版社,2002:1-397.

[4] Marianne Krawczyk,著,姚晓光,孙泱译.游戏开发核心技术[M].北京:机械工业出版社,2007:15-32.

注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文

上一篇:基于单边沿触发器的双边沿时序电路设计 下一篇:Web应用程序漏洞及安全研究