星际争霸小程序:用Java实现策略模式的星际大战

news2025/5/22 20:25:10

  在游戏开发的世界里,策略模式是一种非常实用的设计模式,它允许我们在运行时动态地选择算法或行为。今天,我将带你走进一场星际争霸的奇幻之旅,用Java实现一个简单的星际争霸小程序,通过策略模式来模拟不同种族单位的战斗行为。

实验背景

  星际争霸是一款经典的即时战略游戏,玩家需要控制不同种族的单位进行战斗。每个种族都有其独特的单位和战斗策略。在本次实验中,我选择了Java语言,利用策略模式来实现不同种族单位的攻击行为。通过策略模式,我们可以轻松地为单位切换不同的攻击策略,从而使代码更加灵活和可扩展。

实验设计

1. 整体思路

  为了实现星际争霸小程序,我们需要构建一个包含不同种族单位的战场。每个单位都有其生命值、攻击力和特定的攻击策略。通过策略模式,我们可以为单位动态切换攻击策略,从而模拟不同的战斗场景。

2.UML图

3. 主要模块设计

(1)攻击策略接口
  定义一个攻击策略接口 'Strategy',所有具体的攻击策略类都将实现这个接口。

package attack;

import creature.Creature;

public interface Strategy {
    void fight(Creature c);
    int getattack();
}

 (2)具体攻击策略类
实现具体的攻击策略类,如 'Air' 和 'Ground',分别对应空中攻击和地面攻击。

package attack;

import mutalisk.Mutalisk;
import creature.Creature;

public class Air implements Strategy {
    private int attack = 120;
    private int up = 200;
    private Mutalisk mutalisk;

    public Air(Mutalisk mutalisk) {
        this.mutalisk = mutalisk;
    }

    public void recover(int amount) {
        mutalisk.life += amount;
    }

    @Override
    public void fight(Creature c) {
        System.out.println("空中攻击模式");
        System.out.println(mutalisk.name + "攻击" + c.name + " " + attack + "滴血");
        c.updateLife(attack);
        recover(up);
    }

    @Override
    public int getattack() {
        return this.attack;
    }
}
package attack;

import mutalisk.Mutalisk;
import creature.Creature;

public class Ground implements Strategy {
    private int attack = 400;
    private int up_rc = 100;
    private Mutalisk mutalisk;

    public Ground(Mutalisk mutalisk) {
        this.mutalisk = mutalisk;
    }

    public void recover(int amount) {
        mutalisk.life += amount;
    }

    @Override
    public void fight(Creature c) {
        System.out.println("地面攻击模式");
        System.out.println(mutalisk.name + "攻击" + c.name + " " + attack + "滴血");
        c.updateLife(attack);
        recover(up_rc);
    }

    @Override
    public int getattack() {
        return this.attack;
    }
}

(3)单位抽象类
定义一个抽象类 'Creature',所有具体的单位类都将继承这个类。

package creature;

import attack.Strategy;
import common.ICommon;

public abstract class Creature implements ICommon, Strategy {
    public String name;
    public int life;
    protected int attack;

    public Creature(String name, int life, int attack) {
        this.name = name;
        this.life = life;
        this.attack = attack;
    }

    public Creature(String name, int life) {
        this.name = name;
        this.life = life;
    }

    @Override
    public void state() {
        if (this.isDead()) {
            System.out.println("[" + this.name + "]已阵亡");
        } else {
            System.out.println("[" + this.name + "]的当前生命值为" + life + ";当前攻击值为" + attack);
        }
    }

    @Override
    public abstract void fight(Creature c);

    public boolean isDead() {
        return life <= 0;
    }

    public void updateLife(int damage) {
        life -= damage;
        if (life <= 0) {
            life = 0;
            System.out.println(name + "已阵亡");
        }
    }

    @Override
    public int getattack() {
        return 0;
    }
}

(4)具体单位类
实现具体的单位类,如 'Mutalisk' 和 'Terran'。

package mutalisk;

import attack.Air;
import attack.Strategy;
import creature.Creature;
import zerg.Zerg;

public class Mutalisk extends Zerg {
    private Strategy strategy;
    protected int attack;

    public Mutalisk(String name, int life) {
        super(name, life);
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
        this.attack = strategy.getattack();
    }

