DelphiX教程系列 3 动画 part 3

用到的组件(TDXDraw,TDXImageList,TDXSpriteEngine):TDXDraw TDXImageList TDXSprite


原文链接:http://www.delphigamedev.com/tutorials/dxtut3c.htm
代码下载

在这最后一部分里,我们将引入第二个精灵,让您知道我们是如何添加和使用精灵的。我们也将处理碰撞(collision),并通过程序改变精灵的动画。

首先,我们在之前声明的精灵后面添加如下代码:

TGhost = class(TImageSprite)
public
procedure
DoMove(MoveCount: Integer); override;
end;

这与之前的创建TPacman一样,创建TGhost精灵类型。然后我们只需要在var声明区添加如下代码来分配一个该类型的变量:

Ghost: TGhost;

在继续之前,让我们把ghost精灵添加到DXImageList组件中去,并命名为Ghost。使用到的Ghost图片如下,也是由Dicon Peeke提供。

Ghost Sprites

这次我们需要设置该图像的PatternWidth属性为35,因为它稍微有点“胖”。在这里,也许您也要添加下面的那张图片(命名为Explode),设置其PatternWidth属性为28,我们将在本例子中用到它。

Explode Sprites

现在我们就可以在窗体的OnCreate事件里添加如下代码来初始化Ghost精灵了:

Ghost := TGhost.Create(DXSpriteEngine1.Engine);

Ghost.Image := Form1.DXImageList1.Items.Find('Ghost');
Ghost.X := 400;
Ghost.Y := 10;
Ghost.Width := 35;
Ghost.Height := Ghost.Image.Height;
Ghost.AnimCount := 2;
Ghost.AnimLooped := True;
Ghost.AnimSpeed := 50/1000;
Ghost.AnimStart := 0;

上面的代码就不再细说了,唯一的区别就是更改了X和Y的坐标和用"Ghost"代替了“Pacman”这个词。这次我们为其指定了宽度。因为我们在要处理碰撞时需要让程序知道精灵的宽度。在Pacman.Height那一行前添加如下代码:

Pacman.Width := 28;

目前我们所做的跟之前没什么两样,但我们将为TPacman添加DoCollision过程。我们在TPacman类的DoMove过程后面添加如下的代码:

procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;

这允许我们添加一个用于处理Pacman与其他精灵碰撞的过程。我们应该把下面所示的代码应该放到TPacman.DoMove过程后面,以令代码组织良好。

procedure TPacman.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if Sprite is TGhost then
begin
Pacman.Image := Form1.DXImageList1.Items.Find('Explode');
Pacman.Width := 28;
Pacman.Height := Pacman.Image.Height;
Pacman.AnimCount := 5;
Pacman.AnimLooped := False;
Pacman.AnimSpeed := 50/1000;
Pacman.AnimStart := 0;
PacmanDead := True;
end;
end;

该 过程(Procedure)首先检查当前精灵是否碰到了TGhost类型的精灵。如果是,则执行后面的代码。当然,在我们的程序里,碰转仅能发生在与 TGhost类型精灵之间(因为它是唯一可以碰撞到的精灵)。如果您随后添加其他碰撞时产生不同反应的精灵,这将会很有用。这一行代码有必要放在这里,因 为它对您很有帮助。那么,当Pacman与Ghost碰撞的时候,我们要把它的图片改变成爆炸(explode)的图片,记得改变它宽度、高度、动画单元 格(animation cells)的数目、速度与起始单元格(starting cell)。我们也要设置其looped属性为false,那么它就不会不断重复播放爆炸的动画。最后把布尔变量PacmanDead设置为true,我 们将在下面Pacman.DoMove过程中用到它。您可以在主程序中的var区域以普通方式声明该变量。我们应该注意到,我们在这里所做的只是简单的把最后的动画替换成另外一个,并且告诉程序知道在其之后不需要任何动画。实际上精灵还在那儿,只是因为Explode图像的最后一个动画单元格是空白的,所以我们看不到它。要删除精灵您需要调用Dead;这一行代码,并在OnTimer过程的第一行上写上DXSpriteEngine1.Dead;以检查是否有任何‘dead sprites’。显然在大型游戏里,我们应该调用它来释放废弃精灵所占用的内存空间,但在本例中我们不需要那样做。

那么,为了用到新增的collision过程,我们需要修改TPacman.Domove过程,代码如下:

procedure TPacman.DoMove(MoveCount: Integer);
begin
inherited;
if
PacmanDead = False then begin
PixelCheck := True;
Pacman.X := Pacman.X + 1;
Collision;
end else
end;

这 都干了些什么呢?首先,我们检查PacmanDead变量是true还是false,如果它是false(ie.Pacman还存活),则执行下面的代 码。第二行设置PixelCheck属性为true。该属性允许我们只在Pacman和Ghost图像的实际边缘相接触时执行碰撞,而不是在周围透明的区 域相接触时执行。如果您不确定请看下图。这是一个很棒的特性,它允许我们执行逼真的碰撞(不是那种看上去没有任何东西接触的碰撞)。如果您不明白下图的例 子,试把该值设置成false看看效果。在设置PixelCheck为true之后,我们还需要把Pacman向右移动一个像素(在完成调用 DoCollision过程之前)。因为我们在TPacman的过程里编写代码,所以写成Collision;就可以了。如果我们在其他过程里,则需要写成TPacman.Collision;,这样程序就知道该执行那个Collision过程了。

PixelCheck Bounding Boxes

PixelCheck为false,当精灵的外部区域接触时就发生碰撞(注意这里微亮的红色)。

PixelCheck - pixels

PixcelCheck为true,当Pacman和ghost的实际像素(actual pixels)接触时才发生碰撞。

运 行该程序,您将看到pacman精灵在屏幕上移动,并它碰撞到ghost时自爆:)。或许该程序不是很过瘾,但在下一教程里,我们将学习滚动背景 (scrolling backgrounds)和如何使用DXInput组件来移动Pacman。如果您都完成了本教程的三个部分,给您自己掌声,您已经可以开始思考如何利用 DelphiX来开发一些小游戏了。如果您有任何问题,或者您发现我没有注意到的错误,请给我Email吧。ben@delphigamedev.com
祝编程愉快,see U next time。

版权说明

本 系列译文在博客园发表,除允许在互联网上自由转载外,不允许以其它任何方式拷贝、编辑、印刷出版、制作发行及传播,包括不允许 在笔者未知晓的情况下制作成各种格式的电子文档并传播,更不得在未经笔者本人允许的情况下以任何形式的拷贝用于商业用途。笔者对本系列译文保留有追究其侵 权责任的权利。

若需制成电子文档并用于非商业用途方式的传播,请保留以下版权信息,并与笔者联系邮寄副本一份。

作者:Nicholas.Yuen
网名:小丸
Email:ruanjiayuan AT gmail.com ( AT -> @)
Blog:
http://genkagen.blogspot.com
http://ruanjiayuan.blog.163.com
http://randomforce.cnblogs.com
http://hi.baidu.com/genkagen
时间:2008.08.20
Copyright: 2008 Nicholas.Yuen All right resver

PS:转载请保留以上版权信息

原文地址:https://www.cnblogs.com/waterfalleagle/p/1766336.html