当前位置: 首页 > news >正文

Java小游戏

一、需求

             

 二、思路一

        HP当然是怪物的一个属性成员,而武器是角色的一个属性成员,类型可以使字符串,用于描述目前角色所装备的武器。角色类有一个攻击方法,以被攻击怪物为参数,当实施一次攻击时,攻击方法被调用,而这个方法首先判断当前角色装备了什么武器,然后据此对被攻击怪物的HP进行操作,以产生不同效果

package com.homework.game;public class Monster {//定义怪物名称public String monster_name;//定义怪物血量public int monster_hp;//定义构造方法
//    public Monster(){
//    }//定义有参数的构造方法,主函数中调用此方法可以传递怪物的名称和初始血量public Monster(String name,int hp){//给怪物名称和初始血量赋值this.monster_name = name;this.monster_hp = hp;}
//    //设置怪物的名称
//    public void setMonsterName(String name){
//        this.monster_name = name;
//    }//返回怪物名称public String getMonsterName(){return this.monster_name;}//设置怪物的血量public void setMonsterHp(int hp){this.monster_hp = hp;}
//返回怪物血量public int getMonsterHp(){return this.monster_hp;}
}package com.homework.game;import javax.sound.midi.SoundbankResource;
import java.util.Random;public class Player {//创建玩家名称变量public String player_name;//创建玩家武器变量public String player_weapon;//设置玩家名称方法public void setPlayerName(String name){this.player_name = name;}//获取玩家名称方法public String getPlayerName(){return this.player_name;}//设置玩家武器public void setPlayWeapon(String weapon){this.player_weapon = weapon;}//获取玩家武器public String getPlayerWeapon(){return this.player_weapon;}//玩家攻击方法public void attackMethod(Monster monster){
//        System.out.println(monster.getMonsterHp());
//        System.out.println(this.player_weapon);if (monster.getMonsterHp() > 0){if("木剑".equals(this.player_weapon)){int hp = monster.getMonsterHp();hp = hp - 20;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了20HP,"+monster.getMonsterName()+"还剩余"+monster.getMonsterHp()+"血量,可继续攻击");}else {System.out.println(monster.getMonsterName()+"被击杀!!!");return;}}else if("铁剑".equals(this.player_weapon)){if (monster.getMonsterHp() > 0){int hp = monster.getMonsterHp();hp = hp - 50;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了50HP,"+monster.getMonsterName()+"还剩余"+monster.getMonsterHp()+"血量,可继续攻击");}else {System.out.println(monster.getMonsterName()+"被击杀!!!");return;}}else {System.out.println(monster.getMonsterName()+"死了,不需要攻击了!!!");return;}}else if("魔剑".equals(this.player_weapon)){if (monster.getMonsterHp() > 0){int random = ((int)(Math.random()*10))+1;int less_hp = (random > 5)?200:100;if (less_hp == 200){System.out.println("暴击了!!!!");}int hp = monster.getMonsterHp();hp = hp - less_hp;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了"+less_hp+"HP"+monster.getMonsterName()+"还剩余"+monster.getMonsterHp()+"血量,可继续攻击");}else {System.out.println(monster.getMonsterName()+"被击杀!!!");return;}}}else {System.out.println("没有武器,无法攻击");}}else {System.out.println(monster.getMonsterName()+"死了,无需攻击!!!");}}
}package com.homework.game;import java.util.Scanner;public class TestMain {public static void main(String[] args) {System.out.println("------------------游戏开始------------------");//创建怪物对象Monster monster = new Monster("魔王",500);//创建玩家对象Player player = new Player();//创建两个录入对象Scanner player_name_scanner = new Scanner(System.in);Scanner player_weapon_scanner = new Scanner(System.in);//定义玩家名称变量System.out.println("请输入玩家名称:");String player_name = player_name_scanner.next();while(true){if(monster.getMonsterHp() > 0){System.out.println("请输入武器准备(木剑、铁剑、魔剑):");String player_weapon = player_weapon_scanner.next();player.setPlayerName(player_name);player.setPlayWeapon(player_weapon);player.attackMethod(monster);}else {System.out.println("--------------------You Win----------------------");break;}}}
}

 小结:

计的角色类的攻击方法很长,并且方法中有一个冗长的if…else结构,且每个分支的代码的业务逻辑很相似,只是很少的地方不同。

再者,上述设计思路,违反了O【Open】C【Close】P原则。在这个设计中,如果以后我们增加一个新的武器,如倚天剑,每次攻击损失500HP,那么,我们就要打开角色类,修改攻击方法。而我们的代码应该是对修改关闭的,当有新武器加入的时候,应该使用扩展完成,避免修改已有代码。

一般来说,当一个方法里面出现冗长的if…else或switch…case结构,且每个分支代码业务相似时,往往预示这里应该引入多态性来解决问题。而这里,如果把不同武器攻击看成一个策略,那么引入策略模式(Strategy Pattern)是明智的选择

Tip:OCP原则,即开放关闭原则,指设计应该对扩展开放,对修改关闭。

Tip:策略模式,英文名Strategy Pattern,指定义算法族,分别封装起来,让他们之间可以相互替换,此模式使得算法的变化独立于客户。

三、思路二

        因上述原因,我们重新设计,得到以下思路

 

package com.homework.game2;
//定义一个攻击接口,以怪物作为参数,各类武器实现这个攻击接口
public interface Attack {public void attcak(Monsters monsters);
}package com.homework.game2;
//武器----木剑
public class WoodenSword implements Attack {@Overridepublic void attcak(Monsters monsters) {//通知怪物失去对应血量monsters.bloodLoss(20,"木剑");}
}package com.homework.game2;
//武器----铁剑类
public class IronSword implements Attack{@Overridepublic void attcak(Monsters monsters) {//通知怪物掉血50monsters.bloodLoss(50,"铁剑");}}package com.homework.game2;import javax.sound.midi.SoundbankResource;//武器-----魔剑类
public class MagicSword implements Attack{@Overridepublic void attcak(Monsters monsters) {int random = ((int)(Math.random()*10))+1;if(random > 5){System.out.println("魔剑暴击了,击杀200Hp!!!");monsters.bloodLoss(200,"魔剑");}else {monsters.bloodLoss(100,"魔剑");}}
}package com.homework.game2;
//怪物类
public class Monsters {//定义怪物的名称public String monsters_name;//定义怪物的血量public int monsters_hp;
//    //构造方法,用来创建对象
//    public Monsters(){}
//    //定义怪物的构造方法,在主方法中传入参数,初始化怪物属性public Monsters(String name,int hp){this.monsters_name = name;this.monsters_hp = hp;}
//    //获取怪物名称方法
//    public String getMonstersName(){
//        return this.monsters_name;
//    }
//    //设置怪物血量
//    public void setMonstersHp(int hp){
//        this.monsters_hp = hp;
//    }
//    //获取怪物血量
//    public int getMonsterHp(){
//        return this.monsters_hp;
//    }//怪物掉血的方法,参数  1.掉血量;2.使用的武器Players players =new Players("王也");public void bloodLoss(int hp,String weapon_name){if(this.monsters_hp > 0){this.monsters_hp = this.monsters_hp - hp;if(this.monsters_hp > 0){System.out.println(players.getPlayersName()+"用"+weapon_name+"攻击了"+this.monsters_name+hp+"Hp,剩余"+this.monsters_hp+"Hp,可以继续攻击");}else {System.out.println(this.monsters_name+"死了,无需攻击");}}else {System.out.println(this.monsters_name+"死了,无需攻击");return;}}
}package com.homework.game2;
//玩家类
public class Players {//定义玩家名称public String players_name;//定义玩家武器public Attack players_weapon;//设置玩家构造方法,初始化玩家名称public Players(String name){this.players_name = name;}
//    //设置玩家名称方法
//    public void setPlayersName(String name){
//        this.players_name = name;
//    }//获取玩家名称方法public String getPlayersName(){return this.players_name;}//接口回调 Attack weapon 接口回调变量//设置玩家武器方法,传入接口参数,将变量赋值给this.players_weaponpublic void setPlayersWeapon(Attack weapon){this.players_weapon = weapon;}
//    //获取玩家武器方法
//    public Attack getPlayersWeapon(){
//        return this.players_weapon;
//    }//玩家攻击方法public void player_AttcakMethod(Monsters monsters){this.players_weapon.attcak(monsters);}}package com.homework.game2;public class TestMain {public static void main(String[] args) {//创建怪物对象Monsters monsters = new Monsters("大魔王",200);//创建玩家对象Players players = new Players("王也");players.setPlayersWeapon(new WoodenSword());players.player_AttcakMethod(monsters);players.setPlayersWeapon(new IronSword());players.player_AttcakMethod(monsters);players.setPlayersWeapon(new MagicSword());players.player_AttcakMethod(monsters);}
}

改进后的代码有如下优点:

第一,虽然类的数量增加了,但是每个类中方法的代码都非常短,没有了以前攻击方法那种很长的方法,也没有了冗长的if…else,代码结构变得很清晰。

第二,类的职责更明确了。在第一个设计中,角色不但负责攻击,还负责给怪物减少HP和判断怪物是否已死。这明显不应该是角色的职责,改进后的代码将这两个职责移入怪物内,使得职责明确,提高了类的内聚性。

第三,引入Strategy[策略]模式后,不但消除了重复性代码,更重要的是,使得设计符合了OCP。如果以后要加一个新武器,只要新建一个类,实现武器接口,当角色需要装备这个新武器时,客户代码只要实例化一个新武器类,并赋给角色的武器成员就可以了,已有的角色和怪物代码都不用改动。这样就实现了对扩展开发,对修改关闭

相关文章:

Java小游戏

一、需求 二、思路一 HP当然是怪物的一个属性成员,而武器是角色的一个属性成员,类型可以使字符串,用于描述目前角色所装备的武器。角色类有一个攻击方法,以被攻击怪物为参数,当实施一次攻击时,攻击方法被调…...

服务器Linux系统配置mysql数据库主从自动备份

服务器Linux系统配置mysql数据库主从自动备份 当数据内容越来越多的时候,数据库也变得越来越大了。如果不小心误删了,或者被黑主机了,那就什么都没有了。所以数据库的数据怎么能让它不丢失做到万无一失变得尤为重要! 我是艾西&a…...

Java通过PowerMockito和Mokito进行单元测试

PowerMockito和Mokito的概念 PowerMockito和Mockito都是Java语言中的测试框架,用于进行单元测试和集成测试。它们中的每一个都有不同的功能和应用。 Mockito是一个基于模拟的测试框架。它允许你模拟对象,在测试中隔离被测代码的依赖项。使用Mockito&am…...

数字化技术无限延伸,VR全景点亮智慧生活

随着互联网的发展,我们无时无刻不再享受着互联网给我们带来的便利,数字化生活正在无限延伸,各行各业也开始积极布局智能生活。要说智慧生活哪个方面应用的比较多,那应该就是VR全景了,目前VR全景已经被各个行业广泛应用…...

抖音艺术签名小程序源码/艺术签名设计小程序源码/字节跳动小程序开发

最近很火的抖音艺术签名小程序源码,这是一款艺术签名设计小程序源码,字节跳动小程序开发,之适用于字节系小程序。介意请绕过! 下载地址:https://bbs.csdn.net/topics/616145725...

养号自动化,指纹浏览器和RPA机器人解除烦恼

在这个充满科技魔力的时代,社交媒体已经成为人们生活的一部分,而Facebook更是我们分享欢乐、联络亲友的重要平台。然而,随之而来的是一个棘手的问题:如何保持账号的活跃度,而又不被沉重的养号工作压垮?别担…...

ES6中promise的使用

ES6中promise的使用 本文目录 ES6中promise的使用基础介绍箭头函数function函数状态 原型方法Promise.prototype.then()Promise.prototype.catch() 静态方法Promise.all()Promise.race()Promise.any() 链式回调 基础介绍 官网:https://promisesaplus.com/ window.…...

前端如何走通后端接口

0 写在前面 现在基本都是前后端分离的项目了,那么前端小伙伴如何获取后端小伙伴接口呢? 1 条件 同一WiFi下,让后端小伙伴分享出自己的ip地址: 步骤1:winr调出运行界面 步骤2:cmd调出命令行窗口 步骤3:…...

iOS swift5 扫描二维码

文章目录 1.生成二维码图片2.扫描二维码(含上下扫描动画)2.1 记得在info.plist中添加相机权限描述 1.生成二维码图片 import UIKit import CoreImagefunc generateQRCode(from string: String) -> UIImage? {let data string.data(using: String.En…...

【马拉车算法/动态规划】最长回文字串

最长回文字串 1.问题描述2.中心扩展法(O(N^2))3.动态规划4.Manacher(马拉车算法) 1.问题描述 常用有3种算法:中心扩展法、动态规划和Manacher算法 2.中心扩展法(O(N^2)) 解释: 从中心向外扩展。 分为两种…...

什么是 fail-fast? 什么是fail-safe?

面试回答 在系统设计中,快速失效(fail-fast)系统一种可以立即报告任何可能表明故障的情况的系统。快速失效系统通常设计用于停止正常操作,而不是试图继续可能存在缺陷的过程。 其实,这是一种理念,说白了就是…...

第三届计算机、物联网与控制工程国际学术会议(CITCE 2023)

第三届计算机、物联网与控制工程国际学术会议(CITCE 2023) The 3rd International Conference on Computer, Internet of Things and Control Engineering(CITCE 2023) 第三届计算机、物联网与控制工程国际学术会议(CITCE 2023)…...

react antd 日期选择 WeekPicker MonthPicker 取值转为起止日期

默认WeekPicker 取值,返回的是2023年34周,这样后台用起来不方便。可以转化成指定周的起止日期 const startDate moment(weekData).day(1).format(YYYY-MM-DD); // 周一日期 const endDate moment(weekData).day(7).format(YYYY-MM-DD); // 周日日期同…...

table,设置 数据相同时, 合并列

<el-table :data"tableData" :span-method"objectSpanMethod" border style"width: 100%" show-summary><el-table-column type"index" label"序号" width"100" /><el-table-column prop"dat…...

kotlin如何接收前端传递过来的数据

Kotlin 可以使用 Spring Boot 等框架来接收前端传递过来的数据。 在 Spring Boot 中&#xff0c;你可以使用 RequestBody 注解来将前端传递的 JSON 格式数据转换为相应的 Kotlin 对象。 示例代码&#xff1a; RestController RequestMapping("/api") class UserCo…...

《中国区块链发展报告(2023)》发布 和数集团推动区块链发展

北京区块链技术应用协会与社会科学文献出版社日前在京共同发布《区块链蓝皮书&#xff1a;中国区块链发展报告&#xff08;2023&#xff09;》。蓝皮书归纳梳理了2022年区块链产业发展现状及趋势&#xff0c;并结合行业热点Web3.0、AIGC&#xff0c;探讨我国区块链发展的热点话…...

FreeSWITCH 1.10.10 简单图形化界面3 - 阿里云NAT设置

FreeSWITCH 1.10.10 简单图形化界面3 - 阿里云NAT设置 0、 界面预览1、 查看IP地址2、 修改协议配置3、 开放阿里云安全组4、 设置ACL5、 设置协议中ACL&#xff0c;让PBX匹配内外网6、 重新加载SIP模块7、 查看状态8、 测试一下 0、 界面预览 http://myfs.f3322.net:8020/ 用…...

Android SDK 上手指南||第五章 用户界面设计

第五章 用户界面设计 在本篇教程中我们将为应用程序项目添加布局方案&#xff0c;在这方面XML与Eclipse ADT接口将成为工作中的得力助手——不过在后面两节中还会用到一部分Java开发知识。XML与Java在Android平台的开发工作当中可谓无处不在&#xff0c;如果大家对二者还缺乏基…...

std::list和std::vector删除指定下标的元素

list和vector都可以使用erase函数移除指定下标的元素&#xff0c;注意输入的是迭代器&#xff0c;返回值为指向下一个元素的位置。: iterator erase(iterator position); iterator erase(iterator first,iterator last); 如果下标是index&#xff0c;直接调用即可&#xff1a…...

Apache POI 以及 导出Excel表

一、Apache POI 1、介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 Excel 文件。 2、Apache POI 怎么…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...