从零开始学习cocos2dx 3d开源项目

2015年03月18日 09:45 0 点赞 0 评论 更新于 2025-11-21 13:43

今天,我们将从零开始学习Cocos2d-x 3D开源项目,主要从触摸事件和UI上的对象两个方面展开。

1. 触摸事件

初始化触摸监听器

ChooseRoleScene类中,我们需要初始化触摸事件调度器。以下是具体代码实现:

function ChooseRoleScene:initTouchDispatcher()
-- 初始化监听对象
local listenner = cc.EventListenerTouchOneByOne:create()
-- 注册事件监听器,设置优先级
local eventDispatcher = self:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listenner, self.layer)
-- 设置触摸开始事件的处理函数
listenner:registerScriptHandler(function(touch, event)
-- 获取触摸点
local touchbeginPt = touch:getLocation()
-- (1) EVENT_TOUCH_BEGAN 实现旋转:如果点击到了英雄区域
local heroSize = cc.rect(0, 0, 100, 100) -- 假设英雄区域
if cc.rectContainsPoint(heroSize, touchbeginPt) then
isRotateavaliable = true
return true
end
-- 记录点击位置
-- (2) 判断是否点击背包里的装备
-- 因为 self._weaponItem:getBoundingBox() 获得的区域都是与背包的相对区域,
-- 所以鼠标点击位置需要先转换到与背包的相对位置
touchbeginPt = self._bag:convertToNodeSpace(touchbeginPt)
local weaponBox = self._weaponItem:getBoundingBox()
if cc.rectContainsPoint(weaponBox, touchbeginPt) then
-- 如果点到装备了,放大和调透明度
self._weaponItem:setScale(1.7)
self._weaponItem:setOpacity(150)
end
return true
end, cc.Handler.EVENT_TOUCH_BEGAN)

-- (3) EVENT_TOUCH_MOVED 滑动角色
listenner:registerScriptHandler(function(touch, event)
local touchMovePt = touch:getLocation()
local touchbeginPt = touch:getStartLocation()
local distance = cc.pGetDistance(touchMovePt, touchbeginPt)
if distance > 50 then
-- 调用 rotate3Heroes 函数
local rotatetime = 1.0
local pos = {cc.p(0, 0), cc.p(100, 0), cc.p(200, 0)}
local action = cc.EaseCircleActionInOut:create(cc.MoveTo:create(rotatetime, pos[3]))
self.layer:getChildByTag(sortorder[2]):runAction(action)
end
return true
end, cc.Handler.EVENT_TOUCH_MOVED)

-- (4) EVENT_TOUCH_ENDED 换装的实现
listenner:registerScriptHandler(function(touch, event)
-- 在每个角色中实现了 switchArmour、switchWeapon、switchHelmet
-- 切换两套装备 mesh 的显示与隐藏
for _, hero in ipairs(self.heroes) do
hero:switchArmour()
hero:switchWeapon()
hero:switchHelmet()
end
-- 不过这种实现方式的扩展性有待考量,
-- 难道说有 n 套装备,那么每个部位都需要 n 个对应的 mesh 吗?
return true
end, cc.Handler.EVENT_TOUCH_ENDED)
end

代码解释

  • EVENT_TOUCH_BEGAN:当触摸开始时,判断是否点击到英雄区域,如果是则标记为可旋转状态。同时,判断是否点击到背包里的装备,若点击到则对装备进行放大和调整透明度操作。
  • EVENT_TOUCH_MOVED:当触摸滑动时,计算滑动距离,如果超过50像素,则调用rotate3Heroes函数实现角色的位置轮换,并使用EaseCircleActionInOut动作增加先慢后快的弹性效果。
  • EVENT_TOUCH_ENDED:当触摸结束时,调用角色的换装函数switchArmourswitchWeaponswitchHelmet,切换装备mesh的显示与隐藏。但这种实现方式在处理多套装备时,扩展性可能存在问题。

2. UI上的对象

(1) “进入游戏”按钮

ChooseRoleScene类中,我们需要添加“进入游戏”按钮。以下是具体代码实现:

function ChooseRoleScene:addButton()
-- 使用到了全局变量 ReSkin 来记录穿戴的装备 id
local ReSkin = 1
-- 在跳转 BattleScene 之前把相关的 lua 对象清空
package.loaded["BattleScene"] = nil
package.loaded["Manager"] = nil
package.loaded["Helper"] = nil
package.loaded["MessageDispatchCenter"] = nil
package.loaded["BattleFieldUI"] = nil
-- 创建按钮
local next_Button = ccui.Button:create()
next_Button:setTitleText("进入游戏")
-- 设置按钮位置
next_Button:setNormalizedPosition({x = 0.34, y = 0.13})
-- Node::setNormalizedPosition 方法,Node 的位置像素会根据它的父节点的尺寸大小计算,即按比例
self.layer:addChild(next_Button)
end

(2) 装备和属性

ChooseRoleScene类中,我们需要添加背包相关的UI元素。以下是具体代码实现:

function ChooseRoleScene:addBag()
-- 切换职业图标和设置属性值
self:switchTextWhenRotate()
-- 其实装备的位置都是写死了的,就没有什么参考的必要了
end

(3) 添加角色并旋转英雄

ChooseRoleScene类中,我们需要添加角色并实现英雄旋转功能。以下是具体代码实现:

function ChooseRoleScene:addHeros()
local sortorder = {1, 2, 3}
local rotate = 0.5
local function hero_rotate()
local rotation = self.layer:getChildByTag(sortorder[2]):getRotation3D()
self.layer:getChildByTag(sortorder[2]):setRotation3D({x = rotation.x, y = rotation.y + rotate, z = 0})
end
-- 开启一个 schedule 每次旋转 0.5 个弧度
self:schedule(hero_rotate, 0.1)
end

代码解释

  • addButton:创建“进入游戏”按钮,在跳转场景前清空相关的Lua对象,避免内存泄漏。使用setNormalizedPosition方法设置按钮位置,该位置会根据父节点的尺寸按比例计算。
  • addBag:调用switchTextWhenRotate函数切换职业图标和设置属性值,但装备位置是写死的,参考价值不大。
  • addHeros:定义一个旋转函数hero_rotate,并使用schedule方法定时调用该函数,实现英雄的旋转效果。

通过以上步骤,我们可以实现Cocos2d-x 3D开源项目中的触摸事件处理和UI元素添加功能。

作者信息

feifeila

feifeila

共发布了 3994 篇文章