下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

如何运用JAVA绘制动态游戏角色

作者:课课家教育     来源: http://www.kokojia.com点击数:1498发布时间: 2018-12-01 09:11:22

标签: JAVA代码游戏制作JAVAWEB

大神带你学编程,欢迎选课

  如何运用java绘制动态游戏角色

  二.角色绘制开发过程

  1.新建一个java项目Chap6_1

import java.awt.*;

import java.awt.event.*;

import javax.swing.JFrame;

 

public class Chap6_1 {

 

    public Chap6_1() {

        Frame app = new Frame("GameFrame");

 

        app.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

  1. exit(0);

            }

        });

        app.setLocation(100, 100);

        MyPanel drawB = new MyPanel();

        app.add(drawB, BorderLayout.CENTER);

      

        app.pack();

        app.setVisible(true);

        drawB.gameStart();

    }

 

    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        new Chap6_1();

    // TODO code application logic here

    }

}

如何运用JAVA绘制动态游戏角色_JAVA代码_游戏制作_JAVA_课课家

  并在练习文件夹中复制images文件夹,在Chap6_1上右击,选择Paste,把images文件夹粘贴到项目文件夹中.如下图:

并在练习文件夹中复制images文件夹,在Chap6_1上右击,选择Paste,把images文件夹粘贴到项目文件夹中

并在练习文件夹中复制images文件夹,在Chap6_1上右击,选择Paste,把images文件夹粘贴到项目文件夹中

  粘贴好后:

  再在项目的src上右击,选择Paste粘贴,将images文件粘贴进src文件夹中:

再在项目的src上右击,选择Paste粘贴,将images文件粘贴进src文件夹中:

再在项目的src上右击,选择Paste粘贴,将images文件粘贴进src文件夹中:

  粘贴好后:

  2.建立一个主类Chap6_1(File-new-Class,输入类名Chap5),

  我们先温习以前学过的知识,给这个主类写上代码,代码如下:

  3.新建一个类MyPanel,(File-new-Class,输入类名MyPanel)

import java.awt.*;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

 

 

public class MyPanel extends Panel implements Runnable, KeyListener {

 

    public final static int width = 500;

    public final static int heigth = 400;

    private Image im;

    private Graphics dbg;

    private Thread gamethread;

    private static final int FPS = 50;

 

    public MyPanel() {

 

       

 

        this.setFocusable(true);

        this.requestFocus();

        this.addKeyListener(this);

        setBackground(Color.pink);

        setPreferredSize(new Dimension(width, heigth));

 

    }

 

    public void gameStart() {

 

        gamethread = new Thread(this);

        gamethread.start();

    }

 

    public void gamePaint() {

     Graphics g;

         try {

             g = this.getGraphics();

             if (g != null && im != null) {

                 g.drawImage(im, 0, 0, null);

             }

             g.dispose();

         } catch (Exception e) {

         }

    }

 

    public void gameRender() {

    if (im == null) {

            im = createImage(width, heigth);

            if (im == null) {

  1. out.println("im is null");

            } else {

                dbg = im.getGraphics();

            }

        }

        //下面画图

        dbg.setColor(Color.pink); //设置背景为粉红色

        dbg.fillRect(0, 0, width, heigth);//用背景色填充窗体的矩形框,擦除旧图片

 

      Image image = getToolkit().getImage("Images/p1.gif"); //先载入图片

      dbg.drawImage(image,100,100,100,131,this);

 

    }

 

    public void gameUpdate() {

        

 

    }

 

    public void run() {

        long t1,t2,dt,sleepTime;  

        long period=1000/FPS;  

        t1=System.nanoTime();

 

        while (true) {

            gameUpdate();

            gameRender();

            gamePaint();

            t2= System.nanoTime() ;

            dt=(t2-t1)/1000000L;

            sleepTime = period - dt;

            if(sleepTime<=0)        

                  sleepTime=2;

            try {     

  1. sleep(sleepTime);

           } catch (InterruptedException ex) { }

              t1 = System.nanoTime();  

        }

    }

 

    public void keyTyped(KeyEvent e) {

    }

 

    public void keyPressed(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            

 

        }

        if (keycode == e.VK_LEFT) {

            

        }

    }

 

    public void keyReleased(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            

 

        }

        if (keycode == e.VK_LEFT) {

            

 

        }

    }

}

  根据我们第二周学的画图知识,我们代码用下面的代码画出Images/p1.gif图片:

根据我们第二周学的画图知识,我们代码用下面的代码画出Images/p1.gif图片:

  因此,实际在游戏中,我们很少直接把一个动画gif图片显示在窗体上,这样会造成闪动情况,我们通常采取切割图片的方法。将一个动画切割成几个动作。

  4.新建一个类Animation,(File-new-Class,输入类名Animation),

  我们在这个类里实现动画,再用MyPanel调用它。

  Animation代码如下:

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.IOException;

import javax.imageio.ImageIO;

 

 

public class Animation {

    private BufferedImage[] Images;

    private int numImages;

    private boolean ticksStopped;

