
一句话来说,CL_Sprite可以做到基本的二维精灵所需的大部分事情。
CL_Sprite可用两种方式来构造 - 使用ClanLib 资源,或者通过CL_SpriteDescription 来手动构造。
请阅读精灵资源概述,以了解一下与精灵相关的资源选项的描述。
创建咯精灵资源之后,就可以轻松地从资源中创建CL_Sprite 对象咯。
CL_ResourceManager resources("resources.xml");
CL_Sprite sprite1(gc, "my_simple_sprite", &resources);
CL_Sprite sprite2(gc, "my_advanced_sprite", &resources);
如果妳不想用资源文件,那么妳可以使用CL_SpriteDescription 类来手动创建同样的精灵,这個类描述的是一组图片幀。
就像在资源文件中一样,妳添加一系列的剪切器(cutters),它们會提取出幀,放到精灵里。
CL_SpriteDescription desc_simple;
desc_simple.add_frame(CL_ImageProviderFactory::load("image_single1.tga"));
desc_simple.add_frame(CL_ImageProviderFactory::load("image_single2.tga"));
desc_simple.add_frame(CL_ImageProviderFactory::load("image_single2.tga"));
CL_SpriteDescription desc_advanced;
desc_advanced.add_frame(CL_ImageProviderFactory::load("image1.tga"));
desc_advanced.add_gridclipped_frames(CL_ImageProviderFactory::load("gridframes.tga"), 0, 0, 32, 32, 10, 2, 0, 0);
desc_advanced.add_alphaclipped_frames(CL_ImageProviderFactory::load("alphaframes.tga"), 0, 0, 0.05f);
desc_advanced.add_frame(CL_ImageProviderFactory::load("image2.tga"));
desc_advanced.add_gridclipped_frames(CL_ImageProviderFactory::load("image 3.tga"), 0, 0, 32, 32, 1, 1, 0, 0);
CL_Sprite sprite1(gc, desc_simple);
CL_Sprite sprite2(gc, desc_advanced);
sprite2.set_alpha(0.5f);
sprite2.set_base_angle(CL_Angle::from_degrees(90.0f));
sprite2.set_frame_delay(20, 100);
sprite2.set_frame_offset(20, CL_Point(1, 1));
如果妳阅读精灵资源概述的话,将會发现这段代码创建的是完全相同的精灵,只是这里用的是代码而不是资源文件。
使用代码示例:
// 确保精灵在动
sprite1.update();
sprite2.update();
// 旋转精灵
sprite1.rotate(CL_Angle::from_degrees(0.5f));
// 绘制精灵
sprite1.draw(gc, 10, 10);
sprite2.draw(gc, 100, 100);
如果妳想改变精灵的外观,则使用CL_Sprite::set_image_data()。这個函数會保留当前的属性(旋转、透明……),但是會改变动画状态(当前幀……)。
class Man
{
...
CL_Sprite sprite_man_walk;
CL_Sprite sprite_man_still;
CL_Sprite sprite_man;
}
void Man::init()
{
sprite_man_walk = CL_Sprite(gc, "man_walk", resources);
sprite_man_still = CL_Sprite(gc, "man_still", resources);
set_walking(true);
}
void Man::set_walking(bool walking)
{
if(walking)
sprite_man.set_image_data(sprite_man_walk);
else
sprite_man.set_image_data(sprite_man_still);
}
void Man::draw()
{
sprite_man.update();
sprite_man.rotate(CL_Angle::from_degrees(1.0f));
sprite_man.draw(gc, x, y);
}
要做出一個与幀无关的游戏,有好多方式。一种方式就是计算从上一幀开始到现在已过去的时间。这就是CL_Sprite 中的update()函数的工作方式。在每次调用update()的时候,它會计算已流逝的时间,然后用这個来确定应当显示动画中的哪一幀。在大部分情况下,这已足够,妳也不需要费心去研究下面的第二种方式。
某些游戏工作在“固定滴答模式”(fixed-tick-mode),在一秒之内會X 次调用更新函数,而不是在每次更新时计算时间变量。这一点,仍然可以用CL_Sprite 来实现;只需调用CL_Sprite::update(float time),其中的time 是指每次滴答(tick)的间隔。比如,如果妳的滴答频率是每秒30 次,那么可以调用sprite.update(1000.0f/30)。
HxLauncher: Launch Android applications by voice commands