Java的移动动画(精灵) [英] Java a moving animation (sprite)

查看:163
本文介绍了Java的移动动画(精灵)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好i`ve有一个问题:当我运行此code我得到这样的:

Hello i`ve got a problem: when i run this code i get this:


在一些Java论坛,他们说我需要添加Graphics2DObject.clearRect(X1,Y1,X2,Y2);
(where`s X1和Y1是图像和x2 Y2的坐标是图像的宽高)。当我把它添加到code我得到这样的:

on some java forum they said i need to add Graphics2DObject.clearRect(x1, y1, x2, y2); (where`s x1 and y1 is coordinates of the image and x2 y2 is width height of the image.) when i add it to the code i get this:

在code(带附加功能):

The code(with added function):

主营:

import java.awt.*; 
import javax.swing.*;
public class Main {
    public static void main(String []args){
        Main b = new Main();
        b.run();
    }
    private Sprite sprite;
    private Animation a;
    private ScreenManager s;
    public double sk = 0;

    private static final DisplayMode modes1[] = {
        new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN),
    };

    //load images and add scenes
    public void loadImages() {
        Image face1 = new ImageIcon("C:\\1.jpg").getImage();
        Image face2 = new ImageIcon("C:\\2.jpg").getImage();

        a = new Animation();
        a.addScene(face1, 50);
        a.addScene(face2, 50);

        sprite = new Sprite(a);
        sprite.setVelocityX(0.3f);
        sprite.setVelocityY(0.3f);


    }

    //main method called from main
    public void run() {
        s = new ScreenManager();
        try {
            DisplayMode dm = s.findFirstCompatibleMode(modes1);
            s.setFullScreen(dm);
            loadImages();
            movieLoop();
        }finally {
            s.restoreScreen();
        }
    }

    //play movie
    public void movieLoop() {
        long startingTime = System.currentTimeMillis();
        long cumTime = startingTime;

        while(cumTime - startingTime < 5000) {
            long timePassed = System.currentTimeMillis() - cumTime;
            cumTime += timePassed;
            update(timePassed);

            //draw and update the screen
            Graphics2D g = s.getGraphics();
            draw(g);
            g.dispose();
            s.update();

            try{
                Thread.sleep(20);
            }catch(Exception ex) {
                System.err.println("Error: " + ex);
            }
        }
    }


    // Graphics with new function
    public void draw(Graphics g) {
        g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
        if(sk != 1){
       g.clearRect(Math.round(sprite.getoX()),Math.round(sprite.getoY()),Math.round(sprite.getWidth()),Math.round(sprite.getHeight()));
        }else{
          sk = 1;
       }

    }

    //update sprite
    public void update(long timePassed) {
        if(sprite.getX() < 0) {
            sprite.setVelocityX(Math.abs(sprite.getVelocityX()));
        } else if (sprite.getX() + sprite.getWidth() >= s.getWidth()) {
            sprite.setVelocityX(-Math.abs(sprite.getVelocityX()));
        }

        if(sprite.getY() < 0) {
            sprite.setVelocityY(Math.abs(sprite.getVelocityY()));
        } else if (sprite.getY() + sprite.getHeight() >= s.getHeight()) {
            sprite.setVelocityY(-Math.abs(sprite.getVelocityY()));
        }

        sprite.oldX();
        sprite.oldY();
        sprite.update(timePassed);
    }


}

的精灵(运动类):

The sprite (movement class):

import java.awt.Image;

public class Sprite {

    private Animation a;
    private float x;
    private float y;
    private float vx;
    private float vy;
    private float ox;
    private float oy;


    //Constructor
    public Sprite(Animation a) {
        this.a = a;
    }


    // Get old x and y to delete them later

    public void oldX(){
       this.ox = x;
    }

    public void oldY(){
       this.oy = y;
    }

    public float getoX(){
       return ox;
    }
    public float getoY(){
       return oy;
    }



    //Change position
    public void update(long timePassed) {
        x += vx * timePassed;
        y += vy * timePassed;
        a.update(timePassed);
    }

    //get x position
    public float getX() {
        return x;
    }

    //get y position
    public float getY() {
        return y;
    }

    //set x position
    public void setX(float x) {
        this.x = x;
    }

    //set y position
    public void setY(float y) {
        this.y = y;
    }

    // get sprite width
    public int getWidth() {
        return a.getImage().getWidth(null);
    }

    // get sprite height
    public int getHeight() {
        return a.getImage().getHeight(null);
    }

    //get horizontal velocity
    public float getVelocityX() {
        return vx;
    }

    //get vertical velocity
    public float getVelocityY() {
        return vy;
    }

    //set horizontal velocity
    public void setVelocityX(float vx) {
        this.vx = vx;
    }

    //set vertical velocity
    public void setVelocityY(float vy) {
        this.vy = vy;
    }

    //get sprite/image
    public Image getImage() {
        return a.getImage();
    }
}

屏幕管理器类:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;

public class ScreenManager {

    private GraphicsDevice vc;

    //Constructor // give vc access to monitor screen
    public ScreenManager() {
        GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
        vc = e.getDefaultScreenDevice();
    }

