1

これは、12 年生のオブジェクト指向プログラミング プロジェクトです。

ボール オブジェクトを構築するために、Ball というクラスがあります。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class Ball{
    private double xPos;
    private double yPos;
    private int direction;
    public Ball(int ixPos, int iyPos, int idirection){
        xPos = ixPos;
        yPos = iyPos;
        direction = idirection;
    }
    public int returnX(){
        return (int)xPos;
    }
    public int returnY(){
        return (int)yPos;
    }
    public int returnDirection(){
        return direction;
    }
    public void move(){
        xPos += 1*Math.cos(Math.toRadians(direction));
        yPos -= 1*Math.sin(Math.toRadians(direction));
    }
    public void collide(int collideWith){
        if(collideWith==1){//collide with left wall
            if(90<direction && direction<180){
                direction = 180-direction;
            }
            if(180<direction && direction<270){
                direction = 540-direction;
            }
        }
        if(collideWith==2){//collide with right wall
            if(0<direction && direction<90){
                direction = 180-direction;
            }
            if(270<direction && direction<360){
                direction = 540-direction;
            }
        }
        if(collideWith==3){//collide with up wall
            if(0<direction && direction<90){
                direction = 360-direction;
            }
            if(90<direction && direction<180){
                direction = 360-direction;
            }
        }
        if(collideWith==4){//collide with down wall
            direction = 360-direction;
        }
    }
    public void collidePaddle(int collidePos){
        if(collidePos!=50 && collidePos!=0){
            direction = (50-collidePos)*180/50;
        }
    }
}

「move」関数でわかるように、現在、ボールは非常に低速で移動しています。しかし、私はボールをより速く飛ばす必要があります。1 を 5 のように変更すると、問題が発生します。ボールが壁またはブロックに当たって方向を変えるかどうかをチェックするメイン クラスでは、ボールが毎回移動できるピクセル数が 1 より大きい場合、ボールは壁またはブロックに入ります。

私には、この問題を解決する方法がないように思えます。どこから考え始めるのかわかりません。衝突などをチェックするより良い方法はありますか?

ありがとうございました。

4

1 に答える 1

2

チェックで絶対チェックを使用する代わりにcollidePaddle、範囲を許可する必要があります。

例えば...

public void collidePaddle(int collidePos){
    if (collidePos >= 50) {
        direction = (50-collidePos)*180/50;
        // Correct the position of the ball to meet the minimum requirements
        // of the collision...
    } else if (collidePos <= 0) {
        direction = (50-collidePos)*180/50;
        // Correct the position of the ball to meet the minimum requirements
        // of the collision...
    }
}

(申し訳ありませんが、私はあなたのコードを楽しんでいます;))

これにより、仮想コンテキスト内でボールがこれらのポイントを超えて「パス」できるようになりますが、位置を修正して合成しても、違いはありません...レンダリングすると...

更新しました

これが私が話していることの本当に簡単な例です...

public class SimpleBouncyBall {

    public static void main(String[] args) {
        new SimpleBouncyBall();
    }

    public SimpleBouncyBall() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new CourtPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class CourtPane extends JPanel {

        private Ball ball;
        private int speed = 5;

        public CourtPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Rectangle bounds = new Rectangle(new Point(0, 0), getSize());
                    if (ball == null) {
                        ball = new Ball(bounds);
                    }
                    speed = ball.move(speed, bounds);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            if (ball != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                Point p = ball.getPoint();
                g2d.translate(p.x, p.y);
                ball.paint(g2d);
                g2d.dispose();
            }
        }

    }

    public class Ball {

        private Point p;
        private int radius = 12;

        public Ball(Rectangle bounds) {                
            p = new Point();
            p.x = 0;
            p.y = bounds.y + (bounds.height - radius) / 2;                
        }

        public Point getPoint() {
            return p;
        }

        public int move(int speed, Rectangle bounds) {                
            p.x += speed;
            if (p.x + radius >= (bounds.x + bounds.width)) {                    
                speed *= -1;
                p.x = ((bounds.x + bounds.width) - radius) + speed;                    
            } else if (p.x <= bounds.x) {
                speed *= -1;
                p.x = bounds.x + speed;                    
            }
            p.y = bounds.y + (bounds.height - radius) / 2;                
            return speed;                
        }

        public void paint(Graphics2D g) {
            g.setColor(Color.RED);
            g.fillOval(0, 0, radius, radius);
        }            
    }        
}

私の move メソッドは、境界を越えたかどうかに関係なく、ボールを再配置してそれらの境界内に収まるようにします。

public int move(int speed, Rectangle bounds) {                
    // Apply the delta
    p.x += speed;
    // Have we passed beyond the right side??
    if (p.x + radius >= (bounds.x + bounds.width)) {                    
        speed *= -1;
        p.x = ((bounds.x + bounds.width) - radius) + speed;                    
    // Have we past beyond the left side??
    } else if (p.x <= bounds.x) {
        speed *= -1;
        p.x = bounds.x + speed;                    
    }
    p.y = bounds.y + (bounds.height - radius) / 2;                
    return speed;                
}

速度をいじって、何が得られるか見てみましょう ;)

于 2013-02-14T02:01:20.850 に答える