DreamFairy正在把前年的 苍白的茧大冒险 移植到starling上.
之前的游戏在这里 点我进入

一些一般性常识就不提了,直接记录我遇到的问题

1.创建starling后, 要么设置 starling.start() 要么在 某个render中调用 starling.nextfame(); 否则所有的监听都会失效. 比如 Event.TRIGGERED

2.创建一个MovieClip后 必须使用 Starling.juggler.add 加载后,才会播放帧. 移除MovieClip 后从 juggler移除,然后执行dispose ,它的事件会自动移除

3.在用之前的洛克素材创建MovieClip的时候,发现每帧会出现拉伸和模糊. 原因是 MovieClip会根据其第一个Texture来设置其宽高, 而洛克的素材原本就是矢量的逐帧动画,每帧宽高不一样,导致部分帧被拉伸.

要解决模糊问题, 直接调用 Texture.fromBitmapData(bmd,false); 第二个参数设置为 false即可.
要解决拉伸问题. 我试过几种方法.
1) 遍历洛克的所有帧,取出最大宽和最大高,然后创建一个空的Texture插入 Texture数组. 待创建MovieClip后 将其移除. 结果画面仍然被拉伸, 虽然还没去看源码,但我估计是 MovieClip设置宽高依据的不是第一个 Texture的width 和 height 而是 colorBounds ,因此第一个空的Texuture因为没有任何像素而导致宽高失效.

2) 试着使用TexturePacker 但是这货要导出一张位图和一张xml配置表.这样导致项目的复杂度又高了…(其实是DreamFairy很懒,不舍得写混合loader,连greensock的queueloader都不舍得用, 更别说写一个 xml+png 打包成一个文件的 打包工具了)

3) 于是考虑着既然游戏的体积不大,就适当的浪费一下性能吧.
代码如下:
[cc lang=”actionscript” nowrap=”false”]
private function createIdelTexture() : void
{
var cls : Class = getDefinitionByName(“stand”) as Class;
var standMovie : flash.display.MovieClip = new cls();
var textureList : Vector. = new Vector.();
var bmd : BitmapData;
var maxWidth : Number = 0;
var maxHeight : Number = 0;
for(var i : int = 0; i <= standMovie.totalFrames; i++) { standMovie.gotoAndStop(i); if(standMovie.width > maxWidth) maxWidth = standMovie.width;
if(standMovie.height > maxHeight) maxHeight = standMovie.height;
}

for(var j : int = 0; j <= standMovie.totalFrames; j++) { standMovie.gotoAndStop(j); bmd = new BitmapData(maxWidth, maxHeight, true, 0); bmd.draw(standMovie); textureList.push(Texture.fromBitmapData(bmd,false)); } m_idelMovie = new starling.display.MovieClip(textureList); m_idelMovie.pivotX = m_idelMovie.width >> 1;
m_idelMovie.pivotY = m_idelMovie.height;
}
[/cc]

非常笨的方式,先循环一次,计算出最大宽高.
再循环一次,创建全部等大且为最大宽高的BitmapData.然后构建成Texture
最后设置中心点为洛克的脚下中央…

by the way… stage3d的 实时阴影部分的源码,很多大神明明写出来了,却不公开源码. 我懂得,这是潜规则. It’s ok 我也已经研究出来flare3d 创建实时投影的办法,虽然在我看来我的实现方式比较笨. 嘛嘛~既然是潜规则,你们不公开,那我也不公开.

之前的地址中的demo 没有出现模型, 估计是使用的 lib的问题, 导致load 模型解析失败. 本地是正常的说.
于是在这版直接嵌入了模型,同时加上骨骼绑定和第二摄像机.
地址: http://www.dreamfairy.cn/blog/work/flash/3d/everymounthgame01/bin-debug/FlareShadow.html

总结一下吧, 之前忘了总结了.
1.想模仿<天界>那样做一个2D的地图,于是试着创建一个 4000*4000的 plane 并贴上 4000*4000的位图, 显示的结果只有 2000*2000的位图被拉伸到 4000*4000了,翻阅资料后发现, 向GPU上传位图的时候,不支持超过2000的尺寸. 因此需要将位图切割并 创建4个 2000*2000的 plane进行组合.

2.在创建了水波效果后,试着创建了一个灯光,结果水波的贴图丢失了,无法渲染. 在错误日志中发现是寄存器不够用了. 于是找到水波的flsl文件,将不再使用的属性全部删除,给灯光shader留出位置. 所以对于创建的所有shader程序都要记得释放寄存器.

3.骨骼绑定,直接贴代码吧.
[cc lang=”actionscript3″ nowrap=”true”]
var skinnedMesh:Mesh3D = player.getChildByName( “astronaut”) as Mesh3D;
var weapon:Cube = new Cube( “weapon”, 10, .05, .05 );
weapon.rotateZ(90);
weapon.setPosition(0,-5,0);
weapon.addComponent( new BoneController( skinnedMesh, “Bip01 L Finger2” ) );
scene.addChild(weapon);
[/cc]
new BoneController 是一个自定义类,非官方API 借口是 IComponent. 内容如下.
在3d max中,选取模型后 该模型的名字为 astronaut. 所有的骨骼都在这个容器里. 因此先 getChildByName获得容器. 再通过 skinnedMesh.modifier.root.getChildByName( boneName ); 获取到骨骼, 返回的是一个 Pivot3D类型. 然后将这个我们定制的 weapon 添加到该骨骼上.

4.贴图更换,也是直接上代码.
var curSkin : Shader3D = player.getMaterialByName(“head”) as Shader3D;
首先可以通过材质的名称获取到该材质
然后通过 curSkin.filters[0].texture = new Texture(要替换的bitmapdata贴图); 来改变该材质的贴图.

5.GUI 我试着制作一个3D的UI,但是时间成本太高了,没有快速的解决方案,于是只好使用 starling. 虽然 starling可以在构造函数中设定使用的 stage3D层级. 但是flare3D本身却没有这样的方法. 因此这样会导致 starling会跟 场景出现渲染层级的冲突. 解决方案只有调用 flare3d 的 postRender 来延迟 flare3D的渲染,先调用 starling.nextFrame()来保证 GUI在最前.

6.flsl 是个好东西,把agal code 封装层 pixel bender的语法了,类似C++这样的高级语言, 使我很容易编写出自己想要的效果. 但是 real time shadow 一直很难实现, 会的人不多,但他们也都不肯轻易放出实现方法,原因我懂的. 那就让我自己研究吧.

记得前年暑假的时候,做过一个山寨恶魔城的游戏. 嘛~下个月就做 采用starling来复刻的版本吧~

之前看某国外博客的时候,发现博主每月都会出个游戏,虽然不是很好玩的样子,但是都很有技术性的说.
于是DreamFairy也决定照着这么干了.

这是这个月的demo
里面使用了换肤,灯光,碰撞检测(地面),天空盒

在制作的时候,遇到一件很棘手的事情… 在给场景添加了灯光之后,之前渲染的水波效果就突然丢失贴图了. 于是跟踪了错误后发现,丢失贴图并不是在构造动态材质的时候出的错,而是才设置材质的时候出错. 出错信息是寄存器溢出. 于是才想到这坑爹的 像素着色器只有坑爹的8个寄存器. 于是在所有的 着色器的运行完毕后,将所有用不到的参数全部删除.这下在正常了.

以下是截图, 游戏地址是这里.. 略大 慢慢等. http://www.dreamfairy.cn/blog/work/flash/3d/everymounthgame01/bin-release/FlareShadow.html