Skip to content

Commit 7c06c44

Browse files
committed
Improved Android scrolling (touches are cancelled whenever a gesture is recognized).
1 parent 3e4ec16 commit 7c06c44

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

cocos2d-ui/CCScrollView.m

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
#pragma mark -
6262
#pragma mark Helper classes
6363

64-
6564
#if __CC_PLATFORM_IOS
6665
@interface CCTapDownGestureRecognizer : UIGestureRecognizer
6766
@end
@@ -172,6 +171,7 @@ @implementation CCScrollView {
172171
#elif __CC_PLATFORM_ANDROID
173172
CCGestureListener *_listener;
174173
AndroidGestureDetector *_detector;
174+
CGPoint _rawScrollTranslation;
175175
#endif
176176
}
177177

@@ -355,6 +355,8 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
355355
newPos.x = MAX(MIN(newPos.x, self.maxScrollX), self.minScrollX);
356356
newPos.y = MAX(MIN(newPos.y, self.maxScrollY), self.minScrollY);
357357

358+
[self updateAndroidScrollTranslation:newPos];
359+
358360
BOOL xMoved = (newPos.x != self.scrollPosition.x);
359361
BOOL yMoved = (newPos.y != self.scrollPosition.y);
360362

@@ -409,6 +411,14 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
409411
}
410412
}
411413

414+
- (void)updateAndroidScrollTranslation:(CGPoint)worldPosition
415+
{
416+
#if __CC_PLATFORM_ANDROID
417+
_rawScrollTranslation = [self convertToWindowSpace:worldPosition];
418+
#endif
419+
}
420+
421+
412422
- (void) xAnimationDone
413423
{
414424
_animatingX = NO;
@@ -492,6 +502,8 @@ - (void) update:(CCTime)df
492502

493503
_contentNode.position = ccpAdd(_contentNode.position, delta);
494504

505+
[self updateAndroidScrollTranslation:CGPointMake(_contentNode.position.x, _contentNode.position.y * -1)];
506+
495507
// Deaccelerate layer
496508
float deaccelerationX = kCCScrollViewDeacceleration;
497509
float deaccelerationY = kCCScrollViewDeacceleration;
@@ -820,24 +832,23 @@ - (BOOL)onScroll:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end dista
820832
_velocity = CGPointZero;
821833

822834
// Note about start and end events: We will get a CCTouchPhaseBegan for the start event, followed by CCTouchPhaseMoved in the end event
823-
static CGPoint rawTranslation;
824835
CCTouchPhase phase = [self handleGestureEvent:start end:end];
825836

826837
if(phase == CCTouchPhaseCancelled || phase == CCTouchPhaseEnded)
827-
rawTranslation = CGPointMake(0.0f, 0.0f);
838+
_rawScrollTranslation = CGPointMake(0.0f, 0.0f);
828839

829840
float scaleFactor = [[CCDirector sharedDirector] view].contentScaleFactor;
830841

831842
dx /= scaleFactor;
832843
dy /= scaleFactor;
833844

834-
rawTranslation.x += dx;
835-
rawTranslation.y -= dy;
845+
_rawScrollTranslation.x += dx;
846+
_rawScrollTranslation.y -= dy;
836847

837848
CCDirector* dir = [CCDirector sharedDirector];
838849
[[CCActivity currentActivity] runOnGameThread:^{
839850

840-
CGPoint translation = [dir convertToGL:rawTranslation];
851+
CGPoint translation = [dir convertToGL:_rawScrollTranslation];
841852
translation = [self convertToNodeSpace:translation];
842853

843854
if (phase == CCTouchPhaseBegan)
@@ -868,6 +879,7 @@ - (BOOL)onScroll:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end dista
868879

869880
// Update position
870881
[self panLayerToTarget:newPos];
882+
871883
}
872884
else if (phase == CCTouchPhaseEnded)
873885
{
@@ -891,7 +903,7 @@ - (BOOL)onFling:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end veloci
891903
static CGPoint rawTranslationFling;
892904

893905
CCTouchPhase phase = [self handleGestureEvent:start end:end];
894-
906+
895907
if(phase == CCTouchPhaseCancelled || phase == CCTouchPhaseEnded)
896908
rawTranslationFling = CGPointMake(0.0f, 0.0f);
897909

cocos2d/CCNode.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,16 @@ A common user pattern in building a Cocos2d game is to subclass CCNode, add it t
615615
*/
616616
- (CGPoint)convertToWorldSpaceAR:(CGPoint)nodePoint;
617617

618+
/**
619+
* Converts a local Point to Window space coordinates.The result is in Points.
620+
* Treats the returned/received node point as anchor relative.
621+
*
622+
* @param nodePoint Local position in points.
623+
*
624+
* @return UI position in points.
625+
*/
626+
- (CGPoint)convertToWindowSpace:(CGPoint)nodePoint;
627+
618628

619629
/// -----------------------------------------------------------------------
620630
/// @name Rendering (Used by Subclasses)

cocos2d/Platforms/Android/CCGLView.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ - (BOOL)onTouchEvent:(AndroidMotionEvent *)event
6767
{
6868
assert(pthread_main_np());
6969
@autoreleasepool {
70+
BOOL cancelTouch = NO;
7071
for (AndroidGestureDetector *detector in _gestureDetectors) {
71-
[detector onTouchEvent:event];
72+
cancelTouch = [detector onTouchEvent:event];
7273
}
7374

75+
7476
static dispatch_once_t once = 0L;
7577
dispatch_once(&once, ^{
7678
touches = [[NSMutableDictionary alloc] init];
@@ -98,6 +100,9 @@ - (BOOL)onTouchEvent:(AndroidMotionEvent *)event
98100
return NO;
99101
}
100102

103+
if(cancelTouch)
104+
phase = CCTouchPhaseCancelled;
105+
101106
NSTimeInterval timestamp = event.eventTime * 1000.0;
102107
currentEvent.timestamp = timestamp;
103108
NSMutableSet *eventTouches = [NSMutableSet set];

0 commit comments

Comments
 (0)