This works fine on iOS. But on Android devices I found that the scene does not update until all touch events are processed. So if I continuously move finger around then it will never update, even if I call refreshDisplay() after each move event. I am testing on a recent ASUS tablet. So it should not be due to slow hardware since the same code is fast enough on iPhone 4. Has anyone seen this issue before?
Sorry I forgot refreshDisplay() is my own function. It has only one line:
CCDirector::sharedDirector()->drawScene();
I am using cocos2d-x 2.2. I traced into code, and looks like it draws immediately, not deferring to next loop. But I don’t understand why it works only on iOS.
Not sure if it’s related, but I noticed that on iOS everything runs in main thread. On Android, all display and touch event related code runs in a separate game loop thread.
A bit of background information. My app is not a game, it’s a photo processing app. When user touches on the picture, I draw circles/lines to a CCRenderTexture, then . The drawing is CPU intensive on large pictures, so I drop the frame rate to low number, and call drawScene() after each touch move event. Thanks for looking into this issue, I appreciate it.
The delegate is on my derived CCScene object:
class PMBlenderScene: public CCScene, public CCTouchDelegate;
void PMBlenderScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
_brush.rotation = _deviceOrientation.getDeviceOrientation();
// Keep a list of all active touches to support multi-touch gestures (zoom, rotate etc.)
for (CCSetIterator iterator = pTouches->begin(); iterator != pTouches->end(); ++ iterator) {
if (*iterator) {
CCTouch * touch = static_cast(*iterator);
_activeTouches.insert(touch);
}
}
updateTouchState();
}
void PMBlenderScene::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
for (CCSetIterator iterator = pTouches->begin(); iterator != pTouches->end(); ++ iterator) {
if (*iterator) {
CCTouch * touch = static_cast(*iterator);
_activeTouches.erase(touch);
}
}
updateTouchState();
}
void PMBlenderScene::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
// Removed a few lines of multi touch handling code that's not called in this scenario.
CCTouch * touch = *_activeTouches.begin();
CCPoint location = touch->getLocation();
showCursor(location);
if (location.x != _previousTouchLocation.x || location.y != _previousTouchLocation.y) {
// this _renderTexture was used to initialize a CCSprite which is a child node in this scene.
_brush.drawLineOnRenderTexture(_renderTexture,
convertToRenderContextSpace(_previousTouchLocation),
convertToRenderContextSpace(location));
_previousTouchLocation = location;
}
refreshDisplay();
}
}
void PMBlenderScene::refreshDisplay()
{
CCDirector::sharedDirector()->drawScene();
}