存档

2015年3月 的存档

Cannot implicitly convert type `bool' to `UnityEngine.RaycastHit'

2015年3月28日 没有评论

Hi I tried to cast a line from next to gameObject to gameObject:

bool Valid(Vector3 direction)
{
    Vector3 position = transform.position;
    RaycastHit hit = Physics.Linecast (position + direction, direction);
    return (hit.collider == GetComponent<Collider>());
}

Error:

Cannot implicitly convert type bool' toUnityEngine.RaycastHit’

Physics.Linecast returns true if there is any collider intersecting the line between start and end, it does not return a RaycastHit.

You have to add the hit variable as the third parameter:

RaycastHit hit;
Physics.Linecast(position + direction, direction, out hit);

See the API for more info.

分类: stackoverflow精选, unity3d 标签:

微信开发(七)微信分享接入

2015年3月27日 没有评论

微信分享

微信上做推广活动一般都是着眼于微信分享,这篇文章介绍如何在页面中加入微信分享的处理。本文使用语言为Java+js。

原理

微信分享功能的难点,在于用户是否真正的分享了推广页面,所以我们要知道用户分享成功的操作。经过查询文档,微信提供了对应的JS接口。对应文档在这里 .

大体流程是这样的:

  • 绑定域名
  • 引入JS文件
  • 通过config接口注入权限验证配置
  • 通过ready接口处理成功验证
  • 通过error接口处理失败验证
  • 编写对应回调

如果你自信满满的完成了上面这些步骤,就可以开始着手测试了。 当点击对应功能时,微信会回调对应的接口。我的需求是当用户分享到自己的朋友圈时,做一些猥琐的操作  ,因此下面以分享朋友圈为例,当然其他功能也很类似,此处按下不表。

实现

上面概括了原理了原理,接下来一步一步看。本文可以结合 官方文档 一起看,毕竟它更新维护的比较勤。

绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 备注:登录后可在“开发者中心”查看对应的接口权限。

此处要注意了,微信服务号还没验证的程序狗,赶紧催促贵公司的商务人员,申请微信服务号验证,目前没有认证的服务号是没法使用大多数JS接口的 微信开发(七)微信分享接入

引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):

http://res.wx.qq.com/open/js/jweixin-1.0.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

这个没啥说的,就是注意要把引入放到其他步骤的上面,JS脚本按顺序加载,大家都懂的。

通过config接口注入权限验证配置

这个最麻烦了,首先说脚本的格式:

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});

这部分信息的获取,推荐使用ajax请求一下自己的服务器,毕竟加密这东西没法在客户端搞。所以大体流程是用户打开网页,运行ajax脚本请求服务器一堆信息,成功发下来后,在写到js里面。下面上代码:

var url = location.href.split('#').toString();
$.ajax({
    type : "POST",
    url : "yourInterfaceURL",
    dataType : "html",
    async : false,
    data:"url="+url,
    success : function(dataStr) {
        var data = $.parseJSON(dataStr);
        wx.config({
            debug: true,
            appId: data.appid,
            timestamp: data.timestamp,
            nonceStr: data.nonceStr,
            signature: data.signature,        
            jsApiList: [
                'checkJsApi',
                'onMenuShareTimeline'
            ]
        });
    },
    error: function(xhr, status, error) {
        alert(status);
        alert(xhr.responseText);
    },
});

这里有一点要注意,我们需要将请求页面的URL传上去,因为微信会在页面后面加入一些后缀比如&isInstall=0之类的。所以它要求你动态算一个URL地址,而不能硬编码。

然后服务器收到这请求就加密去。要加密要一个jsapi_ticket,而要jsapi_ticket又需要token.

由于原理一样,这里仅以jsapi_ticket为例:

public String jsapi_ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

public String getJsapiTicket() {
    long now = System.currentTimeMillis();
    if(now - curJSTokenTime > expiresJSToken*1000)
    {
        String requestUrl = jsapi_ticket.replace("ACCESS_TOKEN", getToken());
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
        System.out.println("Getting weixin js_token...URL:"+requestUrl);

        if (null != jsonObject) {
            try {
                curJSToken = jsonObject.getString("ticket");
                expiresJSToken = jsonObject.getInt("expires_in");
                curJSTokenTime = System.currentTimeMillis();
                System.out.println("update weixin token:"+curJSToken+"expires_in is:"+expiresJSToken+" curTime:"+curJSTokenTime);
            } catch (JSONException e) {
                System.out.println("Get JS_Token Error! errcode:{} errmsg:{}"+jsonObject.getInt("errcode")+jsonObject.getString("errmsg")+e);
            }
        } else {
            System.out.println("http for weixin return null");
            curJSToken="";
        }
    } 
    return curJSToken;
}

