Cocos2d game development (I) multi-touch and touch-screen event details

Source: Internet
Author: User

Cocos2d has been being honed over the past few days, and many things have been digested. You can basically grasp the game of a hand-written company. Today, I will share some important points with you to share my experience, provide new children's shoes as a reference;
This article will introduce cocos2d in detail to analyze the user's touch screen listening events (cocos2d has many detailed articles and tutorials, I am here for my own understanding)
Question: There are two types of event listening for touch screens in cocos2d:
1. for a single listener, the so-called single listener is actually related to the cocos2d engine framework. Because each game interface in cocos2d can be completed using a CCLayout, when a CCLayout is displayed on the screen, to listen to a user's key events, the following methods are generally used for listening: (Note: The CCLayout class is used for listening)
Enable the listener first:

Oc code
Self. isTouchEnabled = YES;


Then rewrite the listening function:
Oc code
// Listen for the first trigger event
-(Void) ccTouchesBegan :( NSSet *) touches withEvent :( UIEvent *) event
{
}
// Touch event-move your finger on the screen
-(Void) ccTouchesMoved :( NSSet *) touches withEvent :( UIEvent *) event
{

}
// Touch event-method called when the finger is lifted from the screen
-(Void) ccTouchesEnded :( NSSet *) touches withEvent :( UIEvent *) event
{

}


This kind of listening method applies to eazy, but it should be noted that the CCLayout class is monitored here;

2. listen for distribution. As I said just now, every interface of the game may be a CCLayout, but if I want a CCSprite hero to listen separately, in other words, when I want to listen to one of the many genie in CCLayout, I need to use the listener distribution method;
Assume that we have customized a class XX to inherit CCSprite, and another YY class also inherits CCSprite, and instances of XX and YY classes exist in a Layout, so I want to listen to the XX and YY types separately. First, let the XX inherited CCSprite classes use the <CCTargetedTouchDelegate> protocol for the YY classes;
(No self. isTouchEnabled = YES in CCSprite; Do not write this function directly ~)

The Code is as follows:

Oc code
@ Interface XX: CCSprite <CCTargetedTouchDelegate> {
 
}


Then, rewrite a function in the current implementation class as follows:
Oc code
-(Void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES];
}


(This function registers a listener. If nothing is written in it, no touch screen events will be triggered ;)
Rewrite the touch event functions as follows:

Oc code
// Listen for the first trigger event
-(BOOL) ccTouchBegan :( UITouch *) touch withEvent :( UIEvent *) event
{
Return NO;
}
// Listen for mobile events
-(Void) ccTouchMoved :( UITouch *) touch withEvent :( UIEvent *) event
{
}
// Listen for the exit event
-(Void) ccTouchEnded :( UITouch *) touch withEvent :( UIEvent *) event
{

}


As you can see, this listener method has a return type-Boolean value in the ccTouchBegan function in addition to the various listener functions similar to the first one. The functions are described in detail below; if both XX and YY implement the second listener mode, after the user touch screen (the current user triggers CCLayout of XX and YY instances) first, it will enter the ccTouchBegan function in XX or YY. If it first enters the XX class, the ccTouchBegan in XX class will be responded, if return true; indicates that the user's touch screen message is no longer transmitted to the YY class for response, that is, the user does not respond to the ccTouchBegan function in the YY class, if return false; the current touch screen information will be passed to other registered types;
In a word, the return value indicates that the user's touch event has been processed, and the other event will not be listened on again. If it is false, it will be handed over to other registered types for processing;

The second method of listening is more commonly used to facilitate processing. As for registration, it is generally placed in the onEnter function. The onEnter function is a function that will be responded to during switching between CCScene, the call sequence is as follows:

