cocos2d-x提供2种可进行文本输入的方法,分别是TextFieldTTF及EditBox。本文将贴出这两种方法的简单使用代码,这里在使用EditBox时候使用了extensions的扩展库,读者需要自行添加引用到项目中,要不会出现找不到文件及编译不通过等错误,具体怎么添加及引用,我下篇文章则会给出答案。
EditBox
EditBoxManager.h
#ifndef EDIT_BOX_MANAGER
#define EDIT_BOX_MANAGER
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
class EditBoxManager :public Layer, public EditBoxDelegate{
public:
EditBoxManager();
//当编辑框获得焦点时将被调用
virtual void editBoxEditingDidBegin(EditBox* editBox);
//当编辑框失去焦点后将被调用
virtual void editBoxEditingDidEnd(EditBox* editBox);
//当编辑框内容发生改变将被调用
virtual void editBoxTextChanged(EditBox* editBox, const std::string& text);
//当编辑框的结束操作被调用
virtual void editBoxReturn(EditBox* editBox);
};
void runEditBoxManager();
#endif //EDIT_BOX_MANAGER
EditBoxManager.cpp
#include "EditBoxManager.h"
#include "VisibleRect.h"
#define FONT_NAME "fonts/Marker Felt.ttf"
#define FONT_SIZE 26
void runEditBoxManager(){
auto scene = Scene::create();
EditBoxManager* layer = new EditBoxManager;
layer->autorelease(); //交给内存池进行管理
scene->addChild(layer);
Director::getInstance()->runWithScene(scene);
}
EditBoxManager::EditBoxManager(){
auto s = Size(250, 50); //设置编辑框大小
//Scale9Sprite类似android上的9图工具,可对图片进行拉伸而不失真
auto m9pic= Scale9Sprite::create("Images/green_edit.png");
auto mEditBox = EditBox::create(s, m9pic);
mEditBox->setFontName(FONT_NAME); //编辑框文本字体
mEditBox->setFontSize(FONT_SIZE); //编辑框文本大小
mEditBox->setFontColor(Color3B::BLUE); //编辑框文本颜色
mEditBox->setPlaceHolder("password:"); //编辑框提示语句
mEditBox->setPlaceholderFontColor(Color3B::GRAY); //编辑框提示语句颜色
mEditBox->setMaxLength(10); //编辑框文本长度
mEditBox->setInputFlag(EditBox::InputFlag::PASSWORD);//编辑框文本框输入类型
mEditBox->setInputMode(EditBox::InputMode::NUMERIC); //编辑框文本的输入模式
mEditBox->setDelegate(this); //注册编辑框协议
mEditBox->setPosition(VisibleRect::center());
addChild(mEditBox);
}
void EditBoxManager::editBoxEditingDidBegin(EditBox* editBox){
log("click");
}
void EditBoxManager::editBoxEditingDidEnd(EditBox* editBox){
log("leave click");
}
void EditBoxManager::editBoxTextChanged(EditBox* editBox, const std::string& text){
log("text change=%s", text.c_str());
}
void EditBoxManager::editBoxReturn(EditBox* editBox){
log("returned");
}
TextFieldTTF
TextFieldTTF则比EditBox使用方式要复杂的多,可以进行自定义输入等,本文只实现简单的文本输入,如果读者要自己定制复杂动画等操作可以借鉴官方例子。
TextFiledTTFManager.h
#ifndef TEXT_FILED_TTF_MANAGER
#define TEXT_FILED_TTF_MANAGER
#include "cocos2d.h"
USING_NS_CC;
class keyBoradNotificationLayer :public Layer,public IMEDelegate
{
public:
keyBoradNotificationLayer();
//进行点击
virtual void onClickTrackNode(bool b)=0;
//键盘显示的时候执行的通知方法
virtual void keyboardWillShow(IMEKeyboardNotificationInfo& info);
virtual bool onTouchBegan(Touch *touch, Event *_event);
virtual void onTouchEnded(Touch *touch, Event *_event);
protected:
Node* _trackNode; //被选中的对象节点
Vec2 _beganPos; //开始点击区域
};
class TextFiledTTFTest :public keyBoradNotificationLayer{
virtual void onClickTrackNode(bool b);
virtual void onEnter(); //被载入场景时候调用
};
void runTextFiledTTFManager();
#endif //EDIT_BOX_MANAGER
TextFiledTTFManager.cpp
#include "TextFiledTTFManager.h"
#include "VisibleRect.h"
#define FONT_NAME "fonts/Marker Felt.ttf"
#define FONT_SIZE 36
static Rect getRect(Node* node){
Rect rect;
rect.origin = node->getPosition();
rect.size = node->getContentSize();
rect.origin.x -= rect.size.width / 2;
rect.origin.y -= rect.size.height / 2;
return rect;
}
void runTextFiledTTFManager(){
auto scene = Scene::create();
TextFiledTTFTest* layer = new TextFiledTTFTest();
layer->autorelease(); //交给内存池进行管理
scene->addChild(layer);
Director::getInstance()->runWithScene(scene);
}
keyBoradNotificationLayer::keyBoradNotificationLayer():_trackNode(0){
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(keyBoradNotificationLayer::onTouchBegan,this);
listener->onTouchEnded = CC_CALLBACK_2(keyBoradNotificationLayer::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
bool keyBoradNotificationLayer::onTouchBegan(Touch* touch, Event* event){
_beganPos = convertToNodeSpace(touch->getLocation());
return true;
}
void keyBoradNotificationLayer::onTouchEnded(Touch *touch, Event *event){
if (!_trackNode){
return;
}
auto _endPos = touch->getLocation();
//做了个判断,滑动差距大于5的话则代表不会被触发输入法
float distance = 5.0f;
if (abs(_endPos.x - _beganPos.x) > distance ||
abs(_endPos.y - _beganPos.y) > distance){
//抹掉首次触摸的值
_beganPos.x = _beganPos.y = -1;
return;
}
/*如果点击的区域是在此文本框上就打开输入法*/
Rect rect;
auto touchPoint = convertTouchToNodeSpaceAR(touch);
log("KeyboardNotificationLayer:clickedAt(%f,%f)", touchPoint.x, touchPoint.y);
rect = getRect(_trackNode);
log("KeyboardNotificationLayer:TrackNode at(origin:%f,%f, size:%f,%f)",
rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
this->onClickTrackNode(rect.containsPoint(touchPoint));
}
void keyBoradNotificationLayer::keyboardWillShow(IMEKeyboardNotificationInfo& info){
Rect rect = getRect(_trackNode);
log(" jin ");
//_trackNode和键盘的交集监测
if (!rect.intersectsRect(info.end)){
return;
}
//计算软键盘需要的高度
float adjustHeight = info.end.getMaxY() - rect.getMinY();
/*调整所有的子节点*/
auto& children = getChildren();
Node * node = 0;
ssize_t count = children.size();
Vec2 pos;
for (int i = 0; i < count; ++i)
{
node = children.at(i);
pos = node->getPosition();
pos.y += adjustHeight;
node->setPosition(pos);
}
}
void TextFiledTTFTest::onClickTrackNode(bool b){
auto mTextFiled = (TextFieldTTF*)_trackNode;
if (b){
mTextFiled->attachWithIME();
}
else{
mTextFiled->detachWithIME();
}
}
void TextFiledTTFTest::onEnter(){
keyBoradNotificationLayer::onEnter(); //必须先调用父类的onEnter方法
auto s = Director::getInstance()->getWinSize();
auto mTextFiled = TextFieldTTF::textFieldWithPlaceHolder("click here for input", FONT_NAME, FONT_SIZE);
mTextFiled->setPosition(VisibleRect::center());
addChild(mTextFiled);
_trackNode = mTextFiled;
}