当前位置: 首页 > 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 怎么…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

「Java基本语法」变量的使用

变量定义 变量是程序中存储数据的容器&#xff0c;用于保存可变的数据值。在Java中&#xff0c;变量必须先声明后使用&#xff0c;声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例&#xff1a;声明与初始化 public class VariableDemo {publi…...