`
永远吃不饱
  • 浏览: 10102 次
  • 性别: 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小游戏实现简单打飞机

    【标题】"js小游戏实现简单打飞机"是一个利用JavaScript编程语言和可能的jQuery库来创建的一个基础版在线游戏。这个游戏的实现主要集中在JavaScript的核心概念和技术上,包括事件处理、对象创建、定时器以及DOM操作...

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

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

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

    本篇将深入探讨如何利用Cocos2d-x-2.1.5版本来实现一款简易小游戏,类似于经典的“打飞机”游戏。我们将主要涉及以下几个核心知识点: 1. **Cocos2d-x框架理解**:Cocos2d-x基于C++,支持多平台,包括iOS、Android...

    cocos2d-x 打飞机源码与资源

    【cocos2d-x 打飞机源码与资源】是一个基于Cocos2d-x 3.9版本开发的简易版打飞机游戏的源代码和素材集合。Cocos2d-x是一个开源的游戏开发框架,它使用C++语言编写,支持跨平台开发,包括iOS、Android、Windows等操作...

    仿腾讯打飞机

    "仿腾讯打飞机"是一款基于C++编程语言开发的简易版打飞机游戏,旨在帮助学习者理解游戏开发的基本原理和C++编程技巧。这款游戏的玩法忠实于腾讯原版的打飞机游戏,玩家需要操作自己的飞机躲避敌机的攻击,同时尽可能...

    JavaScript制作简易的微信打飞机

    尽管这个简易版打飞机游戏还有待完善,但它为学习JavaScript和游戏开发提供了一个实践的起点。对于初学者来说,这样的项目可以帮助他们理解JavaScript的事件处理、DOM操作、动画效果以及游戏逻辑的设计。

    微信打飞机的简易版

    【微信打飞机简易版】是Android平台上的一款游戏应用,由开发者li-xiaojun基于ShootPlane项目构建。这个游戏是微信内置经典游戏“打飞机”的一个简化版本,它利用了Android系统的属性动画(Property Animation)技术...

    ios-简易版飞机大战.zip

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

    基于Qt的打飞机小游戏

    【基于Qt的打飞机小游戏】是一款使用Qt框架开发的简易版飞行射击游戏,灵感来源于经典的雷电系列。这个游戏是为初学者设计的,因此代码结构清晰,注释丰富,非常适合学习Qt编程和游戏开发的入门者参考。 Qt是一个跨...

    仿微信打飞机游戏

    【微信打飞机游戏】是一款基于WPF(Windows Presentation Foundation)技术用C#语言开发的简易版小游戏,灵感来源于微信内置的“打飞机”经典小游戏。这款游戏不仅提供了基本的游戏功能,如飞机移动、射击、躲避敌机...

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

    《Scratch微信经典小游戏:飞机大战2》是利用Scratch编程语言开发的一款微信平台上的小游戏。Scratch是由麻省理工学院(MIT)媒体实验室终身幼儿园团队设计的一种面向儿童的图形化编程工具,它通过拖拽积木式的编程块...

    js模仿微信打飞机游戏特效代码

    在本项目中,“js模仿微信打飞机游戏特效代码”是一个基于JavaScript实现的简易版微信打飞机小游戏。这个项目旨在通过JavaScript编程语言,重现微信内置的打飞机小游戏的玩法和视觉效果,让开发者能够学习和理解游戏...

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

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

    F35纸飞机,A4打印

    该网站提供了一系列关于如何用手工制作简易飞机模型的指导。 2. 制作工具: 在制作纸飞机的过程中需要一些特定的工具,包括两把尺子、透明液体粘合剂、剪刀和牙签。这些工具用于折叠纸张、剪裁部件和粘贴飞机的不同...

    飞机小游戏

    【标题】"飞机小游戏"是一款基于Java编程语言开发的简易娱乐项目,专为初学者设计,旨在帮助他们更好地理解和掌握Java编程基础。游戏玩法简单,易于操控,是学习Java编程和游戏开发的绝佳实践案例。 【描述】"飞机...

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

    游戏名为“简易飞机大战”,它是一个经典的打飞机游戏,尽管设计简洁,但游戏性丰富。在这个无敌版中,玩家可以享受无尽的战斗,挑战高分。 C++是一种通用的、面向对象的编程语言,以其高效性和灵活性而著名。在...

    JavaScript 小型打飞机游戏实现原理说明

    在这个标题为“JavaScript小型打飞机游戏实现原理说明”的文档中,重点介绍了如何使用JavaScript结合HTML和CSS来开发一个简易版的“打飞机”游戏。文档不仅提供了游戏的基本玩法和功能,还详细阐述了游戏中的核心类...

    Android代码-ShootPlane

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

Global site tag (gtag.js) - Google Analytics