• Quick Cocos 旋转子弹的实现中我学到的


    self 在lua中相当于java中的this

    lua中的任何变量在没有赋值前, 都可以看做是nil

     lua变量有3种,
    成员变量: self.变量名 = 
    局部变量: local 变量名 = 
    全局变量: 变量名 = 
     
    在一个游戏中和逻辑有关的动作最好不用transition 因为不可控且不稳定
    物体的移动可以用update的方法实现:

      设置一个角色每帧移动的项目距离,比如speed = 5,然后解析几何的方法算出 speedX,和speedY的分量。
    在update里,local curPos = self._imgSpr:getPositionInCCPoint()得到当前的坐标。坐标+速度,然后再setPosition就移动了。

    例如:

     1 function Bullet:update()                    --总函数的update调用每个子弹的update
     2 
     3      local imagex = self._imgSpr:getPositionX();
     4      local imagey = self._imgSpr:getPositionY();
     5      
     6      imagex = imagex - self._speedx
     7      imagey = imagey + self._speedy
     8 
     9      self._imgSpr:pos(imagex, imagey)
    10 
    11 end

    lua中类的创建:

     1 local Bullet = class("Bullet", function()
     2     return display.newNode()
     3 end)
     4 
     5 speed = 20
     6 
     7 function Bullet:ctor()                              --构造函数
     8                                                     --bullet父对象是node 这里把sprite对象添加到node上
     9     self._imgSpr = display.newSprite("img1.png")    --添加bullet图片
    10     self._imgSpr:pos(300,0)
    11     self._imgSpr:scale(0.5)
    12     self:addChild(self._imgSpr)
    13     
    14     self._speedx = nil
    15     self._speedy = nil
    16 
    17 end
    18 
    19 function Bullet:init( x,y )
    20     local mousex = x                                 --bullet init传值 不推荐用构造函数传值 speed在这里计算出来后来直接调用即可
    21     local mousey = y 
    22     local imagex = 300
    23     local imagey = 0
    24 
    25     local distance = math.sqrt((mousex - imagex)*(mousex - imagex)+(mousey - imagey)*(mousey - imagey))
    26     local degree = math.deg(math.asin((y - imagey)/distance))
    27         if(mousex < imagex) then
    28             degree = 180 - degree
    29         end
    30         degree = 180 - degree
    31     
    32     print(degree)
    33     self._imgSpr:setRotation(degree)
    34      
    35     self._speedx = speed*math.cos(math.rad(degree))
    36     self._speedy = speed*math.sin(math.rad(degree))
    37 
    38     print(self._speedx)
    39     
    40 end

    由上文可见此处的bullet类继承自node

    ctor是构造函数,一般不建议传参数。若需要传参应新建一个函数 (如init)用于参数传递。

    在main中新建实例时,首先要require声明此对象的文件。

    例如新建bullet对象:

    1 ClassBullet = require("app/object/Bullet")                 -- require相当于include
    2 
    3 
    4 local bullet = ClassBullet.new()                           --bullet实例
    5         bullet:init(x,y)                                        --init bullet
    6         self:addChild(bullet)                                   --把bullet这个node添加到父节点中
    7         table.insert(self._listBullet, bullet) --1开始          --把listBullet中对象insert到表中

    第一版代码:

    Bullet.lua

     1 local Bullet = class("Bullet", function()
     2     return display.newNode()
     3 end)
     4 
     5 speed = 20
     6 
     7 function Bullet:ctor()                                --构造函数
     8                                                     --bullet父对象是node 这里把sprite对象添加到node上
     9     self._imgSpr = display.newSprite("img1.png")    --添加bullet图片
    10     self._imgSpr:pos(300,0)
    11     self._imgSpr:scale(0.5)
    12     self:addChild(self._imgSpr)
    13     
    14     self._speedx = nil
    15     self._speedy = nil
    16 
    17 end
    18 
    19 function Bullet:init( x,y )
    20     local mousex = x                                 --bullet init传值 不推荐用构造函数传值 speed在这里计算出来后来直接调用即可
    21     local mousey = y 
    22     local imagex = 300
    23     local imagey = 0
    24 
    25     local distance = math.sqrt((mousex - imagex)*(mousex - imagex)+(mousey - imagey)*(mousey - imagey))
    26     local degree = math.deg(math.asin((y - imagey)/distance))
    27         if(mousex < imagex) then
    28             degree = 180 - degree
    29         end
    30         degree = 180 - degree
    31     
    32     print(degree)
    33     self._imgSpr:setRotation(degree)
    34      
    35     self._speedx = speed*math.cos(math.rad(degree))
    36     self._speedy = speed*math.sin(math.rad(degree))
    37 
    38     print(self._speedx)
    39     
    40 
    41 end
    42 
    43 function Bullet:update()                            --总函数的update调用每个子弹的update
    44 
    45      local imagex = self._imgSpr:getPositionX();
    46      local imagey = self._imgSpr:getPositionY();
    47      
    48      imagex = imagex - self._speedx
    49      imagey = imagey + self._speedy
    50 
    51      self._imgSpr:pos(imagex, imagey)
    52 
    53 end
    54 
    55 return Bullet

    MainScene.lua

    local MainScene = class("MainScene", function()
        return display.newScene("MainScene")
    end)
    
    ClassBullet = require("app/object/Bullet")                 -- require相当于include
    intersectLine = {left = display.c_left, right = display.c_right , top = display.c_top, bottom = display.c_bottom}
    
    function MainScene:ctor()
        local layer = display.newLayer()
        layer:setTouchEnabled(true)                             --响应touch事件
        layer:addNodeEventListener(cc.NODE_TOUCH_EVENT,         --添加监听器
            function(event)
                return self:onTouch(event.name, event.x, event.y, event.prevX, event.prevY)
            end
            )
        layer:setTouchSwallowEnabled(false)
        self:addChild(layer)
    
        self._imgBack = display.newSprite("back.jpg")           --添加背景图片
        self._imgBack:setAnchorPoint(ccp(0,0))
        self:addChild(self._imgBack)
    
        self._listBullet = {}                                   --bullet table
       
        self._scheduler = require("framework.scheduler")        --事件调度器 与update搭配使用
        self._scheduler.scheduleGlobal(handler(self, self.update), 1/60)
    
        print(intersectLine.left,intersectLine.right)
    end
    
    
    function MainScene:update()
        for i,bullet in ipairs(self._listBullet) do             --对listBullet表中的所有对象分别调用其update
            bullet:update()
    
            local bulletx = bullet:getPositionX()
            local bullety = bullet:getPositionY()
    
            print(bulletx,bullety)
    
            p = CCPoint(bulletx, bullety)
            ifHit = hitR2P(intersectLine, p)
            if ifHit == true then
                table.remove(self._listBullet, i)
                self:removeChild(bullet)
                print("delete")
            end
      
        end
    end
    
    
    TouchEventString = TouchEventString or {} --------鼠标事件名称
    TouchEventString.began = "began"
    TouchEventString.moved = "moved"
    TouchEventString.ended = "ended"
    TouchEventString.canceled = "canceled"
    
    function MainScene:onTouch(name,x,y)
        if name == TouchEventString.began then
    
            local bullet = ClassBullet.new()                        --bullet实例
            bullet:init(x,y)                                        --init bullet
            self:addChild(bullet)                                   --把bullet这个node添加到父节点中
            table.insert(self._listBullet, bullet) --1开始          --把listBullet中对象insert到表中
        end 
        return true
    end
    
    function hitR2R(rect1,rect2)
        if rect1 and rect2 then
            if rect1.right > rect2.left and rect1.left < rect2.right and rect1.top > rect2.bottom and rect1.bottom < rect2.top then
                return true
            end
        end
        return false
    end
    
    function hitR2P(rect,pos)
        if pos.x <= rect.left or pos.x >= rect.right or pos.y <= rect.bottom or pos.y >= rect.top then
            return true
        end
        return false
    end
    
    return MainScene

    此版代码可以实现基本的旋转和发射功能,但是并不能有效的remove飞出边界的bullet。

    此处原因是对于Bullet的操作要注意不要直接操作class中的子节点,要以整个class为一个对象,在bullet层面上操作。

    如此处update过程中

     local imagex = self._imgSpr:getPositionX();
     local imagey = self._imgSpr:getPositionY();

    操作的是self._imgSpr这个精灵类,并非是bullet的position发生变化。所以在MainScene的update方法中

     local bulletx = bullet:getPositionX()
     local bullety = bullet:getPositionY()

    print(bulletx,bullety) 得到的数总是0.

    修改方法:

     self._imgSpr: 改成 self: 
     注意self. 和self:的区别。

    心得:

    在平时写代码的过程中要有意识的封装一些常用的函数。函数的复用性还是很高的。可以自己做一个functions.lua的文件。然后所有的通用函数都放这里,把这个文件require一下,就可以直接用里面的函数了。

    出错的地方多写一些print帮助查错也是很有帮助的。

     CCNode里的这些方法 setPosition,setScale,setRotation 等等这类的方法,只要不重新set,这些值是不会变的,有些不需要变的值,不用每次update都去set,比如角度如果定好了不变,就不需要每次都去set了。
     
     另外。因为lua的特性。比如CCNode里有一个叫 aaa 函数,而你继承CCNode的时候,自己做了一个 self.aaa的变量。这样的话,父类的aaa函数就会失效了。。

    所以我建议大家把类成员变量做一些特殊标记。比如我一般都会用 self._aaa
     
    正确代码附录:
     1 local Bullet = class("Bullet", function()
     2     return display.newNode()
     3 end)
     4 
     5 speed = 20
     6 
     7 function Bullet:ctor()                                --构造函数
     8                                                     --bullet父对象是node 这里把sprite对象添加到node上
     9     self._imgSpr = display.newSprite("img1.png")    --添加bullet图片
    10     self._imgSpr:pos(300,0)
    11     self._imgSpr:scale(0.5)
    12     self:addChild(self._imgSpr)
    13     
    14     self._speedx = nil
    15     self._speedy = nil
    16 
    17 end
    18 
    19 function Bullet:init( x,y )
    20     local mousex = x                                 --bullet init传值 不推荐用构造函数传值 speed在这里计算出来后来直接调用即可
    21     local mousey = y 
    22     local imagex = 300
    23     local imagey = 0
    24 
    25     local distance = math.sqrt((mousex - imagex)*(mousex - imagex)+(mousey - imagey)*(mousey - imagey))
    26     local degree = math.deg(math.asin((y - imagey)/distance))
    27         if(mousex < imagex) then
    28             degree = 180 - degree
    29         end
    30         degree = 180 - degree
    31     
    32     print(degree)
    33     self._imgSpr:setRotation(degree)
    34      
    35     self._speedx = speed*math.cos(math.rad(degree))
    36     self._speedy = speed*math.sin(math.rad(degree))
    37 
    38     print(self._speedx)
    39     
    40 
    41 end
    42 
    43 function Bullet:update()                            --总函数的update调用每个子弹的update
    44 
    45     
    46      local imagex = self:getPositionX();            --只修改了Bullet的update函数
    47      local imagey = self:getPositionY();
    48 
    49      
    50      imagex = imagex - self._speedx
    51      imagey = imagey + self._speedy
    52 
    53      self:pos(imagex, imagey)
    54 
    55 end
    56 
    57 return Bullet
  • 相关阅读:
    操作系统--进程间同步
    操作系统--进程间通信
    LeetCode-- Unique Binary Search Trees II
    STL源码--序列容器(一)
    操作系统--用户级线程和内核级线程
    非洲孩子
    寻找最大数(三)
    找点
    心急的C小加
    1044 拦截导弹——http://codevs.cn/problem/1044/
  • 原文地址:https://www.cnblogs.com/CrystalN/p/4503404.html
Copyright © 2020-2023  润新知