Cocos2d-x-3.3-018-game joystick source code sharing, cocos2dx3.3
To view the original text or updates, go to my wiki: https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3-018-joystick4cocos3.3
Joystick
- Joystick for cocos2d-x v3.3
- Complete code and resource https://github.com/cheyiliu/joystick
Core Ideology
- Decoupling: events are used to decouple the association between events of joystick and target objects.
Implementation
- 1. inherit from layer and register the listener touch event
- 2. If the touch event is triggered at the center of joystick, continue the following logic
- 3. Update the joystick Center Position
- 4. calculate the angle of the joystick Center (angle range, First quadrant [0, 90], Second quadrant [90,180], third quadrant [-180,-90], quadrant [-90, 0])
- 5. Publish a custom joystick event. Currently, the event only contains the angle value calculated above. You can add or modify the event as needed.
- 6. register the event listener of joystick event and implement your business logic in the callback function.
- 7. The memory of userdata in joystick event is released and handed over to auto-release-pool. For details, see the implementation of JoystickEvent.
Core code
- JoystickEvent is mainly used to standardize memory management and strictly follow the cocos 'Customs ': create + Ref + pool in Two-segment construction modes, so that the created object is like a local variable on a stack. (MainLoop is automatically deleted when the pool is cleaned up next time ).
- Core code of Joystick
Bool Joystick: init () {bool result = false; do {// The parent class initializes if (! Layer: init () {break;} // background of joystick mJsBg = Sprite: create ("joystick_bg.png"); if (nullptr = mJsBg) {break ;} mJsBg-> setPosition (mJsPos); addChild (mJsBg); // center point of joystick mJsCenter = Sprite: create ("joystick_center.png"); if (nullptr = mJsCenter) {break;} mJsCenter-> setPosition (mJsPos); addChild (mJsCenter); // touch event listens to auto touchListener = EventListenerTouchOneByOne: create (); if (nullptr = touchListener) {break;} touchListener-> listener (true); touchListener-> onTouchBegan = CC_CALLBACK_2 (Joystick: callback, this); touchListener-> listener = CC_CALLBACK_2 (Joystick: callback, this); touchListener-> onTouchEnded = CC_CALLBACK_2 (Joystick: onTouchEnded, this); _ eventDispatcher-> destroy (touchListener, this); result = true;} while (0 ); return result;} bool Joystick: onTouchBegan (Touch * touch, Event * unused_event) {log ("onTouchBegan"); auto point = touch-> getLocation (); if (mJsCenter-> getBoundingBox (). containsPoint (point) {// If the touch point is at the center of joystick, the event return true will be accepted;} // otherwise, the subsequent event return false will not be accepted;} void Joystick :: onTouchMoved (Touch * touch, Event * unused_event) {log ("onTouchMoved"); // 1. obtain the angle. // The First quadrant is 90,180 degrees. // the second quadrant is degrees. // The third quadrant is-90, -180 degrees // The Fourth quadrant is-90, 0 degrees Vec2 point = touch-> getLocation (); double y = point. y-mJsPos. y; double x = point. x-mJsPos. x; double angle = atan2 (y, x) * 180/PI; log ("------------------------------------ % f", angle); // 2. update the joystick center position to keep the center always within its background image range. // the radius of the joystick background image is double jsBgRadis = mJsBg-> getContentSize (). width * 0.5; // the actual distance from the touch point to the center point. double distanceOfTouchPointToCenter = sqrt (pow (mJsPos. x-point. x, 2) + pow (mJsPos. y-point. y, 2); if (distanceOfTouchPointToCenter> = jsBgRadis) {// calculate delta x y double deltX = x * (jsBgRadis/distanceOfTouchPointToCenter) using the proportional relationship ); double deltY = y * (jsBgRadis/distanceOfTouchPointToCenter); mJsCenter-> setPosition (Vec2 (mJsPos. x + deltX, mJsPos. y + deltY);} else {mJsCenter-> setPosition (point);} // 3. distribute joystick event JoystickEvent * jsEvent = JoystickEvent: create (); jsEvent-> mAnagle = angle; Director: getInstance ()-> getEventDispatcher ()-> quit (JoystickEvent :: EVENT_JOYSTICK, jsEvent);} void Joystick: onTouchEnded (Touch * touch, Event * unused_event) {log ("onTouchEnded"); // Event ends, restore joystick Central Point Location mJsCenter-> setPosition (mJsPos );}
Integration to project
- Using proj. linx as an Example
- Copy the relevant cpp. H to the project and add cpp in cmakelists.txt.
Set (GAME_SRC Classes/AppDelegate. cpp Classes/HelloWorldScene. cpp Classes/Joystick. cpp # add $ {PLATFORM_SPECIFIC_SRC })
auto joystick = Joystick::create();scene->addChild(joystick);
#include "Joystick.h" auto _listener = EventListenerCustom::create(JoystickEvent::EVENT_JOYSTICK, [=](EventCustom* event){ JoystickEvent* jsevent = static_cast<JoystickEvent*>(event->getUserData()); log("--------------got joystick event, %p, angle=%f", jsevent, jsevent->mAnagle); // do you business you'd like to }); _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);
References
- Https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3rc2-005-cocos%E4%B8%AD%E7%9A%84%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88#%E5%B0%8F%E7%BB%93
- Https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3-012-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%E6%9C%BA%E5%88%B6
- Http://blog.csdn.net/evankaka/article/details/42043509