【问题标题】:Java Sprite Animation - Can't seem to get my sprite to redraw ProperlyJava Sprite Animation - 似乎无法让我的精灵正确重绘
【发布时间】:2016-09-18 10:25:39
【问题描述】:

我一直在尝试使用 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();

    }





}

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

【问题讨论】:

  • 使用 Canvas 的唯一原因是利用 BufferStrategy

标签: java swing animation canvas sprite


【解决方案1】:

最初的问题是,当我重新绘制画布时,以前的帧仍然存在于画布的背景中,因此为了解决这个问题,我添加了对 .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(...) );

【讨论】:

  • 嗯....我正在使用透明背景,我想保持透明。
  • 另外,我尝试调用 super.paint(g);方法,但它只是和 .clearRect();
【解决方案2】:

可能这个小示例代码可以帮助您...

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

它会绘制一个速度可控的玩家... 背景应该是透明的...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多