Java awt重新绘制(),移动时会留下痕迹



我正在尝试用Java进行PAC-MAN克隆。我使用swing和awt作为GUI。我在我的主角身上实现了动作,它对按下的键做出了反应,但当角色移动";旧图像";呆在那里。因此,与其说帕克曼在屏幕上移动,不如说他留下了一条痕迹。我的理解是,当我使用重新绘制((函数时,图像应该被清除并重新绘制。

这是我的代码:

//PACMAN CLASS
import Entities.Ghost;
import Entities.Player;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Pacman extends JPanel implements KeyListener {
Player player = new Player("Pacman.png", 0, 0);
Ghost[] ghosts = new Ghost[4];
public Pacman(){
addKeyListener(this);
setFocusable(true);
ghosts[0] = new Ghost("Ghost_Red.png", 200, 200);
ghosts[1] = new Ghost("Ghost_Red.png", 150, 150);
ghosts[2] = new Ghost("Ghost_Red.png", 300, 100);
ghosts[3] = new Ghost("Ghost_Red.png", 50, 300);
}
public void paintComponent(Graphics g){
player.draw(g, this);
for(Ghost ghost: ghosts){
ghost.draw(g, this);
}
}
public void update() {
repaint();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
new Thread( () -> {
while (true){
update();
try{
Thread.sleep(10);
}catch(InterruptedException err){
err.printStackTrace();
}
}
}).start();
}
int SPEED = 4;
if(e.getKeyCode() == KeyEvent.VK_RIGHT && player.x < (getWidth() - player.width)){
player.x += SPEED;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT && player.x > 0){
player.x -= SPEED;
}
if(e.getKeyCode() == KeyEvent.VK_UP && player.y > 0){
player.y -= SPEED;
}
if(e.getKeyCode() == KeyEvent.VK_DOWN && player.y < (getHeight() - player.height)){
player.y += SPEED;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
//MY MAIN
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pacman");
Pacman panel = new Pacman();
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(224*2,288*2);
frame.setResizable(false);
}
}

我遵循了一个教程来到这里,这家伙的图形做得很好。尽管他使用的是JAva 10,而我使用的是JAva 16

在进行自定义绘制时,尤其是在进行某些"动画";,调用super.paintComponent(g);作为paintComponent(...)方法中的第一行非常重要

这将重新绘制所有你没有在上面绘制的东西;帧";,因此,这就是你解决问题所需要做的。

如果您想更详细地了解super.paintComponent()的作用,请阅读以下答案。

所以你的代码最终应该是这样的:

public void paintComponent(Graphics g) {
super.paintComponent(g);
player.draw(g, this);
for(Ghost ghost : ghosts) {
ghost.draw(g, this);
}
//Any extra painting do it here
}

此外,这一行:

frame.setVisible(true);

应该是你程序上的最后一个

关于这条线:

frame.setSize(224*2,288*2);

最好覆盖你的JPanelgetPreferredSize,然后调用frame.pack(),这将使你的窗格具有该大小,然后添加框架装饰,否则你的面板将比你想象的更小;有关更多信息,请查看以下问答:我应该避免在JavaSwing中使用set(Preferred|Maximum|Minimum(Size方法吗?

作为提示,不要使用";幻数";,相反,声明常量224288的含义以及为什么将它们乘以2。

忘了提一下,在编程游戏时,最好使用KeyBindings,而不是使用KeyListeners的无限循环(while(true)(;这是@HovercraftFullOfEels的一个很好的答案,它展示了如何做到这一点。

相关内容

  • 没有找到相关文章

最新更新