    public void fightStrategy(Creature c) {
        strategy.fight(c);
    }

    public void healZerg(Zerg z) {
        if (z.isDead()) {
            z.setlife(this.life);
            this.life = 0;
            System.out.println("忠诚的献身");
        }
    }
}

package terran;

import creature.Creature;

public class Terran extends Creature {
    public int up = 500;

    public Terran(String name, int life, int attack) {
        super(name, life, attack);
    }

    @Override
    public void fight(Creature c) {
        System.out.println(name + "攻击" + c.name + " " + attack + "滴血");
        c.updateLife(attack);
        repair(up);
    }

    public void repair(int amount) {
        attack += amount;
    }
}

 4. 测试程序

编写测试程序,模拟星际争霸的战斗场景。

package test;

import attack.Air;
import attack.Ground;
import attack.Strategy;
import creature.Creature;
import mutalisk.Mutalisk;
import terran.Terran;
import xrace.Xrace;
import zerg.Zerg;

public class Test {
    public static void main(String[] args) {
        // 创建战场人员
        int n = 1;
        Terran[] terrans = new Terran[n];
        for (int i = 0; i < terrans.length; i++) {
            terrans[i] = new Terran("Terran" + (i + 1), 800, 100);
        }
        Xrace xrace = new Xrace("Xrace", 100, 8000);
        Zerg zerg = new Zerg("Zerg", 50000, 400);
        Mutalisk mutalisk = new Mutalisk("Mutalisk", 20000);

        // 创建两种攻击策略
        Air air = new Air(mutalisk);
        Ground ground = new Ground(mutalisk);

        // 战争开始前展示人员状态
        for (Terran terran : terrans) {
            terran.state();
        }
        xrace.state();
        zerg.state();
        mutalisk.state();

        // 游戏开始
        boolean gameEnd = false;
        while (!gameEnd) {
            // 检测Terran是否死亡
            boolean zergAttacked = false;
            for (Terran terran : terrans) {
                if (!terran.isDead()) {
                    zerg.fight(terran);
                    zergAttacked = true;
                    break;
                }
            }
            if (!zergAttacked && !xrace.isDead()) {
                zerg.fight(xrace);
            }
            for (Creature terran : terrans) {
                if (!terran.isDead() && !zerg.isDead()) {
                    terran.fight(zerg);
                }
            }
            if (!xrace.isDead() && !zerg.isDead()) {
                xrace.fight(zerg);
            }
            if (zerg.isDead() && !mutalisk.isDead()) {
                mutalisk.healZerg(zerg);
            }
            if (!xrace.isDead() && !mutalisk.isDead()) {
                mutalisk.setStrategy(air);
                mutalisk.fightStrategy(xrace);
            } else if (xrace.isDead()) {
                for (Creature terran : terrans) {
                    if (!terran.isDead()) {
                        mutalisk.setStrategy(ground);
                        mutalisk.fightStrategy(terran);
                        break;
                    }
                }
            }

            // 更新状态
            for (Creature terran : terrans) {
                terran.state();
            }
            xrace.state();
            zerg.state();
            mutalisk.state();

            if ((xrace.isDead() && terrans[n - 1].isDead()) || (zerg.isDead() && mutalisk.isDead())) {
                gameEnd = true;
                if (xrace.isDead()) {
                    System.out.println(xrace.name + "已阵亡,游戏失败");
                }
                if (zerg.isDead()) {
                    System.out.println(zerg.name + "已阵亡,游戏胜利");
                }
                System.out.println("游戏结束!");
            }
        }
    }
}

实现效果

  通过调试和验证,星际争霸小程序成功实现!程序能够模拟不同种族单位的战斗行为,包括空中攻击和地面攻击。每个单位都可以动态切换攻击策略,从而适应不同的战斗场景。整个程序运行流畅,战斗逻辑清晰,状态更新及时。

战斗场景模拟

策略模式验证

总结

1. 策略模式的魅力:通过策略模式,我们可以轻松地为单位切换不同的攻击策略,从而使代码更加灵活和可扩展。
2. 面向对象编程的优势:利用Java的面向对象特性,我们可以将不同种族单位的行为封装在各自的类中,从而使代码更加模块化和易于维护。
3. 编程技巧的提升:通过实现这个小程序,我进一步掌握了Java的接口、抽象类和多态等概念,提升了编程技巧。
4. 游戏开发的乐趣:通过模拟星际争霸的战斗场景,我体验到了游戏开发的乐趣,激发了我对游戏开发的进一步学习兴趣。

