我正在游戏中创建一个键盘。我创建的游戏对象有10个按钮:0-9。玩家必须输入4位数代码才能打开门。一旦玩家输入第一个数字,它就会显示在键盘的屏幕上。
我已经完成了所有基本代码,但我确信我已经以非常低效的方式完成了这项工作。现在,我已将以下功能附加到我的一个键上,实际上是数字1键:
public void Key1() {
if (digit1entered == false) {
digit1 = 1;
displaycode.text = digit1.ToString () + digit2.ToString () + digit3.ToString () + digit4.ToString ();
print ("First digit entered");
digit1entered = true;
} else {
if (digit1entered == true && digit2entered == false) {
digit2 = 1;
digit2entered = true;
displaycode.text = digit1.ToString () + digit2.ToString () + digit3.ToString () + digit4.ToString ();
print ("2nd digit entered");
} else {
if (digit2entered == true && digit3entered == false) {
digit3 = 1;
digit3entered = true;
displaycode.text = digit1.ToString () + digit2.ToString () + digit3.ToString () + digit4.ToString ();
print ("3rd digit entered");
} else {
if (digit3entered == true && digit4entered == false) {
digit4 = 1;
digit4entered = true;
displaycode.text = digit1.ToString () + digit2.ToString () + digit3.ToString () + digit4.ToString ();
print ("4th digit entered");
}
}
}
}
}
为了使整个键盘工作,我需要创建9个以上的功能,每个功能都有2-0的更新值。这意味着我最终会得到10个相似的函数,除了它们输入的值。这是糟糕的编程,所以我该如何避免呢?哦,如果上面已经开始编程不好了,欢迎提示所有提示; - )
答案 0 :(得分:5)
很难做到这一点非常困难。你选择了一个真正的挑战。
有这样的功能
Complex.cs
在你的脚本 private string FourOnly(string s)
{
while (s.Length > 4 ) s = s.Substring(1);
return s;
}
中说某个对象
有十个按钮。在Inspector中,拖动以连接...
请注意,您实际上可以输入一个数字 - 我输入" 3"。
所以你实际上设置了值" 0"至" 9"在你的十个按钮上。
{脚注。你不会在真实的"中做到这一点。项目,因为它是正交的,会导致设计人员麻烦。我会根据键盘位置或其他东西神奇地查找数字。但这是一个很好的开始!}
所以你实际连接
一旦你有了这个工作,请告诉我们,我们会找出下一部分!
接下来,您需要一个永远不会让字符串超过四个字符的函数。如果您在最后添加一个,它会删除第一个。
(重要提示:您实际上是通过扩展程序来实现这一点,这是Unity编程的绝对核心。但它太过于一次解释所有内容。当你有时间处理this)
时大致你的功能是..
[System.NonSerialized] public string pin = "";
public void UserClickedButtonNumbered(int digitNumber)
{
Debug.Log("that button name is " +digitNumber);
pin = pin + digitNumber.ToString();
pin = FourOnly(pin);
Debug.Log("So far, the user entered: " +pin);
if ( pin == "1313" ) Debug.Log("code unlocked!");
}
所以现在你可以这样做......
public Text led1; // Text, or whatever your digits are
public Text led2;
public Text led3;
public Text led4;
private void FixLEDs()
{
string show = pin + " "; // just add many spaces on the end
led1.text = show[0].ToString(); // "show[n]" is a char, not a string
led2.text = show[1].ToString();
led3.text = show[2].ToString();
led4.text = show[3].ToString();
}
所以你实际上完成了。
最后!您只想在四个" LED显示屏中显示信息"
你真的需要用 UnityEvent 来做这件事,这让它非常容易。 (Tutorial here.)但是它一下子太多了,所以只需制作一个非常简单的函数......
public void UserClickedButtonNumbered(int digitNumber)
{
pin = FourOnly( pin + digitNumber );
FixLEDs();
if ( pin == "1313" ) Debug.Log("code unlocked!");
}
很容易就像馅饼一样。所以每次用户触摸任何东西时都要调用它,
fs.readdir
你已经完成了。去喝酒。
答案 1 :(得分:1)
我不会在这里发布实际代码,但更多的是为您分配。你应该真正研究多态和状态机。这是我最喜欢的多态性视频Google IO Talk之一。这是关于如何从代码中删除if语句和case语句的一些很好的指针。我没有状态机的视频,但基本上对于你的例子,你可能想要一个有7种状态:Start,Key1,Key2,Key3,Key4,Error,Success。现在您可以使用一些代码来收集输入并将其传递给状态机StateMachine.NextState(输入)。然后,您的状态机可以根据输入跳转到下一个状态。您可以让每个“状态”成为视频解释的对象,并且状态将负责执行它自己的逻辑。您应该能够使用no if语句或case语句重写您的问题。请发布您的解决方案。我很乐意看到它。
请注意,如果您使用此功能,将更改您的状态以接受6位数代码或10位数代码或字母数字代码。这就是多态性如此之大的原因。
答案 2 :(得分:0)
我会像这样清理它
if (digit1Entered == false) {
digit1 = 1;
displaycode.text =
print("First digit entered");
digit1entered = true;
}
else if (digit2Entered == false) {
digit2 = 1;
digit2entered = true;
displaycode.text = dispString;
print("2nd digit entered");
}
else if (digit3Entered == false) {
digit3 = 1;
digit3entered = true;
displaycode.text = dispString;
print("3rd digit entered");
}
else if (digit4Entered == false) {
digit4 = 1;
digit4entered = true;
displaycode.text = dispString;
print("4th digit entered");
}
根据您的代码的性质以及我所看到的,如果条件无论如何都不应该达到多重。如果您正确设置了真/假条件(您),则仅评估相应的if语句
编辑:解决方案二
这个想法需要一些重构,但它将是一个更“可扩展”的解决方案
将每个按钮附加一个调用方法的OnClick事件。然后,该方法将调用附加到主游戏对象的集中管理器。当您拨打电话时,您将传递按下的值和相关图像(,如果需要)
GameManagerThingy {
public int ReqEntries {get;set;}
private string curSelectedString = "";
private image[] selectedImages;
public void AddNumber(string numVal, image img) {
//Insert image and display it on keypad
//curSelectedString += numVal
if (ReqEntries == curSelectedString.length-1)
//This means enough buttons have been pressed and whatever
//Evaluation logic you have for entering correct #'s is here
else
//The game would continue
}
}
ButtonClickScript {
public image buttonImage {get;set;}
public string buttonValue {get;set;}
//Tie an onclick event to your game object for when it is clicked
public void OnClickFunction() {
GameObject.FindWithTag("manager").GetComponent<SomeScript>().AddNumber(buttonValue, buttonImage);
}
}
答案 3 :(得分:0)
使用当前数字指针代替布尔标志并在数组中存储数字 应该从每个按键处理程序调用函数KeyPressed,并使用适当的键值作为参数。
int currentDigit = 0;
char[] digits = new char[4];
public void KeyPressed(char keyDigit)
{
if (currentDigit==digits.Length-1)
{
return; // all digits entered
}
digits[currentDigit] = keyDigit;
displaycode.text = string.Empty;
for (int i = 0; i < digits.Length; ++i)
{
displaycode.text += digits[i];
}
switch(currentDigit)
{
case 0:
print("First digit entered");
break;
case 1:
print("2nd digit entered");
break;
// etc
}
++currentDigit;
}