2013-03-19 3 views
1

Я пытаюсь сделать перемещение спрайта по фоновому изображению в качели, но каждый раз, когда я обновляю позицию и ее перекрашиваю, она также перерисовывается с предыдущей позицией изображения. Однако я просто пытаюсь сделать это так, чтобы он перемещал 10 пикселей за каждый раз при нажатии правой стрелки. Вот основной класс, который контролирует движение.Проблема с анимацией качания?

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. Вместо этого используйте JComponent или JPanel. Override paintComponent() для рисования, а не paint() и не забудьте позвонить super.paintComponent(g)

Посмотрите на Performing Custom Painting учебник для получения дополнительной информации.

Кроме того, прослушиватель клавиш является интерфейсом более низкого уровня. Лучше всего использовать Key Bindings. См. How to Use Key Bindings для получения более подробной информации и примеров.

Кроме того, нет необходимости создавать ImageIcon, чтобы получить Image. Посмотрите на методы ImageIO.read().

+0

Также см. Этот хороший [пример] (http://stackoverflow.com/a/9772966/1048330) от @mKorbel, который демонстрирует, как перемещать значок вокруг панели с помощью привязок клавиш. – tenorsax

+0

Спасибо! Я сделал это, и это было очень полезно. Но знаете ли вы, почему изображение по-прежнему перекрашивается рядом с собой на прежней позиции? Я пытаюсь заставить спрайт оживить, перемещая пиксели, но он, похоже, не работает. Есть предположения? –

+0

@ JakeByman, пожалуйста! Я не мог воспроизвести проблему с артефактами живописи в опубликованном коде. Убедитесь, что вы запустили приложение с помощью 'invokeLater', см. [Начальные потоки] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). Попробуйте написать SSCCE, поэтому проще запустить и воспроизвести проблему. – tenorsax

Смежные вопросы