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

JFrame移动矩形为什么我的矩形没有移动并清除路径

帅令雪
2023-03-14

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

import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;



public class Raycast_World_2 extends JFrame implements ActionListener, KeyListener, Runnable
{
    public int px,py;
    int velx = 0, vely = 0;
    Graphics f;
   
    public Raycast_World_2()
    {
        // Instanzvariable initialisieren
        px = 100;
        py = 100;
        setSize(1280,960);
        setVisible(true);
        setDefaultCloseOperation(3);
        addKeyListener(this);
         setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        setTitle("Raycast_World-Try4_Version 3.0");
        JMenuBar menuBar = new JMenuBar();
JMenu menuFile = new JMenu("File");
JMenuItem menuItemExit = new JMenuItem("Exit");
menuFile.add(menuItemExit);
 
menuBar.add(menuFile);
 
// adds menu bar to the frame
setJMenuBar(menuBar);
    }
    public void actionPerformed(ActionEvent e){
        update(getGraphics());
        repaint();
    
    
}
    public void paint(java.awt.Graphics g) {
    
  g.setColor(Color.red);
  
  g.fillRect(px,py,20,20);
  g.dispose();  
  repaint();
}
public void run(){
   
    
}

    public void keyPressed(KeyEvent e){
    
    int c = e.getKeyCode();
    if(c == KeyEvent.VK_LEFT){
        
        px = px-10;
    }
    if(c == KeyEvent.VK_UP){
        
        py = py -10;
    }
    if(c == KeyEvent.VK_RIGHT){
        
        px = px +10;
    }
    if(c == KeyEvent.VK_DOWN){
        
        py = py +10;
    }
}
public void keyTyped(KeyEvent e){
}
public void keyReleased(KeyEvent e){}
}

请解释我做错了什么。提前谢谢你帮助我!

共有2个答案

太叔京
2023-03-14

不幸的是,你画得不对。

  • 不要扩展JFrame。顶级类很少是子类。您所需要的只是一个JFrame的实例,您将在其中添加一个用于绘制的JPanel。框架用于固定组件

下面是执行上述操作的代码的修改版本。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Raycast_World_2 extends JPanel implements KeyListener{
    public int px, py;
    int velx = 0, vely = 0;
    JFrame frame = new JFrame();
    public Raycast_World_2() {
        // Instanzvariable initialisieren
        px = 100;
        py = 100;
        // okay here but in some situations getPreferredSize() should be
        // overridden.
        setPreferredSize(new Dimension(600,500));
        setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        frame.setTitle("Raycast_World-Try4_Version 3.0");
        frame.add(this);
        JMenuBar menuBar = new JMenuBar();
        JMenu menuFile = new JMenu("File");
        JMenuItem menuItemExit = new JMenuItem("Exit");
        menuFile.add(menuItemExit);
        menuBar.add(menuFile);
        frame.setJMenuBar(menuBar);
        frame.pack(); // size and layout components.
        frame.setLocationRelativeTo(null); // center on screen
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()->new Raycast_World_2());
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics gg = g.create();
        gg.setColor(Color.red);
        
        gg.fillRect(px, py, 20, 20);
        gg.dispose();
    }
    }
    
    
    
    public void keyPressed(KeyEvent e) {
        
        int c = e.getKeyCode();
        if (c == KeyEvent.VK_LEFT) {
            
            px = px - 10;
        }
        if (c == KeyEvent.VK_UP) {
            
            py = py - 10;
        }
        if (c == KeyEvent.VK_RIGHT) {
            
            px = px + 10;
        }
        if (c == KeyEvent.VK_DOWN) {
            
            py = py + 10;
        }
        repaint();
    }
    
    public void keyTyped(KeyEvent e) {
    }
    
    public void keyReleased(KeyEvent e) {
    }
}

查看Java教程中的绘画方法。

还有许多在StackOverflow上正确绘制的优秀示例。

