用Java重构这个函数

发布于 2024-08-24 04:03:25 字数 2432 浏览 4 评论 0原文

我正在学习 Java,我知道对新手程序员最大的抱怨之一是我们创建了非常长且复杂的方法,应该将其分解为几个。这是我写的,是一个完美的例子。 :-D。

public void buildBall(){

        /* sets the x and y value for the center of the canvas */
        double i = ((getWidth() / 2));
        double j = ((getHeight() / 2));

        /* randomizes the start speed of the ball */
        vy = 3.0;
        vx = rgen.nextDouble(1.0, 3.0);
        if (rgen.nextBoolean(.05)) vx = -vx;    

        /* creates the ball */
        GOval ball = new GOval(i,j,(2 *BALL_RADIUS),(2 * BALL_RADIUS));     
        ball.setFilled(true);
        ball.setFillColor(Color.RED);
        add(ball);


        /* animates the ball */ 
        while(true){
            i = (i + (vx* 2));
            j = (j + (vy* 2));  
            if (i > APPLICATION_WIDTH-(2 * BALL_RADIUS)){
                vx = -vx;       
            }

            if (j > APPLICATION_HEIGHT-(2 * BALL_RADIUS)){
                vy = -vy;
            }

            if (i < 0){
                vx = -vx;
            }

            if (j < 0){
                vy = -vy;
            }

            ball.move(vx + vx, vy + vy);
            pause(10);

            /* checks the edges of the ball to see if it hits an object */
            colider = getElementAt(i, j);

            if (colider == null){
                colider = getElementAt(i + (2*BALL_RADIUS), j); 
                }
            if (colider == null){
                colider = getElementAt(i + (2*BALL_RADIUS), j + (2*BALL_RADIUS));   
                }
            if (colider == null){
                colider = getElementAt(i, j + (2*BALL_RADIUS)); 
                }

            /* If the ball hits an object it reverses direction */
            if (colider != null){
                vy = -vy;


             /* removes bricks when hit but not the paddle */
                if (j < (getHeight() -(PADDLE_Y_OFFSET + PADDLE_HEIGHT))){
                remove(colider);
                }

            }

        }

从方法的标题中你可以看出我是出于“建球”的良好意图而开始的。

我遇到了一些问题:

问题是我需要移动球,所以我创建了 while 循环。除了保持“true”之外,我没有看到任何其他方法可以做到这一点,因此这意味着我在此循环下创建的任何其他代码都不会发生。我没有将 while 循环设为不同的函数,因为我使用了这些变量 i 和 j

所以我不知道如何在这个循环之外进行重构。

所以我的主要问题是:

如何将 i 和 j 的值传递给新方法:“animateBall”以及如何使用 ball.move(vx + vx, vy + vy); 在该新方法中,如果 ball 已在 buildBall 方法中声明?

我知道这可能是更好地理解变量范围和传递参数的简单事情,但我还没有完全做到这一点......

I'm learning Java, and I know one of the big complaints about newbie programmers is that we make really long and involved methods that should be broken into several. Well here is one I wrote and is a perfect example. :-D.

public void buildBall(){

        /* sets the x and y value for the center of the canvas */
        double i = ((getWidth() / 2));
        double j = ((getHeight() / 2));

        /* randomizes the start speed of the ball */
        vy = 3.0;
        vx = rgen.nextDouble(1.0, 3.0);
        if (rgen.nextBoolean(.05)) vx = -vx;    

        /* creates the ball */
        GOval ball = new GOval(i,j,(2 *BALL_RADIUS),(2 * BALL_RADIUS));     
        ball.setFilled(true);
        ball.setFillColor(Color.RED);
        add(ball);


        /* animates the ball */ 
        while(true){
            i = (i + (vx* 2));
            j = (j + (vy* 2));  
            if (i > APPLICATION_WIDTH-(2 * BALL_RADIUS)){
                vx = -vx;       
            }

            if (j > APPLICATION_HEIGHT-(2 * BALL_RADIUS)){
                vy = -vy;
            }

            if (i < 0){
                vx = -vx;
            }

            if (j < 0){
                vy = -vy;
            }

            ball.move(vx + vx, vy + vy);
            pause(10);

            /* checks the edges of the ball to see if it hits an object */
            colider = getElementAt(i, j);

            if (colider == null){
                colider = getElementAt(i + (2*BALL_RADIUS), j); 
                }
            if (colider == null){
                colider = getElementAt(i + (2*BALL_RADIUS), j + (2*BALL_RADIUS));   
                }
            if (colider == null){
                colider = getElementAt(i, j + (2*BALL_RADIUS)); 
                }

            /* If the ball hits an object it reverses direction */
            if (colider != null){
                vy = -vy;


             /* removes bricks when hit but not the paddle */
                if (j < (getHeight() -(PADDLE_Y_OFFSET + PADDLE_HEIGHT))){
                remove(colider);
                }

            }

        }

You can see from the title of the method that I started with good intentions of "building the ball".

There are a few issues I ran up against:

The problem is that then I needed to move the ball, so I created that while loop. I don't see any other way to do that other than just keep it "true", so that means any other code I create below this loop won't happen. I didn't make the while loop a different function because I was using those variables i and j.

So I don't see how I can refactor beyond this loop.

So my main question is:

How would I pass the values of i and j to a new method: "animateBall" and how would I use
ball.move(vx + vx, vy + vy); in that new method if ball has been declared in the buildBall method?

I understand this is probably a simple thing of better understanding variable scope and passing arguments, but I'm not quite there yet...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

计㈡愣 2024-08-31 04:03:25

这可以重构为三个方法
a> build ball :创建球对象并设置初始位置:buildBall()
b>为整个 while 循环设置动画,除了碰撞器部分动画(Ball ball, vx, vy)
c>获取对撞机 getCollider()

因为球是一个对象,并且您已经将 i,j 设置为它们将被传递的字段。 Java 按值传递所有参数。对象存在于堆中;对象引用作为方法参数按值传递。

编辑、添加伪代码

    class Animator{
    void animateBall(){
    Ball ball = buildBall(); //Ball will have i,j,radius etc set by this method
    int vx = randomNumber();
    int vy = randomNumber();
    moveIt(vx,vy, ball);
    }
    void moveIt(int vx, int vy, Ball ball){
        while(true){
             //move the ball, change i,j fields of ball
             //check for collission etc
             Collider collider = getCollider(ball);
             //change direction based on collider etc.
        }
    }
    Collider getCollider(Ball ball){
    //collision code here
    }
}

This can be refactored into three methods
a> build ball : create the ball object and set initial location: buildBall()
b> animate the entire while loop except the collider part animate(Ball ball, vx, vy)
c> get the collider getCollider()

Since ball is an object and you are already setting i,j as its fields they will be passed. Java passes all parameters by value. Objects live on the heap; object references are passed by value as method parameters.

Edit, added pseudo code

    class Animator{
    void animateBall(){
    Ball ball = buildBall(); //Ball will have i,j,radius etc set by this method
    int vx = randomNumber();
    int vy = randomNumber();
    moveIt(vx,vy, ball);
    }
    void moveIt(int vx, int vy, Ball ball){
        while(true){
             //move the ball, change i,j fields of ball
             //check for collission etc
             Collider collider = getCollider(ball);
             //change direction based on collider etc.
        }
    }
    Collider getCollider(Ball ball){
    //collision code here
    }
}
情感失落者 2024-08-31 04:03:25

这有点多余

       colider = getElementAt(i, j);

           /* If the ball hits an object it reverses direction */

        if (colider != null && j < (getHeight() -(PADDLE_Y_OFFSET + PADDLE_HEIGHT)))
        {
            vy = -vy;

         /* removes bricks when hit but not the paddle */
            remove(colider);
         }


            else
            {
                colider = getElementAt(i + (2*BALL_RADIUS), j); 
                colider = getElementAt(i + (2*BALL_RADIUS), j + (2*BALL_RADIUS));  
                colider = getElementAt(i, j + (2*BALL_RADIUS));      
            }

This is a bit less redundant

       colider = getElementAt(i, j);

           /* If the ball hits an object it reverses direction */

        if (colider != null && j < (getHeight() -(PADDLE_Y_OFFSET + PADDLE_HEIGHT)))
        {
            vy = -vy;

         /* removes bricks when hit but not the paddle */
            remove(colider);
         }


            else
            {
                colider = getElementAt(i + (2*BALL_RADIUS), j); 
                colider = getElementAt(i + (2*BALL_RADIUS), j + (2*BALL_RADIUS));  
                colider = getElementAt(i, j + (2*BALL_RADIUS));      
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文