隔了1年最近看了看Egret 做了个Demo TP:AE94AD6A

游戏也放上来罢,一个读大学时做的flash小游戏,就打算移植不过,没用用Egret提供的转换工具,全部手写移植,也是为了熟悉下语法

游戏地址 http://www.dreamfairy.cn/h5/poom/

在游戏制作上,看了看还是算蛮成熟的。

EUI的结构类似 MyGUI 且提供了可视化编辑器这店挺爽。 MyGUI官方的编辑器好无语。。

在创建的Game项目模板中,默认是加载所有资源再进游戏,感觉挺不科学,不过在做完这个demo后也就释然了,在微信和opera上跑起来,简单的逻辑就有掉帧2~3帧,不使用webgl. 手机上也用不了,所以只能做小游戏,大型游戏的话就需要打包app了,另说。

语法上,所有的AS3类型,在 egret 包中都基本实现了,不过实践了大半后,觉得一些地方用TS的特点更棒。
比如

public createParticle(idxPos : {x : number, y : number}){
    //TODO
}
请不要无脑复制转载本文, 由 dreamfairy 原创, 转载请注明出处 本文地址 http://www.dreamfairy.cn/blog/2016/01/15/make-a-demo-with-egret/

ASer 转过来一般参数可能会写 idxPos : egret.Point
但是当项目合作有些人不是ASer, 而是JS 同学的话,用Object限制参数类型就是一个很棒的选择,既可以兼容 egret.Point,也可以兼容一个 JS 同学些的 相同属性的 Object 了。

也有一些不科学的地方
比如 所有的成员属性,都需要以 “this.” 开始,好烦
函数定义不需要中间的 “function”表示,经常容易写错。 比如这样写是错的 : public function 函数名
没有const, int 等等。

同时在开发的时候,一些新的特性有兼容问题
比如我写了个 map = new map 在 opera浏览器上正常解析, 在微信中打开会出现创建失败, 所以map 都用传统的 {} 就好,也万能。。。

然后说说配置问题
egret的资源都配置在 json 中。 但是假如游戏交付后,一些前端web同学不熟悉你的配置,想修改游戏中的一些初始信息就不方便了。

所以完全可以前端web同学在游戏的 index.html 中配置一些初始属性给游戏用
比如这样
index.html

<head>
    <ts_param id="xxx" str="fuck me"/>
</head>
<body>

在TS中可以这样读取

        var x = document.getElementById("xxx");
        var data = x.getAttribute("str");
        consolog.log(data); // output = fukc me

是不是很方便~~

最后JS 和 TS 之间的交互也非常简单,熟用 window 这个中介即可

举个例子,我想TS调用JS的一个函数,然后JS函数中创建一句话回传给TS,TS再从html中读取一个参数后合并字符串返回给JS. 最后JS弹窗显示这句话。

首先在 JS 中顶一个函数像这样

    <script>
        function myFunction()
        {
            var str = 'Hello World Java Script!';
            var tsFun = window["TS_Main"].onJsCallMe;
            if (tsFun) {
                var result = tsFun(str);
                alert(result);
            }
        }
    </script>

在TS中这样写

//test call js
var jsFun = window["myFunction"];
if (null != jsFun) {
   window["TS_Main"] = this;
   jsFun();
}

    //test js call ts
    public onJsCallMe(str: any): any {
        //test get html data
        var x = document.getElementById("xxx");
        var data = x.getAttribute("str");
        return data.toString() + " and " + str;
    }

是不是很有意思, 使用 window[“TS_Main”] = this; 就可以不需要定义静态方法了,这样的话,也起到了函数的分类作用,用window的一个key 来标示所在类

最后放个游戏的源码,在git上
https://github.com/dreamfairy/EgretPooms

在Havok Vision 中创建后期处理效果

如果有人参考了 官方手册的教程 Tutorial: Creating Custom Post-Processing Effects
然后使用 PA 的 vGameSolutionCreator 默认设置创建项目,会发现运行报错
active renderer does not provide all buffers required by the post processor.Execute

