I have a code that set's a bow's angle according to where you have touched the screen.
a simple "bow.rotation = X" command is performed on the ccTouchesMoved event.
the problem is, that while running the code on 0.7.1 of cocos2d against 0.9 or 0.8.2
it worked way better, in 0.9 and 0.8.2 it seems like it skippes some of the touchesmove event... what could it be?
heres the code...:
-(BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
if(player.state == StateNotPrepared) {
if(CGRectContainsPoint(spriteToRect(fireButton), location)) {
[player prepareShot];
[powerMeter resetBar];
[powerMeter startLoadingBar];
} else {
float newAngle = [player angleByTouchPoint: location];
[self setAngles: newAngle];
}
}
return kEventHandled;
}
-(BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
if(player.state == StateNotPrepared || player.state == StatePrepared) {
if( !CGRectContainsPoint(spriteToRect(fireButton), location) ) {
float newAngle = [player angleByTouchPoint: location];
[self setAngles: newAngle];
}
}
return kEventHandled;
}
This may be related to the type of director used vs. the OS of the device. Try the different directors and see if you get different behavior.
[Director setDirectorType:XXXX];
Where XXXX is one of:
CCDirectorTypeNSTimer (default)
CCDirectorTypeMainLoop
CCDirectorTypeThreadMainLoop
CCDirectorTypeDisplayLink
I know that some people have reported issues with the DisplayLink director (though that's generally ideal otherwise when available).
Related
I understand the basics of how multi-touch Event works
When a figer touches the view/screen that view will receive ccTouchesBegan with a set of UITouch.
UITouch will hold the location (CGPoint) and its unique for each finger.
If more than one finger touches the view at the same time , 2 UITouch will be send to the view.
Sometime view will receive ccTouchesBegan with 2 UITouch's or ccTouchesBegan will be called twise for each finger touch one after another.
If finger1 is moving view will receive ccTouchesMoved with one UITouch.
My question is how to draw lines with each finger touch seperately , put the 1 or 2 fingers on the screen and draw line for each finger touch began/moved/end?
The below code works when there is only single touch but for multi touch it wont work because of the above point 3 and 4.
Exactly like this
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
[[temEdge1 start] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
[[temEdge2 start] updateXY:touchLocation2];
}
}
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
}
}
}
-(void)draw
{
[super draw];
glLineWidth(5.f);
ccDrawColor4B(0, 0, 255, 255);
for (Edge *temEdge in temEdges) {
CGPoint start = [[temEdge start] toCCP];
CGPoint end = [[temEdge end] toCCP];
ccDrawLine(start , end);
}
}
You can try to associate arrays of touch positions with different touches(something like NSDictionary with UITouches as keys and NSArrays of points as values). Then you can draw these lines using ccDrawLine or any other way if your draw method. Just do not forget to store these arrays somwhere where current touch ends.
I am loading a menu in which i have 7 layers through which i swipe. On first load the swiping is smooth at 60fps, but i then pop the scene and push it again, the swiping is very slow, though the app displays 60fps, and the ccTouchesMoved is called roughly at the same interval as on the first load.
On each layer, i add some statical CCSprites and a CCMenu.
All items are deallocated, and i am testing the app on ipad 3 (so speed isn't quite an issue).
I presume that the cause is more on the settings part and would like to find a solution for it. Here are my touch methods, if it helps:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 1
firstTouch = location;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGSize winSize = [[CCDirector sharedDirector] winSize];
for(int i=0;i<[layerList count];i++)
{
[[layerList objectAtIndex:i] setPosition:CGPointMake((i-currentLayer)*winSize.width + (location.x - firstTouch.x),0) ];
}
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 2
lastTouch = location;
//Swipe Detection Part 2
lastTouch = location;
//Minimum length of the swipe
float swipeLength = ccpDistance(firstTouch, lastTouch);
//Check if the swipe is a left swipe and long enough
if (firstTouch.x > lastTouch.x && swipeLength > 60) {
[self doStuffLeft];
}
else if (firstTouch.x < lastTouch.x && abs(swipeLength) > 60) {
[self doStuffRight];
}
}
Figured it out, [CCDirector sharedInstance] was paused.
Im trying to get my sprite to move on touch but seems to disappear on touch then reappear on second touch . I do not know how to fix this to get my sprite to move at the direction I tap. I have been trying to figure this out for a while but seems I am out of luck. I am hoping someone can point me at the right direction.
CGSize winSize = [[CCDirector sharedDirector] winSize];
player = [CCSprite spriteWithFile:#"Player.png"
rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player z:1];
(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
-(void)setPlayerPosition:(CGPoint)position {
player.position = position;
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
CGPoint playerPos = player.position;
CGPoint diff = ccpSub(touchLocation, playerPos);
if (abs(diff.x) > abs(diff.y)) {
if (diff.x > 0) {
playerPos.x += contentSize_.width;
} else {
playerPos.x -= contentSize_.width;
}
} else {
if (diff.y > 0) {
playerPos.y += contentSize_.height;
} else {
playerPos.y -= contentSize_.height;
}
}
The syntax of your touch function seems to be different.
try this code instead
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
CGPoint playerPos = player.position;
}
my code:
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
//Add a new body/atlas sprite at the touched location
for( UITouch *touch in touches ) {
CGPoint touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
[self setPosition: ccpAdd(self.position, diff)];
}
}
This code lets me move the layer with my fingers. That works fine. But now I want to let the user only move the layer within a predefined CGRect. How to do that?
For example:
CGRect rect = CGRectMake(0,0,600,320);
Now the player should be only allowed to move the layer within this rect. In that example he could only move it (on an ipod touch) to the left and right. (till 600px).
What do I need to change to achieve that?
Thank you for any help.
Have a nice day :)
Keep a variable to check.. eg..
distmoved = distmoved + touchlocation.x - prevlocation.x;
if(distmoved<600)
//move code
note that distmoved is a float..
You should make your own check. It's not hard in your case:
[self setPosition: ccpAdd(self.position, diff)];
if (self.position.x < minX)
{
//correct x position
}
if (...)
// ...
// ans so on
so I got this working:
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for( UITouch *touch in touches ) {
CGPoint touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
[self setPosition: ccpAdd(self.position, diff)];
}
}
I can move the layer with my finger BUT i want to move the cccamera but i don't have any experience with cccamera.
Can anyone help me?
Thank you very much
Have a nice day
:)
Here's what I'm using... this implementation of moving the camera is something I found on the cocos2d forums.
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for( UITouch *touch in touches ) {
CGPoint touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
[self setPosition: ccpAdd(self.position, diff)];
// Get the camera's current values.
float centerX, centerY, centerZ;
float eyeX, eyeY, eyeZ;
[self.camera centerX:¢erX centerY:¢erY centerZ:¢erZ];
[self.camera eyeX:&eyeX eyeY:&eyeY eyeZ:&eyeZ];
// Increment panning value based on current zoom factor.
diff.x = 2 * diff.x * (1+(eyeZ/832));
diff.y = 2 * diff.y * (1+(eyeZ/832));
// Round values to avoid subpixeling.
int newX = centerX-round(diff.x);
int newY = centerY-round(diff.y);
// Set values.
[self.camera setCenterX:newX centerY:newY centerZ:0];
[self.camera setEyeX:newX eyeY:newY eyeZ:eyeZ];
}
}