当前位置: 首页 > 知识库问答 >
问题:

如何使图形只在JFrame内移动,而不在JFrame的边界外移动?

曹鹏海
2023-03-14

我目前正在开发一款接住坠落物体的游戏,但目前的问题是玩家(也就是接住物体的人)。当我从左侧移动到窗口边界时,它会将玩家发送到x-1,但当我移动到右侧时(即使我将代码设置为if(x))

这是代码:

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

public class Game extends JPanel implements ActionListener, KeyListener {

    public int x = 0, y = 0, velx = 0, vely = 0;
    public boolean hitAnObject = false;
    public Color c = Color.BLACK;
    Timer timer = new Timer(5, this);


    public Game() {
        timer.start();
        setBackground(Color.CYAN);
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    @Override
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.fillRect(x, y, 50, 50);
        g.drawString("X = " + x + "Y = " + y, 0, 0);
    }

    public void actionPerformed(ActionEvent ae) {
        repaint();
        x += velx;
        y += vely;
    }

    public void left() {
        velx = -5;
        vely = vely + 0;
    }

    public void right() {
        velx = 5;
        vely = vely + 0;
    }

    public void up() {
        vely = -5;
        velx = velx + 0;
    }

    public void down() {
        vely = 5;
        velx = velx + 0;
    }
    public void stopMovement_UP() {
        vely = 0;
        velx = velx + 0;
    }
    public void stopMovement_DOWN() {
        vely = 0;
        velx = velx + 0;
    }
    public void stopMovement_LEFT() {
        velx = 0;
        vely = vely + 0;
    }
    public void stopMovement_RIGHT() {
        velx = 0;
        vely = vely + 0;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
            left();
            if (x < 0) {
                x = 0;
            }
        }
        else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
            right();
            //checck if the graphic aka player moves out of the boundary
        }
        else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
            down();
        }
        else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
            up();
            if (y < 0) {
                y = 0;
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) { }

    @Override
    public void keyReleased(KeyEvent e) { 
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
            stopMovement_LEFT();
            if (x < 0) {
                x = 0;
            }
        }
        else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
            stopMovement_RIGHT();
            if (x > 436) {
                x = x + 2;
            }
        }
        else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
            stopMovement_DOWN();
        }
        else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
            stopMovement_UP();
            if (y < 0) {
                y = 0;
            }
        }
        
    }

    public static void main(String[] args) {
        Game game = new Game();
        game.getBackground();
    }

}

共有1个答案

年运珧
2023-03-14

在方法actionPerform中,您正在更改x和y的值,但您没有检查计算的值是否在Game面板的范围内。

在方法绘制(在类游戏)中,x和y坐标在面板的坐标空间内,即游戏游戏左边缘的x坐标为0(零)。右边缘的x坐标是游戏的宽度,可以通过getWidth方法检索。

类似地,(游戏的)上边缘的y坐标为零,下边缘的y坐标为游戏的高度,可以通过方法getHeight检索。

因此,您将变量xy(在方法actionPerformed中)的计算值与宽度和高度(游戏Game)进行比较,以查看它们是否在游戏的范围之外。

public void actionPerformed(ActionEvent ae) {
    x += velx;
    if (x > getWidth() || x < 0) {
        // 'x' is outside of the bounds
    }
    y += vely;
    if (y > getHeight() || y < 0) {
        // 'y' is outside of the bounds
    }
    repaint();
}

我认为,在计算了xy的新值后,应该调用方法repaint(而不是像您问题中的代码那样在之前)。

我不知道你希望玩家在碰到其中一个边缘(Game)后如何移动,所以我只在上面代码中的if条件中写了一条注释。

如果您还没有这样做,我建议您阅读“使用Oracle Java教程的Swing trail创建GUI”中的“执行自定义绘制”课程。

 类似资料:
  • 问题内容: 新手程序员在这里。 我正在制作一个在笛卡尔坐标系中呈现用户输入方程式的程序。目前,让用户在坐标中自由移动视图时遇到一些问题。当前,在使用mouseDragged的情况下,用户可以拖动视图一点点,但是一旦用户释放鼠标并尝试再次移动视图,原点就会恢复到鼠标光标的当前位置。让用户自由移动的最佳方法是什么?提前致谢! 这是绘图区域的代码。 问题答案: 基于该示例,以下程序允许用户将轴的交点拖动

  • 问题内容: 我试图在不显示JFrame本身的情况下将JFrame渲染到图像。我试过使用这段代码: 然而,当这仅适用的设置。这将导致图像显示在屏幕上,这不是我想要的。我也尝试创建类似这样的东西: 但是,这将显示黑色图像(如上面的代码)。我很确定我所追求的是可能的,问题是我真的找不到如何做。我在使用自定义Swing组件方面的经验非常有限,因此任何信息都会受到赞赏。 谢谢。 问题答案: 这是应该解决问题

  • 我对java中的JFrames和图形非常陌生。我的长期目标是创建一个RayCast游戏世界。下面的代码是我第一次在jframe中以其坐标移动矩形。当用户按下箭头键时,坐标会发生变化。然而,似乎有些问题,因为当我使用该程序时,矩形只会被绘制并创建一条路径。我想在坐标的位置画一个矩形。 请解释我做错了什么。提前谢谢你帮助我!

  • 问题内容: 我正在作为学习项目来开发2D游戏,但遇到了麻烦。我无法弄清楚如何使用JPanel(添加到JFrame)中的KeyListener移动Polygon对象。我已经尝试过frog.translate(int x,int y)方法,该方法不会更新位置。我也尝试过手动更改数组坐标。我的代码示例如下: /////////////////////// 问题答案: 这段代码有一个简单的问题: 每次绘制

  • 我正在做一个WebGL(带有2d画布后备照片编辑器)。 我决定将旋转直接纳入裁剪工具,以类似于iOS8照片裁剪器的方式。也就是说,当您旋转照片时,照片的大小和位置会动态变化,以便裁剪区域始终包含在照片本身中。 但是,我正在为一些数学而苦苦挣扎。 我有两个矩形,照片和裁剪区域。 两者都被定义为: 定义照片本身的矩形也有一个以弧度表示的< code>rotation属性,它当然描述了照片的角度(以弧度

  • 我在使用 Netbeans GUI 添加的 JPanel 中绘制形状时遇到问题。现在,我不知道在哪里添加代码以在该 JPanel 内部绘制圆,以及如何在现在空置的 JPanel 中插入和调用它,等待绘制此形状。我已经将目标 JPanel 设置为流布局。Netbeans 设计器创建了一个大类,其中我用这个 JPanel 拥有整个框架,我想把它保留在其中,因为我无法以任何其他方式添加它,因为设计器不允