文章目录
游戏项目
坦克大战第一部分
学习思路
因坦克大战难度较高,而且如今的java基础还未学习IO流以及多线程课程,为此,在做坦克大战项目的同时,边做边学,理解IO流以及多线程处理技术,所以,此文章分多个部分
为什么要写这个项目
-
好玩
-
涉及到java各个方面的技术
- java面向对象编程
- 多线程
- 文件i/o操作
- 数据库
- 巩固旧知识,学习新知识
需要多少时间
1.IO流学习
2.多线程学习
3.坦克大战项目完成
目标两周的时间完成这三个内容
2022 - 1 - 11 到 2022 - 1 - 25
项目描述
1. 程序描述
- 本程序是一个简单的坦克游戏程序,用java语言编写,在jdk 环境下运行。游戏开始时,用户通过键盘操纵坦克移动,转弯和射击,与敌人坦克进行交战,直到消灭所有敌人就可以过关。本程序包括23个类,2800多行代码,和三个gif图片
2.功能介绍
1.1 开始游戏
- 本程序运行的主函数类时 tankGame类,将此类编译后直接运行,就会出现如下界面:
- 上图显示的界面为程序的主界面。用户可以通过点击上面的菜单项开始进行游戏或设置游戏规则。界面中的黑色区域为游戏面板,游戏开始时就在此面板中进行。初始时面板中显示 stagel,表示从第一关开始游戏。点击游戏菜单中的“新游戏”菜单项,就可以正是开始游戏,其界面如下显示:
- 在上图显示的界面中,在下方的橘黄色坦克是用户可以操纵的坦克。上面的3辆浅蓝色坦克是敌人坦克。用户可以通过按键盘的W/S/A/D 4个键控制坦克向上下左右移动,按J键可以使坦克射击。在游戏界面中除了坦克还有障碍物,障碍物分为3种,一种是砖墙,砖墙可以阻止坦克移动,但用炮弹可以打穿;一种是铁墙,用炮弹是不能打穿的;一种是河流,可以组织坦克移动,但炮弹可以穿过去。
- 本游戏一共分为8关,每一关的障碍物布局和敌人坦克数量都不同。
- 上图中显示的是第一关的游戏界面。游戏界面下方的数字20表示第一关敌人坦克的数量,当每次消灭一辆坦克时数量会减少,直到敌人坦克的数量为0时第一关结束,继续打下一关。数字3表示用户操纵的坦克的生命值,当玩家坦克被敌人击毁后生命值减1。当生命值减为零后,游戏结束。
1.2 分数统计
-
当游戏打过一关后,就会弹出一对话框显示出玩家在这一关中所得的分数,如下图所示:
-
上图中显示出敌人坦克共分为5种,每种坦克具有的特点不同,分值也不同。浅蓝色坦克是最普通的一种,消灭一辆浅蓝色坦克可得到100分,在敌人坦克中%70的概率会出现浅蓝色坦克。粉色坦克发射出的炮弹速度快,战斗力比浅蓝色坦克要强一些,消灭一辆粉色坦克可得到200分。红色坦克移动速度快,比较灵活,消灭一辆蓝色坦克可得到300分。绿色坦克是重型坦克,击中4次才能将其消灭,消灭一辆绿色坦克可得到400分。最后一种深蓝色坦克是坦克中战斗力最强的,他有着以上几种坦克具有的所有特性,不仅射击,移动速度快,而且生命值也很高,需要击中它6次才能消灭。深蓝坦克有时作为关底出现,而且并不是每一关都有关底,如果按照正常游戏,只有3,6,8关才会出现关底。消灭一辆深蓝色坦克得到1000分
-
当游戏结束后,玩家每一关得到的分数会累积,统计出最后的分数,如果分数破了记录,就会弹出对话框让用户输入姓名,这次游戏的分数会保存到数据库中。本游戏的数据库存放的是玩家的游戏记录,点击设置菜单中的游戏记录选项,就可以查看游戏记录,如下图所示:
写项目前的提醒
- 编写坦克大战游戏,你需要有一定的java基础,是完全可以听懂的
- 记住一点:成为一个编程专家的秘诀就是:思考 ---- 编程 ---- 思考 ----- 编程
- 项目是从小到大的过程,每个完整的项目被分解成不同的版本,从1.0到1.1 …最后版,随版本的增加,将新的功能和新的知识点融入到项目中,整个过程是循序渐进的。
本章内容
1. java绘图坐标体系
坐标体系 - 介绍
- 下图说明了Java坐标系。坐标原点位于左上角,以像素为单位。在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。
坐标体系 - 像素
-
绘图还必须要搞清楚一个非常重要的概念 - 像素 一个像素等于多少厘米?
-
计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的。列入,计算机显示器的分辨率是800 * 600,表示计算机屏幕上的每一行由800个点组成,共有600行,整个计算机屏幕共有480 000 个像素。像素是一个密度单位,而厘米是长度单位,两者无法比较
2.java绘图技术
介绍 - 快速入门
借用案例,来讲解java绘图技术原理(弹出一个窗口,窗口里绘制一个小圆圈)
package com.tao.draw;
import javax.swing.*;
import java.awt.*;
/**
* Create By 刘鸿涛
* 2022/1/11 23:20
*/
public class DrawCicle extends JFrame{
//继承JFrame 框架,可以理解成是一个画框
//定义一个面板
private MyPanel mp = null;
public static void main(String[] args) {
new DrawCicle();
// System.out.println("程序退出");
}
public DrawCicle(){
//初始化面板
mp = new MyPanel();
//把面板放入到窗口(画框)
this.add(mp);
//设置窗口的大小
this.setSize(800,600);
//当点击窗口的 x ,程序完全退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true); //可以显示
}
}
//1.先定义一个MyPanel(),继承JPanel类,画图形,就在面板上面
// Panel:画板,
class MyPanel extends JPanel {
//说明:
//1.MyPanel 对象就是一个画板
//2.Graphics g 把 g理解成一支画笔
//3.Graphics 提供了很多绘图的方法
//Graphics g
@Override
//Graphics:绘图
public void paint(Graphics g){
//绘图方法
System.out.println("paint方法被调用了");
super.paint(g); //调用父类的方法完成初始化
//画出一个圆形
g.drawOval(10,10,100,100);
}
}
绘图原理
Component类提供了两个和绘图相关最重要的方法:
- paint(Graphics g)绘制组件的外观
- repaint()刷新组件的外观
当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件
在以下情况paint()将会被调用:
- 窗口最小化,再最大化
- 窗口的大小发生变化
- repaint函数被调用
思考题:如何证明上面的三种情况,会调用paint()方法
Graphics类
- Graphics类你可以理解就是画笔,为我们提供了各种绘制图形的方法:
- 画直线
drawLine(int x1,int y1,int x2,int y2)
- 画矩形边框
drawRect(int x,int y,int width,int height)
- 画椭圆边框
drawOval(int x,int y,int width,int height)
- 填充矩形
fillRect(int x,int y,int width,int height)
- 填充椭圆
fillOval(int x,int y,int width,int height)
- 画图片
drawImage(Image img,int x,int y,..)
- 画字符串
drawString(String str,int x,int y)
- 设置画笔的字体
setFont(Font font)
- 设置画笔的颜色
setColor(Color c)
package com.tao.draw;
import javax.swing.*;
import java.awt.*;
/**
* Create By 刘鸿涛
* 2022/1/11 23:20
*/
public class DrawCicle extends JFrame{
//继承JFrame 框架,可以理解成是一个画框
//定义一个面板
private MyPanel mp = null;
public static void main(String[] args) {
new DrawCicle();
// System.out.println("程序退出");
}
public DrawCicle(){
//初始化面板
mp = new MyPanel();
//把面板放入到窗口(画框)
this.add(mp);
//设置窗口的大小
this.setSize(800,600);
//当点击窗口的 x ,程序完全退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true); //可以显示
}
}
//1.先定义一个MyPanel(),继承JPanel类,画图形,就在面板上面
// Panel:画板,
class MyPanel extends JPanel {
//说明:
//1.MyPanel 对象就是一个画板
//2.Graphics g 把 g理解成一支画笔
//3.Graphics 提供了很多绘图的方法
//Graphics g
@Override
//Graphics:绘图
public void paint(Graphics g){
//绘图方法
System.out.println("paint方法被调用了");
super.paint(g); //调用父类的方法完成初始化
//画出一个圆形
g.drawOval(10,10,100,100);
//演示绘制不同的图形..
// 1. 画直线
// drawLine(int x1,int y1,int x2,int y2)
g.drawLine(20,20,100,100);
// 2. 画矩形边框
// drawRect(int x,int y,int width,int height)
g.drawRect(50,50,10,10);
// 3. 画椭圆边框
// drawOval(int x,int y,int width,int height)
g.drawOval(60,60,50,30);
// 4. 填充矩形
// fillRect(int x,int y,int width,int height)
g.fillRect(500,300,50,60);
// 5. 填充椭圆
// fillOval(int x,int y,int width,int height)
g.setColor(Color.BLUE); //设置颜色
g.fillOval(400,300,20,30);
// 6. 画图片
// drawImage(Image img,int x,int y,..)
// g.drawImage()
//1.获取图片资源(out -> chapter -根目录)
Image jing = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/jing.jpg"));
g.drawImage(jing,400,200,192,108,this);
// 7. 画字符串
// drawString(String str,int x,int y)
// 8. 设置画笔的字体、颜色
g.setColor(Color.ORANGE);
g.setFont(new Font("黑体",Font.BOLD,50));
g.drawString("幸运星",100,100);
//设置画笔的字体 setFont(Font font)
//设置画笔的颜色 setColor(Color c)
}
}
自己绘制坦克,思维图
package com.tao.draw;
import javax.swing.*;
import java.awt.*;
/**
* Create By 刘鸿涛
* 2022/1/12 3:45
*/
public class DrawTank_ extends JFrame {
//继承JFrame框架,画框
private MyTank tank = null;
public static void main(String[] args) {
new DrawTank_();
}
public DrawTank_(){
tank = new MyTank();
this.add(tank);
this.setSize(800,600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //点x 关闭程序
this.setVisible(true); //可以显示
}
}
class MyTank extends JPanel{
@Override
public void paint(Graphics g){
System.out.println("paint被调用");
super.paint(g); //调用父类的方法完成初始化
//注意,重下往上画
//背景色黑色
g.setColor(Color.BLACK);
g.fillRect(0,0,800,600);
g.setColor(Color.GRAY);
//底盘
g.fillRect(395,288,30,36);
g.setColor(Color.CYAN);
//轮胎
g.fillRect(420,275,15,60); //右
g.fillRect(385,275,15,60); //左
//炮台
g.setColor(Color.RED);
g.fillOval(400,300,20,20);
g.drawLine(410,280,410,320); //400 + 20/2 300 - 20
g.setColor(Color.ORANGE);
g.setFont(new Font("楷体",Font.BOLD,100));
g.drawString("坦 克 大 战",120,200);
}
}
- 有误差,不过影响不大,坐标与大小自行调整