游戏框架_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 游戏框架

游戏框架

 2013/10/6 3:41:51  zhongnansxf  程序员俱乐部  我要评论(0)
  • 摘要:时隔好久才来写技术博客,其实我写技术博客就是想提醒自己学会了一些什么东西,把我认为很重要的东西记录下来,如果我没有弄懂这个东西我是不会随便乱写的,因为我觉得写技术博客首先就是写给自己看,其次是给大家看,自己都没弄懂那你写的东西大家也会看不懂的。下面这个问题是我们最近学的游戏框架问题,主要就是为了解决规范化的书写代码,可以把你的代码供他人使用,就像我们平常用的东西就是其他人写好的供我们用,代码的好坏就是看代码够不够简洁,容不容易更改,可不可以打包发给其他人使用而不出问题
  • 标签:游戏

时隔好久才来写技术博客,其实我写技术博客就是想提醒自己学会了一些什么东西,把我认为很重要的东西记录下来,如果我没有弄懂这个东西我是不会随便乱写的,因为我觉得写技术博客首先就是写给自己看,其次是给大家看,自己都没弄懂那你写的东西大家也会看不懂的。下面这个问题是我们最近学的游戏框架问题,主要就是为了解决规范化的书写代码,可以把你的代码供他人使用,就像我们平常用的东西就是其他人写好的供我们用,代码的好坏就是看代码够不够简洁,容不容易更改,可不可以打包发给其他人使用而不出问题。

本次要做的就是一个“打飞机”的游戏,就是飞机可以不断的移动并且子弹是自动发射,中途不断有boss出现,boss也会发出子弹,背景是在星空。我们要做的是让代码看起来清晰、容易修改。

在这其中我们需要有

????????? 1.一个移动物体Moveable接口,在这个类中要有方法:移动方法move()、draw()画出自己模样的方法、canRemove()移除方法:当物体不再需要而进行移除;而飞机plane、boss、bullet(子弹)implements这个接口,实现其中的方法,规定自己的移动规则等。

????????

class="java">package Model2;

import java.awt.Graphics;
/**
 * 游戏里面的实体接口类
 * 游戏中的每个实体,如人物、怪物,敌人等都要实现该接口
 *
 */
public interface Moveable {

	/**
	 * 物体移动的方法
	 * 每个物体的特性、移动规律等都不相同,要在具体的实现类中去实现
	 */
	public void move();
	
	/**
	 * 物体绘制方法
	 * 将物体画到UI界面上,具体要怎么画,每个物体都不一样,都要在各自具体的实现类中去实现
	 * @param g 物体要画到哪个界面上去的画布
	 */
	public void draw(Graphics g);
	
	/**
	 * 判断物体是否可以被删除了
	 * @return
	 */
	public boolean canRemove();
}

?2.Data类,在这个类中存放的是整个游戏的所有数据,这是为了方便修改,然而这个类要写成单实例,所谓单实例就是只允许有一个类的对象,而实现这个就是要做一标识instance,有个getInstance()方法,如果instance是null,则新new? Data()否则返回instance此类中包括移动物体的图片,界面的宽、高获以及取这些数据的方法,还要有队列,因为每次画的物体都要保存到队列中具体类的内容如下

?

package com.sxf0912第二节课;

import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import Model2.Moveable;
import Model2.Plane;

public class Data {
	private static Data intertance;
	private int ScreenWidth=400;
	private int ScreenHeight=400;
	private Plane plane;
	public Plane getPlane() {
		//System.out.print(planeImage.getImage().getHeight( null));
		return plane;
		
	}
	public void setPlane(Plane plane) {
		this.plane = plane;
		//System.out.print(planeImage.getImage().getHeight( null));
		
	}
       //定义一个线程安全队列保存所有移动的物体
	private List<Moveable> moveList=java.util.Collections.synchronizedList(new ArrayList<Moveable>());
	//背景图片、飞机图片、boss图片、子弹爆炸图片数组
        private ImageIcon bgImage=new ImageIcon("image/BJ.png");
	private ImageIcon planeImage=new ImageIcon("image/plane.png");
	private ImageIcon bossImage=new ImageIcon("image/boss.png");
	private ImageIcon[] bulletIcons = {new ImageIcon("image/0.PNG"),new ImageIcon("image/1.PNG"),new ImageIcon("image/2.PNG"),new ImageIcon("image/3.PNG"),new ImageIcon("image/4.PNG"),new ImageIcon("image/5.PNG"),new ImageIcon("image/6.PNG"),new ImageIcon("image/7.PNG")};
	public ImageIcon getBossImage() {
		return bossImage;
	}

