准备花个三四天来实现一个简单的Galgame框架,作为学习了一周多的实战练习。本日主要是对游戏功能的分析,大致想出怎样实现,用什么方法来实现,为之后的制作铺好路。
Galgame的核心是一个对话系统,在屏幕下方显示文字,并用按钮控制继续显示,一般这种视觉小说游戏的字不是一下显示完的,而是逐渐显示完全的,所以要一个类似迭代器的东西,不断更新显示的字符串。而且玩多了就会发现,正在更新显示时点击按钮,整段文字会立即显示完全,然后暂停,等下一次按下按钮后清空,并开始新一段文字的显示。这样显示的过程就有了两个状态:
1.正在显示
2.显示完全,等待按钮按下
可以写一个全局的变量来控制显示的状态,在状态1点击按钮,更新全局变量,显示转入状态2。在状态2点击按钮,更新全局变量转入状态1。大概就是这么回事。
至于如何实现状态1的显示文字效果,可以定义一个字符串数组,装入几段内容,每一次取一段内容,用一个空字符串每间隔一小段时间加一个字,直到两个字符串相等,让这个变化的字符串在GUI上显示(练习GUI,本次制作不直接使用控件)。
基本的显示过程大概如此,还是比较清晰的。
1.以一个对话为基本Object出发,应该需要一个对话类,里面包括:
需要显示的背景图片
人物图片以及其位置(不止一个)
所有的对话(一个string数组)
目前说话人的名字
反映在代码上:
public class IndividualConversation : MonoBehaviour {
public Texture2D Background;
public Texture2D Character;
public string Speaker;
public string[] Conversations;
}
2.需要一个加载对话并准备下一段对话的Manager,作为ConversationManager,是个比较核心的东西,通过它来绘制GUI的内容,并且还要添加一些显示函数,判断本对话已经显示完毕并切换下一个对话的函数,与其他菜单传递数据的函数。
初定:
GUI绘制
更新对话
判断对话结束
显示状态的切换
public GameObject Current_Conversation;
public GameObject Next_Conversation;
private Texture2D TxtBackground;
private Texture2D TxtCharacter;
void Start () {
TxtBackground = Current_Conversation.GetComponent<IndividualConversation>().Background;
TxtCharacter = Current_Conversation.GetComponent<IndividualConversation>().Character;
}
private void OnGUI()
{
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), TxtBackground);
GUI.DrawTexture(new Rect(200, 50, TxtCharacter.width, TxtCharacter.height), TxtCharacter);
}
当然,这只是随便写写,明天会系统地将功能一个一个实现。
3.光用Manager似乎不够,应该新创一个有Trigger作用的object,对Manager中对话进行更新,并显示。显示部分应该要用协程来达到效果,随便写了个Demo,命名较为混乱,明天来整改。
public GameObject AllConversations;
public IndividualConversation tempCon;
public string display_Str;
public string[] str_array;
private bool state_changed = false;
private int sign = 0;
private void Start()
{
tempCon = AllConversations.GetComponent<IndividualConversation>();
str_array = tempCon.Conversations;
Debug.Log(str_array.Length);
Debug.Log(tempCon.Speaker);
StartCoroutine("TriggerDialogue");
}
private void OnGUI()
{
state_changed = GUI.Button(new Rect(Screen.width - 100, Screen.height - 100, 90, 40),
"continue");
GUI.Label(new Rect(10, Screen.height - 50, Screen.width - 20, 30), display_Str);
}
IEnumerator TriggerDialogue()
{
display_Str = "";
int str_note=0;
string temp_str = "";
yield return new WaitForSeconds(0.05f);
while(sign<str_array.Length)
{
state_changed = false;
temp_str = str_array[sign];
while (display_Str != temp_str)
{
display_Str += temp_str[str_note].ToString();
yield return new WaitForSeconds(0.05f);
str_note++;
}
while(state_changed==false)
{
yield return new WaitForSeconds(0.01f);
}
display_Str = "";
str_note = 0;
sign++;
}
sign = 0;
StopCoroutine("TriggerDialogue");
}
4.全局变量也需要存放在一个脚本上,包括了:显示的状态,好感度的计数,选择分支,还有BGM,人物对话音量的控制,目前就想到了这些。
要体现出层次关系,建立脚本,资源(CG,背景,人物,BGM,视频,GUI)的文件夹,并定义好空脚本,导入一些初始资源作为测试。
找些图挂在脚本上面,角色图片可以先抠一下图
然后来运行一下刚刚写的不成熟的东西试一试
字体大小有问题,创一个变量来控制,人物位置也需要创一个变量来控制,今天就这样吧,把离散的数理逻辑预备知识看完了,还是很充实的。