学习JAVA.day04
--------------------------------飞机大战(一)----------------------------------
功能需求分析:
一.飞机大战游戏步骤:
1.开始界面(进入游戏,退出游戏,排名查询)
2.进入游戏界面
3.空格开始游戏,左右前后移动我的飞机,敌机随机生成,子弹按照一定速度打出
4.碰撞检测,判定游戏结束,记录游戏时间
5.游戏结束,选择重新开始or退回主界面
二.游戏类组成:
1.Images加载
2.敌机类(成员变量:位置信息,大小信息;子类:大飞机,中飞机,小飞机);
3.子弹类(成员变量:位置信息,大小信息);
4.敌机管理类(成员变量:敌机集合;方法:位置移动,效果展示,碰撞检测);
5.子弹管理类(成员变量:子弹集合;方法:位置移动,碰撞检测);
三.涉及知识点
继承,封装,多态;
-----------------------------------------------------------------------------------------
初步效果图像:
1.主程序
package gamepack;
import javax.swing.*;
import java.awt.*;
public class StartGame {
public static void main(String[] args) {
//1.构建窗体
JFrame jf = new JFrame();
//加窗体标题
jf.setTitle("Plane Wars");
//调用setBounds方法设置窗体的弹出位置,窗体大小
int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
int jfWidth = 490;
int jfHeight = 720;
jf.setBounds((screenWidth - jfWidth) / 2, (screenHeight - jfHeight) / 2, jfWidth, jfHeight);
//将窗口设定为不可调节大小
jf.setResizable(false);
//窗口关闭的同时结束程序
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//2.创建一个面板
GamePanel gp=new GamePanel();
//将面板添加到窗体中
jf.add(gp);
//显示窗口
jf.setVisible(true);
}
}
2.面板绘制程序
package gamepack;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
/*
游戏面板:是一个透明的面板,所有的内容都是画在该面板中
继承了JPanel的功能
*/
public class GamePanel extends JPanel {
int backgroundX;
int backgroundY;
int planeX;
int planeY;
int[] bombXs = new int[10];
int[] bombYs = new int[10];
//定义每一个炮弹的弧度
//double[] degrees=new double[10];
//游戏的两个状态
boolean isStart = false;//默认游戏是暂停的
//定义飞机飞的方向
boolean left, right, up, down;
//飞机是否碰撞
boolean isDead = false;
//定义游戏开始时间
long startTime;
//定义游戏结束时间
long endTime;
//定义飞机形态变化时间
long changTime;
//定义一个定时器
Timer timer;
//初始化方法
public void init() {
//游戏开始
startTime = System.currentTimeMillis();
//初始化背景坐标
backgroundX = 0;
backgroundY = 0;
//初始化飞机坐标
planeX = 200;
planeY = 580;
//初始化炮弹坐标
// for (int i = 0; i < 10; i++) {
// bombXs[i]=100;
// bombYs[i]=100;
// //给每一个炮弹设置随机的弧度
// degrees[i]=(int)(Math.random()*2*Math.PI);
// }
}
public GamePanel() {
init();
//将焦点放入面板
this.setFocusable(true);
//加入监听效果
this.addKeyListener(new KeyAdapter() {
//监听键盘的按压
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
//获取按键
int keyCode = e.getKeyCode();
//System.out.println(keyCode);
if (keyCode == KeyEvent.VK_SPACE) {//检测监听的是否是空格
if (isDead) {
init();
isDead = false;
} else {
isStart = !isStart;
//重新绘制页面
repaint();
}
}
if (keyCode == KeyEvent.VK_LEFT) {
left = true;
}
if (keyCode == KeyEvent.VK_RIGHT) {
right = true;
}
if (keyCode == KeyEvent.VK_UP) {
up = true;
}
if (keyCode == KeyEvent.VK_DOWN) {
down = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
//获取按键
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) {
left = false;
}
if (keyCode == KeyEvent.VK_RIGHT) {
right = false;
}
if (keyCode == KeyEvent.VK_UP) {
up = false;
}
if (keyCode == KeyEvent.VK_DOWN) {
down = false;
}
}
});
//初始化定时器:每50ms执行一下actionPerformed中的逻辑
timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isStart == true && isDead == false) {
backgroundY += 10;
if (backgroundY > 700) {
backgroundY = 0;
}
if (left) {
planeX -= 7;
}
if (right) {
planeX += 7;
}
if (up) {
planeY -= 7;
}
if (down) {
planeY += 7;
}
//炮弹按照弧度移动
// for (int i = 0; i < 10; i++) {
// //炮弹的X坐标移动
// bombXs[i]+=Math.cos(degrees[i])*7;
// //炮弹的Y坐标移动
// bombYs[i]+=Math.sin(degrees[i])*7;
// if(bombXs[i]<=0){
// bombXs[i]=490;
// }
// if(bombXs[i]>490){
// bombXs[i]=0;
// }
// if(bombYs[i]<=0){
// bombYs[i]=720;
// }
// if(bombYs[i]>720){
// bombYs[i]=0;
// }
// //每个炮弹和飞机进行碰撞检测
// //封装为举矩形对象
// boolean flag=new Rectangle(planeX,planeY,100,120).intersects(
// new Rectangle(bombXs[i],bombYs[i],60,55));
// if(flag){
// endTime=System.currentTimeMillis();
// isDead=true;
// }
// }
//改变坐标后,重新绘制
repaint();
}
}
});
timer.start();
}
//重写一个方法,用来在画板中添加图层
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//设置背景颜色
//this.setBackground(new Color(255, 255, 255));
changTime = System.currentTimeMillis();
//给面板添加背景图片
Images.groundImg.paintIcon(this, g, backgroundX, backgroundY);
Images.groundImg.paintIcon(this, g, backgroundX, backgroundY - 700);
if ((changTime - startTime) % 2 == 0) {
Images.planeImg.paintIcon(this, g, planeX, planeY);
} else {
Images.planeImg2.paintIcon(this, g, planeX, planeY);
}
// for (int i = 0; i < 10; i++) {
// Images.bombImg.paintIcon(this,g,bombXs[i],bombYs[i]);
// }
if (isStart == false) {
g.setColor(new Color(69, 91, 134));
g.setFont(new Font("微软雅黑", Font.BOLD, 40));
g.drawString("点击开始游戏", 120, 330);
}
if (isDead == true) {
g.setColor(new Color(69, 91, 134));
g.setFont(new Font("微软雅黑", Font.BOLD, 40));
g.drawString("游戏结束" + (endTime - startTime) / 1000 + "秒", 100, 330);
}
}
}
3.图片资源加载程序
package gamepack;
import javax.swing.*;
import java.net.URL;
/*
图片工具类
*/
public class Images {
//1.炸弹
//先把图片的地址封装为一个具体的对象
static URL bombURL=Images.class.getResource("/images/bomb.png");
//把图片封装为一个对象
static ImageIcon bombImg=new ImageIcon(bombURL);//定义为静态,直接通过Images直接调用
//2.背景
static URL groundURL=Images.class.getResource("/images/background.png");
static ImageIcon groundImg=new ImageIcon(groundURL);
//3.我的飞机
static URL planeURL=Images.class.getResource("/images/me1.png");
static ImageIcon planeImg=new ImageIcon(planeURL);
static URL planeURL2=Images.class.getResource("/images/me2.png");
static ImageIcon planeImg2=new ImageIcon(planeURL2);
}
哇,真**难,多态的实现还是C++的指针方便;开发还在继续,后续敬请期待;