	public ImageIcon[] getBulletIcons() {
		return bulletIcons;
	}

	public ImageIcon getPlaneImage() {
		return planeImage;
	}

	public ImageIcon getBgImage() {
		return bgImage;
	}

	private Data(){
		
	}

	public static Data getIntertance() {
		if(intertance==null){
			intertance= new Data();
		}
		return intertance;
	}

	public int getScreenWidth() {
		return ScreenWidth;
	}

	public int getScreenHeight() {
		return ScreenHeight;
	}

	public List<Moveable> getMoveList() {
		return moveList;
	}
}

?3.control类,这是一个线程类,控制移动的物体,因为移动的物体有很多所以继承thread,move()方法是要把从Data类中的队列取出来,然后再调用队列中moveable的move()方法,具体代码如下

package com.sxf0912第二节课;

import java.util.List;

import Model2.Boss;
import Model2.Moveable;

//控制类, 控制游戏中所有物体的移动,及生成新的敌人等物体
public class Control extends Thread {

	private int n;
	public void run(){
		while(true){
			move();
			try{
				sleep(20);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
			if(n++%500==0){
                                //出现boss
				Boss boss=new Boss();
				Data.getIntertance().getMoveList().add(boss);
			}
				
		}
	}
	public void move(){
		Data data=Data.getIntertance();
		List<Moveable> moveList=data.getMoveList();
		for(int i=0;i<moveList.size();i++){
			Moveable moveable=moveList.get(i);
			if(moveable.canRemoved()){
???
                            moveList.remove(moveable);

????                        i--;
???
                        } else {
????moveable.move();
??
                          ?}		
               }
	}
}

?4.UI类,界面类实现Runnable接口,其中方法initUI()是界面初始化,规定大小,结构,可见性等,drawbg()方法画背景的方法,从Data中取得背景图片,画两次,因为背景不断移动,为的是两次刚好接上,而且因为背景是动的,y值不断改变,所以每次调用此方法后要将y值变为0,drawMoveable():画出移动的物体,将存放移动物体的队列从Data中取出来,便利,在调用moveable的draw()方法进行画图在指定的画布上,draw()方法,为了让图片看起来是动的而不用画完擦除,采用缓冲的方法,首先获得缓冲图片的画布,将背景和移动的物体依次画在缓冲图片画布上,然后再将窗体画布上画上缓冲图片,还有键盘监听器,给飞机加上键盘监听器,因为这里需要用到飞机所以在Data类中要将飞机设置成属性具体代码如下:

package com.sxf0912第二节课;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

import Model2.Moveable;
import Model2.Plane;

public class UI implements Runnable {

