【问题标题】:Bouncing rectangle (Graphics g)弹跳矩形(图形 g)
【发布时间】:2019-06-18 18:05:25
【问题描述】:

我正在玩 Java 中的图形。目前我有一个从左到右移动的矩形。我希望它在碰到画布的右侧时开始向左移动,在碰到右侧时向左移动,我已经包含了一个游戏循环,因为这最终将变成我的第一个非常基本的游戏。谢谢。

P.S - 我为这段代码的不同部分遵循了一些教程,因此为什么它可能有点混乱,我正在努力:)

主类:

public class Game extends JFrame implements Runnable {

    private Canvas canvas = new Canvas();
    private RenderHandler renderer;
    private boolean running = true;
    public static int WIDTH = 1200, HEIGHT = WIDTH / 12*9;
    public static int moveX =WIDTH/2;

    public Game() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(WIDTH, HEIGHT);
        setLocationRelativeTo(null);
        setLocationRelativeTo(null);
        add(canvas);
        setVisible(true);
        canvas.createBufferStrategy(3);
        renderer = new RenderHandler(getWidth(), getHeight());

    }


    public void update() {

    }


    public void render() {
            BufferStrategy bufferStrategy = canvas.getBufferStrategy();
            Graphics graphics = bufferStrategy.getDrawGraphics();
            super.paint(graphics);

            renderer.render(graphics);

            graphics.dispose();
            bufferStrategy.show();
    }

    public void run() {
        BufferStrategy bufferStrategy = canvas.getBufferStrategy();
        int FRAMES = 0;
        int TICKS = 0;
        long lastTime = System.nanoTime();
        double unprocessed = 0;
        double nsPerSecs = 1000000000 /60.0;
        long Timer = System.currentTimeMillis();
        while(running) {
            long now = System.nanoTime();
            unprocessed += (now - lastTime) / nsPerSecs;
            lastTime  = now;

            if(unprocessed >= 1) {
                TICKS ++;
                update();
                unprocessed -= 1;
            } 
            try 
            {
                Thread.sleep(3); 
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            FRAMES++;
            render();

            if(System.currentTimeMillis() - Timer > 1000) {
                System.out.println("Ticks: " + TICKS + " FPS: " + FRAMES);
                TICKS = 0;
                FRAMES = 0;
                Timer += 1000;
            }
        }
    }
    public static void main(String[] args) {
        Game game = new Game();
        Thread gameThread = new Thread(game);
        gameThread.start();
    }

}

绘制图形的类:

public class RenderHandler {
public RenderHandler(int width, int height) {

}

public void render(Graphics g) {
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
    g.setColor(Color.RED);
    g.fillRect(Game.moveX, Game.HEIGHT/2, 50, 50);
    if (Game.moveX >= Game.WIDTH) {
        Game.moveX ++;
    } else if (Game.moveX <= 0) {
        Game.moveX --;
    }else { Game.moveX++;
    }
    }
}

【问题讨论】:

  • 那么您具体的问题是什么?
  • @Andreas 如何让 g.drawRect 在碰到框架/画布的右侧时向左移动
  • 这不是正确的方法。首先,永远不要将 AWT 组件 (Canvas) 与 Swing 组件 (JFrame) 混合使用。其次,不要尝试在 JFrame 上绘图;您应该在框架中创建一个 JPanel 并在其 paintComponent() 方法中在面板上绘图。第三,你阻塞了事件线程——你需要创建一个 SwingTimer
  • @FredK 感谢您的帮助!
  • 不要在渲染方法中做出逻辑选择,这些应该作为更新传递的一部分,应该保持为状态模型

标签: java swing graphics awt


【解决方案1】:

如果您知道如何在屏幕上绘图以及这些东西是如何工作的,我认为这更多是为了降低逻辑。

我如此粗暴地从您的问题中撕下的这段代码片段就在渲染发生的位置旁边(这是一个问题,因为我认为它相当杂乱无章;我建议游戏逻辑和渲染在两个不同的函数中进行)。基本上就是说如果超出屏幕右侧就向右移动,如果不是,如果超出屏幕左侧就向左移动,最后如果不是,就向左移动。

if (Game.moveX >= Game.WIDTH) {
        Game.moveX ++;
    } else if (Game.moveX <= 0) {
        Game.moveX --;
    }else { Game.moveX++;
    }

如果你想让它弹跳,你将不得不使用一个布尔值来跟踪它的移动状态,或者,如果你想要更多的通用性,使用一对浮点数或双精度浮点数(浮点数通常用于 Java 游戏设计)跟踪它的位置,另一个跟踪它的速度。我现在很紧张,我会回来的。

【讨论】:

  • 感谢您的评论,这对您有所帮助。正如您可能已经猜到的那样,我不擅长逻辑。我对这种事情不熟悉。
【解决方案2】:

将此添加到渲染处理程序而不是渲染中的当前 if 语句

bool rol = true; // initialize this outside the method


If(Game.movex + 50 >= Game.width)
rol = false;
Else if(Game.movex <= 0)
rol = true;
If(rol)
Game.movex++;
Else
Game.movex--;

【讨论】:

  • 嗨,马特,谢谢您的回复,这比我的效果更好,但它仍然卡在右侧并且没有反弹
  • 你能把新代码复制进去吗?我只是想检查一下
  • 这里是你的代码修正了一点,现在可以完美运行谢谢!
  • if(Game.moveX + 50 >= Game.WIDTH){ rol = false; } else if(Game.moveX
  • 布尔 rol = true; // 在方法外初始化它
【解决方案3】:

您需要在某处存储当前移动方向,因此将其添加到 Game 类中:

public static int deltaX = 1;

并将 render() 中的条件替换为

if (Game.moveX >= Game.WIDTH-50) {
    Game.deltaX =-1;
} else if (Game.moveX <= 0) {
    Game.deltaX =1;
}
Game.moveX += Game.deltaX;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多