`
永远吃不饱
  • 浏览: 9511 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

简易版打飞机

阅读更多
   学得线程后应该就可以进行“雷霆战机”的制作了,这个拖了好久了。
    首先进行界面设计,如图设计:
                   
   主要使用JFrame、JPanel和JButton组件,及添加一些监听器。
   
package 最_雷霆战机;

/**
 * 游戏界面设计
 * @author asus
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LeidianUI extends JFrame {

	public static void main(String[] arg) {
		new LeidianUI().initUI();
	}

	public void initUI() {
		this.setTitle("雷电");
		this.setSize(400, 600);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		this.setLayout(new BorderLayout());

		// 添加游戏界面
		final GamePanel jp1 = new GamePanel();
		jp1.setPreferredSize(new Dimension(380, 500));
		jp1.setBackground(Color.BLACK);

		// 添加操作界面
		JPanel jp2 = new JPanel();
		jp2.setBackground(Color.WHITE);

		this.add(jp1, BorderLayout.NORTH);
		this.add(jp2, BorderLayout.CENTER);

		final JButton start = new JButton("start");
		final JButton pause = new JButton("pause");
		final JButton over = new JButton("over");

		pause.setEnabled(false);
		over.setEnabled(false);

		jp2.add(start);
		jp2.add(pause);
		jp2.add(over);

		this.setVisible(true);

		ActionListener alis = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String s = e.getActionCommand();
				if (s.equals("start")) {
					jp1.initGamePanel(15);

					// 禁用开始按钮,其他按钮启动
					start.setEnabled(false);
					pause.setEnabled(true);
					over.setEnabled(true);
				} else if (s.equals("pause")) {

					pause.setText("continue");

					GamePanel.pauseThread();
				} else if (s.equals("continue")) {

					pause.setText("pause");

					GamePanel.continueThread();
				} else if (s.equals("over")) {

					pause.setText("pause");

					start.setEnabled(true);
					pause.setEnabled(false);
					over.setEnabled(false);

					// 停止敌机
					for (int i = 0; i < jp1.airList.size(); i++) {
						jp1.airList.get(i).stopThread();
					}
					jp1.airList.clear();

					// 停掉子弹线程
					// 停止敌机
					for (int i = 0; i < jp1.myAir.bulletList.size(); i++) {
						jp1.myAir.bulletList.get(i).stopThread();
					}
					jp1.myAir.bulletList.clear();
					// 自己的飞机
					jp1.myAir.stopThread();
					jp1.myAir = null;

				}

			}

		};

		start.addActionListener(alis);
		pause.addActionListener(alis);
		over.addActionListener(alis);

		start.setFocusable(false);
		pause.setFocusable(false);
		over.setFocusable(false);
		
		//添加键盘监听器(GamePanel实现了KeyListener的接口,所以他就是一个监听器)
		this.addKeyListener(jp1);

	}

}


    将一个JPanel写成一个监听器,implements KeyListener。
              
package 最_雷霆战机;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JPanel;

/***
 * 重写paint方法绘制
 * 
 * @author asus
 * 
 */
public class GamePanel extends JPanel implements KeyListener {

	public static boolean isRun = true; // 游戏是否终止

	ArrayList<EAir> airList = new ArrayList<EAir>();// 敌机对象个体存储的动态数组

	MyAir myAir;

	private BackgroundThread bgThread;

	public void initGamePanel(int num) {

		myAir = new MyAir(this);
		myAir.start();

		for (int i = 0; i < num; i++) {
			EAir air = new EAir(this);
			air.start();
			airList.add(air);
		}

	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);

		if (bgThread != null) {
			bgThread.draw(g);
		}

		// 绘制战机
		if (myAir != null) {
			if (myAir.isLive) {
				myAir.draw(g);
			}
			for (int i = 0; i < myAir.bulletList.size(); i++) {
				BulletThread but = myAir.bulletList.get(i);
				// 如果活着就绘制,否则就删除掉
				if (but.isLive) {
					but.draw(g);
				} else {
					myAir.bulletList.remove(i);
				}
			}
		}

		// 绘制敌机
		for (int i = 0; i < airList.size(); i++) {

			EAir air = airList.get(i);
			if (air.isLive) {
				air.draw(g);
			} else {
				airList.remove(i);
			}

		}
		this.repaint();
	}

	@Override
	public void keyTyped(KeyEvent e) {

	}

	public static void pauseThread() {
		isRun = false;
	}

	public static void continueThread() {
		isRun = true;
	}

	@Override
	public void keyPressed(KeyEvent e) {
		int code = e.getKeyCode();
		switch (code) {
		case KeyEvent.VK_LEFT:
			MyAir.left = true;
			break;
		case KeyEvent.VK_RIGHT:
			MyAir.right = true;
			break;
		case KeyEvent.VK_UP:
			MyAir.up = true;
			break;
		case KeyEvent.VK_DOWN:
			MyAir.down = true;
			break;
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		int code = e.getKeyCode();
		switch (code) {
		case KeyEvent.VK_LEFT:
			MyAir.left = false;
			break;
		case KeyEvent.VK_RIGHT:
			MyAir.right = false;
			break;
		case KeyEvent.VK_UP:
			MyAir.up = false;
			break;
		case KeyEvent.VK_DOWN:
			MyAir.down = false;
			break;
		}

	}

}


    新建自己的战机的类MyAir,作为一个线程。
package 最_雷霆战机;

/**
 * 
 * 战机的类
 * 
 * @author asus
 */
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import java.util.ArrayList;

import javax.swing.ImageIcon;

public class MyAir extends Thread {

	// 飞机属性
	int x = 10, y = 10;
	int width = 70;
	int height = 70;
	int xc = 2;
	int yc = 2;
	int blood = 20;

	Image img;

	private int panelWidth;
	private int panelHeight;
	private GamePanel panel;

	boolean isLive = true;// 线程是否活着

	// 方向指令
	public static boolean up, down, left, right;

	// 装子弹的队列
	ArrayList<BulletThread> bulletList = new ArrayList<BulletThread>();

	public MyAir(GamePanel gamePanel) {

		this.panel = gamePanel;
		Dimension dim = gamePanel.getPreferredSize();
		panelWidth = dim.width;
		panelHeight = dim.height;

		// 获取战机图片
		URL url = EAir.class.getResource("feiji.png");
		img = new ImageIcon(url).getImage();

		x = (panelWidth - width) / 2;
		y = panelHeight - height;

	}

	// 绘制战机
	public void draw(Graphics g) {

		g.drawImage(img, x, y, width, height, null);

	}

	public void stopThread() {
		isLive = false;
	}

	public void fire() {
		BulletThread bullet = new BulletThread(panel, x + width / 2, y);
		bullet.start();
		bulletList.add(bullet);
	}

	@Override
	public void run() {

		while (isLive) {
			if (GamePanel.isRun) {

				if (left) {
					xc = -2;
				} else if (right) {
					xc = 2;
				} else {
					xc = 0;
				}

				if (up) {
					yc = -2;
				} else if (down) {
					yc = 2;
				} else {
					yc = 0;
				}

				x += xc;
				y += yc;

				// 战机不出边界
				if (x <= 0) {
					x = 0;
				}

				if (y <= 0) {
					y = 0;
				}

				if (x >= panelWidth - width) {
					x = panelWidth - width;
				}

				if (y >= panelHeight - height) {
					y = panelHeight - height;
				}

			}

			num++;

			if (num % 20 == 0) {
				this.fire();
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	int num = 0;
}

     新建敌机类,extends Thread。存储到GamePanel中的动态数组里。
package 最_雷霆战机;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.ImageIcon;

/**
 * 敌机的属性
 * 
 * @author asus
 * 
 */
public class EAir extends Thread {

	// 敌机
	int x = 10, y = 10;
	int width = 50, height = 50;
	int xc = 2, yc = 2;
	int blood = 5;

	Image img;

	Random rd = new Random();

	int[] c = { 5, 4, 3, 2, 1 };

	ArrayList<EAir> airList;

	private int panelWidth;
	private int panelHeight;
	private GamePanel panel;

	boolean isLive = true; // 线程是否还存在
	// static boolean isRun = true; // 线程是否还在执行逻辑处理-->进行数据的交换

	public EAir(GamePanel gamePanel) {
		
		this.panel = gamePanel;
		this.airList = gamePanel.airList;
		Dimension dim = gamePanel.getPreferredSize();
		panelWidth = dim.width;
		panelHeight = dim.height;

		URL url = EAir.class.getResource("diji.png");
		img = new ImageIcon(url).getImage();

		initDiji();
	}

	// 敌机动作命令初始化
	public void initDiji() {

		yc = c[rd.nextInt(c.length)];

		x = rd.nextInt(panelWidth - width);

		y = -height;

	}

	// 绘制自身
	public void draw(Graphics g) {

		g.drawImage(img, x, y, width, height, null);

	}

	@Override
	public void run() {
		while (isLive) {
			
			check();
			
			if (GamePanel.isRun) {
				if (y >= panelHeight - height) {
					initDiji();
				}

				y += yc;
			}
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void stopThread() {
		isLive = false;
	}
	
	// 检测两个小球是否相碰
	public void check() {
		// 获得玩家飞机
		MyAir myAir = panel.myAir;
		if (myAir != null) {
			// 检测玩家飞机和敌机是否碰撞
			// 计算敌机的圆心
			int xa = this.x + this.width / 2;
			int ya = this.y + this.width / 2;

			// 计算玩家的圆心
			int xb = myAir.x + myAir.width / 2;
			int yb = myAir.y + myAir.width / 2;

			// 计算斜边
			int c2 = Math.abs(xa - xb) * Math.abs(xa - xb) + Math.abs(ya - yb)
					* Math.abs(ya - yb);

			// 计算半径之和
			int r = this.width / 2 + this.width / 2;
			// 碰撞到了
			if (c2 <= r * r) {
				if (this.blood < myAir.blood) {
					myAir.blood -= this.blood;
					this.blood = 0;
				} else {
					myAir.stopThread();
				}
				this.stopThread();
			}

			for (int i = 0; i < myAir.bulletList.size(); i++) {
				// 取出一个子弹
				BulletThread bullet = myAir.bulletList.get(i);

				int xc = bullet.x + bullet.width / 2;
				int yc = bullet.y + bullet.width / 2;

				// 计算斜边
				int c3 = Math.abs(xa - xc) * Math.abs(xa - xc)
						+ Math.abs(ya - yc) * Math.abs(ya - yc);

				// 计算半径之和
				int r3 = this.width / 2 + this.width / 2;
				// 碰撞到了
				if (c3 <= r3 * r3) {

					this.blood -= bullet.blood;
					bullet.blood = 0;
					if (this.blood <= 0) {
						// 敌机Over
						this.stopThread();
					}
					// 子弹OVer
					bullet.stopThread();
				}

			}
		}
	}

	

}


         设置子弹类,由战机发射子弹。
         
package 最_雷霆战机;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

public class BulletThread extends Thread{

	int x, y;
	int width = 5, height = 5;
	int xc = 0, yc = -5;
	boolean isLive = true;
	int blood = 1;

	int screenWidth, screenHeight;

	public BulletThread(GamePanel gamePanel, int a, int b) {

		Dimension dim = gamePanel.getPreferredSize();
		screenWidth = dim.width;
		screenHeight = dim.height;
		this.x = a - width / 2;
		this.y = b - height;

	}

	public void run() {

		while (isLive) {
			if (GamePanel.isRun) {
				if (y <= -height) {
					stopThread();
				}
				// 子弹于飞出屏幕终止

				x += xc;
				y += yc;

			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

	public void stopThread() {
		isLive = false;
	}
	
	public void draw(Graphics g){
		g.setColor(Color.green);
		g.fillOval(x, y, width, height);
	}

}


        注意isRun和isLive是否为静态,这里容易出错。并且over时各个线程要确定关闭。
  • 大小: 12.5 KB
分享到:
评论

相关推荐

    js小游戏实现简单打飞机

    由于这只是基本实现,所以没有兼容性可言,火狐,马桶等流畅运行,IE就算了,没考虑过,供新手了解一下还是可以的,注释我感觉写的挺多的吧,每个实现都有注释。

    简易版打飞机小游戏基于Unity+源代码+文档说明+游戏截图

    -------- 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! &lt;项目介绍&gt; 1、该资源内项目代码都经过测试...

    简易小游戏(类似打飞机)的简单实现cocos2d-x-2.1.5

    简易小游戏(类似打飞机)的简单实现cocos2d-x-2.1.5,几种类的实现

    html5打飞机游戏

    打飞机游戏,html5版,彩色简易版,快速嵌入你的网站里,代码简单易懂,下载即用

    微信打飞机的简易版

    作者li-xiaojun,源码ShootPlane,微信打飞机的简易版,主要用 Android 的属性动画实现!

    ios-简易版飞机大战.zip

    第一次做游戏哈,照着一个小人打怪物的教程改的飞机大战,注释写的挺全的,自己写着玩,没事儿玩一把小游戏,哈哈,比较简陋,大神们别嫌弃

    Scratch 微信经典小游戏:飞机大战2

    有“柠檬飞机大作战”和“飞机大战”,游戏规则自己摸索。干货满满,欢迎转载,记得注明原作者。此后仍有各热门或有趣游戏,请关注原作者,且点赞加收藏,记得推荐好友。快点来玩吧!

    python开发的简易版的飞行棋游戏源码+项目说明.zip

    用Python写的一个简易版的飞行棋游戏单人版 只需要用到pygame模块就可以玩** 由于是简易版,该飞行棋的规则可能没有那么完善,也可能会出现很多BUG 另外我并不没有加上获胜的祝贺提示等 我觉得没有人会一个人玩到...

    基于C++实现简易飞机大战小游戏【100012171】

    项目名称为简易飞机大战,使用者可以操控一架小飞机与敌机战斗很经典的打飞机小游戏,简约而不简单 (此版本为无敌版) 游戏目标:合理操作控制飞机消灭更多的敌人,获得更高分数。

    Android代码-ShootPlane

    ShootPlane 微信打飞机的简易版,主要用Android的属性动画实现! Preview

    微信小游戏初体验

    我们欣喜地看到可以直接点击小游戏体验一下,而且官方也有一个示例源代码,是一个简易版的飞机大战的源码,直接点开模拟器就可以看效果。   (此图片来源于网络,如有侵权,请联系删除! ) 2.源码分析 (还是原汁原味...

    14个appinventor案例源码aia.zip

    14个appinventor案例源码,亲测全部都能正常运行,aia源文件 打地鼠,打飞机,公约数与公倍数,函数曲线,计算器,记账本,购票系统模拟,九格拼图,水果配对,在气预报,鸡兔同笼,天气预报优化版,启蒙加法测试

    若干源程序资料12.rar

    2012-06-11 21:12 1,386,523 C++-打飞机的游戏.rar 2012-06-11 21:06 78,719 C++USB接口的鼠标驱动源程序.rar 2012-06-11 21:07 50,067 C++VC编写的退火算法.rar 2012-06-11 21:06 67,891 C++一示所有点阵字库内容的...

    售票管理系统 V1.01

    1、售票窗口,可根据发车日期和发车班次等信息进行车票打印,并在售票时实时显示当班车次在指定日期的当前售票情况...5、在线升级,支持在线升级软件目前最新版本,更新当前最新的功能,让您的升级工作更加简易、方便。

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目源代码

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

Global site tag (gtag.js) - Google Analytics