2013-03-19 42 views
1

我想讓一個雪碧在擺動中穿過背景圖像,但每次我更新位置並重新繪製時,它都會重新繪製圖像的前一個位置。不過,我只是想讓它每移動一次右箭頭就移動10個像素。這是Main類,它控制着運動。擺動動畫問題?

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import javax.swing.*; 

public class Main extends JFrame implements KeyListener, ActionListener{ 
    private static final long serialVersionUID = 1L; 

    //Caitlan info 
    Image caitlanImage = new ImageIcon("Caitlan.png").getImage(); 
    Person caitlan = new Person(caitlanImage, "Caitlan", 50, 200, true); 

    //Jake info 
    Image jakeImage = new ImageIcon("Jake.png").getImage(); 
    Person jake = new Person(jakeImage, "Jake", 0, 200, true); 

    //Level objects 
    Image granadaBackground = new ImageIcon("Granada Background.jpg").getImage(); 
    Level granada = new Level(granadaBackground, "Granada", new Point(600, 300)); 

    Image elevatorBackground = new ImageIcon("Elevator.png").getImage(); 
    Level elevator = new Level(elevatorBackground, "Elevator", new Point(0,0)); 



    public static void main(String[] args) throws InterruptedException{ 
     new Main(); 
    } 
    public Main() throws InterruptedException{ //Constructor (only should be called once) 
     setSize(700,300); 
     setTitle("Project Anniversary"); 
     setVisible(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     addKeyListener(this); 
    } 
    public void paint(Graphics g){  //Overridden paint method. 

     if(checkIfLevelDone(granada, caitlan)){ 
      granada.setDone(); 
     } 
     if(!granada.isDone()){ 
      g.drawImage(granada.getImage(), 0, 0, granadaBackground.getWidth(null), granadaBackground.getHeight(null),null); 
      g.drawImage(jake.getImage(), jake.getPosX(), jake.getPosY(), jake.getImage().getWidth(null), jake.getImage().getHeight(null),null); 
      g.drawImage(caitlan.getImage(), caitlan.getPosX(), caitlan.getPosY(), caitlan.getImage().getWidth(null), caitlan.getImage().getHeight(null), null); 
     } 
     else if(granada.isDone()){ 
      setSize(300,300); 
      g.drawImage(elevator.getImage(), 0, 0, 
    elevator.getImage().getWidth(null), elevator.getImage().getHeight(null),null); 
      g.drawImage(jake.getImage(), jake.getPosX(), jake.getPosY(), 
    jake.getImage().getWidth(null), jake.getImage().getHeight(null),null); 
      g.drawImage(caitlan.getImage(), caitlan.getPosX(), caitlan.getPosY(), 
    caitlan.getImage().getWidth(null), caitlan.getImage().getHeight(null), null); 
     } 
    } 
    public void keyPressed(KeyEvent e) { //Method called whenever a key is pressed 
     caitlan.printLocation(); 
     int code = e.getKeyCode(); 
     if(code == KeyEvent.VK_RIGHT){ //When the user presses the right arrow 
      caitlan.setLocation(caitlan.getPosX() + 10, caitlan.getPosY()); 
      repaint(); 
     } 
     if(code == KeyEvent.VK_LEFT){ //When the user presses the left arrow 
      caitlan.setLocation(caitlan.getPosX() - 10, caitlan.getPosY()); 
      repaint(); 
     } 
     if(code == KeyEvent.VK_UP){   //Implement jumping code here 
      repaint(); 
     } 
    } 
    public boolean checkIfLevelDone(Level l, Person p){ 
    //Method to check if a given level is done 
     if(l.getCompletionPoint().x <= p.getPosX()){ 
      return true; 
     } 
     return false; 
    } 
    public void followOtherPerson(Person a, Person b) throws InterruptedException{    
    //Method to follow the other character 

    } 
    public void jump(Person p) throws InterruptedException{  //Jump method 
     caitlan.setLocation(caitlan.getPosX(), caitlan.getPosY() - 60); 
     repaint(); 
    } 
    public void keyReleased(KeyEvent e) {   //IGNORE 

    } 
    public void keyTyped(KeyEvent e) {    //IGNORE 

    } 
    public void actionPerformed(ActionEvent e) { //IGNORE 


    } 

    } 

這裏是級別類:

import java.awt.Image; 
import java.awt.Point; 

public class Level { 

//Private attributes 
private Image backgroundImage;   //Image 
private String levelName;    //Name of level 
private boolean levelComplete;  //Status that holds if the level is done 
private Point completionPoint;  //Point at which the level is completed 

public Level(Image i, String l, Point p){  //Constructor 
    this.backgroundImage = i; 
    this.levelName = l; 
    this.completionPoint = p; 
    levelComplete = false; 
} 
public void setDone(){ 
    levelComplete = true; 
} 
public boolean isDone(){  //Returns if the level is done or not 
    return levelComplete; 
} 
public Image getImage(){   //Getters and setters 
    return backgroundImage; 
} 
public String getLevelName(){ 
    return levelName; 
} 
public void setImage(Image i){ 
    this.backgroundImage = i; 
} 
public void setName(String name){ 
    this.levelName = name; 
} 
public Point getCompletionPoint(){ 
    return completionPoint; 
} 
public void setCompletionPoint(Point p){ 
    this.completionPoint = p; 
} 

} 

最後,這裏是Person類。

import java.awt.*; 

public class Person{ 

