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

 

posted @ 2015-05-14 15:10  Crystal_N  阅读(531)  评论(0编辑  收藏  举报