zoukankan      html  css  js  c++  java
  • 发现的lua小技巧记录--在:方法中使用self的技巧

    function class(classname, super)
        local cls
    
        if type(super) ~= "table" then
            super = nil
        end
    
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end
    
        cls.__cname = classname
        cls.__index = cls
    
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
        return cls
    end

    在lua中定义了一个全局的方法class用于模仿编译型语言的类继承的功能,使用class(类名,继承类)声明一个类,第二个参数可选(可以不继承任何类),在类中实现ctor方法作为构造方法,使用类名.new()的方式创建类对象。下面是应用过程中出现的问题:

    1)创建一个类,继承自其他类

    SingleGamePanel = class("SingleGamePanel",BasePanel)

    2)在其他类中创建这个类的对象

    self.View = SingleGamePanel.new()

    3)调用类中定义的方法

    --调用View中的方法
    self.View:InstantiateAChess(position,id)

    4)被调用的方法,注意方法中实例化了一个游戏物体,在添加监听事件和发送通知时都会连续使用:调用成员方法,这个调用就出现了一个问题:我是用的是对象调用的方法,那么self指对象,但是在添加监听事件时使用冒号调用了其他方法,添加的监听事件函数中self就不再指对象了,不能使用self,那么使用类SingleGamePanel可以吗?也不可以,因为在lua中对象和类都是表,本质上类是对象的元表,在对象中做的操作和类中做的操作是分离的,只是对象中找不到的元素到类中去找,如方法最后存储棋子的步骤,就存储在对象中,要是使用类表去调用这个存储的棋子是访问不到的。问题就产生了,我在监听事件函数中要使用对象中定义的函数等怎么办?

    --在指定的position位置实例化给定id对应的棋子
    function SingleGamePanel:InstantiateAChess(position,id)--使用一个表存储棋子
        local chess = {}
    
        --实例化棋子
        chess.gameObject = AssetBundleManager:LoadRes("chesspiece",chessDic[id].name,typeof(GameObject))
        chess.transform = chess.gameObject.transform
        --设置实例出来的棋子的位置
        chess.transform:SetParent(local.chessFather,false)
        chess.transform.localPosition = Tools:PositionCastToLocal(position)
    
        --棋子需要存储自己的位置
        chess.position = position
    
        --为标识棋子状态的图片赋值
        chess.selectedImg = chess.transform:Find(ControlNames.CHESS_SELECTED_IMAGE).gameObject
        chess.selectedImg:SetActive(false)
        chess.canBeEatImg = chess.transform:Find(ControlNames.CHESS_CAN_BE_EAT_IMAGE).gameObject
        chess.canBeEatImg:SetActive(false)
        chess.lastImg = chess.transform:Find(ControlNames.LAST_CHESS_IMAGE).gameObject
        chess.lastImg:SetActive(false)
    
        --为棋子上的Button添加监听事件
        chess.gameObject:GetComponent(typeof(Button)).onClick:AddListener(function()
            if chess.canBeEatImg.activeInHierarchy then
                GameFacade:GetInstance():SendNotification(NotificationNames.EAT_CHESS,MoveChessBody.new(SingleGamePanel.nowSelectedPosition,chess.position))
                SingleGamePanel:CancelAllStatus()
            elseif not chess.selectedImg.activeInHierarchy then
                chess.selectedImg:SetActive(true)
                GameFacade:GetInstance():SendNotification(NotificationNames.CHESS_TOUCHED,chess.position)
            end
        end)
    
        --将棋子存入总表中
        local.chesses[position:ToString()] = chess
    end

    5)解决方法:在方法中都首先使用一个临时变量转存self,接下来临时变量就可以在方法中随意使用,它始终指向对象。

    --在指定的position位置实例化给定id对应的棋子
    function module:InstantiateAChess(position,id)
        local temp = self
        --使用一个表存储棋子
        local chess = {}
    
        --实例化棋子
        chess.gameObject = AssetBundleManager:LoadRes("chesspiece",chessDic[id].name,typeof(GameObject))
        chess.transform = chess.gameObject.transform
        --设置实例出来的棋子的位置
        chess.transform:SetParent(temp.chessFather,false)
        chess.transform.localPosition = Tools:PositionCastToLocal(position)
    
        --棋子需要存储自己的位置
        chess.position = position
    
        --为标识棋子状态的图片赋值
        chess.selectedImg = chess.transform:Find(ControlNames.CHESS_SELECTED_IMAGE).gameObject
        chess.selectedImg:SetActive(false)
        chess.canBeEatImg = chess.transform:Find(ControlNames.CHESS_CAN_BE_EAT_IMAGE).gameObject
        chess.canBeEatImg:SetActive(false)
        chess.lastImg = chess.transform:Find(ControlNames.LAST_CHESS_IMAGE).gameObject
        chess.lastImg:SetActive(false)
    
        --为棋子上的Button添加监听事件
        chess.gameObject:GetComponent(typeof(Button)).onClick:AddListener(function()
            if chess.canBeEatImg.activeInHierarchy then
                GameFacade:GetInstance():SendNotification(NotificationNames.EAT_CHESS,MoveChessBody.new(temp.nowSelectedPosition,chess.position))
                temp:CancelAllStatus()
            elseif not chess.selectedImg.activeInHierarchy then
                chess.selectedImg:SetActive(true)
                GameFacade:GetInstance():SendNotification(NotificationNames.CHESS_TOUCHED,chess.position)
            end
        end)
    
        --将棋子存入总表中
        temp.chesses[position:ToString()] = chess
    end
  • 相关阅读:
    Manjaro Linux自带的Python没有安装IDLE的解决办法
    Python入门 | IDLE的介绍和使用方法
    用U盘装CentOS 7出现dracut:/#问题的解决办法
    在Ubuntu下,如何安装坚果云deb文件
    windows7下进行ubuntu U盘启动盘的制作
    oracle 死锁和锁等待区别
    MySQL数据库设计总结
    oracle开机自启
    微信备份提示当前网络状况复杂,请尝试使用其他网络的解决方法
    ORA-27090 Unable to reserve kernel resources for asynchronous disk I/O
  • 原文地址:https://www.cnblogs.com/movin2333/p/14694620.html
Copyright © 2011-2022 走看看