嗨!这位看官,欢迎你的到来!本作是一个有关Java知识的小游戏案例,一起来看看吧 ^ _ ^
以下是本篇文章正文内容,下面案例可供参考
学习的目的是为了掌握知识并最终运用到实践中,因此在学习一段时间后便需要对所学知识进行整合。
而对于Java知识来说,最好的整合方式便是用所学知识进行自由设计。
某在平时十分喜欢王者荣耀这款手游,于是便有了这个RPG版本的王者小游戏。
某希望在这个程序中实现对进入王者荣耀时登录界面的简单模拟,这里对登录的原理进行简要分析:
首先,因为这只是一个小游戏,不使用申请代理等高级操作,所以要有对应的文档来存储账号信息。
在进入游戏时会弹出输入账号密码的提示操作,在执行完相关操作后,程序根据输入的数据与文档中的数据进行比对,预计出现以下情况:
- 账号密码无误–>登陆成功,进入游戏界面
- 账号错误–>输入账号与文档中数据比对不同,说明该用户未注册,返回“账号有误,请先注册”提示
- 密码错误–>输入账号正确,通过第一次比对,而在比对密码时出现不同,这时返回“密码错误”提示
其次,在登录失败后用户有两个选择,一是退出游戏,二是进行账号注册。
账号注册便是将用户输入的账号与密码以键值对的形式存储进创建的文档中,用以登录时程序执行比对操作。
王者荣耀这款手游被玩家广为吐槽的一点便是它的健康时间限制,其功能是在后台记录自玩家登陆账号之后的时间,在其到达限制时间后对该账号进行强制下线的操作。
某在设计这款小游戏时,也对该功能进行了模拟。
实现该功能的方法非常简单:
- 在完成登录操作之后,获取当前的时间,将其转化为毫秒值存储入文档中
- 新建一个方法,用来读取实时时间,转化为毫秒值之后与初始毫秒值作差,最后转换格式将时间输出
原版手游有着丰富的游戏模式,而在此练习之作中只需要模拟训练营模式作单机游戏即可。
在此模块之后,本作将会频繁用到switch-case的多分支选择结构,在某看来,该结构简直是RPG类游戏制作必备程序运行的不二之选。
在这里的“实战对抗”只是一个空壳,连同在下面的英雄技能攻击,伤害计算模块,装备商店模块都将留作以后进行续作。
而关于“实战对抗”的构想如下:
- 在下面会设有专门的英雄模块,而每个英雄会有其技能,实战对抗便是随机一名英雄做对手,其技能也是随机释放,这里预计会使用到Random类。
- 初始金钱固定,必须经过刷野或者击败小兵获得金钱收益,用来在装备商店购买装备。
- 装备为技能提供属性加成,英雄技能可升级,升级需要获得经验值,经验值由击败野怪或者小兵产出。
本作的主要模式便是“训练营模式”,有关设计如下:
- 攻击对象仅有小兵和野怪。
- 初始金钱随机。
在此某模拟三类场景,并分别设置场景通道和触发对象
- 泉水–>通向野区
- 野区–>通向泉水和交战区,场景特有对象为野怪
- 交战区–>交战或返回泉水,场景特有对象为小兵
为了使小游戏更加还原手游,生物的属性面板的展示是必不可少的。
在此只需要为每个生物定义属性项目,并将其封装成标准类即可。
- 小兵(攻击,防御,血量,敏捷)
- 野怪(攻击,防御,血量,敏捷)
还有必不可少的英雄类,在这里某选择了“鲁班七号”和“吕布”两个英雄,你也可以根据你的喜好修改其他英雄。
- 鲁班七号(攻击,防御,血量,敏捷)
- 吕布(攻击,防御,血量,敏捷)
当然,这里的数据数值是可以根据个人喜好自行修改的。
首先来构造最简单的生物属性模块。这里用到了封装的相关知识。
- 小兵的标准描述类
package Role;
public class littleSoldier {
private int attack;//攻击
private int defense;//防御
private int HP;//血量
private int agile;//敏捷
public littleSoldier(int attack, int defense, int HP, int agile) {
this.attack = attack;
this.defense = defense;
this.HP = HP;
this.agile = agile;
}
public littleSoldier() {
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getAgile() {
return agile;
}
public void setAgile(int agile) {
this.agile = agile;
}
}
- 野怪的标准描述类
package Role;
public class wildMonster {
private int attack;//攻击
private int defense;//防御
private int HP;//血量
private int agile;//敏捷
public wildMonster(int attack, int defense, int HP, int agile) {
this.attack = attack;
this.defense = defense;
this.HP = HP;
this.agile = agile;
}
public wildMonster() {
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getAgile() {
return agile;
}
public void setAgile(int agile) {
this.agile = agile;
}
}
- 鲁班七号的标准描述类
package Role;
public class LuBanQiHao {
private int attack;//攻击
private int defense;//防御
private int HP;//血量
private int agile;//敏捷
public LuBanQiHao() {
}
public LuBanQiHao(int attack, int defense, int HP, int agile) {
this.attack = attack;
this.defense = defense;
this.HP = HP;
this.agile = agile;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getAgile() {
return agile;
}
public void setAgile(int agile) {
this.agile = agile;
}
}
- 吕布的标准描述类
package Role;
public class LvBu {
private int attack;//攻击
private int defense;//防御
private int HP;//血量
private int agile;//敏捷
private int LEVEL;//等级
public LvBu() {
}
public LvBu(int attack, int defense, int HP, int agile) {
this.attack = attack;
this.defense = defense;
this.HP = HP;
this.agile = agile;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getAgile() {
return agile;
}
public void setAgile(int agile) {
this.agile = agile;
}
}
- 定义好人物属性后,创建人物类,类中创建人物选择方法,并在其中设计英雄属性面板
package Role;
import GameMain.GameModule;
import java.util.Scanner;
public class RenWu {
public static void chooseRole() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("=================");
System.out.println("--请挑选你的英雄!--");
System.out.println("----1.鲁班七号----");
System.out.println("------2.吕布------");
System.out.println("=================");
String choice = sc.nextLine();
switch (choice) {
case "1":
System.out.println("召唤师,你选择了英雄-鲁班七号!");
LuBanQiHao LuBan = new LuBanQiHao(200, 100, 500, 50);
System.out.println("以下是该英雄的数据面板");
System.out.println("==================");
System.out.println("姓名:鲁班七号");
System.out.println("攻击:" + LuBan.getAttack());
System.out.println("防御:" + LuBan.getDefense());
System.out.println("生命:" + LuBan.getHP());
System.out.println("敏捷:" + LuBan.getAgile());
System.out.println("一技能:河豚手雷");
System.out.println("------450/500/550/600/650/700");
System.out.println("二技能:无敌鲨嘴炮");
System.out.println("------400/450/500/550/600/650");
System.out.println("大招:空中支援");
System.out.println("------500/650/750");
System.out.println("==================");
System.out.println("你已接入峡谷,开始战斗吧召唤师!");
GameModule.gameModule();
break;
case "2":
System.out.println("召唤师,你选择了英雄-吕布!");
LvBu LB = new LvBu(100, 150, 800, 50);
System.out.println("以下是该英雄的数据面板");
System.out.println("==================");
System.out.println("姓名:吕布");
System.out.println("攻击:" + LB.getAttack());
System.out.println("防御:" + LB.getDefense());
System.out.println("生命:" + LB.getHP());
System.out.println("敏捷:" + LB.getAgile());
System.out.println("一技能:方天画斩");
System.out.println("------650/780/910/1040/1170/1300");
System.out.println("二技能:贪狼之握");
System.out.println("------1050/1470/1890/2310/2730/3150");
System.out.println("大招:魔神降世");
System.out.println("------400/650/900");
System.out.println("==================");
System.out.println("你已接入峡谷,开始战斗吧召唤师!");
GameModule.gameModule();
break;
case "3":
default:
System.out.println("输入有误!");
break;
}
}
}
}
- 同时新建生物类,设计小兵和野怪的数据面板,方便调用
package Role;
public class ShengWu {
public static void littleSoldierPanel() {
littleSoldier ls = new littleSoldier(50, 50, 500, 30);
System.out.println("小兵数据面板");
System.out.println("=============");
System.out.println("攻击:"+ls.getAttack());
System.out.println("防御:"+ ls.getDefense());
System.out.println("生命:"+ls.getHP());
System.out.println("敏捷:"+ls.getAgile());
System.out.println("=============");
}
public static void wildMonsterPanel() {
wildMonster wm = new wildMonster(100, 100, 1000, 30);
System.out.println("野怪数据面板");
System.out.println("=============");
System.out.println("攻击:"+wm.getAttack());
System.out.println("防御:"+ wm.getDefense());
System.out.println("生命:"+wm.getHP());
System.out.println("敏捷:"+wm.getAgile());
System.out.println("=============");
}
}
到此为止所有的角色的有关设计便结束了,以上代码统一归类至Role包中。接下来是健康时间模块的代码实现。
- 这段代码实现了对于时间的记录和查询功能,其中的文件保存地址可自定义修改。
package JianKangSysTem;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class FangChenMiSystem {
/*
* -首先获取当前时间
* -将其加三个小时存储进文档中
* */
public static void StartTime() {
//获取当前时间
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String todaytime = simpleDateFormat.format(date);
System.out.println(todaytime);
//将时间转换为毫秒值存入文档
long todayTime = System.currentTimeMillis();
// System.out.println(todayTime);
try (FileWriter Timess = new FileWriter("Peosing_JavaWork\\src\\JianKangSysTem\\Timess.txt");
) {
long ShiXian = 3 * 60 * 60 * 1000 + todayTime;
Timess.write(String.valueOf(ShiXian));
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* -可以查询剩余游戏时间
* */
public static void EndTime() {
//查询剩余可游戏时间
try (FileReader Timess = new FileReader("Peosing_JavaWork\\src\\JianKangSysTem\\Timess.txt")) {
//获取实时时间
long nowTime = System.currentTimeMillis();
//将限定终止时间读取出来
char[] a = new char[1024];
int len = 0;
String Time_ss = null;
while ((len = Timess.read(a)) != -1) {
// System.out.println(new String(a));
Time_ss = new String(a, 0, len);
}
Long lo = (Long.parseLong(Time_ss)-nowTime) ;
//将毫秒值转换为规定格式的日期时间
SimpleDateFormat ZhuanHuanZhi = new SimpleDateFormat("HH:mm:ss");
ZhuanHuanZhi.setTimeZone(TimeZone.getTimeZone("GMT+00:00:00"));
String SYSJ = ZhuanHuanZhi.format(lo);
System.out.println("您的剩余可游戏时间为"+SYSJ);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 登录与注册模块某参考了一些网上前辈的文章进行了实现,在此是适用于本作版本的代码。参考原版链接
- 首先定义一个用户类的标准描述类
package DengLu;
public class User {
private String userID;
private String passWord;
public User() {
}
public User(String userID, String passWord) {
this.userID = userID;
this.passWord = passWord;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
}
- 接下来定义一个接口来定义注册和登录功能。接口就是对类的功能的一种扩展,它的本质是用来定义规则的。
package DengLu;
import java.io.IOException;
public interface DengLuZhuCe {
public abstract void ZhuCe(User user) throws IOException;
public abstract boolean DengLu(String userID, String passWord);
}
- 接下来定义用户实现类,也就是上面定义的接口的实现类。
package DengLu;
import java.io.*;
import java.util.Properties;
public class DLZCImpl implements DengLuZhuCe {
public static File file = new File("Peosing_JavaWork\\src\\DengLu\\user.txt");
/*静态代码块,随着类的加载而加载
* creatNewFile():当且仅当具有该抽象路径名的文件尚不存在时,以原子方式创建一个由该抽象路径名命名的新的空文件。
* */
static{
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void ZhuCe(User user){
try {
//将用户信息存入文件
String info = user.getUserID() + "=" + user.getPassWord();
//创建可追加写入的FileWriter,避免过往用户数据被覆盖
BufferedWriter bw = new BufferedWriter(new FileWriter("Peosing_JavaWork\\src\\DengLu\\user.txt", true));
bw.write(info);
bw.newLine();
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean DengLu(String userID, String passWord) {
boolean flag = false;
try {
Properties pr = new Properties();
//load()方法:以简单的面向行格式从输入字符流中读取属性列表(键和元素对)。
pr.load(new FileReader("Peosing_JavaWork\\src\\DengLu\\user.txt"));
/*比对数据并返回结果
* getProperty()方法:
* 在此属性列表中使用指定的关键字搜索属性。
* 如果在此属性列表中找不到该键,则将递归检查默认属性列表及其默认值。
* 如果找不到该属性,则该方法返回null。
**/
if (pr.getProperty(userID) != null) {
String p_word = pr.getProperty(userID);
if (p_word.equals(passWord)) {
flag = true;
return flag;
} else {
System.out.println("密码错误!");
flag = false;
return flag;
}
} else {
System.out.println("用户名不存在,请先注册!");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}
}
- RPG地图模块的实质是不同方法的相互调用,以下是地图通道的实现代码,其中包括小兵模块、野怪模块、交战模块、简易的商店模块、泉水模块等等。
将不同功能的代码以独立的方法定义出来有助于提高编写代码的效率。
package GameMain;
import JianKangSysTem.FangChenMiSystem;
import Role.ShengWu;
import java.util.Random;
import java.util.Scanner;
public class GameModule {
public static void gameModule() {
Scanner sc = new Scanner(System.in);
System.out.println("你现在的位置是泉水");
Base();
}
public static void map() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("==========================");
System.out.println("-----选择你的下一步行动-----");
System.out.println("------1.前往野区------");
System.out.println("------2.前往交战区------");
System.out.println("------3.查看时间------");
System.out.println("------4.关闭地图------");
System.out.println("==========================");
String s = sc.nextLine();
switch (s) {
case "1":
while (true) {
System.out.println("位置:野区");
System.out.println("==========================");
System.out.println("-----选择你的下一步行动-----");
System.out.println("------1.返回泉水------");
System.out.println("------2.前往交战区------");
System.out.println("------3.击杀野怪------");
System.out.println("------4.查看时间------");
System.out.println("------5.关闭地图------");
System.out.println("==========================");
String s1 = sc.nextLine();
switch (s1) {
case "1":
System.out.println("回到泉水");
Base();
break;
case "2":
fightAI();
break;
case "3":
fightWildMonster();
break;
case "4":
FangChenMiSystem.EndTime();
break;
case "5":
default:
gameModule();
break;
}
}
case "2":
fightAI();
break;
case "3":
FangChenMiSystem.EndTime();
break;
case "4":
default:
gameModule();
break;
}
}
}
//商店模块
public static void store() {
Random r = new Random();
int gold = r.nextInt(400) + 101;
System.out.println("初始金额:"+gold);
System.out.println("货架建设中,敬请期待!");
}
//小兵模块
public static void fightAI() {
System.out.println("与小兵交战!");
ShengWu.littleSoldierPanel();
fight();
}
//野怪模块
public static void fightWildMonster() {
System.out.println("与野怪交战!");
ShengWu.wildMonsterPanel();
fight();
}
//交战模块
public static void fight() {
Scanner sc = new Scanner(System.in);
System.out.println("===============");
System.out.println("选择你的下一步行动");
System.out.println("---1.交战---");
System.out.println("---2.返回泉水---");
System.out.println("===============");
String s1 = sc.nextLine();
switch (s1) {
case "1":
System.out.println("斩杀!");
System.out.println("结算系统建设中,敬请期待!");
break;
case "2":
System.out.println("回到泉水");
Base();
break;
default:
System.out.println("输入错误!");
break;
}
}
//泉水模块
public static void Base() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("==========================");
System.out.println("-----选择你的下一步行动-----");
System.out.println("------1.打开地图------");
System.out.println("------2.打开商店------");
System.out.println("------3.查看时间------");
System.out.println("------4.离开峡谷------");
System.out.println("==========================");
String choice = sc.nextLine();
switch (choice) {
case "1":
map();
break;
case "2":
store();
break;
case "3":
FangChenMiSystem.EndTime();
break;
case "4":
GameMainMethod.mode();
break;
default:
System.out.println("输入错误!");
break;
}
}
}
}
在完成诸多附属功能模块后便可以进行初始界面的设计了。
- 首先是进入游戏的登录与注册引导。
package MainMethod;
import DengLu.DLZCImpl;
import DengLu.User;
import GameMain.GameMainMethod;
import java.util.*;
public class King_of_Glory {
public static void main(String[] args){
while (true) {
//键盘录入选项
Scanner sc = new Scanner(System.in);
System.out.println("--------欢迎!-------");
System.out.println("-------登录(1)-----");
System.out.println("-------注册(2)------");
System.out.println("-------退出(3)-----");
String choice = sc.nextLine();
//创建用户操作类
DLZCImpl dlzc = new DLZCImpl();
//switch进行选择操作
switch (choice) {
case "1":
System.out.println("欢迎来到登陆界面!");
System.out.println("请输入用户ID:");
String inputuID = sc.nextLine();
System.out.println("请输入密码:");
String inputupass = sc.nextLine();
if (dlzc.DengLu(inputuID, inputupass)) {
System.out.println("登陆成功!欢迎你,召唤师!");
GameMainMethod.playGame();
}
break;
case "2":
System.out.println("欢迎来到注册界面!");
System.out.println("请输入用户ID:");
String uID = sc.nextLine();
System.out.println("请输入密码:");
String upass = sc.nextLine();
User user = new User(uID, upass);
dlzc.ZhuCe(user);
System.out.println("注册成功!");
break;
case "3":
default:
//利用switch穿透性,3或其他数字选择都会退出系统
System.exit(0);
break;
}
}
}
}
- 其次是游戏模式选择的引导。
package GameMain;
import JianKangSysTem.FangChenMiSystem;
import Role.RenWu;
import java.util.Scanner;
public class GameMainMethod {
public static void playGame() {
System.out.println("欢迎来到王者RPG!");
System.out.println("当前时间为:");
FangChenMiSystem.StartTime();
FangChenMiSystem.EndTime();
mode();
}
public static void mode() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("==============");
System.out.println("-请选择游戏模式-");
System.out.println("--1.离线对战--");
System.out.println("--2.实战对抗--");
System.out.println("--3.退出游戏--");
System.out.println("==============");
String choice = sc.nextLine();
switch (choice) {
case "1":
System.out.println("欢迎来到离线对战!");
RenWu.chooseRole();
break;
case "2":
System.out.println("抱歉!实战对抗模式暂未开放!");
System.out.println("试试其他模式吧!");
break;
case "3":
System.exit(0);
break;
default:
System.out.println("输入错误!");
break;
}
}
}
}
至此程序的代码编写便完成了
- 登陆成功演示
- 登陆失败演示
- 注册演示
- 游戏模式选择演示
- 选择英雄演示
- 地图通道演示
- 交战演示
- 查看时间及退出演示
总体来说,本作只是进行了Java知识的简单应用,功能也相对简单,而本作也留有了相当多的拓展空间,例如未完成的实战对抗、英雄模块、装备商店、伤害计算模块,亦或是弹出式窗口设计等等,未来随着技术学习的加深,或许某会进行续作,敬请期待!
- 作者:CEMER216
- 本文版权归作者和CSDN共有,欢迎转载,且在文章页面明显位置给出原文链接,未经作者同意必须保留此段声明,否则保留追究法律责任的权利。