    private boolean isRepeating;

    private int animTime;

    private int animSpeed;

    private int animTotalTime;

    private int showTime;

    private int imPosition;

 

 

    public Animation(String fileName,int num,int speed,int totalTime,boolean repeat) {

        //单张图产生动画,filename表示图片文件名,speed表示速度,totalTime表示时间,repeat表示是否重复true重复,false不重复

    numImages=num;

        animSpeed=speed;

        animTotalTime=totalTime;

        isRepeating=repeat;

        

        animTime=0;

        Images=setAnimImagesFromOneFile(fileName,numImages);

 

        imPosition = 0;

        ticksStopped = false;

    }

 

    public Animation(String prefixfileName,String postfixFileName ,int num,int speed,int totalTime,boolean repeat) {

        //多张图产生动画

    numImages=num;

        animSpeed=speed;

        animTotalTime=totalTime;

        isRepeating=repeat;

 

        animTime=0;

        Images=this.setAnimImagesFromFiles(prefixfileName, postfixFileName, num);

 

        imPosition = 0;

        ticksStopped = false;

    }

 

    public BufferedImage loadImage(String fnm) {

    try {

            BufferedImage im = ImageIO.read(getClass().getResource(fnm));

            return im;

        } catch (IOException e) {

  1. out.println("Load Image error for ");

            return null;

        }

    }

 

    public BufferedImage[] setAnimImagesFromOneFile(String fnm, int num) {

    //单张图片的读取方法

        BufferedImage bim = loadImage(fnm);//读取名为fnm的文件

        BufferedImage[] ims = new BufferedImage[num];//定义数组存放num张图

        int imWidth = (int) bim.getWidth() / num; //图像的宽度

        int imHeight = bim.getHeight(); //图像高度

        Graphics g;

        //以下将单个文件中的图像分割成num个存放在数组ims

        for (int i = 0; i < num; i++) {

            ims[i]= new BufferedImage(imWidth,imHeight,BufferedImage.TYPE_INT_ARGB);

            g=ims[i].getGraphics();

            g.drawImage(bim, 0, 0, imWidth, imHeight, i*imWidth,0,(i*imWidth)+imWidth,imHeight, null);

            g.dispose();

        }

        return ims;

    }

 

   public BufferedImage[] setAnimImagesFromFiles(String prefixFileName,String postFileName, int num){

       //从一组图片中读取图片放进数组        

   BufferedImage[] ims = new BufferedImage[num];

       for(int i=0;i<num;i++){

           ims[i]=loadImage(prefixFileName+String.valueOf(i)+postFileName);

       }

               return ims;

   }

 

 

      public void updateImage()

  /* We assume that this method is called every animPeriod ms */

  {

    if (!ticksStopped) {

      // 更新动画播放时间

      animTime = (animTime + animSpeed) % (1000 * animTotalTime);

      showTime = (int) (1000 * animTotalTime / numImages);

      // 计算动画切换时间

      imPosition = (int) (animTime / showTime);   

 

      if ((imPosition == numImages-1) && (!isRepeating)) {  // 如果指向了图片数组中的最后一张,且不需要动了。

        ticksStopped = true;   // 停止动画

      }

    }

  }

      public BufferedImage getCurrentImage(){

          return Images[imPosition];

      }

        public void stop()

  /* updateTick() calls will no longer update the

     total animation time or imPosition. */

  {  ticksStopped = true;  }

 

  public boolean isStopped()

  {  return ticksStopped;  }

 

    public void resume()

  // start at previous image position

  {

    if (numImages != 0)

      ticksStopped = false;

  }

 

      public void draw(Graphics g,int x ,int y){

          BufferedImage im=Images[imPosition];

          g.drawImage(im, x, y, null);

      }

}

 

5.回去改写前面的MyPanel代码如下:

 

import java.awt.*;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

 

 

public class MyPanel extends Panel implements Runnable, KeyListener {

 

    public final static int width = 500;

    public final static int heigth = 400;

    private Image im;

    private Graphics dbg;

    private Thread gamethread;

    private static final int FPS = 50;

    private Animation   myAnimation;//实例化Animation对像

    private int x,y;//定义显示的坐标

    public MyPanel() {

 

        x=200;//最初显示的x坐标

        y=200;//最初显示的y坐标

    myAnimation=new Animation("/Images/duck_right.gif", 4,80, 2, true);

    //上面,4表示有四张图,80表示播放一组动画的总时间,2表示播放速度,true表示循环播放

        this.setFocusable(true);

        this.requestFocus();

        this.addKeyListener(this);

        setBackground(Color.pink);

        setPreferredSize(new Dimension(width, heigth));

 

    }

 

    public void gameStart() {

 

        gamethread = new Thread(this);

        gamethread.start();

    }

 

    public void gamePaint() {

     Graphics g;

         try {

             g = this.getGraphics();

             if (g != null && im != null) {

                 g.drawImage(im, 0, 0, null);

             }

             g.dispose();

         } catch (Exception e) {

         }

    }

 

