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

Quick-Cocos2d-x的输入框详解

发布时间:2020-12-14 20:09:48 所属栏目:百科 来源:网络整理
导读:游戏引擎一般提供两种输入框:editbox和textfielttf。editbox比较简单,在iOS上效果也还行,但是在Android上就比较丑了,每次输入都会悬浮一个小框框。对于游戏来说eidtbox可以满足基本需求,毕竟输入还是少数情况。textfielttf是一种特殊的label,显示效果比

游戏引擎一般提供两种输入框:editbox和textfielttf。editbox比较简单,在iOS上效果也还行,但是在Android上就比较丑了,每次输入都会悬浮一个小框框。对于游戏来说eidtbox可以满足基本需求,毕竟输入还是少数情况。textfielttf是一种特殊的label,显示效果比较好,但是计算起来比较麻烦,要自己绘制光标,要自己绘制文字,自己计算增加和删除。


这里还是说一下自己实现的一种简陋的支持增加删除的方式吧。其实比较简单,原理就是记录每个字及每个字的位置,然后增加删除的时候既要对字处理也要对位置处理。(这里只针对单行进行说明,多行的还要自己维护高度等信息)。


先来说一下绘制函数,这里用的是自己维护的显示内容contentString

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
bool CCTextFieldTTFExtend::onDraw(CCTextFieldTTF*pSender)
{
CCLog( "thecontentstringinfieldttfextendis%s" ,contentString.c_str());
//检测是否有删改
pSender->setString(contentString.c_str());
if (once==1){
once=0;
if (recordPos.size()>0&&pSender->getContentSize().width-recordPos[recordPos.size()-1].point.x<0){
//有记录的数据,切操作之后显示的文字内容比记录的要短,说明进行的是删除操作
if (posInList>1){
float distance=recordPos[posInList-2].point.x-recordPos[posInList-1].point.x;
m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX()+distance/2);
pSender->setString(contentString.c_str());
updateDelete(pSender);
} else if (posInList==1){
float distance=0-recordPos[posInList-1].point.x;
m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX()+distance/2);
pSender->setString(contentString.c_str());
updateDelete(pSender);
}
return false ;
}
if (recordPos.size()>0&&pSender->getContentSize().width-recordPos[recordPos.size()-1].point.x>1){
//有记录的数据,切操作之后显示的文字内容比记录的要长,说明进行的是增加操作
float distance=pSender->getContentSize().width-recordPos[recordPos.size()-1].point.x;
m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX()+distance/2);
pSender->setString(contentString.c_str());
updateAdd(pSender);
return false ;
} else {
if (recordPos.size()==0&&pSender->getContentSize().width>0){
//显现没有记录说明没有文字,现在有记录说明是增加操作
m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX()+pSender->getContentSize().width/2);
updateAdd(pSender);
}
}
}
return false ;
}


删除内容操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//删除内容
void CCTextFieldTTFExtend::deleteString(){
if ( strcmp (contentString.c_str(), "" )&&posInList<1){
return ;
}
//计算删除了几个汉字或字符
int nDeleteLen=1;
while (0x80==(0xC0&contentString.at(posInString-nDeleteLen)))
{
++nDeleteLen;
}
stringtempNext=contentString.substr(posInString);
stringtempPrev=contentString.substr(0,posInString-nDeleteLen);
contentString=tempPrev+tempNext;
posInString-=nDeleteLen;
once=1;
}


增加内容操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//增加内容
void CCTextFieldTTFExtend::addString( const char *text){
stringtempPrev=contentString.substr(0,posInString);
stringtempNext=contentString.substr(posInString);
stringtempString=tempPrev+text+tempNext;
int addLength=( strlen (tempString.c_str())- strlen (contentString.c_str()));
posInString+=addLength;
contentString=tempString;
judgeChines=addLength;
CCLog( "thecontentStringis%s" ,contentString.c_str());
once=1;
}


删除位置操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CCTextFieldTTFExtend::updateDelete(CCTextFieldTTF*pSender){
//销毁足迹
float distance=0;
if (posInList!=0){
distance=recordPos[posInList].point.x-recordPos[posInList-1].point.x;
}
vector<RecordTTF>temp=recordPos;
recordPos.clear();
for ( int i=0;i<posInList-1;++i){
recordPos.push_back(temp[i]);
}
for ( int i=posInList;i<temp.size();++i){
temp[i].point.x-=distance;
recordPos.push_back(temp[i]);
}
posInList--;
}


