Cocos2d-x - Enable Hardware Keyboard
Before I begin, I assume that the reader of this post are familiar with "Cocos2d-x" platform.
For those who are not familiar with "Cocos2d-x" platform, I would just say that its cross platform open source 2D game engine framework based on "Cocos2d-iPhone" specific mobile platform. You can further read about "Cocos2d-x" Overview.
Keyboard is one of the most important input mechanism in game development. Since, coco2d-x is based on iphone platform, therefore, its architecture design includes only virtual keypad input and not hardware keyboard input. Cocos2d-x is mainly developed for windows users to develop their games with cocos2d-x platform on windows platform instead of mac. This can help the wide range of windows specific developer community to learn cocos2d platform for mobile game development. With cocos2d-x on windows platform, its not always easy to use just mouse as a user input. Many people prefer hardware keyboard input but, its a little bit difficult to enable it with cocos2d-x. So, here today, we shall learn "How to enable hardware keyboard with cocos2d-x?".
There are two methods to enable hardware keyboard with cocos2d-x platform:
1) Enhance Key Dispatcher method.
2) Hook hardware keyboard functions like "ccTouchedBegan or ccTouchesEnded".
I am going to discuss second method here in this post. You can download detail tutorial or you can follow step by step discussion below. You will also need to download "CCEGLView_win32.cpp" file for second method.
Download Now!
Let us begin now.Create new project cocos2d-x project and name it "keyboard_tut". Edit the "HelloWorldScene.h" file which should looks like below:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Box2D/Box2D.h" #include "SimpleAudioEngine.h" class HelloWorld : public cocos2d::CCLayer { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone. virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer. static cocos2d::CCScene* scene(); // implement the "static node()" method manually LAYER_NODE_FUNC(HelloWorld); private: cocos2d::CCSprite *ball; }; #endif // __HELLOWORLD_SCENE_H__
// Get window size and place the label upper. CCSize size = CCDirector::sharedDirector()->getWinSize(); // 3. Add add a ball sprite. this->ball = CCSprite::spriteWithFile("ball.jpg"); CC_BREAK_IF(! this->ball); // Place the sprite on the center of the screen this->ball->setPosition(ccp(size.width/2, size.height/2)); // Add the sprite to HelloWorld layer as a child layer. this->addChild(this->ball, 0); this->setIsTouchEnabled(true);
What we have done here is add ball sprite, then set is position to windows center and enable touch input to receive inputs to ccTouchesBegan method.
Now, its time for us to hook the hardware keys. Save your files and close all visual studios instances before you proceed any further. Go to "~\cocos2dx\platform\win32\" directory inside your cocos2d-x root directory. Then save "CCEGLView_win32.cpp" file some place else before making any new changes. Now open "CCEGLView_win32.cpp" file and make following changes after following lines of code:
case WM_KEYDOWN: if (wParam == VK_F1 || wParam == VK_F2) { if (GetKeyState(VK_LSHIFT) < 0 || GetKeyState(VK_RSHIFT) < 0 || GetKeyState(VK_SHIFT) < 0) CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(wParam == VK_F1 ? kTypeBackClicked : kTypeMenuClicked); }
Add these lines after above code:
// For "Up" key Keyboard changes. if (wParam == VK_UP) { SendMessage(m_hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(480-10, 320-10));// your up button postion SendMessage(m_hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELONG(480-10, 320-10)); } // End // For "Down" key Keyboard changes. if (wParam == VK_DOWN) { SendMessage(m_hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(480-10, 320-10));// your down button postion SendMessage(m_hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELONG(480-10, 320-10)); } // End
What we have done here is hook the ccTouchesBegan & ccTouchesEnded method. You can explore the details about SendMessage Method yourself.
Now run the "build-win32.bat" file provided by the cocos2d-x. After complete build successful execution, open your visual studio project and add following lines in "HelloWorldScene.cpp" file.
#define SHIFTED 0x8000 void HelloWorld::ccTouchesBegan(CCSet* touch, CCEvent* touchEvent) { // Initialization. float pos_y = this->ball->getPositionY(); // Verify whether "UP" keyboard key is pressed or not if(GetKeyState(VK_UP) & SHIFTED) { pos_y = this->ball->getPositionY() + 1; this->ball->setPosition(ccp(this->ball->getPositionX(), pos_y)); } // Verify whether "DOWN" keyboard key is pressed or not if(GetKeyState(VK_DOWN) & SHIFTED) { pos_y = this->ball->getPositionY() - 1; this->ball->setPosition(ccp(this->ball->getPositionX(), pos_y)); } }
Add following line in "HelloWorldScene.h" file under public methods
// Touch(or onClick) event. void ccTouchesBegan(cocos2d::CCSet* touch, cocos2d::CCEvent* touchEvent);
What we have done here is that we use GetKeyState method to verify whether hardware key is being pressed or not. That's about it. Execute the project and press up and down arrow key you should see that the ball will move up and down accordingly.
Enjoy!! Coding.
ccTouchesBegan only fires on mouse click (WinXP 32).
ReplyDeleteYes it is, but, we are hooking it for keyboard key down.
ReplyDeleteThanks for sharing this great article! That is very interesting I love reading and I am always searching for informative information like this.
ReplyDeletecocos2d-x game development
I liked your article and I hope you will have many entries or more.
ReplyDeleteMobile Application Developer USA
In this case, the panic hardware will not properly secure the door to protect against the smoke, fire or other adverse conditions that the cross corridor opening was designed to protect. visit this page
ReplyDeleteThanks for providing solution regarding the keyword specifications regarding the game.
ReplyDeleteNewspaper Ad Agency in Delhi