Xcode - 用户绘制的线条碰撞检测
我正在制作一个游戏,其中 UIImageView(ball) 在 iPhone 屏幕的边缘随机弹跳。然后,用户必须用手指画线以引导球进入洞/目标。我已经成功实现了随机弹跳的球和在屏幕上绘图的能力。我的问题是,我一生都无法检测到球和用户绘制的线之间的碰撞。球刚刚穿过它。我尝试过使用 CGRectIntersectsRect 但我很确定这个方法行不通。我基本上想要的是某种让球从用户绘制的线反弹的方法。如果有人知道如何做到这一点并且可以提供帮助,我将非常感激。
预先感谢
我添加了一些代码来尝试帮助你们理解我的设置是什么。
触摸开始是用户第一次将手指放在屏幕上
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
fingerSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
startPoint = [touch locationInView:self.view];
lastPoint.y -= 0;
}
触摸移动是当手指在屏幕上移动时
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
fingerSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 0;
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
// sets the width of the line
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
//sets the colour of the line drawn
//red
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
//green
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 1.0, 0.0, 1.0);
//blue
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 1.0, 1.0);
//black
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
//draws a line to the point where the user has touched the screen
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
fingerMoved++;
}
这是我目前正在尝试用于实际碰撞检测的内容...
float a = lastPoint.y - startPoint.y;
float b = startPoint.x - lastPoint.x;
float c = lastPoint.x * startPoint.y - startPoint.x * lastPoint.y;
float d = abs(a * ball.center.x + b *ball.center.y + c)/sqrtf(powf(a,2)+ powf(b,2));
if(d ==0){
NSLog(@"collision detected");
}
Im making a game in which a UIImageView(ball) randomly bounces around the edges of the iphone screen. The user then must draw lines with their finger to guide the ball into a hole/target. I have managed to implement the randomly bouncing ball and the ability to draw onto the screen. My problem is that I cant for the life of me get a collision detected between the ball and the user drawn line. The ball just passes through it. I have tried to use a CGRectIntersectsRect but i'm pretty sure that this method wont work. What i'm basically wanting is some way of getting the ball to bounce off of the user drawn line. If anyone has any idea on how to do this and could help I would be very grateful.
Thanks in advance
Ive added some code to try and help you guys understand what my set up is.
touches began is where the user first puts their finger on the screen
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
fingerSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
startPoint = [touch locationInView:self.view];
lastPoint.y -= 0;
}
touches moved is when the finger is moved across the screen
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
fingerSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 0;
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
// sets the width of the line
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
//sets the colour of the line drawn
//red
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
//green
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 1.0, 0.0, 1.0);
//blue
//CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 1.0, 1.0);
//black
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
//draws a line to the point where the user has touched the screen
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
fingerMoved++;
}
Heres what i'm currently trying to use for the actual collision detection...
float a = lastPoint.y - startPoint.y;
float b = startPoint.x - lastPoint.x;
float c = lastPoint.x * startPoint.y - startPoint.x * lastPoint.y;
float d = abs(a * ball.center.x + b *ball.center.y + c)/sqrtf(powf(a,2)+ powf(b,2));
if(d ==0){
NSLog(@"collision detected");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不了解 Xcode,但是,大概这两个绘制的对象(球和线)共享一些坐标空间。我假设球有一个位置和半径,并且线有一些端点。在将球从当前位置移动到下一帧中的任何位置之前,您“测试”建议的新位置以查看圆圈是否已触及线。如果该线是“无限”的,或者至少延伸到屏幕边缘,则两个对象之间最近的距离将是连接圆心和该线并垂直于该线的线。垂直线的斜率是原始线的 -1 * 1/m(其中 m 是斜率)。您可以从圆的中心开始,用该斜率绘制一条测试线,并使用一些代数计算测试线与用户绘制的线的交点。然后计算该段的长度,如果它比球的半径短,则击中线。
如果与球相比,该线是一小段,您可以沿着该线选取几个点,并直接针对球的中心进行测试,再次将到中心的距离与半径进行比较。
I don't know Xcode, but, presumably these two drawn objects (the ball and the line) share some coordinate space. The ball has, I assume, a position and a radius, and the line has some end points. Before moving the ball from where ever it is, to where ever it will be in the next frame, you "test" the proposed new location to see if the circle has touched the line. If the line is "infinite", or at least, going out to the screen edges, than the closest approach between the two objects will be the line that connects the center of the circle to the line and is perpendicular to that line. The slope of the perpendicular line is -1 * 1/m of the original line (where m is the slope). You can start at the center of your circle and draw a test line with that slope, and calculate where the intersection of the test line with the user-drawn line will be with some algebra. Then just calculate the length of that segment, and if it is shorter than the radius of the ball, you hit the line.
If the line is a short segment in comparison to the ball, you could pick several points along the line and test them directly against the center of the ball, again comparing the distance to the center against the radius.
请发布一些代码。
时机对于碰撞检测很重要,但您可能没有在正确的时间提出问题。首先测试你的代码。制作一个球和一条明显碰撞的线并运行您的探测器。如果测试正确,那么很可能与没有在正确的时间询问“这些物体是否发生碰撞”有关。
please post some code.
timing is important to collision detection and you just might not be asking the question at the right time. first test your code. make a ball and a line that clearly colide and run you detector. If it tests correctly then it most likely something to do with not asking "are these objects colliding" at the right time.