经过debug,发现默认创建的render node 实际上是 VMobileForwardRenderingSystem
它只支持一个bufferflag 就是 VBUFFERFLAG_FINALCOLOR

让我们从头开始
postprocessing
打开 VForge 编写我们的后期处理特效,这次范例就用径向模糊(Dx9,Dx11)
继续阅读“在Havok Vision 中创建后期处理效果”

在Havok Project Anarchy 中创建透视效果

先晒晒收到的Havok 活动抱枕

h1h2

进入正题

本人首发于http://www.anarchy.cn/ 本人博客 http://www.dreamfairy.cn 转载请著名出处
很多人都见过 RPG Sample 中的 XRay 透视效果, 像这样

h3

英雄在被铁链遮挡的部位会呈现透视的效果,而不是被遮挡。

这个效果需要2个Pass
即一个用来呈现被遮挡时的表现
一个用来呈现未被遮挡时的表现
继续阅读“在Havok Project Anarchy 中创建透视效果”

在Havok Vision中编写 NavMesh 寻路

这篇教程的前提是已经掌握了如何在PA中创建NavMesh,如果你还不会,请参考官方的教程
http://www.anarchy.cn/portal.php?mod=view&aid=15

首先创建我们的Hero, 寻路的主角
我选择在代码中创建的方式,而创建坐标是在PA中创建一个 名为 Spawn的模型,给它一个 key 比如 9527 . 然后我们在 Vision中通过key 找到它

 VisBaseEntity_cl * pPlayerSpawn = Vision::Game.SearchEntity("9527");
     if(NULL != pPlayerSpawn){
         Vision::Message.Add(1, "Try To CreatePlayer");
         hkvVec3 pos = pPlayerSpawn->GetPosition();
         hkvVec3 rot = pPlayerSpawn->GetOrientation();
         m_playerEntity = SpawnPlayer("Models/Eddy Export/Eddy.MODEL",pos, rot);
         //把出生点隐藏掉
         pPlayerSpawn->SetVisibleBitmask(0);
     }

SpawnPlayer 函数的内如

    VisBaseEntity_cl * tmp = Vision::Game.CreateEntity("VisBaseEntity_cl", position, prefabName);
    if(NULL != tmp){
        tmp->SetOrientation(orientation);
        m_vPos = tmp->GetPosition();
        m_vRot = tmp->GetOrientation();
    }
    return tmp;

有了Hero后,就可以开始创建寻路AI了。
这里有见基础的组件来做

    m_aiSteering = new vHavokAiSteering();
    m_aiSteering->SetRadius(40);
    m_aiSteering->SetDesiredSpeed(400);
    m_aiSteering->SetEntityPivotHeight(0);
    m_aiSteering->SetSensorSize(500);
    m_aiSteering->SetTurnRadius(40);
    m_aiSteering->SetKinematicConstraint(vHavokAiSteering::CONSTRAINT_LINEAR_AND_ANGULAR);
    m_aiSteering->SetMaximalAngularVelocity(4);
    m_aiSteering->SetMaximalAcceleration(2000);
    m_aiSteering->SetMaximalDeceleration(3000);

    m_playerEntity->AddComponent(m_aiSteering);

接下来要做的事情显而易见,就是点击屏幕,然后算出投影到NavMesh上的坐标,然后寻路过去呗
对于lua 来说有个 Sceene:PickPoint. cpp 也有可惜没有 export dll 没事,我们抄写出来就行

like this

hkvVec3 * MyGameManager::PickPoint( float x, float y, float fMaxDist )
{
    hkvVec3 *result = NULL;

    hkvVec3 traceStart = Vision::Camera.GetCurrentCameraPosition();
    hkvVec3 traceDir;
    Vision::Contexts.GetCurrentContext()->GetTraceDirFromScreenPos(x, y, traceDir, fMaxDist);
    hkvVec3 traceEnd = traceStart + traceDir;

    hkVector4 s;
    vHavokConversionUtils::VisVecToPhysVecWorld(traceStart, s);
    hkVector4 e;
    vHavokConversionUtils::VisVecToPhysVecWorld(traceEnd, e);

    hkaiNavMeshQueryMediator::RaycastInput rcInput;
    rcInput.m_from = s;
    rcInput.m_to = e;

    hkaiNavMeshQueryMediator::HitDetails hitInfo;

    const hkaiNavMeshQueryMediator* mediator = vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator();
    hkBool didHit = mediator->castRay( rcInput, hitInfo );

    if (didHit)
    {
        hkVector4 hitPoint;
        hitPoint.setInterpolate4( s, e, hitInfo.m_hitFraction);

        result = new hkvVec3(0);
        vHavokConversionUtils::PhysVecToVisVecWorld(hitPoint, *result);
    }

    return result;
}

