views:

59

answers:

3

enough is enough.

like the title says, I'm in a bit of a pickle.

so here's the outline of my problem. I have this ship right. It rests in the center bottom of the screen (240,0). When the user touches to the right at a point greater than 240 the ship moves right. And left if the user touches at a point less than 240. HOWEVER this is great when there's only one finger on the screen at a time. I need it to where if the user touches right, doesn't lift their finger, then touches left (OH CRAP THERE'S TWO FINGERS ON THE SCREEN) the ship keeps moving right until they lift their right finger, then suddenly the ship moves left towards the second touch.

I'm using timers to add/subtract a number from the current x coordinate to get it to move.

This is what I have in a nutshell: (Don't laugh or hate I'm a noob)

-(void)moveShipLeft:(id)sender {

 shipView.center = CGPointMake(shipView.center.x - 2, 320 - (shipView.image.size.height / 2));

}
-(void)moveShipRight:(id)sender { 

 shipView.center = CGPointMake(shipView.center.x + 2, 320 - (shipView.image.size.height / 2));

}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

 UITouch *touch = [[event allTouches] anyObject];
 CGPoint location = [touch locationInView:touch.view];

 if (240 < location.x){rightTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(moveShipRight:) userInfo:nil repeats:YES];}
 if (240 > location.x){leftTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(moveShipLeft:) userInfo:nil repeats:YES];}

 [shipView setCenter:shipView.center];
 }
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {


  if (rightTimer != nil)               //Kill the timer that goes right upon touch removal
   [rightTimer invalidate];
  rightTimer = nil;

  if (leftTimer != nil)                //Kill the timer that goes left on touch removal
   [leftTimer invalidate];
  leftTimer = nil;
}

I'm trying to fully replicate the controls for the game "Radiant" if its any help. I will seriously love you forever if you help.

Just to clarify, I want this to happen:

  1. user touches the right side of screen
  2. ship moves right
  3. user touches left side of screen with second finger
  4. while the ship is still moving right because the user hasn't lifted their first touch, the user then lifts the first touch
  5. THEN the ship instantly changes course to move left towards the second touch

right now I have multi touch enabled, so now it works like this:

  1. user touches the right side of screen
  2. ship moves right
  3. user touches left side of screen with second finger
  4. ship moves left then user lift first touch
  5. ship is stopped in its tracks even though the user hasn't lifted the second touch
A: 

Each UITouch is unique from the time the user starts touching until they stop. So your problem is really this line:

 UITouch *touch = [[event allTouches] anyObject];

You don't want just any touch. You want a touch that is the same touch you've been moving toward, if it exists. Look for that touch in the set, and if it's not there start moving towards another touch.

Kendall Helmstetter Gelner
A: 

First off, about not activating the leftTimer if the rightTouch is not released.

You could set up two Global Touches. So, if [touch locationInView:self.view] position blah is > 250 globalRightTouch = touch. Same for left.

THen when you hit the right side - you assign the touch to the global Right, and the ship starts to move right -- then you touch the left side simultaneously -- so another touches began thing starts - so you assign it to the globalLeftTouch. Then you can go something like: if(!globalRightTouch){start leftTimer) and vise versa.

In your touhcesEnded function - you are telling the leftTimer to kill if it is not null on touches end - so even if you have your left touch down still -- you are telling both timers to kill on any touch release. You just need to be a little more specific with your touches ended.

Then in your touches ended code you need to go something along the following:

  UITouch *touch = [[event allTouches] anyObject];

  if (rightTimer != nil && touch == globalRightTouch){               //Kill the timer that goes right upon touch removal
   [rightTimer invalidate];
  rightTimer = nil;
   if(globalLeftTouch)
     leftTimerStartFunction //I dont know what your variables are sorry
  }

  if (leftTimer != nil && touch == globalLeftTouch){                //Kill the timer that goes left on touch removal
   [leftTimer invalidate];
  leftTimer = nil;
   if(globalRightTouch){
      rightTimerStartFunction //I dont know what you variables are sorry
   }
 }
}

so essentially you want to say - If I let go of a touch - check which one it is and kill the timer for that touch if it is not null and if there is another touch currently on the screen - start the timer for that side.

Hope this helps,

Cheers,

Michael

Michael O'Brien
thanks, I'm pretty sure this would work. I just kinda worked this through my head and it seemed okay. So what exactly would I put in my touches began. I think I have an idea but it's not working the way I want. Thanks a lot for your help I greatly appreciate it ^_^
Anonymous
I guess if it makes it any easier the ship doesn't have to go towards the second touch until the user lifts their first touch
Anonymous
no problemos, hope it all works out for you :)
Michael O'Brien
no wait I still need your help constructing what goes in my touches began. kind of rephrase what you said a little better
Anonymous
so I got this:- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {UITouch *touch = [touches anyObject];CGPoint locationmoved = [touch locationInView:touch.view];if(locationmoved.x < 240){globalRightTouch = touch;}if (locationmoved.x > 240){globalLeftTouch = touch;}if(!globalRightTouch){//rightTimer}if(!globalLeftTouch){//leftTimer}[shipView setCenter:shipView.center];} BUT IT DOESNT WORK. in the simulator it works ONLy for the first touch, any touch after that the ship doesn't budge
Anonymous
lol copy and paste that code into word, sorry it doesn't show up right
Anonymous
IM adding this as an answer so you can read it better :)
Michael O'Brien
A: 

Here is a real/pseudo code version - hope it helps...

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)even{
UITouch *touch = [touches anyObject];

if(touch.x < 240){
    globalTouchLeft = touch;
    if(!globalTouchRight){
        startLeftTimer; //again I don't know what your timere/variable is
    }
}else if(touch.x  >= 240){

    globalTouchRight = touch;
    if(!globalTouchLeft){
        startRightTimer; //again I don't know what your timere/variable is
    }

    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    if(touch == globalLeftTouch){
        stopLeftTimer
        globalLeftTouch = nil;

        if(globalRightTouch){
            startRightTimer;
        }

    }

    if(touch == globalTouchRight){
        stopRightTimer
        globalRightTouch = nil;

        if(globalLeftTouch){
            startLeftTimer;
        }
    }
}

cheers,

Michael O'Brien

Michael O'Brien
alright! thanks man, I think I got it!
Anonymous