Thursday, April 16, 2015

iphone - How to detect which edges of a rectange touch when they collide in iOS


I'm creating a basic "game" in iOS 4.1. The premise is simple, there is a green rectangle ("disk") that moves/bounces around the screen, and red rectangle ("bump") that is stationary. The user can move the red "bump" by touching another coordinate on the screen, but that's irrelevant to this question.


Each rectangle is a UIImageView (I will replace them with some kind of image/icon once I get the mechanics down). I've gotten as far as detecting when the rectangles collide, and I'm able to reverse the direction of the green "disk" on the Y axis if they do. This works well when the green "disk" approaches the red "bump" from top or bottom, it bounces off in the other direction. But when it approaches from the side, the bounce is incorrect; I need to reverse the X direction instead.


Here's the timer I setup:


- (void)viewDidLoad {
xSpeed = 3;
ySpeed = -3;

gameTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(mainGameLoop:) userInfo:nil repeats:YES];
[super viewDidLoad];
}

Here's the main game loop:


- (void) mainGameLoop:(NSTimer *)theTimer {
disk.center = CGPointMake(disk.center.x + xSpeed, disk.center.y + ySpeed);

// make sure the disk does not travel off the edges of the screen
// magic number values based on size of disk's frame

// startAnimating causes the image to "pulse"
if (disk.center.x < 55 || disk.center.x > 265) {
xSpeed = xSpeed * -1;
[disk startAnimating];
}
if (disk.center.y < 55 || disk.center.y > 360) {
ySpeed = ySpeed * -1;
[disk startAnimating];
}



// check to see if the disk collides with the bump
if (CGRectIntersectsRect(disk.frame, bump.frame)) {
NSLog(@"Collision detected...");
if (! [disk isAnimating]) {
ySpeed = ySpeed * -1;
[disk startAnimating];
}
}
}


So my question is: how can I detect whether I need to flip the X speed or the Y speed? ie: how can I calculate which edge of the bump was collided with?



Answer



Since you're using rectangles and it sounds like you're also confining yourself to eight directional movement, you can probably get away with computing a vector from the ball's center to the bumper's, and examining that; it will tell you about their relative positions. If the magnitude of the Y component is greater the ball is hitting the top or bottom, if the X component is greater the ball is hitting the left or right, and if they are equal it's hitting exactly on the corner (maybe reverse both directions in that case?).


A more robust solution would probably involve the separating axis theorem and use of penetration vectors to gauge response and real reflection vectors to compute the change in velocity. I don't know how robust a solution you need though.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...