- 项目:飞机大战小游戏之绘制我方飞机的骚操作
- 项目简介:飞机大战小游戏的主角,采用两张图片交替显示来达到动态效果,键盘事件更改飞机火力(监听器)
- 开发工具:eclipse
- 语言:Java
- 知识点:模块化、监听器、定时器
代码架构:程序分两个包,共四个类
操作效果图:
ImageUtil.java:游戏加载图片的工具类
HeroPlane.java:我方飞机
package com.demo.model;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import com.demo.util.ImageUtil;
/**
* 英雄飞机
*/
public class HeroPlane {
/**
* 飞机的特征
*/
//用数组定义多张图片
private static BufferedImage[] images;
//静态块
static{
images = new BufferedImage[2];
for(int i=0;i<images.length;i++){
images[i] = ImageUtil.readImage("heroplane"+i+".png");
}
}
//生命:默认10条
private int life = 10;
//分数:默认0分
private int score = 0;
//飞机所在的位置x/y轴
private int x;
private int y;
/**
* 行为特征
*/
//移动
public void move(int x,int y){
this.x = x;
this.y = y;
}
//射击
public List<HeroBullet> fire() {
List<HeroBullet> list = new ArrayList<HeroBullet>();
list.add(new HeroBullet(this.x, this.y)); //发射一枚子弹
return list;
}
private boolean flag = true;
//获取飞机图标
public BufferedImage getImage() {
flag = !flag;
return images[flag?0:1];
}
//getters/setters方法
//...
public int getScore() {
return ++score; //移动加分
}
public void setScore(int score) {
this.score = score;
}
}
HeroBullet.java:我方飞机子弹
package com.demo.model;
import java.awt.image.BufferedImage;
import com.demo.util.ImageUtil;
public class HeroBullet{
protected int x; //画布的x轴
protected int y; //画布的y轴
//子弹图片
private static BufferedImage image = ImageUtil.readImage("herobullet0.png");
//构造函数
public HeroBullet(int x,int y){
this.x = x;
this.y = y;
}
//行为-> 移动
public void move(){
this.y -= 3;
}
//出界
public boolean isOutOfBound(){
return this.y<0;
}
public static BufferedImage getImage() {
return image;
}
public static void setImage(BufferedImage image) {
HeroBullet.image = image;
}
//...x/y的 getters/setters方法
}
GameStart.java:主程序
package com.demo.model;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.demo.util.ImageUtil;
/**
* 飞机大战小游戏(二):我方飞机骚起来
* @author suoyue_zhan
*/
public class GameStart extends JPanel {
public static final int WIDTH = 400; //游戏界面宽度
public static final int HEIGHT = 654; //游戏界面长度
private BufferedImage background1 = ImageUtil.readImage("background.jpg"); // 背景图片:静态
private HeroPlane heroPlane = new HeroPlane(); //英雄机
//英雄飞机子弹对象->list集合
private List<HeroBullet> heroBullets = new ArrayList<HeroBullet>();
//将背景绘制到面板中
private void paintHeroPlane(Graphics g) {
BufferedImage image = heroPlane.getImage();
if(heroPlane.getX() == 0) { //飞机刚出来时候
g.drawImage(image,WIDTH/2-image.getWidth()/2, HEIGHT/2+image.getHeight(), null);
}else {
g.drawImage(image,heroPlane.getX()-image.getWidth()/2, heroPlane.getY() - image.getHeight()/2, null);
}
}
//绘制飞机的分数与生命
private void paintScoreAndLife(Graphics g) {
g.setColor(new Color(255, 0, 0)); //设置画笔颜色 红0 绿0 蓝0 (0~255)
g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20)); //设置字体 字体、样式、字号
g.drawString("score: "+heroPlane.getScore(), 10, 25);
g.drawString("life: "+heroPlane.getLife(), 10, 45);
}
//默认一条火力线
private boolean flag1 = true;
//两条火力线
private boolean flag2 = false;
//三条火力线
private boolean flag3 = false;
//控制子弹移动速度的标记
private boolean flagMax = false;
//绘制飞机子弹
public void paintHeroBullet(Graphics g){
for(int i=0;i<heroBullets.size();i++){
//每个英雄的子弹
HeroBullet heroBullet = heroBullets.get(i);
BufferedImage image = heroBullet.getImage();
BufferedImage hImage = heroPlane.getImage();
if(image != null && !heroBullet.isOutOfBound()) {
if(flag1) {
g.drawImage(image, heroBullet.getX(), heroBullet.getY(), null);
}
if(flag2) {
g.drawImage(image, heroBullet.getX()-hImage.getWidth()/3, heroBullet.getY(), null);
g.drawImage(image, heroBullet.getX()+hImage.getWidth()/3, heroBullet.getY(), null);
}
if(flag3) {
g.drawImage(image, heroBullet.getX()-hImage.getWidth()/3, heroBullet.getY(), null); //左边
g.drawImage(image, heroBullet.getX(), heroBullet.getY(), null); //中间
g.drawImage(image, heroBullet.getX()+hImage.getWidth()/3, heroBullet.getY(), null); //右边
}
}
}
}
// 重写JPanel的绘制方法-->>所有图片都在该方法上执行
@Override
public void paint(Graphics g) {
//绘制背景图
g.drawImage(background1, 0, 0, null);
//调用方法,绘制飞机
this.paintHeroPlane(g);
//调用方法绘制飞机子弹
this.paintHeroBullet(g);
//绘制飞机的分数与生命
this.paintScoreAndLife(g);
}
/**
*********游戏逻辑方法--------------
*/
//英雄飞机发射子弹
private void heroPlaneFire(){
List<HeroBullet> list = heroPlane.fire();
//收集子弹,动态绘制
heroBullets.addAll(list);
}
//英雄子弹移动
private void heroBulletMove() {
for (HeroBullet heroBullet : heroBullets) {
heroBullet.move();
}
}
/**
* 窗口初始化
*/
public void init() {
JFrame jFrame = new JFrame("飞机大战"); // 设置窗口标题
jFrame.add(this); // this表示主类,也表示画板
jFrame.setSize(WIDTH, HEIGHT); // 设置窗口大小
jFrame.setLocationRelativeTo(null); // 设置窗口居中
jFrame.setAlwaysOnTop(true); // 设置窗口总是在顶端
jFrame.setResizable(false); // 设置不允许拖拉
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序
jFrame.setIconImage(new ImageIcon("./images/icon.png").getImage()); // 设置图标
jFrame.setVisible(true); // 使窗口显示出来
initListener(); //安装程序监听器
initTimer(); //设置定时器,用于实现游戏中所有的动态逻辑效果
}
/**
* 监控鼠标的监听器
*/
private void initListener() {
//使用鼠标监听器的适配器
MouseAdapter adapter = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
//获取鼠标的x坐标与y坐标
System.out.println("x: " + e.getX() + "y: " + e.getY());
//飞机跟随鼠标移动
heroPlane.move(e.getX(), e.getY());
repaint(); //重新绘制飞机, 底层是重写执行paint方法
}
};
//添加鼠标监听器
this.addMouseListener(adapter);
this.addMouseMotionListener(adapter);
//设置键盘监听事件
this.setFocusable(true);
//键盘的监控
KeyAdapter k = new KeyAdapter() {
//键盘按键按下时执行方法
@Override
public void keyPressed(KeyEvent e) {
//键盘的按键编码
int keyCode = e.getKeyCode();
//键盘按键编码对应的文字
String text = KeyEvent.getKeyText(keyCode);
if("1".equals(text)) {
flag1 = true;
flag2 = false;
flag3 = false;
}
if("2".equals(text)) {
flag1 = false;
flag2 = true;
flag3 = false;
}
if("3".equals(text)) {
flag1 = false;
flag2 = false;
flag3 = true;
}
if("M".equals(text)) {
flagMax = !flagMax; //M键快挂
}
}
};
this.addKeyListener(k);
}
/**
* 定时器
*/
private long count = 0; //控制频率
public void initTimer(){
Timer timer = new Timer(); //定时器对象
long delay = 10;
long period = 10;
//定时执行操作
//参数1:每隔一段时间执行的操作
//参数2:几毫米之后执行定时器
//参数3:每个几毫米执行一次
timer.schedule(new TimerTask() {
@Override
public void run() {
//飞机发射子弹
if(count % 10 == 0 || flagMax){
heroPlaneFire();
}
//英雄子弹移动
//if(count % 2 == 0){
heroBulletMove();
//}
if(count == Long.MAX_VALUE-1){
count = 0;
}
count++;
repaint(); //重新绘制页面
}
}, delay,period);
}
/*
* 程序入口main()
*/
public static void main(String[] args) {
System.out.println("游戏开始了.....");
GameStart gameStart = new GameStart();
gameStart.init(); //显示主界面
}
}