cocos2d-x lua中实现异步加载纹理

原文地址:  http://www.cnblogs.com/linchaolong/p/4033118.html

前言

  问题:最近项目中需要做一个loading个界面,界面中间有一个角色人物走动的动画,在显示这个loading界面的时候加载资源,项目是用cocos2d-x lua实现的,界面做出来后发现在加载资源的时候界面会卡住。

原因: 因为使用的不是异步加载,而且cocos2d-x没有绑定异步加载资源的api到lua中,其实在lua中实现不了异步。

想通过在lua中启动一个线程去加载资源,但lua是不支持多线程的,只有协程,但并不是真正意义上的多线程,只不过是函数间执行权的相互交换。

 解决思路:

  1. 把需要加载的资源的路径存放到一个CCArray中;
  2. 通过tolua++工具(查看tolua++工具的使用),在C++中绑定一个异步加载纹理的接口到lua中,该接口接收两个参数,参数一为CCArray(资源路径数组),参数二为int类型(lua回调函数)(点击查看C++回调Lua函数    
  3. 在绑定接口方法中迭代资源路径数组,使用CCTextureCache的addImageAsync方法加载纹理,当资源加载完成时回调lua方法

示例代码

1.编写绑定到Lua中异步资源加载接口类

AsynResLoader.h

#ifndef  _ASYNRESLOADER_H_
#define _ASYNRESLOADER_H_  

#include "cocos2d.h"  

USING_NS_CC;  

//供Lua调用的异步的资源加载器
class AsynResLoader: public CCObject
{
private:
    int count;
    int total;
    //lua回调方法
    int mLuaCallback;
public:
    //创建一个异步资源加载器
    static AsynResLoader* create();
    //异步加载纹理
    void asynLoadTexture(CCArray* paths, int luaCallbck);
    //加载回调
    void callback(CCObject* pSender);
};  

#endif

  
AsynResLoader.cpp

#include "AsynResLoader.h"
#include "CCLuaEngine.h"    

//创建一个异步资源加载器
AsynResLoader* AsynResLoader::create(){
    AsynResLoader* instance = new AsynResLoader;
    if (instance)
    {
        instance->autorelease();
        return instance;
    }
    return NULL;
}  

//异步加载纹理
void AsynResLoader::asynLoadTexture(CCArray* paths, int luaCallback){
    this->count = 0;
    this->total = paths->count();
    this->mLuaCallback = luaCallback;  

    for(int idx = 0; idx <total; idx++)
    {
        const char* path = ((CCString*)paths->objectAtIndex(idx))->getCString();
        CCLOG("asynLoadTexture PATH idx=%d : %s",idx,path);
        CCTextureCache::sharedTextureCache()->addImageAsync(path, this, callfuncO_selector(AsynResLoader::callback));
    }
}  

//纹理加载回调方法
void AsynResLoader::callback(CCObject*){
    this->count++;
    //当资源加载完成时,回调指定的lua函数
    if (this->count >= this->total)
    {
        CCLOG("asyn load res completed..");
        if (this->mLuaCallback)
        {
            CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack();
            //第一个参数是函数的整数句柄,第二个参数是函数参数个数
            pStack->executeFunctionByHandler(this->mLuaCallback,0);
            pStack->clean();
            CCLOG("call lua function..");
        }
    }
}

  

2.使用tolua++工具把类绑定到lua中(点击查看使用方法

3.在lua中创建资源路径数组,调用接口方法,把路径数组和回调函数传递进去

lua代码:

function asynLoadTexture(callback)
    local pngs = CCArray:create()
    -- Buff动画帧路径
    for _, anim in ipairs(buff_anim_config.buff_anim_config) do
        pngs:addObject(CCString:create(anim.png))
    end
    -- 技能动画帧路径
    for k, anim in ipairs(skill_anim_config.skill_anim_config) do
        pngs:addObject(CCString:create(anim.png))
    end
    AsynResLoader:create():asynLoadTexture(pngs,callback)
end

4.运行效果

实质就是lua调用C++方法实现异步加载资源。

  

时间: 2024-12-08 23:47:37

cocos2d-x lua中实现异步加载纹理的相关文章

浅谈Android中的异步加载之ListView中图片的缓存及优化三

     隔了很久没写博客,现在必须快速脉动回来.今天我还是接着上一个多线程中的异步加载系列中的最后一个使用异步加载实现ListView中的图片缓存及其优化.具体来说这次是一个综合Demo.但是个人觉得里面还算有点价值的就是里面的图片的缓存的实现.因为老实说它确实能在实际的项目中得到很好的应用.主要学习来源于慕课网中的异步加载学习,来自徐宜生大神的灵感.本次也就是对大神所讲知识的一个总结及一些个人的感受吧. 这次是一个综合的Demo,主要里面涉及到的知识主要有:网络编程.异步加载.JSON解析.

Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

Android中ListView异步加载图片错位.重复.闪烁问题分析及解决方案 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如ListView上有100个Item,一屏只显示10个Item,我们知道getView()中convertView是用来复用View对象的,因为一个Item的对应一个View对象,而ImageView控件就是View对象通

cocos2dx 3.3 异步加载纹理

这里以3d场景加载为例,2d情况类似. 先同步加载模型数据和尺寸缩小了100倍的贴图,创建mesh.然后异步加载所有精细纹理并每加载完一个就替换一个,并进入场景. 如此做法的效果是当刚进入场景时看到的是贴图非常糙的场景,然后逐渐贴换为精细贴图.(就像放大谷歌地图时的情况). 下图左边是 刚进入场景时,右边是 精细纹理异步加载完成后:    具体实现如下: bool ClevelMapLayer::init(){ loadAllModelData(); loadAllRoughTex(); cre

【Cocos2dx3.x Lua】图片异步加载

一.说明 异步加载就是把消耗程序时间比较大的加载操作放到其他线程中,待加载完毕后通过回调函数的方式通知主线程. addImageAsync函数实现(Cocos2dx 3.3) Link: http://codepad.org/UuNcXMqq    [ raw code | fork ]   void TextureCache::addImageAsync(const std::string &path, const std::function<void(Texture2D*)>&am

浅谈android中的异步加载一

1.为什么需要异步加载. 因为我们都知道在Android中的是单线程模型,不允许其他的子线程来更新UI,只允许UI线程(主线程更新UI),否则会多个线程都去更新UI会造成UI的一个混乱有些耗时的操纵(例如网络请求等),如果直接放到主线程中去请求的话则会造成主线程阻塞,而我们系统有规定的响应时间,当响应的时间超过了了阻塞的时间就会造成"Application No Response",也就是我们熟知的ANR错误解决上述问题的时候:我们一般使用的是线程或者线程池+Handler机制如果线程

listview中getview异步加载网络图片

前言:本以为异步加载挺简单,因为网上代码多,但真想要做好,还真不那么简单,从看代码到弄懂再到自己写,实在是有太多的东西需要学了,用了两天的时间,终于弄出来了,因为用到回调函数,所以理解起来可能难度有点大,讲起来也不太好讲,我尽力讲的明白些,其实还是要多看代码,自己摸索摸索,动手写写就什么都理解了.这篇我们只讲怎样实现异步加载,对于滑动时停止加载的事下篇再讲. 实现效果: 1.异步加载图片,在加载图片时,先加载一个默认的图片,然后在后台加载图片,加载完成后显示出来: 2.当用户在滑动时,停止加载图

Android中ListView异步加载数据

http://www.cnblogs.com/snake-hand/p/3206655.html 1.主Activity 1 public class MainActivity extends Activity { 2 3 private ListView listView; 4 private ArrayList<Person> persons; 5 private ListAdapter adapter; 6 private Handler handler=null; 7 //xml文件的

IOS中UITableView异步加载图片的实现

本文转载至 http://blog.csdn.net/enuola/article/details/8639404 最近做一个项目,需要用到UITableView异步加载图片的例子,看到网上有一个EGOImageView的很好的例子. 但是由于,EGOImageView的实现比较复杂,于是自己就动手做了一个AsynImageView,同样可以实现EGOImageView的效果. 而且自己写的代码比较清晰,容易理解,同样可以实现指定placehoderImage以及指定imageURL,来进行图片

Unity中场景异步加载

引入命名空间 using UnityEngine.UI; using UnityEngine.SceneManagement; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; //引入命名空间 using UnityEngine.SceneManagement;//引入命名空间 public class S2Manager : MonoBeha