基于Java实现的课程设计项目——坦克大战

坦克大战游戏背景:

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.游戏功能还有待进一步完善,例如增加更多关卡、敌人种类和道具,提升游戏的丰富性和可玩性。在游戏界面设计、交互反馈等方面仍有改进空间,以提升用户体验。

感想:

       从无到有地设计并完成这个坦克大战小游戏项目,无疑是一段充满挑战与收获的旅程。在这个过程中,我深感每一个困难都是成长的催化剂,每一次突破都是自我价值的实现。虽然起步的时候深感迷茫和困惑,但是在后续设计项目的过程中,我不断尝试新的想法和方案,力求在功能和用户体验上实现创新;通过与团队成员的交流和讨论,我们共同激发出许多富有创意的灵感,并将其付诸实践。这种创新的过程让我深感兴奋和满足。我们共同面对困难、分享成功、互相支持和鼓励。这种团队精神让我深感温暖和自豪,也让我更加珍惜与团队成员的每一次合作。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值