    //Attributes 
    private Image image; 
    private String name; 
    private int xlocation; 
    private int ylocation; 

    /*Boolean that you can publically access to determine if the given Person object is a 
    player*/ 
    public boolean isPlayer;  

    public Person(Image i, String s){  //Really shouldn't be used 
     this.image = i; 
     this.name = s; 
    } 
    public Person(Image i){    //Really shouldn't be used 
     this.image = i; 
    } 
    public Person(Image i, String s, int xloc, int yloc){  //Basic constructor 
     this.name = s; 
     this.image = i; 
     this.xlocation = xloc; 
     this.ylocation = yloc; 
    } 
    public Person(Image i, String s, int xloc, int yloc, boolean isPlayer){ //Detailed constructor 
     this.name = s; 
     this.image = i; 
     this.xlocation = xloc; 
     this.ylocation = yloc; 
     this.isPlayer = isPlayer; 
    } 
    public void printLocation(){ 
     System.out.println("Person " + name + " is at location (" + xlocation +", " + ylocation +")."); 
    } 
    public void incrementPositionX(){      //Increase xlocation by 1 
     xlocation++; 
    } 
    public void incrementPositionY(){      //Increase ylocation by 1 
     ylocation++; 
    } 
    public void setName(String name){      //Method to change the name of a sprite 
     this.name = name; 
    } 
    public void setImage(Image image){ //Method to change the image of a sprite 
     this.image = image; 
    } 
    public Image getImage(){    //Get image 
     return image; 
    } 
    public int getPosX(){     //Get x position 
     return xlocation; 
    } 
    public int getPosY(){     //Get y position 
     return ylocation; 
    } 
    public String getName(){    //Get name 
     return name; 
    } 
    public void setLocation(int x, int y){ //Method to change the location of a sprite 
     this.xlocation = x; 
     this.ylocation = y; 
    } 
} 

回答

4

您不應該直接在頂層容器上塗漆,如JFrame。請改用JComponentJPanel。覆蓋paintComponent()繪畫,而不是paint(),不要忘記打電話super.paintComponent(g)

看看Performing Custom Painting教程瞭解更多信息。

此外,鍵監聽器是一個較低級別的接口。最好使用Key Bindings來代替。有關詳細信息和示例,請參見How to Use Key Bindings

此外,沒有必要創建ImageIcon得到Image。查看ImageIO.read()方法。

+0

另請參閱@mKorbel的[示例](http://stackoverflow.com/a/9772966/1048330),演示如何使用鍵綁定在面板周圍移動圖標。 – tenorsax 2013-03-19 17:45:28

+0

謝謝!我這樣做了,這非常有幫助。但是你是否知道爲什麼這幅圖像在它之前的位置上仍然在重新繪製?我試圖通過移動像素來使精靈動畫,但它似乎不工作。有什麼想法嗎? – 2013-03-19 18:05:39

+0

@JakeByman不客氣!我無法在發佈的代碼中重複繪製工件。確保你用'invokeLater'啓動應用程序,參見[初始線程](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)。嘗試撰寫SSCCE,以便更容易地運行和重現問題。 – tenorsax 2013-03-19 18:17:51