拿到了这个东西就可以算加密串了。当然用这个函数需要先去取Access_Token,这就又要用到appid和appSercet,你必然知道在哪找到这货,啥?不知道?去微信的开发者中心的配置项那边碰碰运气吧。

public Map<String, String> makeWXTicket(String jsapi_ticket, String url) {
    Map<String, String> ret = new HashMap<String, String>();
    String nonce_str = create_nonce_str();
    String timestamp = create_timestamp();
    String string1;
    String signature = "";

    //注意这里参数名必须全部小写,且必须有序
    string1 = "jsapi_ticket=" + jsapi_ticket +
              "&noncestr=" + nonce_str +
              "&timestamp=" + timestamp +
              "&url=" + url;
    try
    {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(string1.getBytes("UTF-8"));
        signature = byteToHex(crypt.digest());
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch (UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }

    ret.put("url", url);
    ret.put("jsapi_ticket", jsapi_ticket);
    ret.put("nonceStr", nonce_str);
    ret.put("timestamp", timestamp);
    ret.put("signature", signature);
    ret.put("appid", appId);

    return ret;
}

private static String byteToHex(final byte[] hash) {
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

private static String create_nonce_str() {
    return UUID.randomUUID().toString();
}

private static String create_timestamp() {
    return Long.toString(System.currentTimeMillis() / 1000);
}

makeWXTicket这个函数有俩参数,第一个是上面的jsapi_ticket,第二个是页面传上来的url,返回值是一个Map。后面就看各路大神八仙过海了,大死不灵啥的,总之你肯定有办法把这货传回去的。传回去后,就到wx.config中把内容填充进去了。

ready & error & 功能调用

最恶心的部分搞过去,其他就一马平川了。

wx.ready(function () {
    wx.onMenuShareTimeline({
      title: '互联网之子?',
      link: 'http://movie.douban.com/subject/25785114/',
      imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
      trigger: function (res) {
        // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回.
        alert('click shared');
      },
      success: function (res) {
        alert('shared success');
        //some thing you should do
      },
      cancel: function (res) {
        alert('shared cancle');
      },
      fail: function (res) {
        alert(JSON.stringify(res));
      }
    });

  wx.error(function (res) {
      alert(res.errMsg);
  });
});

在网页中添加以上内容,用户点击对应的操作就会弹出提示对话框啦 微信开发(七)微信分享接入 如果没有回调,签名又没有问题,去开发者中心检查一下接口是否开通了吧。

总结

接入过程很纠结,测试比较麻烦,微信服务器的回调只认有备案的域名。验签可以使用这个网址 做测试。总之,祝你好运~

分类: 未分类 标签:

Repeating OpenGL-es texture bound to hills in cocos2d 3.2

2015年3月12日 没有评论

ORIGINAL ARTICLE

I am in the process of trying to implement raywenderlich’s tutorial on generating hills with repeating striped coordinates using cocos2d, This article was written for Cocos2D, and as I am trying to port it to Cocos2Dx 3.2 This means updating it for openGl-es 2. So far everything has worked perfectly, However I am having problems with getting the texture of the hill to repeat properly and also after some repeatation the texture start degrade …
please help me to get texture properly…….
Here is my code:

#define Point_FROM_B2VEC(v) Point((v.x*PTM_RATIO),(v.y*PTM_RATIO))
        #define B2VEC_FROM_Point(v) b2Vec2(v.x/PTM_RATIO,v.y/PTM_RATIO)
    #define PTM_RATIO       32
    #define MAX_HILL_POINTS 15
    #define MAX_SEGMENTS    MAX_HILL_POINTS*10
    #define MAX_COORDINATES 600

        Point hillTopVertices[MAX_COORDINATES],hillBottomVertices[MAX_COORDINATES];
            Point hillTopTexCoords[MAX_COORDINATES];
     Point hillBottomTexCoords[MAX_COORDINATES];

            GLuint         terraintopTexId, terrainBottomTexId;
     float         terrainTopTexSize,  terrainBottomTexSize;

Sending the hills the texture:

         texture = Director::getInstance()->getTextureCache()->addImage("surface.png");

            terraintopTexId = texture->getName();
            terrainTopTexSize = texture->getPixelsWide()/2;

    //terrain top texture
        texture1 = Director::getInstance()->getTextureCache()->addImage("old_stone_wall_textures_v3_3000x2000_1.jpg");


        terrainBottomTexId = texture1->getName();
        terrainBottomTexSize = texture1->getPixelsWide()/2;



void Terrain::generateCoordinates()
{
    int nTopVertCount = 0;
     int nTopVertCount1 = 0;

    //get the hill vertex and texcoordinates
    for(short i = 0; i < MAX_SEGMENTS; ++i)
    {
        Point point1 = Point_FROM_B2VEC(vertices[i]);
        Point point2 = Point_FROM_B2VEC(vertices[i+1]);






        CCLOG("%f",terrainBottomTexSize);

        hillTopVertices[nTopVertCount1]      = Point(point1.x, point1.y+16);
        hillTopTexCoords[nTopVertCount1++]   = Point(point1.x/terrainTopTexSize, 1);
        hillTopVertices[nTopVertCount1]      = Point(point2.x, point2.y+16);
        hillTopTexCoords[nTopVertCount1++]   = Point(point2.x/terrainTopTexSize, 1);

        hillTopVertices[nTopVertCount1]      = Point(point1.x, point1.y-16);
        hillTopTexCoords[nTopVertCount1++]   = Point(point1.x/terrainTopTexSize, 0);
        hillTopVertices[nTopVertCount1]      = Point(point2.x, point2.y-16);
        hillTopTexCoords[nTopVertCount1++]   = Point(point2.x/terrainTopTexSize, 0);

    }

        for(short i = 0; i < MAX_SEGMENTS; ++i)
        {
            Point point1 = Point_FROM_B2VEC(vertices[i]);
            Point point2 = Point_FROM_B2VEC(vertices[i+1]);

        hillBottomVertices[nTopVertCount]      = Point(point1.x, point1.y-terrainBottomTexSize+1);
        hillBottomTexCoords[nTopVertCount++]   = Point(point1.x/terrainBottomTexSize, 1);
        hillBottomVertices[nTopVertCount]      = Point(point2.x, point2.y-terrainBottomTexSize+1);
        hillBottomTexCoords[nTopVertCount++]   = Point(point2.x/terrainBottomTexSize, 1);

        hillBottomVertices[nTopVertCount]      = Point(point1.x, point1.y+2);
        hillBottomTexCoords[nTopVertCount++]   = Point(point1.x/terrainBottomTexSize, 0);
        hillBottomVertices[nTopVertCount]      = Point(point2.x, point2.y+2);
        hillBottomTexCoords[nTopVertCount++]   = Point(point2.x/terrainBottomTexSize, 0);
        }
        //energy adding

        //CCLOG("hillsegment---%d,pointx---%f,pointy---%f,offset--%f",i,point1.x,point1.y,offsetX);









}
void Terrain::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{


    Node::draw(renderer, transform, flags);

    _renderCmds[0].init(0.0f);
    _renderCmds[0].func = CC_CALLBACK_0(Terrain::onDraw, this, transform);
    renderer->addCommand(&_renderCmds[0]);



}
void Terrain::onDraw(const Mat4 &transform) {



    auto glProgram = getGLProgram();
    glProgram->use();
    glProgram->setUniformsForBuiltins(transform);

    GL::bindTexture2D( terrainBottomTexId );
    GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, hillBottomVertices);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, hillBottomTexCoords);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)MAX_COORDINATES);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    GL::bindTexture2D(terraintopTexId );
    GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, hillTopVertices);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, hillTopTexCoords);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)MAX_COORDINATES);


    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

}
分类: stackoverflow精选, unity3d 标签:

