加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

仿coc聊天框的cocos2d实现

发布时间:2020-12-14 20:43:29 所属栏目:百科 来源:网络整理
导读:前段时间出的手游有点流行左侧弹出/拉出式的聊天界面,不知道是不是受COC的影响。于是Cici把以前传统的左下角显示加点击按钮弹出整个聊天界面Duang的一下也改成这种了。下面简单的记录一下。 首先这种界面有两种打开方式。一种是单机按钮从边侧弹出,一种是

前段时间出的手游有点流行左侧弹出/拉出式的聊天界面,不知道是不是受COC的影响。于是Cici把以前传统的左下角显示加点击按钮弹出整个聊天界面Duang的一下也改成这种了。下面简单的记录一下。


首先这种界面有两种打开方式。一种是单机按钮从边侧弹出,一种是通过长按按钮让界面跟随手指移动滑出。


先还是说一下界面的制作。由于按钮一直要存在于屏幕的最左边,所以按钮的父节点(整个聊天界面所在的layer)的锚点我设置为(1,0.5),然后将聊天框的UI放在锚点左侧,按钮的UI放在锚点右侧,把聊天layer add到屏幕的最左侧,这样不管屏幕大小怎样变换,按钮就能不受分辨率影响始终在最左侧。(ps.cici的界面是用ccb做的)



然后讲一讲简单的点击按钮弹出界面。
我们需要知道的两个参数,聊天界面的初始位置和弹出后所在位置。

--初始位置
chatViewPos.px = px
chatViewPos.py = py


收回界面代码:
local move = CCMoveTo :create(0.3,ccp(chatViewPos.px,chatViewPos.py))
chatView.node:runAction(move)

弹出时,要考虑一下在不同分辨率下的缩放问题。由于Cici这个聊天系统所在的程序是根据宽高等比缩放,但缩放比例取宽比和高比之中小的那一个进行适配的,所以要先比较比例。(当前程序中是以960X640为标准屏幕大小)

    local width = chatViewNode:getContentSize().width
    if winSize.width/winSize.height < 960/640 then
       rateWidth = winSize.width/960 *width
    else
       rateWidth = winSize.height/640*width
    end
    local move = CCMoveTo :create(0.3,ccp(chatViewPos.px + rateWidth,chatViewPos.px))
    chatViewNode:runAction(move)


实现这滑动弹出我们需要知道聊天框的宽,聊天框当前的position和手指是否在按钮的touch中~

首先给屏幕添加touch事件。


   local function onTouchW(event,x,y)
      if event == "moved" then	
        moveChatView(x,y)
      end
      if event == "ended" then	
        endMoveChatView(x,y)
      end
    end

在move和stopmove的实现,由于是touch事件关联,所以我在每帧的touch检测中setPosition来改变位置而不是用runAction。


这里我们需要两个变量来记录最开始touch的位置和上一帧的位置。

  local chatViewLastPositon = nil
    local touchTag=false -----touch的标志
    local firstTouchX = nil --当chatViewLastPositon点击为nil的时候设置的用于判断有没有移动过

  function moveChatView(x,y) 
	local width = 计算过分辨率适配的chatView的width
	local posiX = chatView的position
	---如果还没有被touch过
	if touchTag==false then
	    --检查touch的坐标是否在按钮Node的坐标里面
	    local touch =nodeContainsPt("按钮的Node",(ccp(x,y)))
	    touchTag = touch
	end
	---如果已经touch了按钮	
	if touchTag==true then
	    ---如果第一次touch坐标和上一次touch坐标还没有值就先赋值
	    if chatViewLastPositon == nil then
		chatViewLastPositon = x
		firstTouchX = x
	    else
		---计算改变的距离
		local dertX = x- chatViewLastPositon
		---三种边界情况的计算
		if posiX<width and posiX >0 then
			chatView["node"]:setPositionX(dertX+chatView["node"]:getPositionX())
			chatViewLastPositon = x 	
		elseif posiX == width then
			if x<=chatViewLastPositon then
				chatView["node"]:setPositionX(dertX+chatView["node"]:getPositionX())
				chatViewLastPositon = x 	
			end
		elseif 	 posiX == 0 then
			if x>=chatViewLastPositon then
				chatView["node"]:setPositionX(dertX+chatView["node"]:getPositionX())
				chatViewLastPositon = x 
			end
		end			
	    end				
	end
    end


function endMoveChatView(x,y)
	local width = 计算过分辨率适配的chatView的width
	local posiX = chatView的position
        if chatViewLastPositon~=firstTouchX and chatViewLastPositon~= nil then
	    ---这里如果在半途中松开手会有自动弹回的效果
	    if posiX<=(width/2) then
		chatViewNode:setPositionX(px)
		chatView.isChatViewOpen = false
	    else
		chatViewNode:setPositionX(width)
		chatView.isChatViewOpen = true
				
	    end
	end	
		
	chatViewLastPositon = nil
	firstTouchX = nil
	touchTag = false
    end


最后讲讲怎么判断点击坐标是否在按钮内~

 function nodeContainsPt(pNode,pt)   --pt为点位世界坐标系点
    -----把pt转为pNode下的本地坐标
      local touchLocation = pNode:getParent():convertToNodeSpace(pt)
      local  bBox=pNode:boundingBox()
      local bRet = bBox:containsPoint(touchLocation)
      return bRet
  end

大概的效果图如下~

(我了个去去去~csdn的网页版格式肿么这么麻烦。。。泪目)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读