我想为Box2D中的动态对象添加颜色。似乎必须在场景渲染中分配动态对象的某些属性。我玩过Box2D演示,但无法弄清楚如何添加颜色(和位图)之类的属性?
SmartMS随附的Box2d演示使用Box2d的“ DebugDraw”功能。此功能仅使用“内部静态对象”,“移动对象”和“静止对象”的一些内部颜色绘制对象的表示。我实际上不确定是否可以覆盖这些...
您需要做的是用您要使用的自定义绘画替换FWorld.DrawDebugData
(在PaintView
方法中)。
您可以像这样遍历所有对象:
Body := FWorld.GetBodyList; //Will give you first object in list
while Assigned(Body) do
begin
//Do something with "Body" here...
Body := Body.GetNext; //Will give you next object in list
end;
例如:
i := 0;
Canvas.Font := '10pt verdana';
Canvas.FillStyle := 'rgb(255,255,255)';
Canvas.FillTextF('Count:' + IntToStr(FWorld.GetBodyCount), 30, 40, MAX_INT);
Body := FWorld.GetBodyList;
while Assigned(Body) do
begin
Canvas.FillTextF('i:' + IntToStr(i), 30, 60+(i*12), MAX_INT);
Canvas.FillTextF('Y:' + FloatToStr(Body.Position.Y, 2), 70, 60+(i*12), MAX_INT);
Body := Body.GetNext;
Inc(i);
end;
要为各种对象绘制精灵,您应该使用一个TW3SpriteSheets
类来处理它。
将精灵表图像作为资源文件添加到项目中,并且在编译时将其提取到res文件夹中。
像这样加载图像:
FSpriteSheet := TW3SpriteSheet.Create;
FSpriteSheet.LoadImage('res/MySpriteSheet.png');
并使用如下图像:
if FSpriteSheet.Ready then
begin
FSpriteSheet.Draw(Canvas, 100, 100, 1); // draw tile #1
FSpriteSheet.Draw(Canvas, 133, 100, 2); // draw tile #2
FSpriteSheet.Draw(Canvas, 166, 100, 3); // draw tile #3
end;
在Sprite表格中,您具有对象的所有旋转需求。
(图片来自:http : //gameonaut.com/wordpress/2011/11/flixel-demo-creating-animated-and-rotated-sprites-from-an-un-rotated-animated-images/)
(图片来自;http://windowsphone7developerguide.blograby.com/more-sprite-transforms-rotation-and-scaling/)
在Angle
你的Box2D得到的是在弧度。使用build int函数RadToDeg
将角度设为0-360。
Canvas.FillTextF('A:' + FloatToStr(Body.Angle, 2), 140, 60+(i*12), MAX_INT);
Canvas.FillTextF('A:' + FloatToStr(RadToDeg(Body.Angle), 0), 220, 60+(i*12), MAX_INT);
角度可以大于360度,您只想知道0到360之间的值。因此,请使用MOD:
SpriteAngle := Round(RadToDeg(Body.Angle)) MOD 360;
此外,角度可以为负,因此您需要将其-1
变为359
:
if SpriteAngle < 0 then
SpriteAngle := SpriteAngle + 360;
最后。由于360度与0度相同,因此您想使用0:
if SpriteAngle = 360 then
SpriteAngle := 0;
现在我们有了一个0到359度的角度,我们想根据该角度选择合适的精灵。如果子图形表中有32个子图形,则360/32 = 11.25
每个扇区具有度数。因此,对于第一个扇区(0到11.25),我们想使用精灵0,对于下一个扇区(11.25到22.5),我们将使用第二个精灵Trunc
,以此类推。359 / 11.25 => 31.911 => 31
FSpriteSheet.Draw(Canvas, X, Y, Trunc(SpriteAngle/11.25));
在此屏幕快照中,我使用了本文中的Sprite工作表(http://www.codeproject.com/Articles/9012/Rotating-Sprite-Objects-on-DirectDraw-Wrapper-for)。它具有101个精灵,非常平滑。
(调试数据:i,Body.Position.Y,Body.Angle,RadToDeg(Body.Angle),最终0-359角,SpriteID)
A few notes about X,Y and using the second half of the sprite sheet...
To avoid a mess, I left out X and Y from the previous code line.
Setting X and Y is basically:
X := Body.Position.X * CScale;
Y := Body.Position.Y * CScale;
However! If you run this with debugdraw, you'll notice that Body.Position.X
and Body.Position.Y
refers to the center of the Box2d object, while FSpriteSheet.Draw(Canvas, X, Y, ...
refers to the top, left corner. You will therefor need to make a minor adjustment:
X := Round(Body.Position.X * CScale) - FSheet.SpriteHalfWidth;
Y := Round(Body.Position.Y * CScale) - FSheet.SpriteHalfHeight;
An how to pick a sprite from the second half of the sprite sheet?
Well, it's pretty easy ;-)
如果要使用后半部分的图像,则需要从第二组中的第一个精灵开始以0索引计数。每组中有112张图像。第一组= 0..111,第二组= 112..223。因此,当您想达到第一组时,请使用0 + SpriteId
。如果要从第二组中选取精灵,请使用112 + SpriteId
。如果您有更多集合,依此类推。
在我的示例中,我为每个第二个对象使用了第二组。通过使用i MOD 2
,每个奇数将为1,每个偶数将为0。
因此,此代码将导致每个偶数为0,每个奇数为112:
SpriteSetStart := (i MOD 2) * 112;
然后,将引用添加到精灵ID。在我的101个精灵(和11个空白精灵)的示例中,每个精灵将覆盖3.564度的扇区。360/101 => 3.564。
SpriteId := Trunc(SpriteAngle/3.564);
最后:
FSpriteSheet.Draw(Canvas, X, Y, SpriteSetStart + SpriteId);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句