Duplicated Animations between prefabs

2015年3月11日 没有评论

I got two and more instances of the same prefab in a scene.
Every one of them has an animator, and every one of them has the same
animator controller connected to it.
When I animate one of them, all of them get the very same animation.
Any clues on what on earth is there happening? Should I have a separate
animator controller for every player on scene? How do I separate animators from each other in C#?

I will add this as an answer even though you didn’t put your code as a resources. This is just going to be my Bet.

I have made a game that also shares animator with the same prefabs but if you are calling just the GameObject that needs to animate. It should not call the other Animator calls An Object is Instantiated with different Animators each time, even if the file of the Animator is the same.

To Test this I would suggest that each time you instantiate your GameObject. name it something else. for example.

public GameObject[] myPrefabs; //make sure to add the size in the inspector

myPrefabs[0] = (GameObject)Instantiate(nameofPrefab);
myPrefabs[0].name = "myPrefabs0"; // this is to make sure that name (Clone) is removed;

// Then call the animation.
myPrefabs[0].GetComponent<Animator>().SetTrigger("Attack");

//SetTrigger, SetBool, SetInt. Since it is an Animator

I use List instead of Array, but I think this is the most basic one that I can give.

The naming of the prefab is not necessary to fix your problem. But you need it so you can check if it is the correct GameObject that is taking your Animator Call

