- 浏览: 10193 次
- 性别:
最新评论
学得线程后应该就可以进行“雷霆战机”的制作了,这个拖了好久了。
首先进行界面设计,如图设计:
主要使用JFrame、JPanel和JButton组件,及添加一些监听器。
将一个JPanel写成一个监听器,implements KeyListener。
新建自己的战机的类MyAir,作为一个线程。
新建敌机类,extends Thread。存储到GamePanel中的动态数组里。
设置子弹类,由战机发射子弹。
注意isRun和isLive是否为静态,这里容易出错。并且over时各个线程要确定关闭。
首先进行界面设计,如图设计:
主要使用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时各个线程要确定关闭。
相关推荐
【标题】"js小游戏实现简单打飞机"是一个利用JavaScript编程语言和可能的jQuery库来创建的一个基础版在线游戏。这个游戏的实现主要集中在JavaScript的核心概念和技术上,包括事件处理、对象创建、定时器以及DOM操作...
-------- 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试...
本篇将深入探讨如何利用Cocos2d-x-2.1.5版本来实现一款简易小游戏,类似于经典的“打飞机”游戏。我们将主要涉及以下几个核心知识点: 1. **Cocos2d-x框架理解**:Cocos2d-x基于C++,支持多平台,包括iOS、Android...
【cocos2d-x 打飞机源码与资源】是一个基于Cocos2d-x 3.9版本开发的简易版打飞机游戏的源代码和素材集合。Cocos2d-x是一个开源的游戏开发框架,它使用C++语言编写,支持跨平台开发,包括iOS、Android、Windows等操作...
"仿腾讯打飞机"是一款基于C++编程语言开发的简易版打飞机游戏,旨在帮助学习者理解游戏开发的基本原理和C++编程技巧。这款游戏的玩法忠实于腾讯原版的打飞机游戏,玩家需要操作自己的飞机躲避敌机的攻击,同时尽可能...
尽管这个简易版打飞机游戏还有待完善,但它为学习JavaScript和游戏开发提供了一个实践的起点。对于初学者来说,这样的项目可以帮助他们理解JavaScript的事件处理、DOM操作、动画效果以及游戏逻辑的设计。
【微信打飞机简易版】是Android平台上的一款游戏应用,由开发者li-xiaojun基于ShootPlane项目构建。这个游戏是微信内置经典游戏“打飞机”的一个简化版本,它利用了Android系统的属性动画(Property Animation)技术...
第一次做游戏哈,照着一个小人打怪物的教程改的飞机大战,注释写的挺全的,自己写着玩,没事儿玩一把小游戏,哈哈,比较简陋,大神们别嫌弃
【基于Qt的打飞机小游戏】是一款使用Qt框架开发的简易版飞行射击游戏,灵感来源于经典的雷电系列。这个游戏是为初学者设计的,因此代码结构清晰,注释丰富,非常适合学习Qt编程和游戏开发的入门者参考。 Qt是一个跨...
【微信打飞机游戏】是一款基于WPF(Windows Presentation Foundation)技术用C#语言开发的简易版小游戏,灵感来源于微信内置的“打飞机”经典小游戏。这款游戏不仅提供了基本的游戏功能,如飞机移动、射击、躲避敌机...
本源码提供了一个基于C++的飞机大战小游戏设计。项目包含69个文件,其中包括24个PNG图片、16个C++源文件、12个TLOG文件、3个LOG文件、2个EXE文件、2个DB文件和2个LASTBUILDSTATE文件。这个项目是一个飞机大战小游戏...
《Scratch微信经典小游戏:飞机大战2》是利用Scratch编程语言开发的一款微信平台上的小游戏。Scratch是由麻省理工学院(MIT)媒体实验室终身幼儿园团队设计的一种面向儿童的图形化编程工具,它通过拖拽积木式的编程块...
在本项目中,“js模仿微信打飞机游戏特效代码”是一个基于JavaScript实现的简易版微信打飞机小游戏。这个项目旨在通过JavaScript编程语言,重现微信内置的打飞机小游戏的玩法和视觉效果,让开发者能够学习和理解游戏...
用Python写的一个简易版的飞行棋游戏单人版 只需要用到pygame模块就可以玩** 由于是简易版,该飞行棋的规则可能没有那么完善,也可能会出现很多BUG 另外我并不没有加上获胜的祝贺提示等 我觉得没有人会一个人玩到...
该网站提供了一系列关于如何用手工制作简易飞机模型的指导。 2. 制作工具: 在制作纸飞机的过程中需要一些特定的工具,包括两把尺子、透明液体粘合剂、剪刀和牙签。这些工具用于折叠纸张、剪裁部件和粘贴飞机的不同...
【标题】"飞机小游戏"是一款基于Java编程语言开发的简易娱乐项目,专为初学者设计,旨在帮助他们更好地理解和掌握Java编程基础。游戏玩法简单,易于操控,是学习Java编程和游戏开发的绝佳实践案例。 【描述】"飞机...
游戏名为“简易飞机大战”,它是一个经典的打飞机游戏,尽管设计简洁,但游戏性丰富。在这个无敌版中,玩家可以享受无尽的战斗,挑战高分。 C++是一种通用的、面向对象的编程语言,以其高效性和灵活性而著名。在...
在这个标题为“JavaScript小型打飞机游戏实现原理说明”的文档中,重点介绍了如何使用JavaScript结合HTML和CSS来开发一个简易版的“打飞机”游戏。文档不仅提供了游戏的基本玩法和功能,还详细阐述了游戏中的核心类...