Oc code
// When [ccdirereplreplacescene: XX] is used to replace a scenario, the following three methods are called:
// The call sequence is as follows:
// 1. + (id) Scene of othterScene -->
// 2. init of otherScene -->
// 3. otherScene onEnter -->
// 4. Running transition effect
// 5. The onExit function of the current Scene -->
// 6. onEnterTransitionDidFinish () of otherLayout ()
// 7. dealoc function of the current Scene
-(Void) onEnter {
// This method will be called after other Scene init methods are called
// If CCTransitionScene is used, this method will be called after the transition effect starts.
// (If you do not call super onEnter, there may be no issue to the touch or accelerator)
[Super onEnter];
}
-(Void) onEnterTransitionDidFinish {
// This function will be called after onEnter is called
// If CCTransitionScene is used, this method is called when the transition effect is complete.
[Super onEnterTransitionDidFinish];
}
-(Void) onExit {
// This function is called before dealloc is called;
// If CCTransitionScene is used, this method will be called after the transition effect ends.
// (If super onExit is not called, the current scenario may not be released from the memory)
[Super onExit];
}


After introducing the monitoring event, the most important thing on the touch screen should be multiple contacts;

Oc code
// ----- Obtain multi-point touch
NSSet * allTouches = [event allTouches];
UITouch * touchOne = [[allTouches allObjects] objectAtIndex: 0];
UITouch * touchTwo = [[allTouches allObjects] objectAtIndex: 1];
//... And so on


It is easy to get multiple points, so we will write down several common judgments below:
1-determine whether the user clicks or double-click (for a contact)

Oc code
If ([allTouches count] = 1 ){
UITouch * touchOne = [[allTouches allObjects] objectAtIndex: 0];
Switch ([touchOne tapCount]) {
Case 1:
// Click
CCLOG (@ "% @", @ "click ");
Break;
Case 2:
// Double-click
CCLOG (@ "% @", @ "double-click ");
Break;
}
}


1-determine whether the user's two contacts are closed or separated (for two contacts)
Oc code
If ([allTouches count] = 2 ){
// Modify and handle the modification as appropriate. The operation cannot be obtained at the same time. Otherwise, it must be the same (one can be obtained at the beginning and the other can be obtained at the end)
UITouch * touchOne = [[allTouches allObjects] objectAtIndex: 0];
UITouch * touchTwo = [[allTouches allObjects] objectAtIndex: 1];
CGFloat * disFirst = [self distance: [touchOne locationInView: [self view]
Todistance: [touchTwo locationInView: [self view];

UITouch * touchOne = [[allTouches allObjects] objectAtIndex: 0];
UITouch * touchTwo = [[allTouches allObjects] objectAtIndex: 1];
CGFloat * disFinal = [self distance: [touchOne locationInView: [self view]
Todistance: [touchTwo locationInView: [self view];
If (disFirst> disFinal ){
CCLOG (@ "% @", @ "");
} Else {
CCLOG (@ "% @", @ "separate ");
}
}


Here I will roughly write it together to determine whether the two contacts are combined. In fact, when the user just clicked the screen, he recorded the distance between the two points as disFirst, and then left the screen (or moved the event) at the two contacts) computing
The distance between the current two contacts is disFinal. The distance between disFirst and disFinal can be used to determine whether to combine or separate them;
(CCLOG is a cocos2d packaging printing method. This type of printing will not be compiled into the program during compilation and release of the official game program, but NSLOG will always exist! Note !)
Finally, two functions are provided to obtain (convert) coordinates in functions monitored in different ways. cocos2d is a framework built by openGL, so coordinate conversion is required;

Oc code
+ (CGPoint) locationFromTouches :( NSSet *) touches
{
Return [self locationFromTouch: [touches anyObject];
}
+ (CGPoint) locationFromTouch :( UITouch *) touch
{
CGPoint touchLocation = [touch locationInView: [touch view];
Return [[CCDirector shareddire] convertToGL: touchLocation];
}


You can see the difference between the two methods. One is UITouch, the other is NSSet, the other is single listener, and the other is distribution listener;

Author "Arctic"
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.