2012-07-10 61 views
3

我創建了一個視頻遊戲,當我調用repaint()方法時,整個屏幕更新並不規則地閃爍。我通過在這行代碼中指定重繪的內容(charRect,它是一個Rectangle對象)稍微解決了這個問題:repaint(charRect.x,charRect.y,20,32);整個屏幕停止閃爍,但角色令人難以置信地出現毛病。我只需要幫助讓動畫(a和d)和跳躍(w)順暢地運行。什麼代碼用於繪製單個對象,而不使用repaint()方法更新整個屏幕?

import javax.swing.*; 
import javax.swing.event.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.*; 
import java.util.*; 
import java.io.*; 
import java.net.*; 
import java.lang.*; 
import static java.lang.Math.*; 
import static java.lang.System.out; 
import java.util.Random.*; 
import javax.swing.JApplet; 
import java.awt.Graphics; 

public class UltimaBlade extends JApplet implements KeyListener 
{ 
public final int  WIDTH = 900; 
public final int  HEIGHT = 650; 

public int    score = 0; 
private boolean   jumping = false; 
private boolean   moveRight = false; 
private boolean   moveLeft = false; 
private boolean   jumpRight = false; 
private boolean   jumpLeft = false; 
private boolean   moveRightWhileJumping = false; 
private boolean   moveLeftWhileJumping = false; 

public JFrame   JTitle = new JFrame("UltimaBlade"); 
     Image   characterImg = null; 
     Image   blockImg1 = null; 
     Image   floorImg1 = null; 
     Image   wallImg1 = null; 
      JLabel   scoreLabel = new JLabel("Score: " + score); 

     Rectangle  charRect = new Rectangle(25, 450, 20, 32); 
     Rectangle  blockRect1 = new Rectangle(25, 482, 30, 30); 
     Rectangle  floorRect1 = new Rectangle(25, 482, 200, 1);CHANGE BACK TO 30 
     Rectangle  wallRect1 = new Rectangle(55, 490, 1, 30); 
     //Rectangle  tempGhost = new Rectangle(charRect.x, charRect.y, 20, 32); 

public JMenuBar  mb = new JMenuBar(); 
public JMenu   menuFile = new JMenu("File"); 
public JMenuItem  menuItemSave = new JMenuItem("Save"); 
public JMenuItem  menuItemLoad = new JMenuItem("Load"); 
     Container  cont; 
     Runner   runner; 

public void init() 
{ 
    setSize(WIDTH, HEIGHT); 

    JTitle.setJMenuBar(mb); 
    menuFile.add(menuItemSave); 
    menuFile.add(menuItemLoad); 
    mb.add(menuFile); 
    JTitle.getContentPane().setLayout(new BorderLayout()); 
    menuItemSave.addActionListener(new ListenMenuSave()); 
    setJMenuBar(mb); 
    new UltimaBlade(); 
} 

public UltimaBlade() 
{ 
    setLayout(null); 
    setSize(WIDTH, HEIGHT); 
    setVisible(true); 

    cont = getContentPane(); 
    cont.setLayout(null); 
    addKeyListener(this); 
    cont.setBackground(Color.WHITE); 

    cont.add(scoreLabel); 
    scoreLabel.setBounds(50, 50, 100, 30); 
    scoreLabel.setForeground(Color.BLACK); 
    cont.setLayout(null); 

    repaint(); 
    cont.validate(); 

    runner = new Runner(); 
    runner.start(); 
    setContentPane(cont); 
} 

public class ListenMenuSave implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     new Save(); 
    } 
} 

public void paint(Graphics g) 
{ 
    super.paint(g); 

    try 
    { 
     URL  url1 = this.getClass().getResource("character.gif");  //Character 
       characterImg = Toolkit.getDefaultToolkit().getImage(url1); 
     URL  url2 = this.getClass().getResource("block.gif");   //Block 
       blockImg1 = Toolkit.getDefaultToolkit().getImage(url2); 
     URL  url3 = this.getClass().getResource("floor_line.gif");  //Floor Line 
       floorImg1 = Toolkit.getDefaultToolkit().getImage(url3); 
     URL  url4 = this.getClass().getResource("wall_line.gif");  //Wall Line 
       wallImg1 = Toolkit.getDefaultToolkit().getImage(url4); 
    } 
    catch(Exception e) 
    { 

    } 

    g.drawImage(characterImg, charRect.x, charRect.y, this); 
    g.drawImage(floorImg1, floorRect1.x, floorRect1.y, this); 
    g.drawImage(blockImg1, blockRect1.x, blockRect1.y, this); 
    g.drawImage(wallImg1, wallRect1.x, wallRect1.y, this); 
} 

public void keyPressed(KeyEvent e) 
{ 
    if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D') 
    { 
     moveRight = true; 
     if(jumping) 
      moveRightWhileJumping = true; 
    } 
    if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A') 
    { 
     moveLeft = true; 
     if(jumping) 
      moveLeftWhileJumping = true; 
    } 
} 