No, you can use an animator controller for several prefabs. I don’t know what did you try, what is your mistake. if you put your code I can help more.

All of your prefabs must have its own Animator components. Then, this objects can use same animator controller.

For example,

Animator animator;

GameObject prefab;
List<GameObject> prefabs;

prefab = (GameObject)Instantiate(Resources.Load("prefabNameinAssets"));
prefab.AddComponent<Animator>(); // add each prefab its own Animator component

animator = prefab.GetComponent<Animator>();
animator.runtimeAnimatorController = (RuntimeAnimatorController)Instantiate(Resources.Load("animatorControllerNameinAssets"));
//get prefab's Animator Component and set its controller

prefab.name = "prefabName";
prefabs.Add(prefab);

After that you can use all prefabs animator controller separately. It will not affect other prefabs AnimatorControllers.

prefabs[0].GetComponent<Animator>().setTrigger("Animation");
分类: stackoverflow精选, unity3d 标签:

angular 使用 ui-router 设计网页

2015年3月9日 没有评论

ui-router是一个web客户端的路由解决方案。我觉得它最大的作用是将web界面的设计分块了。

分块分层

最初的web访问模型,是这样的:

angular 使用 ui-router 设计网页

我们访问page1,然后访问page2….

在新的模型中它变成了这个样子:

angular 使用 ui-router 设计网页

访问效果是一样的,但是从设计上已经有了变化。它变成了:只有一张网页,在网页中有不同的区域,每个区域都可擦写。仔细想想好像也挺常见的,不知道其他技术是不是也这样 angular 使用 ui-router 设计网页

代码实现

原理讲完再简述一下实现吧

  1. 下载js文件,引入到index.html文件中。
  2. 在html中,添加注入位置: <div ui-view="">。它是当被触发注入时,填充的位置。
  3. 在html中,添加触发器:<ANY ui-sref="XXX">。XXX是$state,它遵循xxx.xxx的树形结构,渲染时从根节点开始渲染。
  4. 在app.js中,配置路由函数 .config(function($stateProvider, $urlRouterProvider) {});

细说一下:

引入代码

没啥要细说的,要说就是路径别写错吧 angular 使用 ui-router 设计网页

注入位置

对于多个分栏的结构,可以使用多个view的实现,然后反过来在config中使用bbb@AAA的声明指定本state中子view对应的模板,例如:

//in js
$stateProvider
    .state('index', {
        url: '/index',
        views: {
            '': {
                templateUrl: 'tpls/index.html'
            },
            'main1@index': {
                templateUrl: 'tpls/form1.html'
            },
             'main2@index': {
                templateUrl: 'tpls/form2.html'
            }
        }
    })
    
//in html     
<div class="container">
    <div ui-view="main1"></div>
    <div ui-view="main2"></div>
</div>

这个代码中将form1.html 和 form2.html 填充到了对应的的view中。

添加触发器

如果在标签中添加了 ui-sref="xxx",未激活状态时,它是看不到的。具体描述可以看下官网. 通常我们都是激活状态,但有时总想自己控制一下。可以参考:

 

	<ul>
	  <li ui-sref-active="active" class="item">
	    <a href ui-sref="app.user({user: 'fansy'})">@fansy</a>
	  </li>
	</ul>

 

当user是fansy时,显示后面那行字。这个例子是官方的,我是没用明白这个功能,回头在研究吧。

配置路由

首先是 $urlRouterProvider

它通常用来配置非 $state 的额外的路由.例如:

$urlRouterProvider.when("","/home");

将默认页设置为/home的URL。注意哦,这里用的是URL,别写错成state了。

当然也可以写一个任何额外页面的定向:

$urlRouterProvider.otherwise("/home");

这样访问其他阿猫阿狗的页面,就都跑到/home那去了。

