views:

39

answers:

1

Hi,

So, I am trying to recreate one of those "virtual joysticks" on some of those iPhone games. And basically, heres the problem I can make sure that the user is touching the circle (that is the "virtual joystick") and I can also move the thing around (or at least was able to move it around because since then I have messed around with it). But, I can not give it a range.

What the heck do I mean by a range?

Let me, hopefully, explain correctly what I mean a range is. So when messing with an actual joystick on something like a Playstation controller, you can obviously not drag it everywhere like I could with that circle i was describing. So, it has a range which is anywhere within an imaginary circle that you cannot see.

I have tried the following:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint currentPosition = [touch locationInView:self.view];
    if (g == true) {
        if (joystick.center.x > 330 && currentPosition.x > 330 || joystick.center.x < 130 && currentPosition.x < 130) {
            joystick.center = CGPointMake(joystick.center.x, currentPosition.y);
            j = true;
        }
        if (joystick.center.y > 508 && currentPosition.y > 508 || joystick.center.y < 308 && currentPosition.y < 308) {
            joystick.center = CGPointMake(currentPosition.x, joystick.center.y);
            j = true;
        }
        if (j == false) {
            joystick.center = CGPointMake(currentPosition.x, currentPosition.y);
        }
    }
}

One note before I begin explain what my logic for my attempt was, the joystick is located on the screen at (230, 408) and I didn't do anything to the coordinate system (so its based off the top left hand corner). Now, let me explain what this is supposedly doing:

  1. Well first I get the coordinates of the touch with the first two lines of code in the method.
  2. Then if (g == true) actually has to do if the touch is on the circle or not and is set by touchesBegan.
  3. Then the second if is checking if the joystick's x location is greater than 330 or less then 130 which will give the radius of the imaginary range that is a circle. Also, note the additional && currentPosition.x > 330 and currentPosition.x < 130 this is for if the person is moving the virtual joystick back toward the center since you don't want the user from no being able to do so.
  4. The else if does the same as 3 except for the y direction.
  5. For the final if uses a bool j to determine if the other two`if statements have been executed.

This plan doesn't work obviously, or else I wouldn't be asking for your help, so do you perchance know what I am doing wrong?

A: 
  1. In case the user moves the touch beyond your range you should be setting the center of the joystick to the original center position, (probably 230, 408), i dont see that being done anywhere in your code.

  2. It is ok if you don't set anything in touches began, as you want to move the joystick only in if the touch is moved. Just check [touch view] == joystick in touches moved.

  3. You don't need to check for x and y separately as moving the joystick beyond the range in any direction should bring it back to the center.

  4. You need to animate the motion of the joystick returning to the original center else it wont look good.

So, have the original center as a constant CGPoint. And in touches moved check for the distance between this center and the touch location. If it is beyond a range animate the joystick back to that original center.

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

    //self.joyStickCenter is the defined original center CGPoint.

    if ([touch view] == self.joystickImageView) {
        CGPoint location = [touch locationInView:self.view];

        if((fabs(location.x - self.joyStickCenter.x) < 15.0) && (fabs(location.y - self.joyStickCenter.y) < 15.0)) {
            [self.joystickImageView setCenter:location];

            //your joystick action code         

            return;
        }
        else if((fabs(location.x - self.joyStickCenter.x) > 40.0) || (fabs(location.y - self.joyStickCenter.y) > 40.0)) {
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.25f];
            [self.joystickImageView setCenter:self.joyStickCenter];
            [UIView commitAnimations];
            return;
        }
    }
}
lukya
Thanks, it took a little messing around but I got it!
thyrgle