public void keyReleased(KeyEvent e) 
{ 
    if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D') 
    { 
     moveRight = false; 
     if(!jumping) 
      moveRightWhileJumping = false; 
    } 
    if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A') 
    { 
     moveLeft = false; 
     if(!jumping) 
      moveLeftWhileJumping = false; 
    } 
} 

public void keyTyped(KeyEvent e) 
{ 
    if(e.getKeyChar() == 'w' || e.getKeyChar() == 'W') 
    { 
     jumping = true; 
    } 
} 

public class Runner extends Thread// implements Runnable 
{ 
    public void run() 
    { 
     while(true) 
     { 
      try 
      { 
       int  j = 5;  //Beginning velocity 
       double t = 0; 
       double sum = j/5; 
       while(jumping) 
       { 
        repaint(charRect.x, charRect.y, 20, 32); 
        cont.validate(); 
        int jump = (int)((-4.9 * ((t * t)/10)) + (j * t)); 
        if(moveRightWhileJumping) 
        { 
         charRect.x = charRect.x + j; // Move Right while jumping. 
         if(charRect.intersects(wallRect1)) 
         { 
          charRect.x = wallRect1.x - 21; 
          moveRightWhileJumping = false; 
         } 
        } 
        if(moveLeftWhileJumping) 
        { 
         charRect.x = charRect.x - j; //Move Left while jumping. 
         if(charRect.intersects(wallRect1)) 
         { 
          charRect.x = wallRect1.x + 1; 
          moveLeftWhileJumping = false; 
         } 
        } 
        if(jump > 0) 
        { 
         charRect.y = charRect.y - Math.abs(jump); 
         if(charRect.intersects(floorRect1)) 
         { 
          charRect.y = floorRect1.y - 32; 
          jumping = false; 
          moveRightWhileJumping = false; 
          moveLeftWhileJumping = false; 
          break; 
         } 
        } 
        else if(jump < 0) 
        { 
         charRect.y = charRect.y + Math.abs(jump); 
         if(charRect.intersects(floorRect1)) 
         { 
          charRect.y = floorRect1.y - 32; 
          jumping = false; 
          moveRightWhileJumping = false; 
          moveLeftWhileJumping = false; 
          break; 
         } 
        } 
        else 
        { 
         if(charRect.intersects(floorRect1)) 
         { 
          charRect.y = floorRect1.y - 32; 
          jumping = false; 
          moveRightWhileJumping = false; 
          moveLeftWhileJumping = false; 
          break; 
         } 
        } 

        t++; 
        Thread.sleep(30); 
       } 


       while(moveLeft) 
       { 
        repaint(charRect.x, charRect.y, 20, 32); 
        cont.validate(); 
        charRect.x = charRect.x - j; //Move Left speed. 
        if(charRect.intersects(wallRect1)) 
        { 
         charRect.x = wallRect1.x + 1; 
        } 
        if(charRect.intersects(floorRect1)) 
        { 
         charRect.y = floorRect1.y - 32; 
         jumping = false; 
         moveRightWhileJumping = false; 
         moveLeftWhileJumping = false; 
         break; 
        } 
        t++; 
        Thread.sleep(30); 
       } 


       while(moveRight) 
       { 
        repaint(charRect.x, charRect.y, 20, 32); 
        cont.validate(); 
        charRect.x = charRect.x + j; //Move Left speed. 
        if(charRect.intersects(wallRect1)) 
        { 
         charRect.x = wallRect1.x + 1; 
        } 
        if(charRect.intersects(floorRect1)) 
        { 
         charRect.y = floorRect1.y - 32; 
         jumping = false; 
         moveRightWhileJumping = false; 
         moveLeftWhileJumping = false; 
         break; 
        } 
        t++; 
        Thread.sleep(30); 
       } 
      } 
      catch(Exception e) 
      { 
       break; 
      } 
     } 
    } 
} 

}

回答

3

你的一個主要問題是,你直接畫在paint(...)方法JApplet的本身,而在一個JPanel或JCompnent的paintComponent(...)方法由小程序舉行。如果你使用後者,你將獲得Swing的默認雙緩衝的好處,這可以使所有的差異。此外,可以使用repaint(...)重載之一重新繪製GUI的較小矩形,但這是次要的。首先,你應該解決你的雙緩衝問題。

請與本教程開始學習基礎知識:Lesson: Performing Custom Painting

再往前就到這文章更高級的信息,關於擺動拉絲:Painting in AWT and Swing

編輯
此外,你應該從不讀取paint(...)paintComponent(...)方法中的文件,因爲這會降低繪畫速度,從而降低GUI的感知響應速度。爲什麼不簡單地在文件中讀取一次和在applet啓動時,然後將它們的內容存儲到變量中?

+1

在這個答案中有智慧... – 2012-07-10 01:03:32

相關問題