在一个圆圈内弹跳球 [英] Bouncing a ball within a circle

查看:126
本文介绍了在一个圆圈内弹跳球的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Pong-360游戏,其中弧形球拍使应该留在圆形边界内的球偏转.如果球到达边界时没有碰到球拍,它将继续超出范围,并且玩家最后一次击中球的得分.我遇到的问题是在用桨撞击时将球按正确的方向返回.如果球与球拍的某一部分接触,则球应朝该方向弹跳,但无论如何应回到边界的另一侧,而不必再次击中边界的同一侧.

I have a Pong-360 game in which the arc shaped paddles deflect a ball that should stay within the circular boundary. If the ball does not encounter a paddle when it gets to the boundary, it continues out of bounds and the player to last hit the ball scores. The problem I am having is returning the ball in the correct direction upon impact with a paddle. If the ball contacts a certain half of the paddle it should bounce in that direction but in any case should be returned to the opposite side of the boundary without hitting the same side of the boundary again.

现在,我已经完成了弹跳动作,将边界分成16个切片并给出了球在一个范围内的任意角度,该角度取决于撞击时所处的切片.即使这样也无法按预期工作,因为我的数学不正确,但是需要以任何方式重做.我无法弄清楚如何获得一个角度,以确保无论在哪里击球,球都返回到边界的另一半.我已经尝试过几次尝试从变量中获取角度,例如球的行进方向,边界内的当前位置以及进行接触的球拍的位置,但是到目前为止,我经历了失败.当前,用于更改球方向的代码如下:

Right now I have accomplished bouncing by dividing the boundary into 16 slices and giving the ball a random angle within a range that depends on which slice it was at on impact. Even this does not work as intended because my math is not correct but it needs to be redone any way. I can not figure out how to obtain an angle that will ensure the ball returns to the opposite half of the boundary no matter where it was hit. I have made several attempts to get the angle from variables such as direction of travel of the ball, current position within the boundary, and position of the paddle that made contact, but so far I have experienced failure. Currently, the code for changing the ball's direction is as follows:

    public void bounce(){

        boolean changeAngle = false;

        if( bluePaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 1;
            changeAngle = true;
        }
        else if( redPaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 2;
            changeAngle = true;
        }

        if ( changeAngle ){

            //  Right side of boundary
            if ( ball.getX() > center_x ) {

                //  Quadrant 4
                if ( ball.getY() > center_y ){

                    //  Slice 13
                    if ( ball.getY() - center_y > Math.sin(3 * Math.PI / 8) ){                      
                        angle = (double) ( randNum.nextInt(90) + 90 );
                    }
                    //  Code for other slices omitted
                }//end Quadrant 4
                // Code for other quadrants omitted
            }//end right side of boundary

            //  Code for Left side of boundary omitted

            ball.setDx( (int) (speed * Math.cos(Math.toRadians(angle))) );
            ball.setDy( (int) (speed * Math.sin(Math.toRadians(angle))) );
        }//end if (changeAngle)

        bouncing = false;       
    }//end bounce method

您现在可以看到,角度只是在我认为对每个切片都有利的范围内随机产生的.要强调的是,我主要需要数学方面的帮助,而使用Java进行辅助则是辅助.可以在这里找到编译和运行的整个代码(所有.java和.class文件): https://github.com/pideltajah/Pong360/tree/master/Pong360

As you can see, as it is now, the angle is simply generated at random within a range that I thought would be good for each slice. To emphasize, I primarily need help with the math, implementing it with Java is secondary. The entire code (all .java and .class files) which compiles and runs can be found here: https://github.com/pideltajah/Pong360/tree/master/Pong360

主要方法在Pong.java文件中.

The main method is in the Pong.java file.

任何帮助将不胜感激.

推荐答案

首先,找到它在桨上的撞击位置.对于红色桨,您可以这样做(蓝色桨将类似,但是您可能需要交换ang0和ang1):

First, find where it hit on the paddle. You can do this like so in the case of the red paddle (the blue paddle will be similar, but you may need to swap ang0 and ang1):

桨的边缘由圆上的两个角度ang0和ang1定义,其中ang0是下边缘,而ang1是上边缘

Edges of paddle are defined by two angles on your circle, ang0 and ang1, where ang0 is the lower edge, and ang1 is the upper edge

假设圆的中心是点(0,0)并且球在点pBall =(xBall,yBall)

Assume center of circle is point (0, 0) and the ball is at point pBall = (xBall, yBall)

该球将处于[ang0 .. ang1]范围内的某个角度ballAng = atan2(yBall,xBall)

The ball will be at a certain angle ballAng = atan2(yBall, xBall) within the range [ang0 .. ang1]

现在将其在拨片上的角度位置转换为[0 .. 1]之间的参数. 您可以将其定义为

Now convert its angle position on the paddle into a parameter between [0 .. 1]. You can define this as

u = (ballAng - ang0) / (ang1 - ang0);

现在,您要将其映射到中心线,如下所示:

Now you want to map it to the centerline, like so:

假设圆心线的底部位置是点p0,中心线的顶部是点p1

Say that the bottom position of the circle centerline is point p0, and the top of the centerline is point p1

现在将与中心线的交点定义为

Now define the point of intersection with the centerline as

p = p0 + u * (p1 - p0)

作为球的速度矢量,它必须是归一化的差异矢量

As a velocity vector for the ball, this needs to be the normalized difference vector

velBall = normalize(p - pBall)

希望这很有意义

这篇关于在一个圆圈内弹跳球的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