cocos2d-x中添加Enter键和方向键按键响应

最近有个机顶盒项目,需要用到遥控器的方向键在游戏中控制方向。

如果是一般Android设备、iOS设备或Win32平台,cocos2d-x提供了“CCAccelerometer”类,可用于游戏控制UI。但由于机顶盒在使用过程中是使用遥控器与玩家交互,而遥控器中缺少GSenser,所以只能暂时使用方向键和中键。好在机顶盒厂家使用了Android标准的键值,方向键和中键与Andriod DPAD按键一一对应。

下面讲一下如何修改cocos2d-x,以使我们在游戏中能感知DPAD按键消息。

一 修改cocos2dx\keypad_dispatcher\CCKeypadDelegate.h

为” CCKeypadDelegate”添加2个虚函数,完成后为:

class CC_DLL CCKeypadDelegate
{
public:
    // The back key clicked
    virtual void keyBackClicked() {}

    // The menu key clicked. only available on wophone & android
    virtual void keyMenuClicked() {};

    // The enter key clicked. only available on win32 & android
    virtual void keyEnterClicked() {};

    // The arrow key clicked. only available on win32 & android
    virtual void keyArrowClicked(int arrow) {};
};

其中” keyEnterClicked”函数用于响应”Enter”键,”keyArrowClicked”函数用于响应方向键消息。

二 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.h

修改枚举 ccKeypadMSGType的定义为:

typedef enum {
    // the back key clicked msg
    kTypeBackClicked = 1,
    // the menu key clicked msg
    kTypeMenuClicked,
    // the Enter key clicked msg
    kTypeEnterClicked,
    // the arrow key clicked msg
    kTypeLeftArrowClicked,
    kTypeUpArrowClicked,
    kTypeRightArrowClicked,
    kTypeDownArrowClicked,
} ccKeypadMSGType;

三 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.cpp
修改” dispatchKeypadMSG”函数,在:

case kTypeMenuClicked:
                pDelegate->keyMenuClicked();

后添加:

		case kTypeEnterClicked:
				pDelegate->keyEnterClicked();
				break;
		case kTypeLeftArrowClicked:
		case kTypeUpArrowClicked:
		case kTypeRightArrowClicked:
		case kTypeDownArrowClicked:
			pDelegate->keyArrowClicked(nMsgType);
               break;

针对Android平台还需要一下修改:

cocos2dx\platform\android\java\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java
找到” onKeyDown”函数,在其中添加几个键值处理,使函数如下:

@Override
public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
	switch (pKeyCode) {
		case KeyEvent.KEYCODE_BACK:
		case KeyEvent.KEYCODE_MENU:
		case KeyEvent.KEYCODE_DPAD_UP:		// 19
		case KeyEvent.KEYCODE_DPAD_DOWN:	// 20
		case KeyEvent.KEYCODE_DPAD_LEFT:	// 21
		case KeyEvent.KEYCODE_DPAD_RIGHT:	// 22
		case KeyEvent.KEYCODE_DPAD_CENTER:	// 23
			this.queueEvent(new Runnable() {
				@Override
				public void run() {
					Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);
				}
			});
			return true;
		default:
			return super.onKeyDown(pKeyCode, pKeyEvent);
	}
}
*注意:项目目录中proj.android\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java需要修改与此相同。

五 cocos2dx\platform\android\jni\TouchesJni.cpp

找到:


    #define KEYCODE_BACK 0x04
    #define KEYCODE_MENU 0x52

紧接着在下面添加:

	#define KEYCODE_DPAD_UP		19
    	#define KEYCODE_DPAD_DOWN	20
    	#define KEYCODE_DPAD_LEFT	21
    	#define KEYCODE_DPAD_RIGHT	22
    	#define KEYCODE_DPAD_CENTER	23
然后修改”Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown”函数,如下:

    JNIEXPORT jboolean JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown(JNIEnv * env, jobject thiz, jint keyCode) {
        CCDirector* pDirector = CCDirector::sharedDirector();
        switch (keyCode) {
            case KEYCODE_BACK:
                  if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked))
                    return JNI_TRUE;
                break;
            case KEYCODE_MENU:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeMenuClicked))
                    return JNI_TRUE;
                break;      
            case KEYCODE_DPAD_UP:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeUpArrowClicked))
                    return JNI_TRUE;
                break;
            case KEYCODE_DPAD_DOWN:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeDownArrowClicked))
                    return JNI_TRUE;
                break;
            case KEYCODE_DPAD_LEFT:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeLeftArrowClicked))
                    return JNI_TRUE;
                break;
            case KEYCODE_DPAD_RIGHT:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeRightArrowClicked))
                    return JNI_TRUE;
                break;     
            case KEYCODE_DPAD_CENTER:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked))
                    return JNI_TRUE;
                break;     
            default:
                return JNI_FALSE;
        }
        return JNI_FALSE;
    }
至此Android平台修改完成。
为了方便我们在VS2010中开发,还有针对Win32平台进行修改:
六 cocos2dx\platform\win32\CCEGLView.cpp

