2010-03-16 26 views
5

He creado un UIScrollView en una aplicación cocos2d. Estoy agregando sprites dinámicamente, más de 3 páginas. En la primera página, tocar funciona perfectamente en un sprite, sin embargo, si utilizo la vista de desplazamiento y navego a la segunda página, tocar no funciona del todo bien ... el sprite responderá al tacto cuando toque la pantalla, aproximadamente el cantidad que he desplazado hacia la izquierda. Si me desplazo hacia atrás a la primera página, tocar funciona perfectamente para un sprite. ¿Algunas ideas? Estoy utilizando el siguiente tutorial: http://getsetgames.com/2009/08/21/cocos2d-and-uiscrollview/ :)UIScrollView y Cocos2D


Creo que algo de código podría ser útil: -

Estoy utilizando el código exacto de su demostración ...

CocosOverlayScrollView y CocosOverlayViewController

estoy creando el CocosOverlayViewController en mi capa de: -

CocosOverlayViewController *scrollView = [CocosOverlayViewController alloc]; 
[[[Director sharedDirector] openGLView] addSubview:scrollView.view]; 

estoy creando la capa en mi escena: -

Scene *scene = [Scene node]; 
GridLayer *layer = [GridLayer node]; 
[scene addChild: layer z:-1]; 
[scene setTag:12]; 

Estoy creando los sprites en mi capa de: -

myImage.position = ccp(53 * (coordinate.x + 0.52), 57 * (coordinate.y + 1.45)); 
    [myImage runAction:[FadeIn actionWithDuration:0.3]]; 
    myImage.relativeAnchorPoint = YES; 
    [self addChild:myImage z:-1]; 

El sprite está utilizando el TouchesDispatcher y los detalles son resuelto en la clase.

Si utilizo la función moveto cocos2d en la capa, puedo tocar un sprite y responde, así sé que funciona, las cosas se ponen un poco raras cuando uso UIScrollView.

espero que entiendan mi problema y puede ayudar, todo lo mejor :)

Carl

+0

¡Hola Carl, estás hablando con el tipo que escribió ese artículo! Me alegro de que lo haya encontrado y espero que haya comenzado bien con las cosas. En cuanto a su problema, parece que está utilizando una instancia de desplazamiento de página paginada, ¿verdad? No escribí el artículo teniendo en cuenta ese caso, pero estoy seguro de que podemos resolverlo –

+0

Estoy utilizando una vista de desplazamiento de página, pero mi aplicación no depende de eso, así que puedo eliminarla. No creo haberlo explicado muy bien antes, el evento táctil funciona perfectamente en la primera 'página', pero cuando me desplazo (aunque sea un poco) el sprite se mueve pero el evento táctil aún responde a la posición anterior de los sprites. ¿Algunas ideas? – Carl

+1

Creé un proyecto de muestra usando Cocos2d y UIScrollView y publiqué un enlace en los foros de cocos2d: http://www.cocos2d-iphone.org/forum/topic/9417 –

Respuesta

10

por fin llegué a la implementación de un desplazamiento CCLayer mediante el uso de una clase derivada UIScrollView, siguiendo los tutoriales mencionados en este pregunta:

Ambos son una lectura excelente, y muy recomendables para obtener una comprensión más profunda sobre cómo UIScrollViews (y UIViews en general) pueden hacerse para manejar toques en cooperación con Cocos2D.

Sin embargo, al implementar estas soluciones, también experimenté el error descrito en la pregunta: si no se desplaza, los toques se propagan correctamente desde el UIScrollView al CCLayer. Si se desplaza, la capa se desplaza bellamente, pero los toques sin desplazamiento en UIScrollView se propagan al CCLayer con un desplazamiento que aumenta cuanto más se desplaza, lo que hace que el CCLayer (y/o el CCMenus que lo acompaña) no se pueda utilizar.

He encontrado que la causa de este problema es un error en cómo Cocos2D traduce los toques enviados a OpenGLView a los sistemas de coordenadas locales CCNode o CCMenu. Este error está presente en 1.0 RC, y sólo afecta a los toques que se generan en la subvista de un OpenGLView (como nuestro UIScrollView) y ser propagado a la zona sensible al tacto principal Cocos2D (a saber, la OpenGLView) llamando a la línea siguiente en el interior -touchesBegan del UIScrollView: Método

[[[CCDirector sharedDirector] openGLView] touchesBegan:touches withEvent:event]; 

(Tenga en cuenta que llamar a esta línea anterior es suficiente para propagar nonscrolling y nonzooming toques de la UIScrollView a Cocos2D, no es necesario llamar a nextResponder: como las entradas del blog antes mencionados hacen.)

la solución viene con una pequeña modificación en dos fuentes de Cocos2D:

CCNode.m

- (CGPoint)convertTouchToNodeSpace:(UITouch *)touch { 
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView). 
    // CGPoint point = [touch locationInView: [touch view]]; 
    CGPoint point = [touch locationInView: [[CCDirector sharedDirector] openGLView]]; 
    point = [[CCDirector sharedDirector] convertToGL: point]; 
    return [self convertToNodeSpace:point]; 
} 

- (CGPoint)convertTouchToNodeSpaceAR:(UITouch *)touch { 
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView). 
    // CGPoint point = [touch locationInView: [touch view]]; 
    CGPoint point = [touch locationInView: [[CCDirector sharedDirector] openGLView]]; 
    point = [[CCDirector sharedDirector] convertToGL: point]; 
    return [self convertToNodeSpaceAR:point]; 
} 

CCMenu.m

-(CCMenuItem *) itemForTouch: (UITouch *) touch { 
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView). 
    // CGPoint touchLocation = [touch locationInView: [touch view]]; 
    CGPoint touchLocation = [touch locationInView: [[CCDirector sharedDirector] openGLView]]; 
    touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation]; 
    ... 

La clave aquí es locationInView de UITouch: método. El argumento para este método debería ser el UIView en el que desea traducir las coordenadas de los toques. La mayoría del proyecto Cocos2D solo tiene una UIView: la OpenGLView, por lo que los toques se generan en OpenGLView (= vista táctil) y se traducen a la misma vista. Sin embargo, si agrega superposiciones para recibir toques, como UIScrollView, 'touch view' tendrá este valor, que ya no corresponde con el OpenGLView deseado.

+1

Solo quería señalar que el segundo archivo para editar es CCMenu.m y no CCLayer.m ;-) – fedmest

+0

¡Gracias! Fijo. –

+0

Creo que hice esta revisión de forma independiente, ya que también estaba usando UIScrollView y EAGLView. –