【Java實體】-王者榮耀RPG-從設計思路到代碼實作
- 前言
- 一、案例分析
- 1. 設計理念
- 2. 功能設計
- (1)登錄與注冊
- (2)游戲時間記錄
- (3)選擇游戲模式
- (4)游戲地圖
- (5)生物屬性
- 二、程式實作
- 1.生物屬性模塊
- 2.屬性面板模塊
- 3.時間記錄模塊
- 4.登錄與注冊模塊
- 5.地圖通道模塊
- 6.初始界面UI模塊
- 三、運行結果
- 總結
前言
嗨!這位看官,歡迎你的到來!本作是一個有關Java知識的小游戲案例,一起來看看吧 ^ _ ^
以下是本篇文章正文內容,下面案例可供參考
一、案例分析
1. 設計理念
學習的目的是為了掌握知識并最終運用到實踐中,因此在學習一段時間后便需要對所學知識進行整合,
而對于Java知識來說,最好的整合方式便是用所學知識進行自由設計,
某在平時十分喜歡王者榮耀這款手游,于是便有了這個RPG版本的王者小游戲,
2. 功能設計
(1)登錄與注冊
某希望在這個程式中實作對進入王者榮耀時登錄界面的簡單模擬,這里對登錄的原理進行簡要分析:
首先,因為這只是一個小游戲,不使用申請代理等高級操作,所以要有對應的檔案來存盤賬號資訊,
在進入游戲時會彈出輸入賬號密碼的提示操作,在執行完相關操作后,程式根據輸入的資料與檔案中的資料進行比對,預計出現以下情況:
- 賬號密碼無誤–>登陸成功,進入游戲界面
- 賬號錯誤–>輸入賬號與檔案中資料比對不同,說明該用戶未注冊,回傳“賬號有誤,請先注冊”提示
- 密碼錯誤–>輸入賬號正確,通過第一次比對,而在比對密碼時出現不同,這時回傳“密碼錯誤”提示
其次,在登錄失敗后用戶有兩個選擇,一是退出游戲,二是進行賬號注冊,
賬號注冊便是將用戶輸入的賬號與密碼以鍵值對的形式存盤進創建的檔案中,用以登錄時程式執行比對操作,

(2)游戲時間記錄
王者榮耀這款手游被玩家廣為吐槽的一點便是它的健康時間限制,其功能是在后臺記錄自玩家登陸賬號之后的時間,在其到達限制時間后對該賬號進行強制下線的操作,
某在設計這款小游戲時,也對該功能進行了模擬,
實作該功能的方法非常簡單:
- 在完成登錄操作之后,獲取當前的時間,將其轉化為毫秒值存盤入檔案中
- 新建一個方法,用來讀取實時時間,轉化為毫秒值之后與初始毫秒值作差,最后轉換格式將時間輸出

(3)選擇游戲模式
原版手游有著豐富的游戲模式,而在此練習之作中只需要模擬訓練營模式作單機游戲即可,
在此模塊之后,本作將會頻繁用到switch-case的多分支選擇結構,在某看來,該結構簡直是RPG類游戲制作必備程式運行的不二之選,

在這里的“實戰對抗”只是一個空殼,連同在下面的英雄技能攻擊,傷害計算模塊,裝備商店模塊都將留作以后進行續作,
而關于“實戰對抗”的構想如下:
- 在下面會設有專門的英雄模塊,而每個英雄會有其技能,實戰對抗便是隨機一名英雄做對手,其技能也是隨機釋放,這里預計會使用到Random類,
- 初始金錢固定,必須經過刷野或者擊敗小兵獲得金錢收益,用來在裝備商店購買裝備,
- 裝備為技能提供屬性加成,英雄技能可升級,升級需要獲得經驗值,經驗值由擊敗野怪或者小兵產出,
本作的主要模式便是“訓練營模式”,有關設計如下:
- 攻擊物件僅有小兵和野怪,
- 初始金錢隨機,
(4)游戲地圖
在此某模擬三類場景,并分別設定場景通道和觸發物件
- 泉水–>通向野區
- 野區–>通向泉水和交戰區,場景特有物件為野怪
- 交戰區–>交戰或回傳泉水,場景特有物件為小兵

(5)生物屬性
為了使小游戲更加還原手游,生物的屬性面板的展示是必不可少的,
在此只需要為每個生物定義屬性專案,并將其封裝成標準類即可,
- 小兵(攻擊,防御,血量,敏捷)
- 野怪(攻擊,防御,血量,敏捷)
還有必不可少的英雄類,在這里某選擇了“魯班七號”和“呂布”兩個英雄,你也可以根據你的喜好修改其他英雄,
- 魯班七號(攻擊,防御,血量,敏捷)
- 呂布(攻擊,防御,血量,敏捷)

當然,這里的資料數值是可以根據個人喜好自行修改的,
二、程式實作
這是某的程式串列,這里用的環境是IDEA

1.生物屬性模塊
首先來構造最簡單的生物屬性模塊,這里用到了封裝的相關知識,
- 小兵的標準描述類
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;
}
}
2.屬性面板模塊
- 定義好人物屬性后,創建人物類,類中創建人物選擇方法,并在其中設計英雄屬性面板
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包中,接下來是健康時間模塊的代碼實作,
3.時間記錄模塊
- 這段代碼實作了對于時間的記錄和查詢功能,其中的檔案保存地址可自定義修改,
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();
}
}
}
4.登錄與注冊模塊
- 登錄與注冊模塊某參考了一些網上前輩的文章進行了實作,在此是適用于本作版本的代碼,參考原版鏈接
- 首先定義一個用戶類的標準描述類
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;
}
}
5.地圖通道模塊
- 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;
}
}
}
}
6.初始界面UI模塊
在完成諸多附屬功能模塊后便可以進行初始界面的設計了,
- 首先是進入游戲的登錄與注冊引導,
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共有,歡迎轉載,且在文章頁面明顯位置給出原文鏈接,未經作者同意必須保留此段宣告,否則保留追究法律責任的權利,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/265496.html
標籤:其他
上一篇:Unity 簡單的傷害數字顯示
