无法弄清楚如何重绘

Ves*_*ske 0 java swing keylistener paintcomponent

所以我有这个小项目让我跳马里奥.但我无法弄清楚如何重新绘制它.如果我在点击后在Main类中执行它,那么整个跳跃将非常不稳定.

我尝试在跳转功能结束时执行此操作,但这也不起作用.

这是我的代码:

主要:

package klassid;

import java.awt.Color;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;


public class Main extends JComponent implements KeyListener, ActionListener{
    static Hero hero;
    Timer t = new Timer(500,this);

    public static void main(String[] args) {
        JFrame aken = new JFrame("Simple jumping simulator");
        aken.setSize(600, 600);
        aken.getContentPane().setBackground(new Color(255,255,255));
        aken.getContentPane().add(new Main());
        aken.setVisible(true);
        aken.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        hero.the_jump();
    }

    public Main(){
        addKeyListener(this);
        setFocusable(true);
        t.start();
        hero = new Hero(0, 320);
    }

    public void paintComponent(Graphics g){
        hero.render(g, this);
        g.setColor(Color.GREEN);
        g.fillRect(0, 550, 600, 2);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        hero.move(e.getKeyCode());
    }
    public void keyReleased(KeyEvent e) {
        hero.move2(e.getKeyCode());
    }
    public void keyTyped(KeyEvent e) {}
    public void actionPerformed(ActionEvent e) {}
}
Run Code Online (Sandbox Code Playgroud)

我的英雄课:

package klassid;

import java.awt.Toolkit;
import java.awt.Image;
import java.awt.Graphics;

public class Hero {
    static Main main;
    int y;
    Image pilt = Toolkit.getDefaultToolkit().getImage("../mario.png");
    private double height = 0, speed = 4;
    public static final double gravity = 9.81;
    private double x = 25;
    private boolean left = false, right = false, up = false;


    public Hero(int x, int y){
        this.x = x;
        this.y = y;
    }

    public void render(Graphics g, Main pohiKlass){
        g.drawImage(pilt, (int) (x), (int) (500-(height*100)), 50, 50, pohiKlass);
    }

    public void the_jump() {
        long previous = 0, start = 0;

        while(true){
            start= System.nanoTime();  
            if(previous != 0 && up){
                double delta = start - previous;

                height += (delta/1000000000) * speed;        
                speed -= (delta/1000000000)  * gravity; 
            }  
            if(left)
                x -= 3;
            if(right)
                x += 3; 
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(height < 0){
                height = 0;
                speed = 4; 
                up = false;
            }      
            previous = start;
            repaint();
        }
    }
    public void move(int i){
        if(i == 38)
            up=true;
        if(i == 37)
            left=true;
        if(i == 39)
            right=true;
    }
    public void move2(int i){
        if(i == 37)
            left=false;
        if(i == 39)
            right=false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试访问the_jump函数中的paintComponent,但它不起作用,因为我不知道它期望什么样的参数.

这个烂摊子怎么解决?

Nat*_*han 5

paintComponent方法的第一行应该是:

super.paintComponent(g);
Run Code Online (Sandbox Code Playgroud)

JComponent将为您做很多事情,但您需要显式调用超类方法来执行此操作.在这里查看Oracle文档.

repaint()如果将计时器值降低到非常低的值,则可以调用actionPerformed方法.这将为您提供"连续"重新绘制(您可以合理执行的次数).