探究在小学阶段C++语言的学习方式

2021-05-30 04:53贾莉
中国信息技术教育 2021年26期
关键词:小游戏子弹队列

贾莉

引言

我在刚开始学习C语言的时候只有一个目的,就是给51单片机机器人编写程序。每学习一个抽象的知识点,就可以通过机器人的动作,形象地表现出来,每完成一段程序会很有成就感。这种学习方式有两个好处,即可以加深理解和正向激励。后期,我接触到java和C++之类的语言,感觉奋斗了半天,只是在屏幕上出现了“Hello world!”,或者控制台出现了“0110”之类的数字,瞬间积极性被打消很多。人们更容易理解形象直观的东西,通过一些实验发现,做一些小游戏或者网页动画,更容易让初学者喜欢上编程。

现在市面流行的青少年代码编程语言,有Python,JavaScript,HTML等可以做小游戏的语言(小学段),还有C++语言,学习它是用来参加信息学奥林匹克竞赛的(初高中段)。细看学习内容,两个年龄段衔接是有缝隙的。Python虽然热度高,但学习的知识点无外乎“变量”“if else”“for while”之类的基础知识。如果直接用C++语言来制作小游戏,用这种方式学习能达到相同的效果。而且在以后,可以直接衔接到高级别的比赛如“信息学奥赛”等。因此,我制作了一个“飞机大战”的小游戏,拆分以后即可用于课堂教学。

研究目的

利用“飞机大战”小游戏,探究在小学阶段C++语言的学习方式。

实验环境

环境:Visual Studio-2019,Easy_X图形库,C++语言。

当初计划使用Turbo C来编写这个程序,但通过实践环节验证,这个环境太老了,复制粘贴都不太方便。最后选择了安装VS2019集成开发环境,这个软件兼容很多语言,对非企业版本用户是免费的,非常方便使用。

然后下载安装easyX图形库插件,借助VS2019优秀的编辑和调试环境,再用easyX避开了注册窗口等非常复杂的操作,这样就能轻松繪制出图片或者图形。这对于初学者来说,是非常容易接受的。

实验内容及实验原理

1.需求分析(如图1)

2.流程设计(如下页图2)

3.详细设计

(1)绘制背景

背景图比较好做,把找到的背景图片直接放到窗口坐标(0,0)的位置。窗口的大小与背景图大小一致。

解决背景不能动的问题:

这样背景的是不能动的,为了模拟飞机和背景的“相对移动”,可以让背景向上移动。在这里我们需要两个背景图,当第一张背景图移动步数超过本身的长度像素数值时,就恢复(0,0)从头开始。第二张背景图一直跟在第一张背景图的下面,这样循环起来,就能实现动态的背景。

(2)绘制飞机

先从网上找一些飞机的图片素材,再使用ps软件,把图片处理成透明图,起名叫hero.png,导入到窗体。直接把飞机的透明图hero.png放到背景上,会有黑色的边缘。如何处理这种情况呢?需要制作一张掩码图。另外,利用三元光栅操作,可以制作出没有黑边的飞机。

(3)按键控制

点击键盘的上下左右按键,来控制英雄飞机的移动。飞机的移动即坐标的加减,增减量的多少,就是飞机的速度。

首先声明一个名字叫key的子函数。

子函数内容是:①先判断“键盘按键”是否被按下,当_kbhit()等于1的时候,键盘被按了。②如果键盘被按下,就把_getch()获取的按键值赋予变量mo储存起来。③else否则,也就是键盘没有被按下的时候,mo一直赋值为0。这段程序,就完成了检测按键值的任务。

下面就可以根据mo的值的不同来完成不同的动作:当按下“向上”按键的时候,mo的值为72;当按下“向下”按键的时候,mo的值为80;当按下“向左”按键的时候,mo的值为75;当按下“向右”按键的时候,mo的值为77。

用switch语句来判断mo的值:如果mo等于72,也就是按了“向上”按键,我方飞机(英雄机)的y坐标减少10;如果mo等于80,也就是按了“向下”按键,我方飞机(英雄机)的y坐标增加10;如果mo等于75,也就是按了“向左”按键,我方飞机(英雄机)的x坐标减少10;如果mo等于77,也就是按了“向右”按键,我方飞机(英雄机)的x坐标增加10;如果不是以上几个数字,直接break,不做任何变化。

(4)发射子弹,让子弹动起来

为了实现发射子弹的效果,首先处理了两张子弹的图片,一张是“透明图”,一张是“掩码图”。然后利用三元光栅操作,制作出透明的子弹图片。在这里,子弹的原图不要做得太大,除了子弹的主体图之外,边缘部分尽可能减少,这样能方便后期制作“子弹”碰到“敌飞机”的效果,减少误差。

第一种发射子弹的方式:直接将子弹图片的左上角坐标——变量初始值设定为飞机头部的坐标(x+20,y-10),让子弹的y坐标每隔一段时间就减少一定量。这样就能实现发射子弹的效果,但是屏幕上只能存在一颗子弹。“第一颗”子弹不消失,“第二颗”子弹就不能发射出来。其实,它们本来就是同一个。

第二种发射子弹的方式:要想实现连续发射子弹的效果,需要声明一个队列储存子弹的变量。让子弹在飞机头部发射,子弹每隔一段时间,坐标减少5,实现了子弹向上飞。当子弹变量减少到小于0的时候,不再压入队列,子弹消失。这样能实现连续发射的效果,所以我采用了这种方式。

(5)碰撞检测

子弹与敌飞机的碰撞检测程序:先遍历fire队列里面的子弹坐标,再把每一个子弹的坐标和敌飞机的坐标做比较。如果子弹与敌飞机碰撞,被击中的敌飞机坐标就不再压入队列。后面在运行Print_fire()的时候,这架被击中的敌机就不会被绘制出来。每检测一个子弹的坐标,先把KillEnemy变量改为0,当有敌机被击中的时候,KillEnemy变量改为1,KillEnemy作为一个标记。如果这颗子弹击中了敌机,那它也消失,就是不再继续压入队列了。这样就实现了当子弹击中敌机的时候,敌机消失、子弹消失的效果。

(6)设置时间间隔

这个相当于两个计时器,主函数每执行一次,程序会Sleep(5)5毫秒,切T和T2变量都加1。

当T>=a,也就是主函数重复执行了a次的时候,产生一个新的子弹,然后T赋值为0,重新开始计时。

当T2>=b,也就是主函数重复执行了b次的时候,产生一个新的敌飞机,然后T2赋值为0,重新开始计时。

总的来说,a越大,子弹出现的时间间隔就越大,b越大,敌飞机出现的时间间隔就越大。

(7)打印我方飞机

在打印我方飞机之前,先遍历每一架敌飞机的坐标。如果我方飞机与敌飞机相撞则life生命值减1,主函数检测到生命值小于0,则游戏停止。

检测碰撞的方式跟检测子弹碰撞敌飞机的方式相同。

首先设定我方英雄机的坐标(x, y),英雄机的像素是57*45,那么子弹的中心坐标大约是(t.x+30, t.y+22)。接着确定敌飞机的坐标(u.x, u.y) ,敌飞机的像素是50*68,那么敌飞机的中心坐标大约是(u.x+25, u.y+12)。然后把敌飞机和英雄机的外形类比成一个圆,英雄机的圆半径p大约是12,敌飞机的圆半径R大约是34。如果英雄机的圆心到敌飞机圆心的距离小于p+R的和,那么就证明英雄机与敌飞机相撞了。

(8)显示英雄机的生命值Life和得分Score(如图3)

结论

绘制图片→变量控制坐标→按键控制→敌飞机及子弹的(队列)绘制→循环遍历(碰撞检测)。这几个步骤能直观地呈现学习效果,能由浅入深地进入编程的学习之路。

参考文献:

[1]殷志坚,段晓磊.基于EasyX的俄罗斯方块游戏的设计和分析[J].科技传播,2015,7(21):137+157.

[2]赵敏,庞蕊.基于EasyX图形库的C语言课程改革研究与实践[J].电脑知识与技术,2015,11(32):124-125.

猜你喜欢
小游戏子弹队列
队列里的小秘密
基于多队列切换的SDN拥塞控制*
三颗子弹
子弹VS防弹
专注力小游戏
Karma:让子弹飞一会儿
在队列里
子弹
丰田加速驶入自动驾驶队列