	private JFrame jf=new JFrame();
	public void initUI(){
		Data data =Data.getIntertance();
		jf.setSize(data.getScreenWidth(),data.getScreenHeight());
		jf.setLocationRelativeTo(null);
		jf.setResizable(false);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setVisible(true);
		jf.addKeyListener(keylistener);
		}
	public void run() {
		Graphics graphics=jf.getGraphics();
		while(true){
			draw(graphics);
			try{
				Thread.sleep(20);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		
		
	}
	public void draw(Graphics graphics){
		//创建图片缓冲对象
		BufferedImage  image =new BufferedImage (jf.getWidth(), jf.getHeight(), BufferedImage.TYPE_INT_RGB);
		Graphics g=image.getGraphics();
		//画背景在缓冲区的图片上
		drawbg(g);
                //在缓冲区画移动的物体
		drawMoveable(g);
                //将缓冲区的图片画到界面上
		graphics.drawImage(image, 0, 0, jf);
		
	}
	private Data data=Data.getIntertance();
	private int bgX,bgY;
	private void drawbg(Graphics g){
	              //g.setColor(jf.getBackground());
                      // g.fillRect(0, 0, jf.getWidth(), jf.getHeight());
		ImageIcon image=data.getBgImage();
		g.drawImage(image.getImage(), bgX, bgY, jf);
		g.drawImage(image.getImage(), bgX, bgY-image.getIconHeight(), jf);
		bgY++;//让图片动起来
		if(bgY>jf.getHeight()){
			bgY=0;
		}
	}
	private void drawMoveable(Graphics g){
		
		List<Moveable> moveList=data.getMoveList();
		for(int i=0;i<moveList.size();i++){
			Moveable moveable =moveList.get(i);
			moveable.draw(g);
		}
	}
	KeyListener keylistener =new KeyListener(){

		@Override
		public void keyTyped(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyPressed(KeyEvent e) {
			Plane plane =data.getPlane();
			int code =e.getKeyCode();
			switch (code){
			case KeyEvent.VK_LEFT:
				plane.leftMove(true);
				break;
			case KeyEvent.VK_RIGHT:
				plane.rightMove(true);
				break;
			case KeyEvent.VK_UP:
				plane.upMove(true);
				break;
			case KeyEvent.VK_DOWN:
				plane.downMove(true);
				break;
			}
			
			
			
		}

		@Override
		public void keyReleased(KeyEvent e) {
			Plane plane =data.getPlane();
			int code =e.getKeyCode();
			switch (code){
			case KeyEvent.VK_LEFT:
				plane.leftMove(false);
				break;
			case KeyEvent.VK_RIGHT:
				plane.rightMove(false);
				break;
			case KeyEvent.VK_UP:
				plane.upMove(false);
				break;
			case KeyEvent.VK_DOWN:
				plane.downMove(false);
				break;
			
		   }
	    }
		
	};

}

?

?5.plane类,实现Moveable,其中实现三个方法,还要有上下左右移动方法的设置标识方法,以及上下左右移动坐标变化的方法,具体代码如下:

package Model2;

import java.awt.Graphics;

import javax.swing.ImageIcon;

import com.sxf0912第二节课.Data;

public class Plane implements Moveable{

	private int x,y;
	private boolean LEFT=false;
	private boolean RIGHT=false;
	private boolean UP=false;
	private boolean DOWN=false;
	private int speed=5;
	
	public Plane(){
		x=Data.getIntertance().getScreenWidth()/2;
		y=Data.getIntertance().getScreenHeight()-100;
		//System.out.print(x);
	}
    int n=0;
    public void move() {
		if(LEFT){
			x-=speed;
			//防止飞机超过窗体
			if(x<0)	
				x=0;
		}
		if(RIGHT){
			x+=speed;
                        //防止飞机超过窗体
			if(x>Data.getIntertance().getScreenWidth()-Data.getIntertance().getPlaneImage().getIconWidth())
				x=Data.getIntertance().getScreenWidth()-Data.getIntertance().getPlaneImage().getIconWidth();
		}
		if(UP){
			y-=speed;
			if(y<0)	
				y=0;
		}
		if(DOWN){
			y+=speed;
			if(y>Data.getIntertance().getScreenHeight()-Data.getIntertance().getPlaneImage().getIconHeight())
				y=Data.getIntertance().getScreenWidth()-Data.getIntertance().getPlaneImage().getIconHeight();
		}
		if(n++%20==0){
			Bullet bullet=new Bullet(x+25,y,270);
			//System.out.print(x);
			Data.getIntertance().getMoveList().add(bullet);
			
		}
		
	}
    public void leftMove(boolean flag){
    	LEFT=flag;
    }
    public void rightMove(boolean flag){
    	RIGHT=flag;
    }
    public void upMove(boolean flag){
    	UP=flag;
    }
    public void downMove(boolean flag){
    	DOWN=flag;
    }

	@Override
	public void draw(Graphics g) {
		ImageIcon image=Data.getIntertance().getPlaneImage();
		g.drawImage(image.getImage(), x, y, null);
		//System.out.print(x);
		
	}

	@Override
	public boolean canRemove() {
		// TODO Auto-generated method stub
		return false;
	}

}

?6.boss类,同样实现Moveable接口,实现三个方法,移动,画,移除方法,然而boss要随机出现,具体代码如下:

package Model2;

import java.awt.Graphics;
import java.util.Random;

import javax.swing.ImageIcon;

import com.sxf0912第二节课.Data;

public class Boss implements Moveable{
    private int x,y;
    private int n;
	public Boss(){
		Random rand =new Random();
		y=-200;
		x=rand.nextInt(Data.getIntertance().getScreenWidth()-Data.getIntertance().getBossImage().getIconWidth());
	}
	public void move() {
		y++;
		if(n++%100==0){
			ImageIcon image=Data.getIntertance().getBossImage();
			Bullet bullet =new Bullet(x+image.getIconWidth()/2,y+image.getIconHeight(),90);
			Data.getIntertance().getMoveList().add(bullet);
		}
		
	}

	
	public void draw(Graphics g) {
		ImageIcon image =Data.getIntertance().getBossImage();
		g.drawImage( image.getImage(), x, y, null);
		
	}

	@Override
	public boolean canRemove() {
		if(y > Data.getInstance().getScreenHeight())
			return true;
		return false;
	}

}

?7.bullet类,同样实现了Moveable类,实现三个方法,具体代码如下

package Model2;

import java.awt.Graphics;
import javax.swing.ImageIcon;
import com.sxf0912第二节课.Data;

public class Bullet implements Moveable{

	private int x,y;
	private int speed=3;
	private double angle;
	private int n;
	private int vx,vy;
	/**
	 * 初始化子弹
	 * @param x 初始位置坐标
	 * @param y 初始位置坐标
	 * @param angle  角度
	 */
	public Bullet(int x,int y,double angle){
		this.x=x;
		this.y=y;
		this.angle=angle*Math.PI/180;
		this.vx=(int)(speed*(Math.cos(this.angle)));
		this.vy=(int)(speed*(Math.sin(this.angle)));
	}
	public void move() {
		x+=vx;
		y+=vy;
	}
	public void draw(Graphics g) {
	    //子弹爆炸
		if(++n>50){
			int i=(n-50)/2;
			if(i>7)
				return;
			ImageIcon [] icons=Data.getIntertance().getBulletIcons();
			int xx = x-icons[i].getIconWidth()/2;
			int yy = y-icons[i].getIconHeight()/2;
			g.drawImage(icons[i].getImage(),xx , yy, null);
			return;
		}
	    //普通子弹
		g.fillOval(x, y, 5, 5);
		
	}
	public boolean canRemove() {
	    if(x<0||x>Data.getIntertance().getScreenWidth()||y<0||y>Data.getIntertance().getScreenHeight()){
	    	return true;
	    }
		return false;
	}

}

?8.game类,控制游戏开始的类

package com.sxf0912第二节课;

import Model2.Plane;

public class Game {

	//游戏启动
	public static void main(String[] args) {
		Plane plane =new Plane();
		Data.getIntertance().setPlane(plane);
		Data.getIntertance().getMoveList().add(plane);
		//启动界面
		UI ui =new UI();
		ui.initUI();
		new Thread(ui).start();
		//启动移动控制线程
		new Control().start();
		
	}

}

?综上就是打飞机游戏的简单功能,至于子弹与飞机以及boss碰撞并发生爆炸,其中一方消失我还没有加上,等以后写出来会来加上。

?

  • 大小: 18.6 KB
  • 查看图片附件
发表评论
用户名: 匿名