然后是 $stateProvider

触发点是按层级来的,它遵守的路由规则可以从官网的,这个页面 中找到。通过 $state.go 函数可以将状态位置强行切换,我们可以在任何一处写下面的js代码:

$state.go('home.state1');

另外,你也可以在$stateProvider 中对应的state里面配置controller,当这种state被激活,就会调用对应的函数了,例如:

 

	$stateProvider
		.state("home",{
			url:"/home",
			templateUrl:"tmpls/home.html",
			controller:function($scope,$state) {
				console.log("enter home");
			}
		})

 

每当状态变为home时,都输出一条日志。

最后,渲染是按层级来的。因此改变同级节点并不会重新渲染父节点。并且不改变状态就不会重新渲染。比如一直按同一个按钮,就不会重新渲染;没更改跟节点,点一个”刷新”按钮,也不会刷新整个页面。

分类: 未分类 标签:

Orientation Auto Rotation旋转屏幕crash问题(Unity3D开发之十四)

2015年3月8日 没有评论

猴子原创,欢迎转载。转载请注明: 转载自Cocos2Der-CSDN,谢谢!

原文地址: http://blog.csdn.net/cocos2der/article/details/44133127

今天运行一个场景时候,welcome场景可以旋转,进入主场景后发现只要旋转手机屏幕就会crash。

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'UnityDefaultViewController should be used 
only if unity is set to autorotate'

出错信息已经显示是使用auto rotation导致的。

Unity Build setting里面已经是Auto Rotation,为何主场景无法旋转?

而且错误表示:是我在调用autorotate,但是我设置的模式却不是autorotate。

最后全局搜索了下,果然有测试代码手工设置了屏幕方向为Left。修改为自动后,问题解决。

Screen.orientation = ScreenOrientation.AutoRotation;

问题虽然是个小问题,但是想起了那谁谁前天线上游戏由于开发写的测试代码跑到线上,导致玩家多了一个装了很多道具的宝箱。

所以,谁要是说:”这个功能先这样就好了, 等正式配置出来了,我在修改。“,我保证不掐死你…

分类: unity3d 标签:

web开发工具 http-server , grunt 使用

2015年3月7日 没有评论



http-server

它是一个简单的服务部署,与Express相比,这货更轻了,它只是一个服务搭建工具,完全可以不安装到项目的目录中。安装使用:

npm install -g http-server

成功安装后,使用:

http-server -a hostip -p port

即可拉起当前目录的web应用。

当然,如果少年你比较倔强,非得安装到本地项目中也是可以的。启动时,就要在web应用的根目录运行:

node ../node_modules/http-server/bin/http-server

其他参数用-h查看就行。有个小坑,有时候更改文件后重启服务页面不一定立刻生效 web开发工具 http-server , grunt 使用 删掉浏览器缓存吧。

grunt

这货是个自动化的插件,编译,压缩,单测啥的,只要够懒,它就够强大。它官网在这,感觉本土化做得不错,估计有坑挖的也挺漂亮。安装运行:

npm install -g grunt-cli

这个是一个启动器,有点像Express创建项目那个东西。也建议全局安装了,估计每个项目都得用。

在项目中安装可以使用命令:

npm install grunt --save-dev

算是下载并保存到package.json里面。然后加入其他好基友的方法也是一样的,常用的有:

  • grunt-contrib-jshint 检测js文件
  • grunt-contrib-uglify 混淆压缩
  • grunt-contrib-nodeunit node单测
  • grunt-contrib-watch 检测文件变化

安装好grunt后得配置一下,在package.json文件同级目录下创建一个Gruntfile.js 。根据官方文档 ,Gruntfile由以下几部分构成:

  • "wrapper" 函数
  • 项目与任务配置
  • 加载grunt插件和任务
  • 自定义任务

一个例子是这样的:

module.exports=function(grunt){

    grunt.initConfig({
        pkg:grunt.file.readJSON('package.json'),
        uglify:{
            options:{
                banner:'/*!<%=pkg.name%> <%=grunt.template.today("yyyy-mm-dd")%> *//n'
            },  
            build:{
                src:'src/<%=pkg.name%>.js',
                dest:'build/<%= pkg.name %>.min.js'
            }   
        }   
    }); 

    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('default',['uglify']);
};

编写好后运行grunt 或者 grunt uglify就可以将src目录下的包名文件压缩到build目录下。这个功能能干的事情还是挺多的。看到另一篇文章 可以参考一下。