找到”WindowProc”函数,找到:

	if (wParam == VK_F1 || wParam == VK_F2)
        {
            CCDirector* pDirector = CCDirector::sharedDirector();
            if (GetKeyState(VK_LSHIFT) < 0 ||  GetKeyState(VK_RSHIFT) < 0 || GetKeyState(VK_SHIFT) < 0)
                pDirector->getKeypadDispatcher()->dispatchKeypadMSG(wParam == VK_F1 ? kTypeBackClicked : kTypeMenuClicked);
        }
        else if (wParam == VK_ESCAPE)
        {
            CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked);
        }
紧接着在后边添加:

	else if (wParam == VK_RETURN)
	{
		CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked);
	}
	else if (wParam >= VK_LEFT && wParam <= VK_DOWN)
	{
		CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG((ccKeypadMSGType)(kTypeLeftArrowClicked + wParam - VK_LEFT));
	}
好,现在Win32平台也添加完成了,程序中可以响应键盘上的方向键和回车键。

使用方法如下:
假设我们要在继承自CCLayer的HelloWorld中相应按键,那么首先在HelloWorld的头文件中添加两个函数:

void keyArrowClicked(int arrow);
void keyEnterClicked();
然后,在HelloWorld初始化时启用按键功能:

setKeypadEnabled(true);
在HelloWorld中实现之前声明的2个虚函数:

void LLPlaneControlLayer::keyArrowClicked(int arrow)
{	
	if (arrow == kTypeLeftArrowClicked)
	{
		// 左方向键按下
	}
	else if (arrow == kTypeRightArrowClicked)
	{
		// 右方向键按下
	}
	
	if (arrow == kTypeUpArrowClicked)
	{
		// 上方向键按下
	}
	else if (arrow == kTypeDownArrowClicked)
	{
		// 下方向键按下
	}
}

void LLPlaneControlLayer::keyEnterClicked()
{
	// Enter键按下
}
当用户按下方向键,keyArrowClicked会被执行,参数arrow表示按下的键;当用户按下Enter键(Android平台为DPAD_CENTER键),keyEnterClicked函数会执行。

你不知道的SAM V系列MCU:SAM V MCU基于 ARM Cortex:trade_mark:-M7 的微控制器系列可提供最佳的连接接口组合,包括以太网 AVB、MediaLB、USB 和 CAN-FD,以及可提供高达 1500 CoreMark 的高性能 ARM Cortex-M 内核。SAM V MCU专注于音频放大器、汽车通信控制单元或车头单元的车载信息娱乐链接。 关键特性: 高性能—由于 Cortex-M7 能够以 300 MHz 的频率运行,外加前所未有的 DSP 性能,可实现高达 1500 CoreMark 先进的存储器架构— 高达 384 KB 的多端口存储器,其中高达 256 KB 可分配作为紧密耦合存储器(数据和指令),实现以 300 MHz 频率运行时零等待 以太网 AVB— SAM V71 在以太网 MAC 中嵌入了对音频视频桥接 (AVB) 的特定硬件支持。在 MAC 的硬件中实现了基于信用的流量整形,从而无需 CPU 干预 高速 USB— 主机和器件模式高速 USB 控制器集成了 PHY 以降低 BOM 成本 MOST 连接— MediaLB 3 线接口可无缝集成到 MOST 总线 音频接口— 灵活的 TDM/I2S 接口可以连接音频源、编解码器或 DSP CAN-FD— 最新的 CAN 2.0 和 CAN 灵活数据速率 (FD) 控制器可实现更高带宽 汽车等级— 通过 AEC-Q100 等级 2 (-40C/105C) 认证 2015年最新评估开发板——SAM V71 Xplained Atmel年初刚刚推出了基于SAM V71Xplained评估套件,目前已在官网发布出售。 开发板资源: 处理器:ATSAMV71Q21(ATSAMV71Q21数据手册) 用户:一个电源开关按钮、一个机械复位按钮、两个用户按钮、两个黄色LED指示灯 存储:2MB SDRAM、2MB QSPI Flash、256KByte EEPROM 网口:IEEE 802.3az 10Base-T/100Base-TX Ethernet RMII PHY 媒体接口:立体音频编解码器、相机接口、耳机和麦克风接口 SDIO接口SD连接器、CAN收发器 MediaLB接口 接口:外部调试连接器接口、一个扩展LCD接口、两个外部扩展接口、调试接口、虚拟COM口、USB接口 电源:外部电源输入、USB供电 用到的主要芯片: 基于 ARM Cortex:trade_mark:-M7 的微控制器:ATSAMV71Q21 AVR 32-bit RISC MCU:AT32UC3A4256J CAN收发器:ATA6561-GBQW 超低功耗、便携式音频编解码器:WM8904 IEEE 802.3az 10Base-T/100Base-TX Ethernet RMII PHY:KSZ8061RNBVA 2kbit I2C EEPROM:AT24MAC402-MAHM-T
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值