2014-02-24 106 views
0

所以我有這個小項目,我在那裏做馬里奧跳。但我無法弄清楚如何重新繪製它。如果我在點擊後在主類中做了這個動作,那麼整個跳躍將會非常生澀。不知道如何重畫

我試圖在我的跳轉功能結束時做到這一點,但這並沒有奏效。

這裏是我的代碼:

主營:

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) {} 
} 

我的英雄職業:

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; 
    } 
} 

我也試圖訪問的paintComponent在the_jump功能,但它並沒有爲工作我不知道它期望什麼樣的參數。

這個混亂是如何解決的?

回答

5

在你的paintComponent方法中的第一行應該是:

super.paintComponent(g); 

的JComponent會做很多的事情,但是你需要顯式調用父類的方法來做到這一點。查看Oracle文檔here

如果您將計時器值減少到非常低的值,您可以在actionPerformed方法中調用repaint()。這會給你「持續」重新粉刷(每秒可以合理執行多次)。

+0

如果我循環重繪這麼多次,這是一個巨大的性能打擊嗎? – Veske

+0

以圖形方式在CPU上做任何事情都不理想。我會建議測試它,看看它是否在性能範圍內。您可以隨時使用計時器值進行微調(33可能是一個很好的起點,因爲這會給您每秒大概30幀)。 – Nathan