如果你觉得这篇文章对你有帮助,可以顺手点个,不但不会喜当爹,还能让更多人能看到它… web开发工具 http-server , grunt 使用

分类: 未分类 标签:

angularJS 基础回顾

2015年3月6日 没有评论



数据

“I'm string”
123
{A:"I'm",B:"Dictory"}
{"I","am","array"}

基本数据使用 ng-init,ng-bind 关联。

	<div ng-init="firstName='Json'">
	    <p><span ng-bind="firstName"></span></p>
	</div>

表达式

可以写在文本区域的内容,表达方式为:{{expression}}它其实定价于ng-bind

 <p>My express:{{"check Now~"+firstName}}</p>

指令

  • ng-app 指令定义了 AngularJS 应用程序的根元素。
  • ng-repeat 指令对于集合中(数组中)的每个项会 克隆一次 HTML 元素。
	<div ng-app="" ng-init="names=[
	{name:'Jani',country:'Norway'},
	{name:'Hege',country:'Sweden'},
	{name:'Kai',country:'Denmark'}]">
	
	<p>循环对象:</p>
	<ul>
	  <li ng-repeat="x in names">
	    {{ x.name + ', ' + x.country }}
	  </li>
	</ul>
	</div>

控制器

注意 脚本加载要放在使用前 例如在head中:

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="bower_components/angular/angular.min.js"></script>  
    <script type="text/javascript">
    var myModel = angular.module("myModel",[]);
    myModel.controller("myController",function($scope) {
        $scope.persion = {
            firstName:"Dan",
            lastName:"Jao"
        };
    });
    </script>
</head>

使用控制器要先声明一个对应的module。如上面的代码,使用angular.module('appName',['dependcyModuleNmae'])来实现,并调用controller方法添加对应的controller。使用时直接使用对应的$scope即可

	<div ng-app="myModel" ng-controller="myController">
	    FirstName:<input type="text" ng-model="persion.firstName"><br>
	    LastName:<input type="text" ng-model="persion.lastName"><br>
	    Whole: {{persion.firstName+" "+persion.lastName}}
	</div>

一个页面控制器只能加载一个ng-app,它相当于main()。

过滤器

使用管道符可开启过滤功能

  • currency 格式化数字为货币格式。
  •  filter 从数组项中选择一个子集。
  •  lowercase 格式化字符串为小写。
  •  orderBy 根据某个表达式排列数组。
  •  uppercase 格式化字符串为大写。

例如:

{{ (x.name |uppercase)+","+x.others }}
<p>总价 = {{ (quantity * price) | currency }}</p>
<li ng-repeat="x in names | orderBy:'country'">

事件

向上传播事件$emit('myEvent'),同层传播时间$broadcast('myEvent') 收事件使用:

$scope.$on('myEvent'),function() {
    $scope.count++;
}

$scope

$scope是angularjs的基础。它是树形结构,根节点为`$rootScope。可以使用angular.element($0).scope()`进行调试。

如果你觉得这篇文章对你有帮助,可以顺手点个,不但不会喜当爹,还能让更多人能看到它… angularJS 基础回顾

分类: 未分类 标签:

添加启动游戏过渡场景Default Splash Scene(Unity3D开发之十三)

2015年3月6日 没有评论

添加启动游戏过渡场景Default Splash Scene(Unity3D开发之十三)

猴子原创,欢迎转载。转载请注明: 转载自Cocos2Der-CSDN,谢谢!

原文地址: http://blog.csdn.net/cocos2der/article/details/44099095

Unity5个人版会添加Unity Logo作为启动画面,咱们既然没花钱,打个广告也应该。但Unity Logo结束后可以再添加一个自己的启动画面。

下面是添加一个简单的FadeIn->FadeOut过渡场景。

先看下效果图:
添加启动游戏过渡场景Default Splash Scene(Unity3D开发之十三)

代码如下 LHSplashScreens.cs:

using UnityEngine;
using System.Collections;

public enum FadeStatus
{
    FadeIn,
    FadeWaiting,
    FadeOut
}

public class LHSplashScreens : MonoBehaviour 
{
    public string levelToLoad;
    public bool waitForInput;
    public float timeFadingInFinished;
    public Sprite splashSprite;

    private float m_fadeSpeed;
    private float m_waitTime;
    private float m_alpha;
    private FadeStatus m_status;
    private SpriteRenderer m_splashSpriteRenderer;