最后的最后,在Run函数中检测鼠标是否按下,然后做这样的事情

if(bOnMouseClick){
                    hkvVec3 * goal = PickPoint(posX, posY);
                    if(goal){
                        m_aiSteering->RequestPathTo(*goal);
                    }else{
                        m_aiSteering->CancelPath();
                    }
                }

这个时候如果你想说,我看不到鼠标咋办? 很好办,自己画一个

void MyGameManager::DrawCursor(float posX, float posY)
{
    Vision::Game.DrawSingleLine2D(posX,posY,posX + 10, posY + 5, V_RGBA_GREEN);
    Vision::Game.DrawSingleLine2D(posX,posY,posX + 5, posY + 10, V_RGBA_GREEN);
    Vision::Game.DrawSingleLine2D(posX + 10,posY + 5,posX + 5, posY + 10, V_RGBA_GREEN);

    Vision::Message.Print(1,200,500,"Mouse Pos X %f Y %f", posX, posY);
}

最后如果你又问,我的Hero在寻路的时候不会转向怎么办,也好办,写个Hkt 或者,用代码来动态算
在 Run 函数中加入如下

                if(m_aiSteering->HasPath()){
                    hkvVec3 lastPos = m_vPos;
                    hkvVec3 nowPos = m_playerEntity->GetPosition();
                    float dx = lastPos.x - nowPos.x;
                    float dy = lastPos.y - nowPos.y;
                    float degree = hkvMath::atan2Deg(dy,dx) - 90;
                    m_vRot = hkvVec3(degree,0,0);
                    m_eState = ROLE_RUN;
                }
                                m_playerEntity->SetOrientation(m_vRot);

如果你问我Hkt 怎么做转向? 改日再说吧,我要睡觉啦。

Havok Vision Project Anarchy 创建项目的二三事

最近开始深入开发C++ 的 Havok Vision, 遇到许多许多的坑,整个互联网上居然都没有前人列出来,于是我决定把遇到的坑都填上,造福你们这些看到本文章的有缘人

1.从project anarchy生成项目的时候,如果要使用ScaleForm ,请务必勾选 Enable ScaleForm Support
2.如果运行demo, 遇到无法加载 vHavokAI.Plugin 或者 vHavokBehavior.Plugin 那是因为模板文件没有把这个文件拷贝的项目的运行目录下,需要到你 vForge.exe 运行目录下找到这2个文件,然后拷贝到你项目的生成目录下
3.一旦使用了 vHavokAI 相关API 就会报错,找不到函数实现的错误, 比如使用的 vHavokAIModule 等模块, 那么需要编译一下它的依赖lib. 这个项目在类似这样的目录下 HavokVisionSDKWorkspaceWin32_VS2012_win7_DX9HavokVision_Editor_Win32_VS2012_win7_DX9.sln 找到你项目依赖的lib平台 dx9,dx11 x32 x64 等,把它们生成一下
4.如果做完第3点后,仍然报错,在使用AI相关的项目上做如下设置 项目->属性->C/C++->预处理器->预处理器定义 加上一个宏 VHAVOKAIMODULE_IMPORTS 即可 Behavior有问题的话,同理

etc…

最近无聊写了个Havok Demo,顺便发出来好了

话说Havok 自从 project anarchy 出来后,就没看到任何教程=。=, 社区也几乎没人。
切官网文档都是Lua的。 我写个C++的Demo 真是困难耶. 不过慢慢找到诀窍了。

