本篇文章使用纯java代码实现一个飞机大战的小游戏,具体展示为:
具体目录结构为:
静态资源有:
游戏背景类BackGround.java:
package game05_plane_fight;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
//游戏背景类
public class BackGround {
public void draw(Graphics2D g2d){
try {
g2d.drawImage(ImageIO.read(PlaneFightGameEngine.class.getClassLoader().getResourceAsStream("map.jpg"))
,0,0,null);
} catch (IOException e) {
e.printStackTrace();
}
}
}
游戏公共类Game.java:
package game05_plane_fight;
import javax.swing.*;
import java.awt.*;
/**
* 大牛程序员写的游戏的公共类 <p></p>
* 使用Game.init()方法初始化游戏<p></p>
* 使用Game.gameOver()方法退出游戏<p></p>
*/
public class Game extends JPanel {
private GameEngine engine;
private Graphics2D g2d;
private static JFrame frame;
@Override
public void paint(Graphics g) {
super.paint(g);
g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
engine.renderUI(g2d);
}
/**
* 使用游戏引擎初始化游戏的方法
* @param title 游戏窗体的标题
* @param width 游戏窗体的宽度
* @param height 游戏窗体的高度
* @param engine 游戏引擎
*/
public static void init(String title, int width, int height, GameEngine engine){
frame = new JFrame(title);
Game game = new Game();
game.engine = engine;
game.addKeyListener(engine.listener);
game.setFocusable(true);
game.setPreferredSize(new Dimension(width, height));
frame.add(game);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
engine.updateLogic();
game.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 显示退出游戏对话框的方法
* @param message 对话框提示的消息
* @param title 对话框提示的标题
*/
public static void gameOver(String message,String title) {
JOptionPane.showMessageDialog(frame, message, title, JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
}
游戏引擎的抽象模板类GameEngine.java:
package game05_plane_fight;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* 由大牛程序员编写的游戏引擎的抽象模板类<p></p>
* 需要调用者实现两个抽象方法, 更新逻辑方法updateLogic<p></p>
* 更新ui方法 renderUI<p></p>
*/
public abstract class GameEngine {
KeyListener listener;
private int currentPressedKeyCode;
/**
* 构造方法,创建出游戏引擎
*/
public GameEngine(){
this.listener = new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
currentPressedKeyCode = e.getKeyCode();
}
@Override
public void keyReleased(KeyEvent e) {
currentPressedKeyCode = -1;
}
};
}
/**
* 获取当前用户的按键代码 按键代码的定义在KeyEvent对象中定义
* @return 返回KeyEvent的按键代码
*/
public int getCurrentPressedKeyCode(){
return currentPressedKeyCode;
}
/**
* 重置用户的按键,防止按一次就执行很多次
*/
public void setCurrentPressedKeyCode(){
currentPressedKeyCode=-1;
}
/**
* 根据用户行为或者游戏的时间更新游戏的逻辑
*/
public abstract void updateLogic();
/**
* 根据用户需求更新绘制图形化界面的内容<p></p>
* 示例代码,绘制矩形: g2d.fillRect(左上角x的坐标, 左上角y的坐标, 矩形的宽度, 矩形的高度);<p></p>
* 示例代码:绘制椭圆形: g2d.fillOval(椭圆外包裹矩形左上角x的坐标, 椭圆外包裹矩形y的坐标, 要填充椭圆形的宽度, 要填充椭圆形的高度);<p></p>
* @param g2d
*/
public abstract void renderUI(Graphics2D g2d);
}
敌方飞机EnemyPlayer.java:
package game05_plane_fight;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
//敌方飞机
public class EnemyPlayer {
int x;
int y;
boolean isDead=false;
String[] names={"ep_1.png","ep_2.png","ep_3.png"
,"ep_4.png","ep_5.png","ep_6.png"};
String name;
public EnemyPlayer() {
name=names[(int)(Math.random()*6)];
x=(int)(Math.random()*300);
y=(int)(Math.random()*100);
}
public void draw(Graphics2D g2d) {
if (!isDead) {
try {
g2d.drawImage(ImageIO.read(PlaneFightGameEngine.class.getClassLoader().getResourceAsStream(name))
, x, y, null);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 敌人飞机自动移动
*/
public void autoMove(){
x+=(int)(Math.random()*5);
if (x>=400){
x=0;
}
}
/**
* 判断子弹的坐标是否与敌机的坐标重合,重合则判定死亡
*/
public void isDead(ArrayList<Bullet> bullets){
for (int i = 0; i <bullets.size() ; i++) {
Bullet bullet=bullets.get(i);
if (bullet.x>=x && bullet.x<x+100
&& bullet.y>=x&&bullet.y<y+100){
isDead=true;
}
}
}
}
飞机大战游戏引擎PlaneFightGameEngine.java:
package game05_plane_fight;
import javax.sound.sampled.Clip;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.ArrayList;
public class PlaneFightGameEngine extends GameEngine {
BackGround bg = new BackGround();
Player player = new Player();
EnemyPlayer[] enemys={new EnemyPlayer(),new EnemyPlayer(),new EnemyPlayer()
,new EnemyPlayer(),new EnemyPlayer(),new EnemyPlayer()};
// Bullet bullet=null;
ArrayList<Bullet> bullets=new ArrayList<>();
ArrayList<Bullet> filterbullets;
@Override
public void updateLogic() {
filterbullets=new ArrayList<>();
for (int i = 0; i <bullets.size() ; i++) {
if (bullets.get(i).y<0){
//当前子弹已经跑到屏幕外面了
//bullets.get(i)=null;
}else {
//当前还在界面上的子弹
filterbullets.add(bullets.get(i));
}
}
bullets=filterbullets;
for (EnemyPlayer enemy:enemys) {
enemy.autoMove();
enemy.isDead(bullets);
}
int keycode = getCurrentPressedKeyCode();
if (keycode == KeyEvent.VK_LEFT) {
player.x-=10;
}
if (keycode == KeyEvent.VK_DOWN) {
player.y+=10;
}
if (keycode == KeyEvent.VK_RIGHT) {
player.x+=10;
}
if (keycode == KeyEvent.VK_UP) {
player.y-=10;
}
if (keycode == KeyEvent.VK_ENTER) {
URL url=PlaneFight.class.getClassLoader().getResource("ringing_short.wav");
AudioClip clip= Applet.newAudioClip(url);
clip.play();
Bullet bullet=player.shoot();
bullets.add(bullet);
setCurrentPressedKeyCode();
}
// if (bullet!=null){
// bullet.autoMove();
// }
for (int i = 0; i <bullets.size() ; i++) {
bullets.get(i).autoMove();
}
}
@Override
public void renderUI(Graphics2D g2d) {
bg.draw(g2d);
player.draw(g2d);
// for (int i = 0; i <enemys.length ; i++) {
// enemys[i].draw(g2d);
// }
for (EnemyPlayer enemy:enemys){
enemy.draw(g2d);
}
// if (bullet!=null){
// bullet.draw(g2d);
// }
for (int i = 0; i <bullets.size() ; i++) {
bullets.get(i).draw(g2d);
}
}
}
我方玩家Player.java:
package game05_plane_fight;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
//我方玩家
public class Player {
int x=150;
int y=550;
public void draw(Graphics2D g2d){
try {
g2d.drawImage(ImageIO.read(PlaneFightGameEngine.class.getClassLoader().getResourceAsStream("my_1.png"))
,x,y,null);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 开炮的逻辑
*/
public Bullet shoot(){
return new Bullet(x+50,y-50);
}
}
子弹类Bullet.java:
package game05_plane_fight;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
//子弹
public class Bullet {
int x;
int y;
public Bullet(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics2D g2d){
try {
g2d.drawImage(ImageIO.read(PlaneFightGameEngine.class.getClassLoader().getResourceAsStream("bullet.png"))
,x,y,null);
} catch (IOException e) {
e.printStackTrace();
}
}
public void autoMove(){
y-=3;
}
}
运行类PlaneFight.java:
package game05_plane_fight;
public class PlaneFight {
public static void main(String[] args) {
Game.init("飞机大战",400,1024, new PlaneFightGameEngine());
//1.创建一个文件夹 叫 resources
//2,者resources文件夹点右键, mark dirctory as resources文件
//3, 把图片拷贝到resources 文件夹里面
}
}
将上方的运行类运行即可。