添加足迹的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void CCTextFieldTTFExtend::updateAdd(CCTextFieldTTF*pSender){
//原先字段的前部
vector<RecordTTF>temp=recordPos;
recordPos.clear();
for ( int i=0;i<posInList;++i){
recordPos.push_back(temp[i]);
}
//现增加的部分
float distance=0;
if (posInList>0){
RecordTTFlocal;
distance=pSender->getContentSize().width-temp[temp.size()-1].point.x;
local.point=CCPoint(temp[posInList-1].point.x+=distance,0);
CCLog( "现在的%f" ,local.point.x);
local.flag=judgeChines;
recordPos.push_back(local);
} else {
if (temp.size()<1){
RecordTTFlocal;
local.point=CCPoint(pSender->getContentSize().width,0);
local.flag=judgeChines;
recordPos.push_back(local);
} else {
RecordTTFlocal;
CCLog( "thecontentSizeis%f" ,pSender->getContentSize().width);
distance=pSender->getContentSize().width-temp[temp.size()-1].point.x;
local.point=CCPoint(temp[posInList-1].point.x+=distance,0);
CCLog( "现在的%f" ,local.point.x);
local.flag=judgeChines;
recordPos.push_back(local);
}
}
//原先文字的后部
for ( int i=posInList;i<temp.size();++i){
temp[i].point.x+=distance;
recordPos.push_back(temp[i]);
}
posInList++;
}


还有一种可能,如果要换行的话,我这里采用的是用系统控件的方式
但是iOS上输入完内容之后,只有回车才能关闭键盘,点击空白处,或者自己的按钮都接收不到触摸事件,这时改一下lib/cocos2d-x/cocos2dx/platform/ios/EAGLView.mm,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-( void )handleTouchesAfterKeyboardShow
{
NSArray*subviews=self.subviews;
for (UIView*viewinsubviews)
{
if ([viewisKindOfClass:NSClassFromString(@ "CustomUITextField" )])
{
if ([viewisFirstResponder])
{
[viewresignFirstResponder];
return ;
}
}
if ([viewisKindOfClass:NSClassFromString(@ "UITextView" )])
{
if ([viewisFirstResponder])
{
[viewresignFirstResponder];
return ;
}
}
}
}

原因代码也说的比较清楚了,原先Quick只对自己的控件进行了处理,现在你增加一下把系统控件也处理以下。

此外,在做Android微信授权登陆的时候出现从cocos2dActivity跳转出去再跳转回来之后所有的cocos2d输入框不显示键盘,跟踪发现启动键盘确实走到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Cocos2dxGLSurfaceView.sHandler= new Handler(){
@Override
public void handleMessage(finalMessagemsg){
switch (msg.what){
case HANDLER_OPEN_IME_KEYBOARD:
Log.i( "" , "接收到启动键盘通知" );
if (null!=Cocos2dxGLSurfaceView. this .mCocos2dxEditText&&Cocos2dxGLSurfaceView. this .mCocos2dxEditText.requestFocus()){
Log.i( "" , "接收到启动键盘通知开始启动键盘" );
Cocos2dxGLSurfaceView. this .mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
Cocos2dxGLSurfaceView. this .mCocos2dxEditText.setText( "" );
finalStringtext=(String)msg.obj;
Cocos2dxGLSurfaceView. this .mCocos2dxEditText.append(text);
Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper.setOriginText(text);
Cocos2dxGLSurfaceView. this .mCocos2dxEditText.addTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
finalInputMethodManagerimm=(InputMethodManager)Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(Cocos2dxGLSurfaceView. this .mCocos2dxEditText,0);
Log.d( "GLSurfaceView" , "showSoftInput" );
}
break ;


原因是我将微信授权的回调activity也设成了cocos2dActivity。具体是什么造成的没有去深究,将其改为activity,并注意下到底是UIThread还是OpenGLThread,这样的问题就没有了。大部分这种操作都是线程混乱造成的,出现这种类似的情况,多看一下是否是线程的原因。

Cocos引擎中文官网有奖征集优秀原创Cocos教程 奖品丰厚!活动地址:http://www.cocoachina.com/bbs/read.php?tid-274890.html

来源网址:http://www.52php.cn/article/p-gdkhsxyl-bbe.html

(编辑:李大同)

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

    推荐文章
      热点阅读