2dx-lua-class

本文详细介绍在Lua中实现面向对象编程的过程,包括基础类的定义、子类的继承及方法覆盖。通过Circle和Rectangle两个具体类的示例,展示了如何在Lua中使用类和对象,以及如何通过构造函数初始化对象属性。

{class
    Shape  基类(模型)
    Circle 子类(圆)
    Rectangle 子类(矩形)
    main 调用类
    继承C++类
}

借鉴 https://blog.youkuaiyun.com/u012278016/article/details/79624525


{Shape.lua
    --定义名为 Shape 的基础类
    local Shape = class("Shape")

    --ctor() 是类的构造函数,在调用 Shape.new() 创建 Shape 对象实例时会自动执行
    function Shape:ctor(shapeName)
        self.shapeName = shapeName;
        printf("Shape:ctor(%s)", self.shapeName)
    end

    --shapeName是类的一个成员变量,在lua中成员变量可以直接通过self.shapeName=shapeName来生成并同时赋值,不用先声明,另外,前面不用local修饰,用local修饰的是局部变量而不是成员变量,成员变量前面用self.

    --为 Shape 定义个名为 draw() 的方法
    function Shape:draw()
        printf("draw %s", self.shapeName)
    end

    return Shape;
}


{Circle.lua

    local Shape=require("example/class/Shape");

    --//Circle 是 Shape 的继承类
    local Circle = class("Circle", Shape)

    function Circle:ctor()
        -- 如果继承类覆盖了 ctor() 构造函数,那么必须手动调用父类构造函数
        -- 类名.super 可以访问指定类的父类
        Circle.super.ctor(self, "circle");
        self.radius = 100;
    end

    function Circle:setRadius(radius)
        self.radius = radius
    end

    --// 覆盖父类的同名方法
    function Circle:draw()
        printf("draw %s, raidus = %0.2f", self.shapeName, self.radius)
    end

    return Circle;
}


{Rectangle.lua

    local Shape=require("example/class/Shape");
    local Rectangle = class("Rectangle", Shape)
    function Rectangle:ctor()
        Rectangle.super.ctor(self, "rectangle")
    end
    return Rectangle;
}

{main.lua

    local Circle =require "example/class/Circle";
    local Rectangle =require "example/class/Rectangle";

    local circle = Circle.new() -- Shape:ctor(circle)
    circle:setRadius(200)
    circle:draw() --  draw circle, raidus = 200.00

    local rectangle = Rectangle.new() -- Shape:ctor(rectangle)
    rectangle:draw() -- draw rectangle

}


{继承C++类

---@Class Enemy: Sprite
    local Enemy=class("Enemy",function ()
        local sprite = cc.Sprite:create()
        return sprite;
    end);

    function Enemy:ctor()
        Log.debug('enemy.ctor-------');
        self.startPosition=cc.p(0,0);--敌人初始化坐标
    end

    function Enemy:setStartPosition(x,y)
        self.startPosition=cc.p(x,y);
        Log.debug('\t\tenemyx:'..x);
        Log.debug('\t\tenemyy:'..y);
    end

    function Enemy:toString()
        Log.debug('敌人类');
    end
    return Enemy;

--调用
    local Enemy=require("Scene/Enemy/Enemy");
    self.enemy=Enemy:create();
    self.layer:addChild(self.enemy);

    local vvv= cc.Sprite:create("cocosui/sliderballpressed.png")
    local spriteFrame= vvv:getSpriteFrame();
    self.enemy:setSpriteFrame(spriteFrame);
    self.enemy:setPosition(cc.p(display.cx, display.cy));

--其他


    class()的这种用法让我们可以在 C++ 对象基础上任意扩展行为。既然是继承,自然就可以覆盖 C++ 对象的方法


    local Toolbar = class("Toolbar", function()
        return cc.Node:create(); -- 返回一个 CCNode 对象
    end)

    --构造函数
    function Toolbar:ctor()
        self.buttons = {} -- 用一个 table 来记录所有的按钮
    end

    --添加一个按钮,并且自动设置按钮位置
    function Toolbar:addButton(button)
        --将按钮对象加入 table
        self.buttons[#self.buttons + 1] = button
        --添加按钮对象到 CCNode 中,以便显示该按钮
        --因为 Toolbar 是从 CCNode 继承的,所以可以使用 addChild() 方法
        self:addChild(button)
        --按照按钮数量,调整所有按钮的位置
        local x = 0
        for _, button in ipairs(self.buttons) do
            button:setPosition(x, 0)
                --依次排列按钮,每个按钮之间间隔 10 点
            x = x + button:getContentSize().width + 10
        end
    end
    return Toolbar;
}
 

### 实现微信登录功能 为了在 Cocos2d-x 中使用 Lua 实现微信登录,需考虑平台差异处理以及接口调用方式。对于 Android 平台,在涉及本地方法调用时应适当加入条件编译语句来防止 iOS 版本构建时报错[^4]。 #### 创建 Java 类用于封装微信 SDK 登录逻辑 首先要在 Android 工程里引入 WeChat OpenSDK,并编写相应的 Java 类作为桥梁连接原生层与脚本层: ```java package org.cocos2dx.lua; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; public class WXLoginBridge { private IWXAPI api; public void registerApp(String appId){ api = WXAPIFactory.createWXAPI(AppActivity.getContext(), appId); api.registerApp(appId); } public void sendReq(){ SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req); } } ``` 此部分代码实现了应用注册及发送授权请求给微信客户端的功能。 #### 修改 `app_activity` 添加回调监听器 接着修改项目的主活动类(通常是 AppActivity.java),以便接收来自微信的响应并传递至 Lua 层: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ...其他初始化操作... final WXLoginBridge bridge = new WXLoginBridge(); bridge.registerApp("your_wechat_app_id"); addCallback(new JSCallback() { @Override protected boolean onStringMessageReceived(String message, String data) { if ("wx_login".equals(message)){ bridge.sendReq(); return true; }else{ return false; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); .bridge.api.handleIntent(intent, this); } }); } // 处理微信返回的结果 @Override protected void handleWeChatResp(BaseResp resp) { JSONObject jsonResult = new JSONObject(); try { switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: // 成功获取code后可以在这里发起网络请求换取access_token break; default: Log.e(TAG,"Failed to login with wechat"); break; } } catch (JSONException e) { e.printStackTrace(); } callLuaFunctionWithJson("onWeiXinLoginFinished",jsonResult.toString()); } ``` 上述代码片段展示了如何通过 JavaScript 接口触发微信登录流程,并且定义了一个名为 `handleWeChatResp()` 的函数用来解析从微信传来的结果对象。 #### Lua 侧调用示例 最后是在 Lua 脚本中调用微信登录的方法: ```lua function wxLogin() cc.Application:getInstance():getJavaScriptInterface():call("wx_login") end -- 定义一个全局函数等待接收微信登录完成的通知 function onWeiXinLoginFinished(result) local retObj = cjson.decode(result) if(retObj["errCode"] == 0 then print("success:" .. retObj["code"]) else print("fail:"..retObj["errMsg"]) end end ``` 以上就是在 Cocos2d-x 使用 Lua 实现微信登录的大致过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值