当前位置: 首页 > 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+PyTorch搭建你的第一个遥感变化检测模型(附实战代码)

用PythonPyTorch实现遥感变化检测&#xff1a;从数据预处理到模型部署全流程指南 遥感影像的变化检测技术正在城市规划、环境监测、灾害评估等领域发挥越来越重要的作用。传统人工比对方法效率低下&#xff0c;而基于深度学习的自动化解决方案正在重塑这个领域的技术格局。本文…...

BepInEx:Unity游戏插件框架的模块化解决方案

BepInEx&#xff1a;Unity游戏插件框架的模块化解决方案 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是一款针对Unity游戏的插件框架&#xff0c;提供模块化的插件管理与…...

深入排查k8s集群6443端口连接拒绝:从kubectl故障到系统级修复

1. 当kubectl突然罢工&#xff1a;6443端口连接拒绝的紧急处理 那天早上我像往常一样打开终端&#xff0c;准备用kubectl get pods查看集群状态&#xff0c;结果终端冷冰冰地抛出一行错误&#xff1a;"Unable to connect to the server: dial tcp 192.168.1.1:6443: conne…...

老设备重生:老旧MacBook Pro系统升级完全指南

老设备重生&#xff1a;老旧MacBook Pro系统升级完全指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 老旧硬件适配是延长设备生命周期的关键挑战&#xff0c;而开源解…...

不用npm!3分钟搞定微信小程序引入Animate.css的另类方法

微信小程序免npm引入Animate.css的极简方案 最近在开发微信小程序时&#xff0c;发现很多开发者都在寻找一种更简单的方法来引入Animate.css动画库&#xff0c;而不必依赖npm。对于不熟悉node环境的开发者来说&#xff0c;npm安装过程可能会遇到各种问题。今天我就分享一个完全…...

蓝芯算力:RISC-V 芯片破局之路

字节跳动前高管卢山创办的蓝芯算力完成数亿元融资&#xff0c;专注 RISC-V AI 算力芯片研发。目前已获超 20 万片订单&#xff0c;在 x86 和 ARM 主导的市场中开辟差异化道路。创始人背景与创业初衷蓝芯算力创始人卢山毕业于清华&#xff0c;有超 20 年芯片设计经验。他曾就职英…...

Jaspersoft Studio 动态字体颜色设置实战指南

1. 为什么需要动态字体颜色&#xff1f; 在报表开发中&#xff0c;数据可视化是提升信息传达效率的关键手段。想象一下&#xff0c;当你的老板查看月度销售报表时&#xff0c;如果所有数字都是千篇一律的黑色&#xff0c;他需要花费多少时间才能找到异常数据&#xff1f;而如果…...

ANIMATEDIFF PRO效果展示:森林晨雾中飘落树叶+光线穿透动态GIF集

ANIMATEDIFF PRO效果展示&#xff1a;森林晨雾中飘落树叶光线穿透动态GIF集 1. 引言&#xff1a;当AI遇见电影级动态美学 想象一下&#xff0c;你脑海中有一个绝美的画面&#xff1a;清晨的森林&#xff0c;薄雾缭绕&#xff0c;阳光透过层层叠叠的树叶&#xff0c;形成一道道…...

计算机毕设 java 基于 HTML5 的酒店预订管理系统 java 基于 HTML5 的智能酒店预订系统 java 基于 HTML5 的酒店在线预订管理平台

计算机毕设 java 基于 HTML5 的酒店预订管理系统 4u2r79&#xff08;配套有源码 程序 mysql 数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联 xi 可分享在互联网和移动互联网飞速发展的当下&#xff0c;线上预订已成为酒店行业的主流消费模式…...

3步搞定黑苹果:OpCore-Simplify自动化配置工具深度体验

3步搞定黑苹果&#xff1a;OpCore-Simplify自动化配置工具深度体验 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的黑苹果配置而头痛不已…...