准备工作
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个的情况,已经告知作者,后续跟踪~~~~