微信打飞机--Java版(一)

2014-11-24 03:00:35 · 作者: · 浏览: 3

世风日下啊,大家现在动不动就打飞机。。。

上个周末实在是无聊,就写了个Java版的微信打飞机游戏。。拿上来和大家交流交流,不喜勿喷(网络上这个资源已经很多了很多了)


目前实现的功能:

1、敌方有两类飞机:小飞机和大BOSS飞机(小飞机1滴血;BOSS有10滴血,我方我只设置一滴血,可以修改blood参数)

2、药丸:有蓝色药丸和红色药丸

3:蓝色药丸能双发子弹 (有时间限制)

4:红色药丸全屏爆炸 屏幕下方显示已有的红色药丸数目

5:按键说明:游戏暂停p 游戏继续s 游戏重开始 r 方向键控制上下左右 红色药丸使用空格

先上几副图看看吧(那个。。。飞机爆炸有点土。。。用一陀屎黄色的东西代替哈。。)

\ \ \ \

(注意)游戏制作中细节的地方:

(1)图一中左下角的显示

(2)双发子弹的设计,如果有一发击中敌机,另一发也应该继续往前走


那个图形美化实在是不善长,就借用微信上的飞机截图做素材哈,,,版权归原作者所有。


------------------------------------------------------------------------

1 简单入门

其实做这个游戏主要你规划好有什么角色,每帧他们都在做什么就好了,然后用什么数据结构去表示(应该说压根就不设计什么算法,数据结构的东西)

在进行冗长的说明之前,我先举个例子,比如如何实现一个物体在界面中随着时间移动(暂时不考虑边界问题)

实现:
1:实时绘制背景 为黑色
2:一红色小球从界面顶部下落
3:随着时间增长,速度增快
4:为了不出先卡吨,实现双缓冲机制


首先,我们需要一个JFrame窗口,这个继承就好,然后实现paint()方法,来实现我们的绘制,制作背景简单,可是为什么要实时更新呢?

因为这里我们所看见的动画就是每帧图像快速拼接起来的,而每幅图像都需要我们重新绘制,否则都是在原有图像上再次绘制,所以,如果每次都不刷新界面,那么会有上一次的滞留图像。

paint方法如下:


@Override
	public void paint(Graphics g) {
		//super.paint(arg0);
		//before draw, move first
		time++;
		y += velocity + time;
		//draw
		Color c = g.getColor();
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, 480, 800);
		g.setColor(Color.RED);
		g.fillOval(x, y, 10, 10);
		g.setColor(c);
	}

可是,如果绘制物体过多,我们会发现,存在卡顿现象,这也是所有显示都会遇到的问题,一般采用双缓冲方式解决,我们这里不是什么大型游戏,就简单用下面方法实现双缓冲机制,即我们先绘制好下一帧图像,再显示,而不是边显示边绘制。

我们在先申明一个公共变量Image buffer;专门存储下一帧图像,并且在update()函数里实现绘制

@Override
	public void update(Graphics g) {
		//super.update(g);
		if(buffer == null)
			buffer = this.createImage(480, 800);
		Graphics gBuffer = buffer.getGraphics();
		paint(gBuffer);//先绘制在缓冲中
		g.drawImage(buffer, 0, 0, null);
	}

当然,这里update()传入的g参数就是我们这个窗口的画笔。

随着时间增加,速度增快,这个在paint()函数里已经简单实现了。。

然后就是怎么实现实时绘制,当然是需要开一个定时器啦。。那就开一个线程专门负责更新图像不久好了?

这里关键的更新就是利用mf.update(mf.getGraphics());然后就调用我们刚才实现的update(),然后里面再调用paint()

class MainThread implements Runnable{
		MainFrame mf = null;
		public MainThread(MainFrame mf) {
			this.mf = mf;
		}
		@Override
		public void run() {
			while(true){
				try{
					Thread.sleep(50);
					mf.update(mf.getGraphics());
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
	}

上面这个流程很清晰了,就是让线程负责时间刷新,然后通知窗口,要更新啦!!窗口对象调用更新函数,更新函数通知逻辑绘制函数paint(),要更新啥,你说了算。。。所以把这个程序分为两部分:

UI更新:逻辑更新(目前都是在paint()里面具体实现的)

所以这个程序一封装,以后我们要先游戏,不久只需要在paint()函数里做手脚不就行了么?


下面给出这个小demo的代码

package ylf.graphics;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.JFrame;
/**
 * @author ylf
 */
public class MainFrame extends JFrame{
	int time ;
	int velocity ;
	int x ;
	int y;
	Image buffer = null;
	
	public MainFrame() {
		init();
		
		this.setSize(480, 800);
		this.setVisible(true);
		
		new Thread(new MainThread(this)).start();
	}
	
	public void init(){
		time = 0;
		velocity = 0;
		x = 240;
		y = 0;
	}
	
	@Override
	public void paint(Graphics g) {
		//super.paint(arg0);
		//before draw, move first
		time++;
		y += velocity + time;
		//draw
		Color c = g.getColor();
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, 480, 800);
		g.setColor(Color.RED);
		g.fillOval(x, y, 10, 10);
		g.setColor(c);
	}
	
	@Override
	public void update(Graphics g) {
		//super.update(g);
		if(buffer == null)
			buffer = this.createImage(480, 800);
		Graphics gBuffer = bu