一個卡牌遊戲的DEMO(0)
最近有一個卡牌遊戲的創意,打算用Unity把Demo實現出來練練手。我儘量嘗試每天記錄一下開發的進度。
打算在這裡主要記錄遊戲設計和開發的過程,作為自己的一個摸索的記錄。
雖然只有一個人在做,但還是打算用git來做一下版本控制,畢竟回退之類的相當方便
https://github.com/LouisHuangGT/Yggdrasills-dream
這個遊戲類似於卡牌遊戲和類《神界:原罪》的回合制RPG結合。玩家扮演一個召喚師,可以將隨從召喚到戰場上(類似爐石和萬智牌),而在戰場上則遵循回合制戰棋遊戲的規則。玩家每個回合的資源由Action Point決定。做任何的動作:移動隨從,攻擊、打出卡牌都會消耗Action Point,因此玩家必須合理的規劃自己的Action Point來進行對戰。
此外,我們的Action Point不像爐石或萬智牌一樣每回合增長,而更像戰場女武神,每一個玩家召喚的強力角色(例如一個英雄單位)都會提高總的Action Point。為了增加趣味性,還為每個隊伍增加一個Magic Point資源,玩家作為召喚師,召喚到戰場上的隨從是靠法力進行維持的,因此在戰場上的每一個單位都會佔用一定的Magic Point,玩家需要規劃自己召喚出的隨從:例如可以召喚一個強力的隨從,但這會佔用全部的MP;也可以召喚許多脆弱的隨從。遊戲設計上大致就是這樣。一些具體的細節規則我還在進行調整。
可以看到,從實現的角度來看,我們主要要開發兩套系統:一個戰棋類回合制RPG和一個卡牌系統。兩者其實耦合程度很低,完全可以分開來進行實現。我打算先從比較核心的戰棋類回合制遊戲入手。
在寫程式碼之前我們先分析一遍戰棋類回合制RPG的戰鬥流程:
首先是回合內的流程:
之後是回合間的流程
這個流程我們把它拆成兩塊來實現。首先一個全域性的TurnManager負責管理回合的進行:例如回合的切換等,這個類也負責用滑鼠選取的方式生成一個controllingUnit,使得玩家可以對其進行操作。即第一張流程圖到選取單位這個部分的內容在TurnManager中實現。而對於單個單位的操作可以抽象出來,由一個controller來進行。controller負責接收按鈕的回撥,確定玩家下的指令,並分配當前這個controller正在操作的unit來執行這個指令。Controller主要通過一個Run函式進行實現,這個函式輸入一個選中的單位,然後對這個單位進行一系列的玩家操作。返回操作是否成功/完成。如果操作成功則進入下一個選單位流程,否則不做任何操作,繼續這個操作(如流程圖1所示)。
玩家的單位目前用一個基類Unit來處理,玩家的具體操作以及一系列的判定就在unit中進行實現。
首先是TurnManager的update()實現:
整個遊戲程序的執行相當於全部在這個update中實現。這個update的作用相當於選中單位和對應的操作後等待操作完成,操作完成後選下一個單位,如果沒有完成則阻塞等待操作完成(這裡的阻塞利用了update每幀迴圈呼叫的特性來實現,不需要自己寫一個死迴圈來阻塞)
void Update () {
if (selectedUnit != null)
{
if (controller.run(selectedUnit))
{
team[currenTeamIndex].ActionPoint--;
selectedUnit = selectUnit();
}
//選中一個單位,把它放到controller進行操作,並返回一個操作是否完成的布林值。
//如果操作完成,那麼這個隊伍的AP減少1,並選一個新的單位
//如果操作還沒完成,那麼不做任何事情,下一幀繼續這個操作
}
if (team[currenTeamIndex].ActionPoint <= 0)
{
team[currenTeamIndex].ActionPoint = team[currenTeamIndex].maxActionPoint;
currenTeamIndex = 1 - currenTeamIndex;
}
//當一個隊伍的AP小於等於0時,我們重置這個隊伍的AP並將當前的控制權轉移到另一支隊伍上面(即改變當前索引值)
}
其中的SelectUnit函式實現比較簡單,目前用了一個滑鼠raycast的方法來選中對應物體
GameObject selectUnit()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (isIn(hit.transform.gameObject, team[currenTeamIndex].units))
//判斷選中的這個單位是不是在(isIn)當前的隊伍列表中,只有選中當前隊伍的單位才返回
return hit.transform.gameObject;
else
return null;
}
else
return null;
}
else
return null;
}
有了TurnManager以後,我們就可以開始實現Controller裡面的Run函式。這個函式負責給selectedUnit分配一個操作,並執行。
public bool run(GameObject selectedUnit)
{
controllerMenu.SetActive(true);
Unit unit = selectedUnit.GetComponent<Unit>();
bool result = false;
switch (currentState)
{
case State.IDLE:
result = false;
break;
case State.MOVE:
result = unit.Move();
break;
case State.ATTACK:
result = unit.Attack();
break;
case State.SKILL:
result = unit.Cast();
break;
case State.SUMMON:
result = unit.Summon();
break;
default:
result = false;
break;
}
if (result == true)
{
currentState = State.IDLE;
controllerMenu.SetActive(false);
}
return result;
}
目前暫定有四種操作:移動、攻擊、使用技能(一些隨從有主動技能)和召喚(即使用卡牌)。在unit類中進行具體實現。
其中currentState由四個按鈕的回撥函式來設定對應的值,例如按下Move按鈕對應的值就是State.MOVE。最後這個函式需要返回一個執行的結果,如果進行了操作,那麼返回操作的結果,如果沒有按下任何按鈕(沒有輸入,即IDLE狀態),則返回false。
最後,在Unit類中,實現了一個移動的功能
public bool Move()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
}
}
if (agent.remainingDistance < agent.radius && agent.hasPath)
return true;
else
return false;
}
一個比較簡單的點選地面移動的實現。每次執行的時候檢測是否有滑鼠按鍵擡起,如果有則射一道光束到地面,並用NavMeshAgent將當前單位移動過去。設定完目的地後判斷一下剩餘距離是否小於agent的半徑,如果是的說明到達目的地,返回true說明操作結束,可以進行下一個單位的選擇和操作;如果沒有,說明操作沒有結束,返回false,下次update繼續這個操作。
這邊的實現其實會有一點bug,如果選擇move以後在到達目的地前不停點選滑鼠會使單位不停的重新定向,可以考慮在input裡面加一個flag使得在到達目的地前只能接受一次滑鼠的輸入。另外在移動過程中我個人傾向於還是需要把選單暫時關閉,這個需要調整一下controller中的實現。
程式碼寫完以後場景就比較好處理了。我做了一個賊簡單的場景,其中藍色方塊是己方單位,紅色方塊是敵方單位。選中效果還沒有加上,但目前已經可以接近回合制式的移動各個單位了。
今天基本上把回合制的框架搭了個七七八八,下面可以往裡面填unit中的幾個操作的實現了。下面一個比較麻煩是一套RPG系統,例如實現血量、攻擊等等機制。另外ActionPoint這個機制也要做更復雜的實現,每一個技能、每一個動作都應該有一個自己消耗的ActionPoint。最後,其實這樣去實現一個回合制的流程動作應該還有不少bug,還要等後面慢慢進行重構。
相關推薦
一個卡牌遊戲的DEMO(0)
最近有一個卡牌遊戲的創意,打算用Unity把Demo實現出來練練手。我儘量嘗試每天記錄一下開發的進度。 打算在這裡主要記錄遊戲設計和開發的過程,作為自己的一個摸索的記錄。 雖然只有一個人在做,但還是打算用git來做一下版本控制,畢竟回退之類的相當方便 ht
利用Vuforia開發一個AR卡牌對戰(一):多圖識別+EventHandler框架
卡牌對戰1:多圖識別+EventHandler框架 這個系列主要講解實現一個簡易的AR卡牌對戰的功能,這次首先實現多圖識別和EventHandler的框架介紹。 首先我們來實現多圖識別。 1.上傳識別圖並下載資料包,然後得到LicenseKey。這裡用了兩個識別圖,一次打包
使用unity製作的一款生存類遊戲demo(一)
花了20多天的時間來完成這個demo,主要是為了實現一些自己設想的功能,並未注重關卡和玩法的設計,整體上還不夠完善或者說不夠完整。 demo中的美術資源均來自asset store和各種資源網站。使用的外掛有NGUI,post progressing stack
【BZOJ】3191 [JLOI2013]卡牌遊戲(概率dp)
如果 style ++ bzoj mem color con size oid 題目 傳送門:QWQ 分析 算是概率dp不錯的題。 $ dp[i][j] $表示有i個人時,這i個人中的第j個獲勝的概率。 我們把i從1推到n,那麽答案就是$ dp[n
H - 卡牌遊戲(簡單期望)
Description 小貝喜歡玩卡牌遊戲。某個遊戲體系中共有N種卡牌,其中M種是稀有的。小貝每次和電腦對決獲勝之後都會有一個抽卡機會,這時系統會隨機從N種卡中選擇一張給小貝。普通卡可能多次出現,而稀有卡牌不會被重複抽到。小貝希望收集到K種稀有卡牌,她想知道期望需要多少次獲勝才能實現這個目標
(概率/dp)P2059 [JLOI2013]卡牌遊戲
https://www.luogu.org/problemnew/show/P2059 第一次做概率dp的題,還以為要用組合數學知識去推公式 上次牛客也遇到概率dp的題,就忘了補題 考慮從1個人正推到n個人的情況,發現k個人的時候通過抽牌淘汰掉一個人之後能從k-1已經計算的狀態轉
【貪心】【2018.10.1提高組模擬】T1(WOJ 2687) 卡牌遊戲
題目(卡牌遊戲): 【題目描述】 L最近喜歡上了一個卡片遊戲,遊戲規則是: 2個人一共拿2n張卡片,編號1..2n,每個人n張,然後進行n輪出牌,每輪2個人都打一張牌,,點數大的玩家每次獲1分 L可以預測到對方要打牌的順序。 同時,L有一次機會選擇了某個時間點,從
2018.10.01 NOIP模擬 卡牌遊戲(貪心)
描述 L最近喜歡上了一個卡片遊戲,遊戲規則是: 2個人一共拿2n張卡片,編號1…2n,每個人n張,然後進行n輪出牌,每輪2個人都打一張牌,,點數大的玩家每次獲1分 L可以預測到對方要打牌的順序。 同時,
卡牌遊戲(簡單期望)
Description 小貝喜歡玩卡牌遊戲。某個遊戲體系中共有N種卡牌,其中M種是稀有的。小貝每次和電腦對決獲勝之後都會有一個抽卡機會,這時系統會隨機從N種卡中選擇一張給小貝。普通卡可能多次出現,而稀有卡牌不會被重複抽到。小貝希望收集到K種稀有卡牌,她想知道期望需要多少次獲
第一個AngularJS Demo(購物車)
mod 購物 set sco tle ng-model -m -c 刪除 <!DOCTYPE html><html><head> <meta charset="utf-8" /> <script sr
Java反射機制demo(五)—獲得並調用一個類中的方法
color 擁有 oca logs over super getmethod equals() bool 這個demo在使用反射機制操作屬性之前,主要原因是因為在.class文件字節碼中,方法排在屬性的前面。 1,獲得一個類中的方法 先看一下方法和運行結果。獲取所有的方
PTA 陣列迴圈左移 (20 分) 本題要求實現一個對陣列進行迴圈左移的簡單函式:一個數組a中存有n(>0)個整數,在不允許使用另外陣列的前提下,將每個整數迴圈向左移m(≥0)個位置,即將a中的
陣列迴圈左移 (20 分) 本題要求實現一個對陣列進行迴圈左移的簡單函式:一個數組a中存有n(>0)個整數,在不允許使用另外陣列的前提下,將每個整數迴圈向左移m(≥0)個位置,即將a中的資料由(a0a1⋯an−1)變換為(am⋯an−
細解一個dubbo的小demo(附原始碼)
今天小編來說說怎麼使用dubbo+zookeeper+maven+Idea搭建一個小demo——HelloWorld。 新建框架 首先新建專案框架,並在pom.xml中進行maven的相關配置。 完善api專案 我們知道,client和server專案都依賴於
一天練習一個小C/C++程式(一) 控制檯版“金山打字”遊戲
今天練習了一個C語言小程式,控制檯版的簡易“金山打字”小遊戲。 效果圖: 程式碼: #include<stdio.h> #include<stdlib.h> #incl
手把手教你做一個 C 語言編譯器(0):前言
“手把手教你構建 C 語言編譯器” 這一系列教程將帶你從頭編寫一個 C 語言的編譯器。希望通過這個系列,我們能對編譯器的構建有一定的瞭解,同時,我們也將構建出一個能用的 C 語言編譯器,儘管有許多語法並不支援。 在開始進入正題之前,本篇是一些閒聊,談談這個系列的初衷
造輪子:搭建一個簡單的nodejs伺服器,從零開始搭建一個自用網站(0)
伺服器用的是阿里雲最早期的伺服器低配版本1Gcpu,512M記憶體,20G硬碟,1M頻寬,平常只是用來做測試,目前只處理業務邏輯,網站的設計上儘量避免佔用太多的頻寬, 靜態檔案的儲存用的是阿里雲oss,100G空間,夠放視訊,圖片什麼的, html/js/c
5分鐘搭建一個HTML5視訊聊天Demo(WebRTC+NodeJS)
轉載自: http://blog.csdn.net/u012377333/article/category/2670379 謝謝版主 到 http://nodejs.org/ 下載最新版nodejs,我下的是“node-v0.10.7-x86.msi”。 安裝,
怎麼通過Unity和谷歌紙盒做一個VR遊戲?(譯)
作者是用iPhone適配的,我是用的Android手機且由於SDK版本的關係所以會有些小細節不一樣。 遊戲工程地址:忍者飛鏢
使用php完成一個使用者註冊以及管理的demo(一)
1.設計mysql的使用者表 2.設計檔案結構 3.製作後臺增加使用者的介面 4.對於資料庫操作的封裝,用來操作資料庫的一些方式 5. include.php的製作 (1)使用者表的設計 mysql資料庫 /如果使用者表user已經存在的
一個jmter介面測試的demo(轉載)
轉載地址忘了。。。 將下面的程式碼貼上儲存為demotest.jmx檔案,然後再jmeter中開啟 <?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properti