    public LHSplashScreens()
    {
        levelToLoad = "";
        m_fadeSpeed = 0.3f;
        m_waitTime = 0.5f;
        m_status = FadeStatus.FadeIn;
    }

    void Awake()
    {
        Application.targetFrameRate = 60;
    }

    // Use this for initialization
    void Start () 
    {
        if (Application.levelCount <= 1 || levelToLoad == "")
        {
            Debug.LogWarning("Invalid levelToLoad value.");
        }

        GameObject m_splashSpriteGO = new GameObject("SplashSprite");
        m_splashSpriteGO.AddComponent<SpriteRenderer>();
        m_splashSpriteRenderer = m_splashSpriteGO.GetComponent<SpriteRenderer>();
        m_splashSpriteRenderer.sprite = splashSprite;

        Transform m_splashSpriteTransform = m_splashSpriteGO.gameObject.transform;
        m_splashSpriteTransform.position = new Vector2(0f, 0f);
        m_splashSpriteTransform.parent = this.transform;
    }

    // Update is called once per frame
    void Update () 
    {
        FadeStatus fadeStatus = m_status;
        if (fadeStatus == FadeStatus.FadeIn)
        {
            m_alpha += m_fadeSpeed * Time.deltaTime;
        }
        else if (fadeStatus == FadeStatus.FadeWaiting)
        {
            if ((!waitForInput && Time.time >= timeFadingInFinished + m_waitTime) || (waitForInput && Input.anyKey))
            {
                m_status = FadeStatus.FadeOut;
            }
        }
        else if (fadeStatus == FadeStatus.FadeOut)
        {
            m_alpha -= m_fadeSpeed * Time.deltaTime;
        }

        UpdateSplashAlpha();
    }

    private void UpdateSplashAlpha()
    {
        if (m_splashSpriteRenderer != null)
        {
            Color spriteColor = m_splashSpriteRenderer.material.color;
            spriteColor.a = m_alpha;
            m_splashSpriteRenderer.material.color = spriteColor;

            if (m_alpha > 1f)
            {
                m_status = FadeStatus.FadeWaiting;
                timeFadingInFinished = Time.time;
                m_alpha = 1f;
            }

            if (m_alpha < 0)
            {
                if (Application.levelCount >= 1 && levelToLoad != "")
                {
                    Application.LoadLevel(levelToLoad);
                }
            }
        }
    }
}

在你工程中,建立一个新的场景,作为游戏的启动场景。

添加一个Empty GameObject, 添加上面的LHSplashScreens.cs脚本:
Level To Load: 完成启动画面后你需要加载的场景
Splash Sprite:过渡使用的logo sprite

最后完成后如下:

添加启动游戏过渡场景Default Splash Scene(Unity3D开发之十三)


用了markdown之后,停不下来啊。呵呵

分类: 未分类 标签:

What is the meaning of std::function<void(Ref*)> in C++

2015年3月5日 没有评论

I got into trouble of this function, and I don’t know what is the meaning of that:

menuItem1->setCallback([&](cocos2d::Ref *sender)

Enter the function, the param is ccMenuCallback&:

    /** set the callback to the menu item
    * @code
    * In js,can contain two params,the second param is jsptr
    * @endcode
    * @lua NA
    */
    void setCallback(const ccMenuCallback& callback);

And

typedef std::function<void(Ref*)> ccMenuCallback;

That’s a C++11 lambda.

Basically setCallback accepts as an argument a std::function that takes a cocos2d::Ref* and returns void. That’s a type which is able to hold a callable function.

A lambda is an anonymous function which in that situation is stored inside a std::function<void(cocos2d::Ref*)> variable and passed to the function.

Indeed it’s something like:

auto lambda = [&](cocos2d::Ref* sender) {
  /* implementation */
};
// ^ store the anonymous function in a variable

menuItem1->setCallBack(lambda);

std::function can hold function pointer, method binding, lambda expression and any object with overloaded operator()

void someFunc(cocos2d::Ref *sender)
{
    //some code
}

std::function<void(Ref*)> f1 = someFunc;
std::function<void(Ref*)> f2 = [&](cocos2d::Ref *sender) {
    //some code
}

Probably void setCallback(const ccMenuCallback& callback); takes a callback which is called when a menu item is clicked or something like this.

This expression is a lambda:

[&](cocos2d::Ref *sender)
分类: cocos2d, stackoverflow精选 标签: