这,是一个萍乡某培训机构的C++兴趣班的教学程序,你绝对在其它地方找不到。因为它是唯一的存在。就算是一线城市人才辈出的地方也是没有的。让我们来看一下这个程序长什么样吧:
C++
/*
本程序描述了一个两个葫芦娃(合用一个造型),以铁臂阿童木或超人的姿势向深空飞翔的动画,
通过星星的向左下角快速移动,采用相对运动的原理,就好像葫芦朝右上角移动。
本程序是综合性较强的一个程序,演示了C++精灵库或相关知识的一些用法,如:
1. 给角色换上新的造型
2. 动态数组,就像Python列表
3. for循环,这里产生1千颗星星
4. 相对运动的体验
5. 自定义角色的属性,通过映射(字典)
6. 内置全局指针变量g_screen的使用
7. 窗口屏幕坐标的判断
8. 这可是逐帧动画
*/
#include "sprites.h" //包含C++精灵库
#include <vector> //包含向量,就像Python的列表
using namespace std;
Sprite 葫芦娃{"res/2huluwa.png"}; //建立角色叫葫芦娃
//g_screen是全局屏幕对象的指针,所以可以直接使用
int width = g_screen->width(); //窗口屏幕宽高
int height = g_screen->height(); //窗口屏幕高度
int main(){ //主功能块
葫芦娃.hide().scale(0.01).bgcolor("black").color("cyan").write("加载中...");
vector<Sprite*> stars; //新建动态数组,保存星星指针
for(int i=0;i<1000;i++){ //产生一千颗星星
Sprite *star = new Sprite("res/circle_white.png");
float tmp = random(0.01,0.3); //作为星星的大小比例
star->scale(tmp); //设定星星的大小
star->penup(); //抬笔
star->speed(0); //速度最快
int x = randint(width/2,width*5);
int y = randint(height/2,height*5);
star->go(x,y);
//下面是映射来自定义属性,就像Python的列表
star->property["velocity"] = tmp * 100;
star->setheading(225); //朝向左下角
stars.push_back(star); //把星星的地址放到stars向量(列表中)
}
//探除所写的文字,并且设定手动刷新,然后到最上层,显示出来。
float k = 0.01; //作葫芦娃大小的比例
葫芦娃.clear().tracer(0).set_layer(1000).show();
while(g_screen->exitonclick()){
if(k<1.0)葫芦娃.scale(k); k = k+0.01;
for(Sprite *star:stars){ //每个星星都朝右上角移动
star->fd( star->property["velocity"] );
//如果到了左下角就隐藏再移到右上角的一个随机位置
if(star->xcor() < -width/2 && star->ycor() < -height/2){
star->hide();
star->go(randint(width/2,width*5),randint(height/2,height*5));
star->show();
}
}
g_screen->update(); //更新动画显示
g_screen->wait(0.01);
}
return 0;
}
先看第一行代码,它包含了一个叫sprites.h的头文件。你在哪里看过这个头文件吗?好在有个注释。它的名字叫C++精灵库。什么鬼?听说过godot,听说过虚幻引擎,听说过unity3D,但没听说过什么C++精灵库。这大概是新出的一个不知名的库吧。毕竟在中国某个角落某个程序员搞出个什么库来,别人都不知道,这不是很正常吗? 然后我们来看下这个角色是怎么创建的。代码是:
C++
**Sprite 葫芦娃{"res/2huluwa.png"};**,
变量名还是中文的,可真是顾名思义 啊。是个人都知道这是把葫芦娃给请出来了。
接着,我们看下main函数,哦,不对,应该叫主功能块。平时我们习惯了叫主函数。这里作者为什么要把它叫主功能块呢? 经过思考,这是一个青少年C++兴趣班的教学程序,叫功能块比叫函数更好理解。所以注释就变成了"主功能块"了。在主功能块里,我们看到了一行长长的代码:
C++
**葫芦娃.hide().scale(0.01).bgcolor("black").color("cyan").write("加载中...");**
翻译成中文就是让葫芦娃隐藏并且缩小,然后设定背景颜色为黑色,并且设定画笔颜色为青色后写文字。啊,好长,这C++代码真是牛逼,像自然语言一样"顺口"。
我们从最开始的注释里得知。这个程序会生成一个动画,有一千颗星星星,所以在主功能块我们看到一个for循环。它把星星们的指针都放到了stars向量里了。每颗星星的大小、位置、速度都能随机设置,比如tmp = random(0.01,0.3)控制星星大小,star->go(x,y)直接定位到屏幕随机位置。但是要注意,方向却是统一为225度。为什么要这么设定呢?225度是向左下角的方向,难道要让星星们都朝左下角移动?还真是的!
那么葫芦娃是如何向右上角飞翔的呢?其实葫芦娃根本没有动。刚才让星星们的方向为225度,利用相对运动的原理, 这样就能让星星向左下角移动,从而制造出葫芦娃向右上角飞行的效果。这种效果在游戏或动画制作中非常常见,可以增加视觉上的动感和真实感。
还有一些细节,比如其实星星的移动速度和大小是关联的。越大的星星移动的速度越快,越小的星星,就好像越在远处,所以移动速度越慢。以下这行代码:
C++
**star->property["velocity"] = tmp * 100;**
其实就是设定星星的速度,由于tmp被用于设定了星星的大小:star->scale(tmp); 所以就会呈现"立体"效果。
最后,在while循环中,星星是不断地复用的。它们不断地从右上角移到左下角,以衬托出葫芦娃的向右上角移动。一旦星星移到了左下角边缘处,则会瞬移到右上角某个位置。就像给星星们设置了一个电子围栏,跑出去就抓回来。这个程序直观地演示出相对运动这个物理原理,对于物理的学习及以后做游戏或动画的视觉逻辑非常有帮助。
总地来说,库的核心功能(从代码看),用这个C++精灵库编写动画的框是这样的:
C++
// 创建角色 - 就像在游戏里拖入一个角色
Sprite 角色{"图片.png"};
// 控制角色 - 一句话一个动作
角色.fd(100); // 前进
角色.scale(2.0); // 缩放放
角色.right(45); // 旋转
角色.write("文字"); //与字
// 动画循环 - 像电影一帧帧播放
while(游戏没结束){
更新所有角色位置();
重新绘制画面();
}
它的核心优势是可以用于快速原型:想个创意,几十分钟就能做出demo,代码简洁,比用传统游戏引擎(如SDL、SFML)代码量少很多,学习曲线平缓:比学Unity、Unreal简单得多了。这个程序本来就是一个青少年C++兴趣班教学程序,所以它无疑是中国少儿C++兴趣班新的福音啊。 `