准备工作
1. 使用CompositeSprite作为地块管理类,每个地块视为一个精灵,这是引擎默认提供的一种SceneLayer实现方式.
2. 直接改写CompositeSpriteToy例子中的isoLayout.cs代码,引擎提供了一个Iso的演示,不过地块图不是常规的菱形,这里会改进为菱形地块.
3. 资源准备,一张菱形地块组合图,使用TexturePack生成对应的ImageAsset.
第一回合
function CompositeSpriteToy::createIsoLayout( %this )
{
// Set the layer #0 sort mode to be depth.
SandboxScene.setLayerSortMode( 0, "-y" );
// 创建一个组合精灵
%composite = new CompositeSprite();
// 设置精灵位置跨度
// 这个参数在等轴视距的时候会对地块排列进行缩放
%composite.setDefaultSpriteStride( 4, 2 );
// 设置默认的精灵大小
%composite.setDefaultSpriteSize( 8, 4 );
// 设置模式,这个必须在添加精灵之前进行
%composite.SetBatchLayout( "iso" );
// Set the batch sort mode for when we're render isolated.
%composite.SetBatchSortMode( "-y" );
// Set the batch render isolation.
%composite.SetBatchIsolated( CompositeSpriteToy.RenderIsolated );
// 添加精灵
for ( %y = -%range; %y <= %range; %y++ )
{
for ( %x = -%range; %x <= %range; %x++ )
{
// Add a sprite with the specified logical position.
// In isometric layout this two-part position is scaled by the default sprite-stride.
%composite.addSprite( %x SPC %y );
// 对当前选择的精灵设置图像,在添加一个精灵的同时, %composite会自动将其设为当前选择
%composite.setSpriteImage( "CompositeSpriteToy:sand_tiles.asset", getRandom(5,7) );
}
}
// Add to the scene.
SandboxScene.add( %composite );
// Set the composite sprite toy.
CompositeSpriteToy.CompositeSprite = %composite;
}
演示的结果:
地块中间有缝隙,这是因为没有设置图像资源的采样模式,解决的方法有两种:
一种是在ImageAsset中增加FilterMode="Nearest"
另一种是增加全局变量配置: $pref::T2D::imageAssetGlobalFilterMode = "Nearest";
结果:
第二回合
地块的拣选操作是基础功能,下面我们实现地块拣选.
因为引擎扔处于开发阶段,很多功能需要互动沟通,以便于在后期提供出来.所以在主分支中,没有地块拣选功能.我在论坛上联系到了作者,在今天早上开发库中上传了对应的三种方法,分别是:
ConsoleMethod(CompositeSprite, pickRay, const char*, 4, 6, "(startx/y, endx/y) Picks sprites intersecting the specified ray with optional group/layer masks.\n"
"@param startx/y The coordinates of the start point as either (\"x y\") or (x,y)\n"
"@param endx/y The coordinates of the end point as either (\"x y\") or (x,y)\n"
"@return Returns list of sprite Ids");
ConsoleMethod(CompositeSprite, pickArea, const char*, 4, 6, "(startx/y, endx/y ) Picks sprites intersecting the specified area with optional group/layer masks.\n"
"@param startx/y The coordinates of the start point as either (\"x y\") or (x,y)\n"
"@param endx/y The coordinates of the end point as either (\"x y\") or (x,y)\n"
"@return Returns list of sprite Ids.");
ConsoleMethod(CompositeSprite, pickPoint, const char*, 3, 4, "(x / y ) Picks sprites intersecting the specified point with optional group/layer masks.\n"
"@param x/y The coordinate of the point as either (\"x y\") or (x,y)\n"
"@return Returns list of sprite Ids.");
并更新了CompositeSpriteToy,增加了拣选的示例代码.下面解释重要的代码段:
// 输入消息处理包
package CompositeSpriteToyPackage
{
function SandboxWindow::onTouchDown(%this, %touchID, %worldPosition)
{
// Call parent.
Parent::onTouchDown(%this, %touchID, %worldPosition );
// Fetch the composite sprite.
%compositeSprite = CompositeSpriteToy.CompositeSprite;
// 精灵拣选
%sprites = %compositeSprite.pickPoint( %worldPosition );
// Fetch sprite count.
%spriteCount = %sprites.count;
// Finish if no sprites picked.
if ( %spriteCount == 0 )
return;
// 选择的精灵遍历
for( %i = 0; %i < %spriteCount; %i++ )
{
// Fetch sprite Id.
%spriteId = getWord( %sprites, %i );
// 设为当前选择
%compositeSprite.selectSpriteId( %spriteId );
// 删除
%compositeSprite.removeSprite();
}
}
引擎例子中,对于消息截获的设计都是以功能包的方式.
static void activatePackage(StringTableEntry name);
static void deactivatePackage(StringTableEntry name);
我们需要分别在create和destroy中激活和搁置功能包.
运行结果如图:
有了拣选功能,但是从提供的新方法来看,并没有对菱形和不规则多边形支持,在地块选择的时候会存在一次拣选0-4个的情况,已经告知作者,后续跟踪~~~~