by the way
百度BCS 貌似图标全部失效了, 之前的Flash档Demo貌似加密无法解析了, 空间貌似访问的速度好慢。。。 时候全部换掉了 =。=

然后上个截图 < 西游记之大圣归来>
monkeyking

看完表示很值票价,同时期评分最高有木有,大家快去看。

好,进入正题~
继续阅读“最近无聊写了个Havok Demo,顺便发出来好了”

Unity3D中使用有米广告SDK By Android Studio

最近准备对接广告SDK, 网路上搜索全是有米SDK的,fuck~ 有些还是几年前的版本
于是我决定作死,使用最新的 Android Studio 1.2.2 来打包Jar. 对接有米SDK, Unity3D 使用 5.1.2 版本,顺便试下调用Android 函数.

打开创建一个Project
create_project

这里注意下下面的包名 dreamfairy.com.adtest 之后要在Unity中填,要一模一样
点击Next

select_devices

什么都不用改,直接Next

add_activity

这里选择 Blank Activity 后点击 Finish 等 项目初始化后,开始正式工作
继续阅读“Unity3D中使用有米广告SDK By Android Studio”

在Unity3D中创建反射纹理

距离上次技术相关的博文有半年了吧。。。这次回来了,会坚持下去。
说到反射纹理,本质上就是创建一个 CubeMap 立方体贴图, 把需要被反射的目标渲染的6个纹理上, 然后反射的物体根据自身的法线方向在对应的6个面上进行采样。
一步一步来

首先创建一个CubeMap纹理
在project面板上右键->Create->Legacy->CubeMap
然后在Inspector面板上将前后左右上下的纹理添加进去 like this..
cubemaptex
创建好后,不如把它作为天空盒吧,这样到时候反射物体可以直接反射周围的天空的说,说干就干。。
首选创建一个材质,设置材质的Shader为skybox->Cubemap,然后把刚才创建的纹理赋予它 like this
cubemapmat
打开菜单 Window->Lighting 将创建的材质放入 SkyBox槽位,我们就能看见天空啦
skyboxview

之后我们需要编写一个Shader来对天空盒的cubemap 进行采样,就是反射啦

Shader "Custom/CubeMap" {
    Properties {
        _Cube("Reflection Map", Cube) = "" {}
    }
    SubShader {
        Pass
        {
            CGPROGRAM
            #pragma  vertex vert
            #pragma  fragment frag

            #include "UnityCG.cginc"

            uniform samplerCUBE _Cube;

            struct vertexInput
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };

            struct vertexOutput
            {
                float4 pos : SV_POSITION;
                float3 normalDir : TEXCOORD0;
                float3 viewDir : TEXCOORD1;
            };

            vertexOutput vert(vertexInput input)
            {
                vertexOutput output;
               
                float4x4 modelMatrix = _Object2World;
                float4x4 modelMatrixInverse = _World2Object;

                //计算视野方向,世界空间顶点与世界空间内相机位置相减
                output.viewDir = mul(modelMatrix, input.vertex).xyz - _WorldSpaceCameraPos;
                //将法线从模型空间也统一转换到世界空间
                output.normalDir = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
                output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
                return output;
            }

            float4 frag(vertexOutput input) :COLOR
            {
                //计算视线方向与法线法线方向的反射向量
                float3 reflectDir = reflect(input.viewDir, input.normalDir);
                //texCUBE是CubeMap采样,tex2D是2D纹理采样
                return texCUBE(_Cube, reflectDir);
            }

            ENDCG
        }
    }
    FallBack "Diffuse"
}

继续阅读“在Unity3D中创建反射纹理”

Loog time no see~

很久,很久,很久没有写博客,好像都有半年的样子了 😀
一直都在忙项目的说~
好歹游戏游戏上线了,目前正在公测beta阶段
KindomsCHarge
相关主页在FB上啦 https://www.facebook.com/kingdomscharge

我表示一个人完成所有技能表示心理好虚~一共170+个技能。
顺带提供一下apk网盘地址吧~
http://pan.baidu.com/s/1c0m4eo4