本篇博客主要利用java实现了一个简易版的飞机大战,适合初学者练手,所涉及到的知识主要有以下几点:
1,面向对象。飞机大战的功能是针对每个英雄机、子弹和敌机对象实现的。
2,数组。由于敌机和子弹对象有多个,创建一个List数组用来存储相应对象,之后针对数组中的对象进行操作。
3,图片。站在用户的角度,我们看到的是一张张飞机、子弹的图片,对对象的操作要和相应的图片联系起来。
4,线程。利用sleep()函数使线程休眠,让游戏效果可以用视觉捕捉。
一,游戏规则:
当英雄机发射的子弹击中敌机,敌机产生爆炸效果并消失,每击中一架敌机分数+10。
二,游戏效果:

三,游戏制作
1,窗口的实现
package PlaneGame;
import java.awt.Graphics;
import javax.swing.JFrame;
public class GameMain {
//窗口宽高
static int width=550;
static int heigh=700;
public void UI() {
//创建一个窗体
JFrame frame = new JFrame();
frame.setTitle("飞机大战");//设置标题
frame.setSize(width, heigh);//设置窗体大小
frame.setLocationRelativeTo(null);//使窗体显示在屏幕中央
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//退出时关闭窗口
frame.setVisible(true);//显示窗体可见
}
//主函数 程序入口
public static void main(String[] args) {
GameMain gamemain= new GameMain();
gamemain.UI();
}
}
效果如下:

2,英雄机的显示与移动
<1>创建一个GamePanel类继承JPanel。JFrame是最顶层组件,每一个窗口都是JFrame,其他组件都要放在窗口里面。窗口里面可以有好几个区域,每个区域都可以称做一个面板,这个面板可以叫做JPanel(别的容器也可以)。JPanel是Java的一个轻量级容器,JPanel可以添加到JFrame中,反之则不行。本次游戏制作我们将主要功能全部放在GamePanel中,因为JPanel默认使用了双缓冲绘图,可以解决闪频问题。
package PlaneGame;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
}
<2>在主窗口类GameMain中创建一个GamePanel对象并添加到窗口对象中。
//创建JPanel 添加到窗体上 监听在JPanel中
GamePanel panel = new GamePanel();
frame.add(panel);
<3>展示英雄机的图片。这里我们将游戏的图片全部放在Eclipse的一个img图片包中,这样只需要从img包中获取图片就可以了。

//英雄机左上角坐标 初始位置 之后根据鼠标拖拽改变位置
int heroX=300;
int heroY=400;
//英雄机图片 图片路径
ImageIcon heroImage = new ImageIcon("img/hero.png");
//paint方法窗口对象自动调用 不需手动调用 绘制图片
public void paint(Graphics g) {
super.paint(g);
//绘制英雄机
g.drawImage(heroImage.getImage(), heroX, heroY,null);
}
得到效果如下:

<4>创建鼠标拖拽监听器,使英雄机位置随鼠标拖拽移动。
public class GamePanel extends JPanel implements MouseMotionListener{
//重写鼠标拖拽方法
public void mouseDragged(MouseEvent e) {
//鼠标的x、y
int x=e.getX();
int y=e.getY();
//将鼠标拖拽位置赋给英雄机坐标
heroX=x;
heroY=y;
}
//重写鼠标移动方法
public void mouseMoved(MouseEvent e) {
//System.out.println("鼠标移动");
}
}
- 在paint()方法中添加repaint()方法,这样英雄机坐标改变后自动重新绘制,达到移动效果。
//重新绘制自动调用paint方法 更新图片 否则实现不了动画效果
repaint();
- 在GameMain类的UI方法中给窗口添加鼠标监听器。
//添加鼠标移动监听器
frame.addMouseMotionListener(panel);
效果如下:

<5>使鼠标位置处于图片中央。按照上述移动图片发现鼠标位置始终处于图片的左上角,这是因为英雄机图片是一张去除背景的矩形图片,鼠标位置就是矩形图片的左上角。为了更好地控制英雄机,我们要让鼠标位置出现在图片中央,就是对英雄机的左上角位置进行处理,使英雄机左上角位置不再是鼠标位置,而变为鼠标坐标减去图片大小的1/2,这样鼠标就能出现在图片中央了。
heroX=x-(heroImage.getIconWidth()/2);//使鼠标在英雄机图片的中央
heroY=y-(heroImage.getIconHeight()/2);
效果如下:

<6>限制英雄机位置,使英雄机的移动不超过窗体。在上面的效果中我们发现英雄机会随着鼠标的拖拽移除窗体边界,但在游戏中我们不希望这样的效果发生,因此当英雄机的图片边缘移动到窗体边缘时,将英雄机图片位置限定为窗体边界,这样英雄机的移动就不会超过窗体。
public void mouseDragged(MouseEvent e) {
//鼠标的x、y
int x=e.getX();
int y=e.getY();
//将鼠标拖拽位置赋给英雄机坐标
heroX=x-(heroImage.getIconWidth()/2);//使鼠标在英雄机图片的中央
heroY=y-(heroImage.getIconHeight()/2);
//使英雄机不超出边界
//右边界
if((x+heroImage.getIconWidth())>GameMain.width) {
heroX=GameMain.width-heroImage.getIconWidth()-20;
}
//左边界
if((x)<80) {
heroX=0;
}
//下边界
if((y+heroImage.getIconHeight())>GameMain.heigh) {
heroY=GameMain.heigh-heroImage.getIconHeight()-20;
}
//上边界
if(y<80) {
heroY=0;
}
//System.out.println(heroX+" "+heroY);
}
效果如下:

3,敌机效果
<1>创建敌机类,每一个敌机都是一个敌机对象,在敌机类中得到敌机的图片,定义敌机的各种属性和方法,同时定义敌机类的构造方法,这样在之后创建敌机对象的同时就能初始化敌机的位置和宽高。
package PlaneGame;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.ImageIcon;
//敌机对象
public class Enemy {
//敌机宽高
private int width;
private int heigth;
//敌机坐标
private int x;
private int y;
//敌机图片
private ImageIcon enemyImageIcon = new ImageIcon("img/enemy.png");
//构造方法 获取敌机宽高 敌机x、y位置随机出现
//敌机对象有多个 每次创建对象的时候立刻得到该对象的宽高和位置
public Enemy() {
this.width=enemyImageIcon.getIconWidth();
this.heigth=enemyImageIcon.getIconHeight()

最低0.47元/天 解锁文章
902

被折叠的 条评论
为什么被折叠?



