Java精灵动画 - 似乎无法让我的精灵正确地重绘

时间:2016-05-21 04:13:14

标签: java swing animation canvas sprite

我一直在用Java尝试一些精灵动画并重新绘制它,但是我似乎无法让我的精灵在Canvas上正确地重绘。起初问题是,当我重新绘制它时,之前的帧仍然在Canvas的背景中,所以为了解决这个问题我添加了对.clearRect()的调用;然而,虽然添加对该函数的调用确实解决了这个问题,但它导致我开始像疯了一样丢失帧。我已经搜索并尝试了一些东西,但可以找到解决方案,并且尽可能接近我的想象.clearRect()有时会在.drawImage()之后执行。我的画布代码就像Fallows:

package rpg;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

public class Sprite extends Canvas{

    /**
     * 
     */
    private BufferedImage img;
    private static final long serialVersionUID = 1L;

    public Sprite(int width, int height, BufferedImage img){
        this.img = img;
        setSize(width, height);
    }
    @Override
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;
        g2d.clearRect(0, 0, this.getWidth(), this.getHeight());
        g2d.drawImage(img, 0, 0, null);
        g2d.dispose();
    }

    @Override
    public void update(Graphics g) {
        paint(g);

     }

    public void changeSprite(BufferedImage img)
    {
        this.img = img;
        repaint();

    }





}

注意:我使用透明背景并希望保持透明。

2 个答案:

答案 0 :(得分:1)

  

起初问题是,当我重新绘制它时,前面的帧仍然在Canvas的背景中,所以为了解决这个问题我添加了对.clearRect()的调用;

不要使用clearRect()。相反,您应该使用fillRect(...)绘制组件的背景颜色。

以下内容来自clearRect()方法的API:

从Java 1.1开始,屏幕外图像的背景颜色可能与系统有关。应用程序应使用setColor,后跟fillRect,以确保将屏幕外图像清除为特定颜色。

但是,你甚至不需要这样做。当您重写绘制方法时,您需要调用super.thePaintingMethod(...)。在这种情况下,您尝试覆盖paint()方法,因此第一个语句应为:

super.paint(g);

然后组件的默认绘制代码将为您绘制背景。

另外,这不是Swing绘画代码。这是AWT代码。你真的应该正确标记你的问题。我们不知道您是否真的尝试使用Swing技术进行绘画,或者您是否找到旧的AWT绘画代码并假设它在Swing中是相同的。

  

我正在使用透明背景

嗯......你为什么要尝试使用AWT?你仍然没有资格问题。由于您尚未删除“Swing”标记,因此我假设您使用的是Swing。

使用Swing代码将是:

JLabel sprite = new JLabel( new ImageIon(...) );

就是这样。一行代码。不需要自定义类。

要更改图像,您只需使用:

sprite.setIcon( new ImageIcon(...) );

答案 1 :(得分:0)

可能这个小例子代码可以帮助你...

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.EventQueue;

class Player {
     public float health;
     public float yvel;
     public float xvel;
     public float x;
     public float y;
     public BufferedImage image;
     public void work(Graphics g, int[] keys) {
         g.drawImage(image,(int)x,(int)y,null);
         if (keys[0]==1) { //Is the UP-Key pressed
             yvel=yvel-1;
         }
         if (keys[1]==1) { //Is the DOWN-Key pressed
             yvel=yvel+1;
         }
         if (keys[2]==1) { //Is the LEFT-Key pressed
             xvel=xvel-1;
         }
         if (keys[3]==1) { //Is the RIGHT-Key pressed
             xvel=xvel+1;
         }
         x=x+xvel;
         y=y+yvel;
         xvel=xvel-(xvel/4); //One fourth gets lost
         yvel=yvel-(yvel/4); //One fourth gets lost
     }

     public Player(BufferedImage imagew,float xw, float yw, float healthw) {
         x=xw;
         y=yw;
         image=imagew;
         health=healthw;
     }
}
public class Game extends JFrame implements KeyListener {
     public BufferedImage playerimage;
     public Player player;
     public int[] keys=new int[4];

     public void keyTyped(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_UP) {
                 keys[0]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                 keys[1]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                 keys[2]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                 keys[3]=1;
             }
     }
     public void keyReleased(KeyEvent e) { 
             if (e.getKeyCode() == KeyEvent.VK_UP) {
                 keys[0]=0;
             }
             if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                 keys[1]=0;
             }
             if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                 keys[2]=0;
             }
             if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                 keys[3]=0;
             }
     }
     public void keyPressed(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_UP) {
                 keys[0]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                 keys[1]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                 keys[2]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                 keys[3]=1;
             }
             if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                 keys[4]=1;
             }
     } 
     public Game(){
          super("Game");
          try {
          playerimage = ImageIO.read(getClass().getClassLoader().getResource("player.gif")); //Player Image
          } catch(IOException bug) {
          System.out.println(bug);
          }

          player=new Player(playerimage,100,100,100);

          addKeyListener(this);

          setTitle("Game");

          setContentPane(new Pane());

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          setSize(800, 600);

          setResizable(false);

          setVisible(true); 

          long start = System.currentTimeMillis();

          while (true){
              long now = System.currentTimeMillis();
              if (now-start > 40) {
                  System.out.println("FPS : "+Long.toString(1000/(now-start)));
                  start=now;
                  framec++;
                  if (framec==250) {
                      System.gc();
                  }
                  validate();
                  repaint();
              }
          }
     }


     class Pane extends JPanel{
        public Pane() {
        }
        public void paintComponent(Graphics g){
            player.work(g,keys);
        }   
     }
     public static void main(String args[]){
            new Game();
     }
}

它以速度吸引可控制的玩家...... 背景应该是透明的......