In the previous article, we introduced how to add a touch listener to your custom ccsprite, but you will find that our genie will receive a touch event no matter where you click the screen. Why, cctouchdispatcher only distributes touch events. Therefore, each cctouchdelegate added to cctouchdispatcher is a layer of screen size, this is also why we can accept touch listening when we click outside the layer. In any case, this is what we don't want to see. In fact, here the cocos2dx source code has provided a solution, that is, ccmenu, look at its source code, you will find that it is done to determine the touch area operation. We will do the same here. The Code is as follows:
Bool testsprite: isinsprite (cctouch * thetouch ){
// Returns the OpenGL coordinates of the current touch position.
Ccpoint touchpoint = thetouch-> getlocation ();
// Convert the world coordinates to the local coordinate system of the current parent view.
Ccpoint reallypoint = This-> getparent ()-> converttonodespace (touchpoint );
// Obtain the current Coordinate System Based on the parent View
Ccrect rect = This-> boundingbox ();
// Ccnode-> converttonodespace or converttoworldspace is related to the current node based on the current node
If (rect. containspoint (reallypoint )){
Return true;
}
Returnfalse;
}
In this way, we can see if we click our Genie. Next we will judge double-click. The Code is as follows:
// Obtain the current time precise to the number of milliseconds
Static inline long millisecondnow ()
{
Struct cc_timeval now;
Cctime: gettimeofdaycocos2d (& now, null );
Return (now. TV _sec * 1000 + now. TV _usec/1000 );
}
// Double-click or not
Static inline bool isdoubletouch (){
Static long lasttouchtime = 0;
Long thistouchtime = millisecondnow ();
If (ABS (thistouchtime-lasttouchtime) <250 ){
Lasttouchtime = 0;
Return true;
}
Else {
Lasttouchtime = millisecondnow ();
Return false;
}
}
It is simply the interval between two clicks. If it is less than 250mm, double-click the button. We have solved the problem of standalone, so now we have a long press. Changan is actually very simple. If your touch time is longer than two seconds, we will calculate it as a long press. Or not to mention, on the code
Void testsprite: checklongpress (){
This-> unschedule (schedule_selector (testsprite: checklongpress ));
If (isintouch &&! Isinmove ){
Cclog ("Longlong ");
This-> setscale (2 );
This-> setopacity (200 );
Afterlongpress = true;
}
}
Bool testsprite: cctouchbegan (cctouch * ptouch, ccevent * pevent ){
If (this-> isinsprite (ptouch )){
Isintouch = true;
If (isdoubletouch ()){
This-> doubleclicksprite ();
This-> touchbegintime = millisecondnow ();
} Else {
This-> singleclicksprite ();
This-> touchbegintime = millisecondnow ();
This-> schedule (schedule_selector (testsprite: checklongpress), 2 );
}
Return true;
}
Returnfalse;
}
Void testsprite: cctouchmoved (cctouch * ptouch, ccevent * pevent ){
Ccpoint deltapoint = ptouch-> getdelta ();
Cclog ("x = % F, y = % F", deltapoint. X, deltapoint. y );
If (FABS (deltapoint. X)> 1 | FABS (deltapoint. Y)> 1 ){
Isinmove = true;
}
}
Void testsprite: cctouchended (cctouch * ptouch, ccevent * pevent ){
Isintouch = false;
Isinmove = false;
Afterlongpress = false;
// Restore the genie
This-> setscale (1 );
This-> setposition (orignalpoint );
This-> setopacity (255 );
}
Void testsprite: cctouchcancelled (cctouch * ptouch, ccevent * pevent ){
Isintouch = false;
Isinmove = false;
Afterlongpress = false;
// Restore the genie
This-> setscale (1 );
This-> setposition (orignalpoint );
This-> setopacity (255 );
}
Of course, we also made a simple judgment here. If the touch has never been moved for more than two seconds, we would be able to make a long press.