结语

  通过这次实验,我不仅在技术上有了新的突破,更对游戏开发充满了兴趣。策略模式虽然简单,但它在游戏开发中有着广泛的应用。如果你对Java编程或游戏开发感兴趣,欢迎一起交流探讨!让我们在技术的道路上共同进步,继续探索更多神奇的魔法!✨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2383363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python数据可视化高级实战之一——绘制GE矩阵图

目录 一、课程概述 二、GE矩阵? 三、GE 矩阵图的适用范围 五、GE 矩阵的评估方法 (一)市场吸引力的评估要素 二、企业竞争实力的评估要素 三、评估方法与实践应用 1. 定量与定性结合法 2. 数据来源 六、GE矩阵的图形化实现 七、总结:GE 矩阵与 BCG 矩阵的对比分析 (一)GE…

StreamSaver实现大文件下载解决方案

StreamSaver实现大文件下载解决方案 web端 安装 StreamSaver.js npm install streamsaver # 或 yarn add streamsaver在 Vue 组件中导入 import streamSaver from "streamsaver"; // 确保导入名称正确完整代码修正 <!--* projectName: * desc: * author: dua…

CSS【详解】弹性布局 flex

适用场景 一维&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素为容器 所有被布局的元素为项目 项目的排列方向&#xff08;垂直/水平&#xff09;为主轴 与主轴垂直的方向交交叉轴 容器上启用 flex 布局 将容器的 display 样式设置为 flex 或 i…

自回归图像编辑 EditAR: Unified Conditional Generation with Autoregressive Models

Paperhttps://arxiv.org/pdf/2501.04699 Code (coming soon) 目录 方法 实验 EditAR是一个统一的自回归框架&#xff0c;用于各种条件图像生成任务——图像编辑、深度到图像、边缘到图像、分割到图像。 next-token预测的功效尚未被证明用于图像编辑。 EditAR主要构建在Ll…

React Flow 中 Minimap 与 Controls 组件使用指南:交互式小地图与视口控制定制(含代码示例)

本文为《React Agent&#xff1a;从零开始构建 AI 智能体》专栏系列文章。 专栏地址&#xff1a;https://blog.csdn.net/suiyingy/category_12933485.html。项目地址&#xff1a;https://gitee.com/fgai/react-agent&#xff08;含完整代码示​例与实战源&#xff09;。完整介绍…

STM32之串口通信WIFI上云

一、W模块的原理与应用 基本概念 如果打算让硬件设备可以通过云服务器进行通信&#xff08;数据上报/指令下发&#xff09;&#xff0c;像主流的云服务器有阿里云、腾讯云、华为云&#xff0c;以及其他物联网云平台&#xff1a;巴法云.......&#xff0c;硬件设备需要通过TCP…

PCB智能报价系统——————仙盟创梦IDE

软件署名 代码贡献&#xff1a; 紫金电子科技有限公司 文案正路&#xff1a;cybersnow 正文 对企业的竞争力有着深远影响。传统的 PCB 报价方式往往依赖人工核算&#xff0c;不仅耗时较长&#xff0c;还容易出现误差。随着科技的发展&#xff0c;PCB 自动报价系统应运而生&a…

LeetCode-链表-合并两个有序链表

LeetCode-链表-合并两个有序链表 ✏️ 关于专栏&#xff1a;专栏用于记录 prepare for the coding test。 文章目录 LeetCode-链表-合并两个有序链表&#x1f4dd; 合并两个有序链表&#x1f3af;题目描述&#x1f50d; 输入输出示例&#x1f9e9;题目提示&#x1f9ea;AC递归&…

sqli-labs靶场29-31关(http参数污染)

目录 前言 less29&#xff08;单引号http参数污染&#xff09; less30&#xff08;双引号http参数污染&#xff09; less31(双引号括号http参数污染) 前言 在JSP中&#xff0c;使用request.getParameter("id")获取请求参数时&#xff0c;如果存在多个同名参数&a…

JVM 垃圾回收机制深度解析(含图解)