    public void gameRender() {

    if (im == null) {

            im = createImage(width, heigth);

            if (im == null) {

  1. out.println("im is null");

            } else {

                dbg = im.getGraphics();

            }

        }

        //下面画图

        dbg.setColor(Color.pink); //设置背景为粉红色

        dbg.fillRect(0, 0, width, heigth);//用背景色填充窗体的矩形框,擦除旧图片

 

        myAnimation.draw(dbg, x, y);//调用Animation类中的draw方法,在x,y坐标处显示图片

 

    }

 

    public void gameUpdate() {

        myAnimation.updateImage();

 

    }

 

    public void run() {

        long t1,t2,dt,sleepTime;  

        long period=1000/FPS;  

        t1=System.nanoTime();

 

        while (true) {

            gameUpdate();

            gameRender();

            gamePaint();

            t2= System.nanoTime() ;

            dt=(t2-t1)/1000000L;

            sleepTime = period - dt;

            if(sleepTime<=0)        

                  sleepTime=2;

            try {     

  1. sleep(sleepTime);

           } catch (InterruptedException ex) { }

              t1 = System.nanoTime();  

        }

    }

 

    public void keyTyped(KeyEvent e) {

    }

 

    public void keyPressed(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            x++;//按下向右时,x增加

 

        }

        if (keycode == e.VK_LEFT) {

           x--;//按下向左时,x减少

        }

    }

 

    public void keyReleased(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            

 

        }

        if (keycode == e.VK_LEFT) {

            

 

        }

    }

}

 

  事实上,当我们控制移动时,向左和向右,选用的是不同的图像。所以上面的代码并不完美,我们还需要修改,实现向右显示的是duck_right.gif图片,向左显示的是duck_left.gif图片

  6.再修改MyPanel代码如下:

import java.awt.*;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

 

 

public class MyPanel extends Panel implements Runnable, KeyListener {

 

    public final static int width = 500;

    public final static int heigth = 400;

    private Image im;

    private Graphics dbg;

    private Thread gamethread;

    private static final int FPS = 50;

    private Animation   myAnimation1,myAnimation2;

    private int x,y;//定义显示的坐标

    private int d=1;//定义d表示方向,1表示向右,0表示向左

    public MyPanel() {

 

        x=200;

        y=200;

    myAnimation1=new Animation("/Images/duck_right.gif", 4,80, 2, true);

//定义向右的图片

    myAnimation2=new Animation("/Images/duck_left.gif", 4,80, 2, true);

//定义向左的图片

    //上面,4表示有四张图,80表示播放一组动画的总时间,2表示播放速度,true表示循环播放

        this.setFocusable(true);

        this.requestFocus();

        this.addKeyListener(this);

        setBackground(Color.pink);

        setPreferredSize(new Dimension(width, heigth));

 

    }

 

    public void gameStart() {

 

        gamethread = new Thread(this);

        gamethread.start();

    }

 

    public void gamePaint() {

     Graphics g;

         try {

             g = this.getGraphics();

             if (g != null && im != null) {

                 g.drawImage(im, 0, 0, null);

             }

             g.dispose();

         } catch (Exception e) {

         }

    }

 

    public void gameRender() {

    if (im == null) {

            im = createImage(width, heigth);

            if (im == null) {

  1. out.println("im is null");

            } else {

                dbg = im.getGraphics();

            }

        }

        //下面画图

        dbg.setColor(Color.pink); //设置背景为粉红色

        dbg.fillRect(0, 0, width, heigth);//用背景色填充窗体的矩形框,擦除旧图片

        if(d==1)

          myAnimation1.draw(dbg, x, y);//如果是向右,调用Animation1 

        if(d==0)

            myAnimation2.draw(dbg, x, y);//如果是向左,调用Animation2 

    }

 

    public void gameUpdate() {  

    if(d==1)

           myAnimation1.updateImage();

    if(d==0)

            myAnimation2.updateImage();

    }

 

    public void run() {

        long t1,t2,dt,sleepTime;  

        long period=1000/FPS;  

        t1=System.nanoTime();

 

        while (true) {

            gameUpdate();

            gameRender();

            gamePaint();

            t2= System.nanoTime() ;

            dt=(t2-t1)/1000000L;

            sleepTime = period - dt;

            if(sleepTime<=0)        

                  sleepTime=2;

            try {     

  1. sleep(sleepTime);

           } catch (InterruptedException ex) { }

              t1 = System.nanoTime();  

        }

    }

 

    public void keyTyped(KeyEvent e) {

    }

 

    public void keyPressed(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            x++;//按下向右时,x增加

            d=1;//方向向右

 

        }

        if (keycode == e.VK_LEFT) {

           x--;//按下向左时,x减少

           d=0;//方向向左

        }

    }

 

    public void keyReleased(KeyEvent e) {

        int keycode = e.getKeyCode();

        if (keycode == e.VK_RIGHT) {

            

 

        }

        if (keycode == e.VK_LEFT) {

            

 

        }

    }

}

  保存并运行,按向左右的箭头,看一下的移动效果。

赞(21)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程