- cocos2d UI Controls 1.1 (15.62 kB)
If you find this software useful, please consider making a donation to help us continue to provide and support quality products like this.
This cocos2d framework package includes several useful cocos2d user interface controls and frameworks, including:
- Joystick – a flexible joystick for user control in two dimensions with a single finger
- CCNodeAdornments – a framework for assigning adornments to
CCNodesto temporarily change the appearance of the
CCNode, such as scaling, fading, adding visual embellishments, etc. This is most useful when used with menu items to temporarily change the appearance of the menu item during user selection.
For many games, controlling the action using a joystick is an integral and indispensable part of the game.
The joystick developed by us here is a subclass of
CCLayer that contains two
CCNode children, each of which is typically a
CCSprite image. The thumb image is a smaller image that the user moves by touching and dragging. The second is an optional background image over which the thumb image is moved. The sizes of the thumb and background nodes can be set independently, or in the case of a joystick with no background image, the size of the
Joystick node itself is set during initialization instead.
The following figure shows a
Joystick control with a round green thumb and no background image controlling the player movement in a first-person game within a three-dimensional world. Like most first-person games, the player can be moved forward or backward and turn left or right by user movement of the joystick control.
This is a visually trivial example of the Joystick control, stripped to the basics. In a real game, much more interesting thumb and background images would of course be applied to match the look and feel of the game.
To use the joystick, the user touches within the bounds of the
Joystick node. Movement of the thumb image is constrained to the size of the
Joystick node, however, the user may continue dragging outside the bounds of the joystick without losing control of the joystick. When the user lifts the finger from the screen, the joystick thumb will glide smoothly back to the center of the joystick (complete with a little bounce as it centers), just like a real physical joystick.
Joystick in your code is simple, as shown in the following, which sets up the
Joystick shown above:
CCSprite* jsThumb = [CCSprite spriteWithFile: kJoystickThumbFileName]; // jsThumb.scale = 0.80; // change thumb size if you like joystick = [Joystick joystickWithThumb: jsThumb andSize: CGSizeMake(kJoystickSideLength, kJoystickSideLength)]; joystick.position = ccp(kJoystickPadding, kJoystickPadding); [self addChild: joystick];
Joystick with a background image is desired instead, just use a different creation method:
CCSprite* jsThumb = [CCSprite spriteWithFile: kJoystickThumbFileName]; // jsThumb.scale = 0.80; // change thumb size if you like CCSprite* jsBackdrop = [CCSprite spriteWithFile: kJoystickBackdropFileName]; joystick = [Joystick joystickWithThumb: jsThumb andBackdrop: jsBackdrop]; joystick.position = ccp(kJoystickPadding, kJoystickPadding); [self addChild: joystick];
The application can read the position of the
Joystick thumb, relative to its resting position, at any time from either the
velocity property or the
velocity property returns a
CGPoint reporting the relative position of the thumb in cartesian X-Y coordinates. The X-Y values returned range from
+1, with zero being the center position. However, the magnitude of the
velocity vector is clamped to unit length, so the set of possible points returned by the
velocity property therefore covers the area of a circle of unit radius, centered on zero. This means, for instance, that pulling the thumb as far as it will go up and right will not take both X and Y each to a value of one at the same time. Instead, the thumb will stop when the radial distance from the origin is equal to one. This design provides a more natural range of values for controlling motion within a game.
angularVelocity property returns a structure reporting the position of the thumb in an angular coordinate system, in terms of an angle plus a radius. The angle is given in positive or negative degrees from vertical (forward), and the radius ranges from zero to one. As with the
velocity property, the set of points returned by the
angularVelocity property therefore also covers the area of a circle of unit radius.
To add a
Joystick to your game, download and install the cocos2d UI Controls framework code into your
Xcode project as described below, then
Joystick.h file into your code where it is needed, typically into a custom
CCLayer subclass file. The
Joystick.h header file contains extensive documentation on the
Joystick API and is your best source for understanding how to use it in your project.
Adornments are visual components that can be added to a subclass of
CCNode to provide a visual appearance that can be activated and deactivated on demand. Familiar examples of this might be the icon tags associated with
iOS app icons. Or within a cocos2d game, adornments can provide visual feedback when a user touches a game element, menu item, or other button-like nodes. The example shown below is the same scene shown in the
Joystick description above, but in this case, the user is currently pressing the sunshine button (actually a
CCMenuImageToggle) on the right. Doing so has activated the adornment and a yellow ring has faded in around the button. When the user releases the button, or drags his finger away from the button, the adornment will be deactivated, and the ring will fade away again.
To be clear, this image shown here is not the alternate toggled image of the
CCMenuItemToggle. Nor is it the
selected image of a
CCMenuItemImage, which cannot be made to fade in and out in an animated manner. The adornment is a separate image that appears over or under the basic images of the menu item. In fact, in the action above, once the user releases the button, the
CCMenuItemToggle itself will toggle to a different image altogether to show the changed state. The adornment is displayed only during the transitional stage while the user is actually pressing the button.
Instead of a ring, the adornment image could also have been a semi-transparent colored “shine” image that faded in and out over the main button image as the user touches and releases the button.
Another type of adornment scales the adorned node when activated. For example, the button could be made to grow in size when touched, and shrink back again when released, with the scaling up and down being animated for effect. Should fading and scaling seem boring to you, other adornment effects can easily be developed should you have other interesting effects in mind (spinning, changing color, etc).
Using adornments is fairly straightforward. At the very basic level, an adornment can simply be added as a child to any
CCNode, and then tracked, activated and deactivated manually by the application. But where adornments really become interesting is when a
CCNode is made adornable so it can automatically
deactivate its adornment at the appropriate times.
To make a
CCNode adornable, you first create a subclass of the
CCNode and add the
AdornableCCNodeProtocol protocol to it. In this framework, we’ve done that already for
CCMenuItemImage, and tied the activation and deactivation of its adornment to the
unselected actions of the adornable subclasses. So when an
AdornableMenuItemToggle is selected by the user, its adornment is automatically activated, and when the menu item is unselected, the adornment is automatically deactivated. As described above, depending on the adornment type, when the user selects and unselects the menu item, this might expand and shrink the menu item, or might fade in and out a shine or ring on top of the menu item.
The adornments themselves are
CCNodes that support the
CCNodeAdornmentProtocol protocol. To support development of new adornments, we’ve included in the framework an abstract
CCNodeAdornmentBase class, along with concrete
CCNodeAdornmentScaler classes to perform the overlay fading and node scaling I’ve been describing above.
Putting this into practice then, the scene displayed in the picture above, with the yellow adornment ring, was created with the following code in the custom
CCLayer that forms the scene:
// Toggle between two subitems: one for shutter button, one for sky button CCMenuItem* camMI = [CCMenuItemImage itemFromNormalImage: kShutterButtonFileName selectedImage: kShutterButtonFileName]; CCMenuItem* skyMI = [CCMenuItemImage itemFromNormalImage: kSkyButtonFileName selectedImage: kSkyButtonFileName]; backdropToggleMI = [AdornableMenuItemToggle itemWithTarget: self selector: @selector(changeBackdropSelected:) items: camMI, skyMI, nil]; backdropToggleMI.position = ccp(self.contentSize.width - kBackdropToggleMenuInset, kBackdropToggleMenuInset); // Instead of having different normal and selected images, the toggle menu item uses an // adornment, which is displayed whenever an item is selected. CCNodeAdornmentBase* adornment; // The adornment is a ring that fades in around the menu item and then fades out when // the menu item is no longer selected. CCSprite* ringSprite = [CCSprite spriteWithFile: kButtonRingFileName]; adornment = [CCNodeAdornmentOverlayFader adornmentWithAdornmentNode: ringSprite]; adornment.zOrder = kAdornmentUnderZOrder; // Attach the adornment to the menu item and center it on the menu item adornment.position = backdropToggleMI.anchorPointInPixels; backdropToggleMI.adornment = adornment; CCMenu* bgMenu = [CCMenu menuWithItems: backdropToggleMI, nil]; bgMenu.position = CGPointZero; [self addChild: bgMenu];
If you would rather see the “shine” adornment described above, replace lines
17-19 above with:
CCSprite* shineSprite = [CCSprite spriteWithFile: kButtonShineFileName]; shineSprite.color = ccYELLOW; adornment = [CCNodeAdornmentOverlayFader adornmentWithAdornmentNode: shineSprite peakOpacity: kPeakShineOpacity];
Or to have the menu item grow and shrink when pressed by the user, replace the original lines
17-19 above with:
adornment = [CCNodeAdornmentScaler adornmentToScaleUniformlyBy: kButtonAdornmentScale];
To add adornments to your project, download and install the cocos2d UI Controls framework code into your
Xcode project as described below, then
CCNodeAdornments.h file into your code where it is needed. That header file also contains extensive documentation on the adornments API and is your best source for understanding the adornments framework. And once you get some experience with the framework, don’t be timid about extending the framework by inventing your own adornments!
You can download the source code for this framework in the download area at the top-right of this article. It is distributed under an MIT license, which makes it free for you to use in your projects. However, if you find this code is useful, please remember to make a donation above to help us fund the ongoing development and support of frameworks such as this.
Once downloaded, unzip the file, and drag the extracted directory to your
Classes group within your
Xcode project. On the dialog that pops up when you do that, make sure both the Copy items into destination group’s folder and Recursively create groups for any added folders options are both selected.
Credit Where Credit is Due
Our Joystick code was inspired by code donated to the cocos2d community by cocos2d user adunsmoor. The original inspirational code can be found here.