    //get all compatible DM's
    public DisplayMode[] getCompatibleDisplayModes() {
        return vc.getDisplayModes();
    }

    //compares DM passed in to vc and see if they match
    public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
        DisplayMode goodModes[] = vc.getDisplayModes();

        for(int x = 0; x <modes.length; x++){
            for(int y = 0; y < goodModes.length; y++){
                if(displayModesMatch(modes[x], goodModes[y])) {
                    return modes[x];
                }
            }
        }
        return null;
    }

    //get current DM
    public DisplayMode getCurrentDisplayMode() {
        return vc.getDisplayMode();
    }

    //checks if two modes match each other
    public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) {
        if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()) {
            return false;
        }

        if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()) {
            return false;
        }

        if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()) {
            return false;
        }

        return true;
    }

    //make frame full screen
    public void setFullScreen(DisplayMode dm) {
        JFrame f = new JFrame();
        f.setUndecorated(true);
        f.setIgnoreRepaint(true);
        f.setResizable(false);
        vc.setFullScreenWindow(f);

        if(dm != null && vc.isDisplayChangeSupported()) {
            try{
                vc.setDisplayMode(dm);
            }catch(Exception e) {System.out.println("");}
        }
        f.createBufferStrategy(2);

    }

    //we will set Graphics object = to this
    public Graphics2D getGraphics() {
        Window w = vc.getFullScreenWindow();
        if(w != null) {
            BufferStrategy s = w.getBufferStrategy();
            return (Graphics2D)s.getDrawGraphics();
        }
        else {
            return null;
        }
    }

    //updates display
    public void update() {
        Window w = vc.getFullScreenWindow();
        if(w != null) {
            BufferStrategy s = w.getBufferStrategy();
            if(!s.contentsLost()) {
                s.show();
            }
        }
    }

    //returns full screen window
    public Window getFullScreenWindow() {
        return vc.getFullScreenWindow();
    }

    //get width
    public int getWidth() {
        Window w = vc.getFullScreenWindow();
        if(w != null) {
            return w.getWidth();
        }
        else {
            return 0;
        }
    }

    //get height
    public int getHeight() {
        Window w = vc.getFullScreenWindow();
        if(w != null) {
            return w.getHeight();
        }
        else {
            return 0;
        }
    }

    //get out of full screen
    public void restoreScreen(){
        Window w = vc.getFullScreenWindow();
        if(w != null) {
            w.dispose();
            vc.setFullScreenWindow(null);
        }
    }

    //create image compatible with monitor
    public BufferedImage createCompatibleImage(int w, int h, int t) {
        Window win = vc.getFullScreenWindow();
        if(win != null) {
            GraphicsConfiguration gc = win.getGraphicsConfiguration();
            return gc.createCompatibleImage(w, h, t);
        }
        return null;
    }





}/////////END///////////

动画类

import java.util.ArrayList;
import java.awt.Image;

public class Animation {

    private ArrayList scenes;
    private int sceneIndex;
    private long movieTime;
    private long totalTime;

    //Constructor
    public Animation() {
        scenes = new ArrayList();
        totalTime = 0;
        start();
    }

    //add scenes to the array list and set time for each scene
    public synchronized void addScene(Image i, long t) {
        totalTime += t;
        scenes.add(new Onescene(i, totalTime));
    }

    //start animation from beginning
    public synchronized void start() {
        movieTime = 0;
        sceneIndex = 0;
    }

    //change scenes
    public synchronized void update(long timePassed) {

        if(scenes.size() > 1 ) {
            movieTime += timePassed;

            if(movieTime >= totalTime) {
                movieTime = 0;
                sceneIndex = 0;
            }
            while(movieTime > getScene(sceneIndex).endTime) {
                sceneIndex++;
            }
        }
    }

    //get animations current scene
    public synchronized Image getImage() {

        if(scenes.size() == 0) {
            return null;
        }

        else {
            return getScene(sceneIndex).pic;
        }
    }

    //get scene
    private Onescene getScene(int x) {
        return (Onescene)scenes.get(x);
    }

    /////PRIVAT INNER CLASS/////
    private class Onescene{
        Image pic;
        long endTime;

        public Onescene(Image pic, long endTime) {
            this.pic = pic;
            this.endTime = endTime;
        }
    }






}////END/////

修改

可能有人尝试运行此code?

Could someone try running this code ?

也许你会发现我犯的错误...

Maybe You'll find the mistakes I made...

推荐答案

您回路看起来有点不正确

Your loop looks a bit incorrect

       Graphics2D g = s.getGraphics();  
      while(cumTime - startingTime < 5000) {
        long timePassed = System.currentTimeMillis() - cumTime;
        cumTime += timePassed;
        update(timePassed);

        //draw and update the screen
        draw(g);
        g.dispose();
        s.update();

        try{
            Thread.sleep(20);
        }catch(Exception ex) {
            System.err.println("Error: " + ex);
        }
    }
}

也尝试一下本作的画法。

also try this for your draw method.

// Graphics with new function
public void draw(Graphics g) {
    g.clearRect(0,0,800,600);
    g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
}

这篇关于Java的移动动画(精灵)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