坦克大战游戏背景:
1 环境要求
操作系统:Windows 7(SP1)以上
JAVA虚拟机:JDK1.8以上
开发环境:Eclipse(4.5以上)
2 角色设定
用户在系统中扮演的角色,以及可以执行的职责。
玩 家 操纵玩家坦克,与敌方坦克作战,同时保护本基地。敌方坦克随机移动,发射子弹。
3 设定玩家(玩家一,玩家二,即一个人玩还是两个人玩),我方坦克的方向和子弹由用户控制,所有墙块都可以打碎,但是铁墙是打不碎的,草地不能阻止坦克和子弹的前进,河流能阻止坦克前进,但是不能阻止子弹前进。我方基地被毁则游戏结束,自己的坦克被毁游戏也结束,唯一赢得方式是消灭所有的敌方坦克,则可以进入下一关。一关比一关的难度大,通过地图来实现。
git提交截图:
负责的任务与功能描述:
序号 | 完成的任务 | 功能描述 |
1 | 创建Util包 | 完成游戏运行的配置优化 |
2 | 面向对象设计 | 使用了面向对象技术设计系统。 |
3 | 实现游戏存档功能 | 1.使用Java的序列化机制将游戏的关键数据写入到文件中 2.调用存档类中的保存方法,将当前游戏状态写入到指定的文件 3.读取存档文件,使用Java的反序列化机制恢复游戏状态 |
4 | 进行关卡敌人和子弹的初始配置 | 设计不同难度的关卡配置 |
关键代码:
子弹对象池类:
package com.qlgy.util;
import com.qlgy.game.Bullet;
import java.util.ArrayList;
import java.util.List;
public class BulletsPool {
public static final int DEFAULT_POOL_SIZE = 200;
public static final int POOL_MAX_SIZE = 300;
//用于保存所有的子弹的容器
private static List<Bullet> pool = new ArrayList<>();
//在类加载的时候创建200个子弹对象添加到容器中
static{
for (int i = 0; i <DEFAULT_POOL_SIZE ; i++) {
pool.add(new Bullet());
}
}
/**
* 从池塘中获取一个子弹对象。
* @return
*/
public static Bullet get(){
Bullet bullet = null;
//池塘被掏空了!
if(pool.size() == 0){
bullet = new Bullet();
}else{//池塘中还有对象,拿走第一个位置的子弹对象
bullet = pool.remove(0);
}
// System.out.println("从对象池中获取了一个对象,剩余:"+pool.size());
return bullet;
}
//子弹被销毁的时候,归还到池塘中来
public static void theReturn(Bullet bullet){
//池塘中的子弹的个数已经到达了最大值。那就不再归还
if(pool.size() == POOL_MAX_SIZE){
return;
}
pool.add(bullet);
// System.out.println("对象池中归还了一个子弹对象,数量为:"+pool.size());
}
}
敌人坦克对象池类:
package com.qlgy.util;
import com.qlgy.tank.EnemyTank;
import com.qlgy.tank.Tank;
import java.util.ArrayList;
import java.util.List;
public class EnemyTanksPool {
public static final int DEFAULT_POOL_SIZE = 20;
public static final int POOL_MAX_SIZE = 20;
private static List<Tank> pool = new ArrayList<>();
static{
for (int i = 0; i <DEFAULT_POOL_SIZE ; i++) {
pool.add(new EnemyTank());
}
}
/**
* 从池塘中获取一个对象。
* @return
*/
public static Tank get(){
Tank tank = null;
//池塘被掏空了!
if(pool.size() == 0){
tank = new EnemyTank();
}else{//池塘中还有对象,拿走第一个位置的子弹对象
tank = pool.remove(0);
}
return tank;
}
//子弹被销毁的时候,归还到池塘中来
public static void theReturn(Tank tank){
//池塘中的子弹的个数已经到达了最大值。那就不再归还
if(pool.size() == POOL_MAX_SIZE){
return;
}
pool.add(tank);
}
}
爆炸效果对象池类:
package com.qlgy.util;
import com.qlgy.game.Explode;
import java.util.ArrayList;
import java.util.List;
public class ExplodesPool {
public static final int DEFAULT_POOL_SIZE = 10;
public static final int POOL_MAX_SIZE = 20;
//用于保存所有的爆炸效果的容器
private static List<Explode> pool = new ArrayList<>();
//
static{
for (int i = 0; i <DEFAULT_POOL_SIZE ; i++) {
pool.add(new Explode());
}
}
/**
* 从池塘中获取一个爆炸对象。
* @return
*/
public static Explode get(){
// MusicUtil.playBomb();
Explode explode = null;
//池塘被掏空了!
if(pool.size() == 0){
explode = new Explode();
}else{//池塘中还有对象,拿走第一个位置的子弹对象
explode = pool.remove(0);
}
return explode;
}
public static void theReturn(Explode explode){
if(pool.size() == POOL_MAX_SIZE){
return;
}
pool.add(explode);
}
}
地图对象池类:
package com.qlgy.util;
import com.qlgy.map.MapTile;
import com.qlgy.tank.EnemyTank;
import com.qlgy.tank.Tank;
import java.util.ArrayList;
import java.util.List;
public class MapTilePool{
public static final int DEFAULT_POOL_SIZE = 50;
public static final int POOL_MAX_SIZE = 70;
private static List<MapTile> pool = new ArrayList<>();
static{
for (int i = 0; i <DEFAULT_POOL_SIZE ; i++) {
pool.add(new MapTile());
}
}
/**
* 从池塘中获取一个对象。
* @return
*/
public static MapTile get(){
MapTile tile = null;
//池塘被掏空了!
if(pool.size() == 0){
tile = new MapTile();
}else{//池塘中还有对象,拿走第一个位置的子弹对象
tile = pool.remove(0);
}
return tile;
}
//子弹被销毁的时候,归还到池塘中来
public static void theReturn(MapTile tile){
//池塘中的子弹的个数已经到达了最大值。那就不再归还
if(pool.size() == POOL_MAX_SIZE){
return;
}
pool.add(tile);
}
}
后期维护类:
package com.qlgy.util;
import java.awt.*;
/**
* 游戏中的常量都在该类中维护,方便后期的管理
*/
public class Constant {
/******************游戏窗口相关******************/
public static final String GAME_TITLE = "坦克大战";
public static final int FRAME_WIDTH = 800;
public static final int FRAME_HEIGHT = 600;
//动态的获得系统屏幕的宽高
public static final int SCREEN_W = Toolkit.getDefaultToolkit().getScreenSize().width;
public static final int SCREEN_H = Toolkit.getDefaultToolkit().getScreenSize().height;
public static final int FRAME_X = SCREEN_W-FRAME_WIDTH>>1;
public static final int FRAME_Y = SCREEN_H-FRAME_HEIGHT>>1;
/*********************游戏菜单相关*********************/
public static final int STATE_MENU = 0;
public static final int STATE_HELP = 1;
public static final int STATE_ABOUT = 2;
public static final int STATE_RUN = 3;
public static final int STATE_LOST = 4;
public static final int STATE_WIN = 5;
public static final int STATE_CROSS = 6;
public static final String[] MENUS = {
"开始游戏",
"继续游戏",
"游戏帮助",
"游戏关于",
"退出游戏"
};
public static final String OVER_STR0 = "ESC键退出游戏";
public static final String OVER_STR1 = "ENTER键回主菜单";
//字体
public static final Font GAME_FONT = new Font("宋体",Font.BOLD,24);
public static final Font SMALL_FONT = new Font("宋体",Font.BOLD,12);
public static final int REPAINT_INTERVAL = 30;
//最大敌人数量
public static final int ENEMY_MAX_COUNT = 10;
public static final int ENEMY_BORN_INTERVAL = 5000;
public static final int ENEMY_AI_INTERVAL = 3000;
public static final double ENEMY_FIRE_PERCENT = 0.03;
}
背景音乐类:
package com.qlgy.util;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.io.IOException;
public class MusicUtil {
private static AudioClip start;
private static AudioClip bomb;
//装载音乐资源
static {
try {
//引号里面的是音乐文件所在的绝对路径
start = Applet.newAudioClip(new File("music/start.wav").toURL());//加载音频
bomb = Applet.newAudioClip(new File("music/bomb.wav").toURL());//加载音频
} catch (IOException e) {
e.printStackTrace();
}
}
public static void playStart() {
start.play(); //播放音频
}
public static void playBomb() {
bomb.play(); //播放音频
}
}
命名及图片加载工具类:
package com.qlgy.util;
import java.awt.*;
public class MyUtil {
private MyUtil(){}
/**
* 得到指定的区间的随机数
* @param min 区间最小值,包含
* @param max 区间最大值,不包含
* @return 随机数
*/
public static final int getRandomNumber(int min, int max){
return (int)(Math.random()*(max-min)+min);
}
/**
* 得到随机的颜色
* @return
*/
public static final Color getRandomColor(){
int red = getRandomNumber(0,256);
int blue = getRandomNumber(0,256);
int green = getRandomNumber(0,256);
return new Color(red,green,blue);
}
/**
* 判断一个点是否在某一个正方形的内部,
* @param rectX 正方形的中心点的x坐标
* @param rectY 正方形的中心点的y坐标
* @param radius 正方形的边长的一半
* @param pointX 点的x坐标
* @param pointY 点的y坐标
* @return 如果点在正方形内部,返回true,否则返回false
*/
public static final boolean isCollide(int rectX,int rectY,int radius,int pointX,int pointY){
//正方形中心点 和 点 的 x y 轴 的距离
int disX = Math.abs(rectX - pointX);
int disY = Math.abs(rectY - pointY);
if (disX <= radius && disY <= radius)
return true;
return false;
}
/**
* 根据图片的资源路径创建加载图片对象
* @param path 图片资源的路径
* @return
*/
public static final Image createImage(String path){
return Toolkit.getDefaultToolkit().createImage(path);
}
private static final String[] NAMES = {
"行人","乐园","花草","人才","左手","目的","课文","优点","年代","灰尘",
"沙子","小说","儿女","难题","明星","本子","彩色","水珠","路灯","把握",
"房屋","心愿","左边","新闻","早点",
"市场","雨点","细雨","书房","毛巾","画家","元旦","绿豆","本领","起点",
"青菜","土豆","总结","礼貌","右边",
"老虎","老鼠","猴子","树懒"," 斑马","小狗","狐狸","狗熊","黑熊",
"大象","豹子"," 麝牛","狮子","熊猫","疣猪","羚羊","驯鹿","考拉",
"犀牛","猞猁","猩猩","海牛","水獭","海豚","海象","刺猬","袋鼠",
"犰狳","河马","海豹","海狮","蝙蝠","白虎","狸猫","水牛","山羊",
"绵羊","牦牛","猿猴","松鼠","野猪","豪猪","麋鹿","花豹","野狼",
"灰狼","蜂猴","熊猴","叶猴","紫貂","貂熊","熊狸","云豹","雪豹",
"黑麂","野马","鼷鹿","坡鹿","豚鹿","野牛","藏羚","河狸","驼鹿",
"黄羊","鬣羚","斑羚","岩羊","盘羊","雪兔"
};
private static final String[] MODIFIY = {
"可爱","傻傻","萌萌","羞羞","笨笨","呆呆","美丽","聪明","伶俐","狡猾",
"胖乎乎","粉嫩嫩","白胖胖","漂亮","可爱","聪明","懂事","乖巧","淘气",
"淘气","顽劣","调皮","顽皮","天真","可爱","无邪","单纯","纯洁","无暇",
"纯真","稚气","温润","好奇"
};
/**
* 得到一个随机的名字
* @return
*/
public static final String getRandomName(){
return MODIFIY[getRandomNumber(0,MODIFIY.length)] + "的" +
NAMES[getRandomNumber(0,NAMES.length)];
}
}
总结:
1.成功实现了坦克的移动、射击、敌人生成与行为控制、道具使用等核心游戏功能。通过合理的关卡设计和游戏机制,为玩家提供了紧张刺激的游戏体验。
2.采用了Java游戏开发框架,降低了开发难度,提高了开发效率。
3.通过基本的图形渲染技术,实现了游戏的视觉呈现,包括坦克、敌人、道具等元素。成功将背景音乐和音效集成到游戏中,增强了游戏的沉浸感。
4.团队成员之间分工明确,各自负责不同的游戏功能和模块开发。面对项目中的问题和挑战,团队成员能够共同协作,及时找到解决方案。通过本项目的开发,团队成员在Java游戏开发、图形渲染、音频处理等方面的技能得到了提升。
5.游戏功能还有待进一步完善,例如增加更多关卡、敌人种类和道具,提升游戏的丰富性和可玩性。在游戏界面设计、交互反馈等方面仍有改进空间,以提升用户体验。
感想:
从无到有地设计并完成这个坦克大战小游戏项目,无疑是一段充满挑战与收获的旅程。在这个过程中,我深感每一个困难都是成长的催化剂,每一次突破都是自我价值的实现。虽然起步的时候深感迷茫和困惑,但是在后续设计项目的过程中,我不断尝试新的想法和方案,力求在功能和用户体验上实现创新;通过与团队成员的交流和讨论,我们共同激发出许多富有创意的灵感,并将其付诸实践。这种创新的过程让我深感兴奋和满足。我们共同面对困难、分享成功、互相支持和鼓励。这种团队精神让我深感温暖和自豪,也让我更加珍惜与团队成员的每一次合作。