JVM 垃圾回收机制深度解析&#xff08;含图解&#xff09; 一、垃圾回收整体流程 垃圾回收图解 #mermaid-svg-KPtxlwWntQx8TOj3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-KPtxlwWntQx8TOj3 .error-icon{fill…

如何利用 Conda 安装 Pytorch 教程 ?

如何利用 Conda 安装 Pytorch 教程 &#xff1f; 总共分为六步走&#xff1a; &#xff08;1&#xff09;第一步&#xff1a;验证conda 环境是否安装好&#xff1f; 1) conda -V2) conda --version&#xff08;2&#xff09;第二步&#xff1a;查看现有环境 conda env list…

uniapp vue 开发微信小程序 分包梳理经验总结

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“uniapp vue 开发微信小程序 分包梳理经验总结”。 在使用 UniAppvue框架开发微信小程序时&#xff0c;当项目比较大的时候&#xff0c;经常需要分包加载。它有助于控制主包的大小&#xff0c;从而提升小程序的启…

什么是VR展示?VR展示的用途

随着科技的迅猛发展&#xff0c;我们步入一个全新的数字时代。在这个时代&#xff0c;虚拟现实&#xff08;VR&#xff09;技术崭露头角&#xff0c;逐步改变我们对世界的认知。全景展示厅作为VR技术与传统展览艺术的完美结合&#xff0c;以独特的全景视角&#xff0c;引领我们…

.NET外挂系列:4. harmony 中补丁参数的有趣玩法(上)

一&#xff1a;背景 1. 讲故事 前面几篇我们说完了 harmony 的几个注入点&#xff0c;这篇我们聚焦注入点可接收的几类参数的解读&#xff0c;非常有意思&#xff0c;在.NET高级调试 视角下也是非常重要的&#xff0c;到底是哪些参数&#xff0c;用一张表格整理如下&#xff…

Go语言中new与make的深度解析

在 Go 语言中&#xff0c;new 和 make 是两个用于内存分配的内置函数&#xff0c;但它们的作用和使用场景有显著区别。 理解它们的核心在于&#xff1a; new(T): 为类型 T 分配内存&#xff0c;并将其初始化为零值&#xff0c;然后返回一个指向该内存的指针 (*T)。make(T, ar…

3、ubantu系统 | 通过vscode远程安装并配置anaconda

1、vscode登录 登录后通过pwd可以发现目前位于wangqinag账号下&#xff0c;左侧为属于该账号的文件夹及文件。 通过cd ..可以回到上一级目录&#xff0c;通过ls可以查看当前目录下的文件夹及文件。 2、安装 2.1、下载anaconda 通过wget和curl下载未成功&#xff0c;使用手动…

【Unity】 HTFramework框架(六十五)ScrollList滚动数据列表

更新日期&#xff1a;2025年5月16日。 Github 仓库&#xff1a;https://github.com/SaiTingHu/HTFramework Gitee 仓库&#xff1a;https://gitee.com/SaiTingHu/HTFramework 索引 一、ScrollList滚动数据列表二、使用ScrollList1.快捷创建ScrollList2.ScrollList的属性3.自定义…

Swagger在java的运用

Swagger 是一个广泛使用的工具&#xff0c;用于设计、构建、记录和使用 RESTful Web 服务。它通过提供交互式的 API 文档、客户端 SDK 生成和 API 发现功能&#xff0c;极大地简化了 API 的开发和使用过程。以下是对 Swagger 的详细介绍&#xff0c;包括它的功能、使用场景、如…

代码随想录算法训练营 Day49 图论Ⅰ 深度优先与广度优先

图论 基础 图的概念 图的概念 概念清单有向图 (a)无向图 (b)有向/无向如图 a 所示每条边有指向如图 b 所示每条边没有箭头指向权值每条边的权值每条边的权值度-有几条边连到该节点 (eg V 2 V_2 V2​ 度为 3)入度/出度出度&#xff1a;从该节点出发的边个数入度&#xff1a;…

.NET外挂系列:1. harmony 基本原理和骨架分析

一&#xff1a;背景 1. 讲故事 为什么要开这么一个系列&#xff0c;是因为他可以对 .NET SDK 中的方法进行外挂&#xff0c;这种技术对解决程序的一些疑难杂症特别有用&#xff0c;在.NET高级调试 领域下大显神威&#xff0c;在我的训练营里也是花了一些篇幅来说这个&#xf…