这是另一个建议,但不是必需的。使用内部类来创建您的keyListener。通过子类化KeyAdapter,您不必自己添加未实现的方法。KeyAdapter只是一个具有空方法的类。MouseAdapter是另一个。请注意,内部类可以访问包含类的字段。因此您可以执行以下操作:

public class MyKeyListener extends KeyAdapter {
     public void keyPressed(KeyEvent e) {
    
    int c = e.getKeyCode();
    if (c == KeyEvent.VK_LEFT) {    
        px = px - 10;
    } else
    if (c == KeyEvent.VK_UP) {
        py = py - 10;
    } else
    if (c == KeyEvent.VK_RIGHT) {
        px = px + 10;
    } else
    if (c == KeyEvent.VK_DOWN) {
        py = py + 10;
    }
    repaint();
}

然后您可以执行以下操作。

addKeyListener(new MyKeyListener());
符懿轩
2023-03-14

您的问题似乎是每次调用“油漆”方法时都没有重置屏幕。所以发生的情况是,每次您运行此方法时,它都会采用屏幕的先前状态并在该现有状态上绘制您想要的任何内容。更清楚地说,它只是使屏幕上的油漆过载。为了修复它,您所要做的就是在油漆方法的开头添加以下代码行:

super.paint(g);

这个从超类JFrame调用的方法将确保之前绘制到屏幕上的所有内容都将被擦除。因此,这一行代码之后的屏幕将是空的,并且现在将只使用这一行代码之后在屏幕上绘制的内容进行绘制。

 类似资料:
  • 我有两个矩形:红色和绿色。对于它们中的每一个,我有以下信息: 中心点( 和 坐标)。 旋转角度 宽度和高度 矩形将始终以正坐标移动。编辑:没有坐标可以是负的:矩形总是位于正坐标。因此,中心永远不会是(0,0)。 问题 我有一个起始位置。为了简化示例,假设我的红色和绿色矩形的位置如下: 现在,我使用0º和90º之间的角度φ旋转红色矩形。但是,绿色矩形需要旋转并保持其相对于红色矩形的位置。绿色矩形不仅

  • 请检查这段代码,看看@Arun R在如何计算覆盖另一个矩形的矩形面积中所说的算法有什么问题 为什么它没有删除其他内部的矩形

  • 我有两个带枢轴的矩形, 我需要根据红色矩形的旋转来附加绿色矩形的位置 结果应该如图所示: 我尝试了不同的公式,但没有成功 红色矩形: 绿色矩形: 我尝试了这样的方法: 非常感谢所有帮助过我的人!

  • 我有一个名为“DisplayPanel”的类(它扩展了JPanel),我在那里画了一个正方形,它来自一个名为“square”的类(它扩展了JComponent)。如何使用键在JPanel中移动矩形? 正方形类有通常的绘制方法: “squarishThing”是一个普通矩形: 问题是:与“游戏库”不同,尝试“手动”做这样的事情是相当令人困惑的。我不知道“while循环”去哪里了。我试图在显示面板中放

  • 我有一个pygame精灵动画,其中精灵的位置和形状在整个特定的动画序列中发生变化(例如-攻击)。我如何为碰撞调整精灵的矩形? 我的图像:在动画的一部分中,我的精灵位于png图像文件的中心(96x64像素)。在动画的另一部分中,我的精灵靠近png图像文件的右侧(96x64像素)。在动画的另一部分中,精灵改变形状(由剑移动引起)。等等。 我是否必须进行一些数学运算和计算来调整动画每帧子画面的碰撞条件,

  • 虽然我明白绘制函数的目的是绘制到某个表面,但我不明白为什么它不简单地返回pyplay。表面对象,您可以稍后在需要时将其烧毁到表面。到目前为止,当我只想创建一个表面并稍后将其绘制到其他地方时,这非常不方便。 有没有什么方法可以让类似的函数返回曲面对象,而不是执行额外的步骤并直接绘制到另一个曲面?