[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名

学习Unity脚本推荐:Unity3D官网索引


上一章已经可以实现最高分的本地存储,接下来的任务就是插入最高分并且实现排行榜其余分数的依次下调。

在代码中的修改十分简单,使用for循环依次调整即可:

function AddNewHighscore() {

	var curRounds = PlayerPrefs.GetInt("highscoreCurrentRounds");
	var curKills = PlayerPrefs.GetInt("highscoreCurrentKills");
	var newHighscorePosition: int;
	
	
	// check if the current score are good / above the highscores in the playersPrefs
	
	// are we assuming the local and playerprefs data is the same? - Yes
		
	for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores
	
		if (curRounds > score[i].rounds) {
			// new score is higher!
			newHighscorePosition = i;
			break;
		} else if (curRounds == score[i].rounds && curKills > score[i].kills) {
			// new score is equal in rounds and kills are greater
			newHighscorePosition = i;
			break;
		} // if the rounds are equal and kills are less
	} // if the rounds are less
	
	
	
	Debug.Log (newHighscorePosition);
	
	//if it is calculate what the # of the new houigschore would be
	
	// 1-8
	// new highscore 4
	
	// 1,2,3,4,5,6,7,8
	// 1,2,3,4,4,5,6,7,8
	// 1,2,3,4,5,6,7,8
	
	// 4 -> 5
	// ? 5 -> 6
	
	// 8 -> 9
	// 7 -> 8
	// 6 -> 7
	
	if (newHighscorePosition < numberHighscores) 
	{
		for(i = numberHighscores - 1 ; i >= newHighscorePosition ; i-- ) { // for the number of highscores
			//8
			
			if (i == newHighscorePosition) {
				// highscore enter code
				PlayerPrefs.SetString("highscore" + i + "name" , score[i].name); // ask the player for name
				score[i].name = score[i].name;
				PlayerPrefs.SetInt("highscore" + i + "rounds" , curRounds);
				score[i].rounds = curRounds;
				PlayerPrefs.SetInt("highscore" + i + "kills" , curKills);
				score[i].kills = curKills;				
			} else {
				PlayerPrefs.SetString("highscore" + i + "name" , score[i-1].name);
				score[i].name = score[i-1].name;
				PlayerPrefs.SetInt("highscore" + i + "rounds" , score[i-1].rounds);
				score[i].rounds = score[i-1].rounds;
				PlayerPrefs.SetInt("highscore" + i + "kills" , score[i-1].kills);
				score[i].kills = score[i-1].kills;
			}
		}
	}
	
	
	
	// add it into our data and save it.


}

接下来的的问题便是如何是用户自己输入用户名,因为现在并不能正确显示最新分的用户名:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第1张图片

这里要用到GUI中的TextField,和xcode中的TextField十分类似。

我们可以在官网查找TextField的相关数据:Unity3D官网索引

官方给出的重载函数如下:

static function TextField (position : Rect, text : String) : String
static function TextField (position : Rect, text : String, maxLength : int) : String
static function TextField (position : Rect, text : String, style : GUIStyle) : String
static function TextField (position : Rect, text : String, maxLength : int, style : GUIStyle) : String
脚本案例
var stringToEdit : String = "Hello World";

function OnGUI () {
    // Make a text field that modifies stringToEdit.
    stringToEdit = GUI.TextField (Rect (10, 10, 200, 20), stringToEdit, 25);
}
我们可以在脚本中添加一下代码:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第2张图片

可以发现游戏运行后多了一个可以输入的文本框:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第3张图片

接下来要做的就是在TextField和排行榜的数据之间建立连接,使得输入框中的数据可以显示在排行榜上面。

在代码中添加两行:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第4张图片

这个时候再运行游戏就会发现显示发生了变化:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第5张图片

下面便是如何隐藏掉这个难看的输入框。

这里要介绍一个新的概念FocusControl官网解释

简单来说的就是移动键盘焦点的一个方法。

官网给的简单案例如下:

// When pressed the button, selects the "username" Textfield.
var username : String = "username";
var pwd : String = "a pwd";
function OnGUI () {
    // Set the internal name of the textfield
    GUI.SetNextControlName ("MyTextField");
    
    // Make the actual text field.
    username = GUI.TextField (Rect (10,10,100,20), username);
    pwd = GUI.TextField (Rect (10,40,100,20), pwd);

    // If the user presses this button, keyboard focus will move.
    if (GUI.Button (Rect (10,70,80,20), "Move Focus"))
        GUI.FocusControl ("MyTextField");    
}

在OnGUI函数中作如下修改:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第6张图片

再次运行项目便会发现文本输入框已经有了高亮显示,表示获取到了焦点。

也就是,现在不需要任何点击就可以直接输入了

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第7张图片

接下来的任务便是实现文本输入框的动态显示。

对代码做如下修改实现文本框的隐藏:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第8张图片

此时再次运行就会发现,输入框已经没有了,但是依旧可以输入你的姓名:

[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名_第9张图片

完整的脚本如下:

// this is called after a player dies OR from the main menu

// Display the highscore
// track the follow: Player Name, highscore number of the rounds survived and kills 

//Upon entering the High Score menu, test if we have a high score and if we do, ask the
// player to enter a name and add it to the High Score save data.

/*
class Highscore { // highscore class to hold information specific to one highscore
	var name:String; // player name entered at time of highscore
	var rounds:int; // number of rounds won in this highscore
	var kills:int; // number of kills in this highscore
}*/

var boxStartLocation:Vector2; // offset of main GUI element
var center = Location(); // handy class for calculating the center of the screen

function Start() {
	Debug.Log("The value of key 'highscoreCurrentRounds' is: " + PlayerPrefs.GetInt("highscoreCurrentRounds"));
	Debug.Log("The value of key 'highscoreCurrentKills' is: " + PlayerPrefs.GetInt("highscoreCurrentKills"));
	AddNewHighscore();
}

function Update() {
	center.updateLocation(); // every frame, check if the screen has changed and re-calculate the screen center value.
	//SyncPlayerPrefs();
	//Start();
}

// draw a text string to the screen

var textGUIStyle : GUIStyle; // to control the display of text
var roundsGUIStyle : GUIStyle; // to control the display of text for kills
var score = new Highscore[10]; // array of names for the highscore

score[0].name = "www.DigitalTutors.com"; // Highscore #1
score[1].name = "Papa";
score[2].name = "Kyle";
score[3].name = "Tanya";
score[4].name = "Delano";
score[5].name = "Justin";
score[6].name = "Eddie";
score[7].name = "Josh";
score[8].name = "Chris";
score[9].name = "Steve";
score[0].rounds = 99;
score[0].kills = 999;
score[1].rounds = 1;
score[1].kills = 9;
var heightOffset: float = 10; // how much space to place between each highscore level
var roundsOffset:float; // horizontal offset for rounds column
var killsOffset:float; // horizontal offset for kills column

var numberHighscores:int = 8; // controls how many loops to run to display

var newName:String = "-type your name-";

function OnGUI() {

	GUI.SetNextControlName ("NameTextField");
	newName = GUI.TextField(Rect(-100,-100,1,1),newName,30);
	GUI.FocusControl ("NameTextField");
	
	
	PlayerPrefs.SetString("highscore" + newHighscorePosition + "name" , newName); // ask the player for name
	score[newHighscorePosition].name = newName;
	
	
	for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores to display
		GUI.Box(Rect(center.offset.x + boxStartLocation.x, // draw a box with the name
		center.offset.y + boxStartLocation.y + i * heightOffset,
		222,34),score[i].name,textGUIStyle); // using textGUIStyle
		
		GUI.Box(Rect(center.offset.x + boxStartLocation.x + roundsOffset, // draw a box with the rounds
		center.offset.y + boxStartLocation.y + i * heightOffset,
		222,34),score[i].rounds.ToString(),roundsGUIStyle); // using roundsGUIStyle
		
		GUI.Box(Rect(center.offset.x + boxStartLocation.x + killsOffset, // draw a box with the kills
		center.offset.y + boxStartLocation.y + i * heightOffset,
		222,34),score[i].kills.ToString(),roundsGUIStyle); // using roundsGUIStyle
	}
}

	// Highscore naming scheme
	// key starts : "highscore"
	// past that, whatever the setting needs to be
	
	// a specific high score would look like this:
		// highscore4name
	
var newHighscorePosition: int;
	
function AddNewHighscore() {

	var curRounds = PlayerPrefs.GetInt("highscoreCurrentRounds");
	var curKills = PlayerPrefs.GetInt("highscoreCurrentKills");
	
	
	// check if the current score are good / above the highscores in the playersPrefs
	
	// are we assuming the local and playerprefs data is the same? - Yes
		
	for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores
	
		if (curRounds > score[i].rounds) {
			// new score is higher!
			newHighscorePosition = i;
			break;
		} else if (curRounds == score[i].rounds && curKills > score[i].kills) {
			// new score is equal in rounds and kills are greater
			newHighscorePosition = i;
			break;
		} // if the rounds are equal and kills are less
	} // if the rounds are less
	
	
	
	Debug.Log (newHighscorePosition);
	
	//if it is calculate what the # of the new houigschore would be
	
	// 1-8
	// new highscore 4
	
	// 1,2,3,4,5,6,7,8
	// 1,2,3,4,4,5,6,7,8
	// 1,2,3,4,5,6,7,8
	
	// 4 -> 5
	// ? 5 -> 6
	
	// 8 -> 9
	// 7 -> 8
	// 6 -> 7
	
	if (newHighscorePosition < numberHighscores) 
	{
		for(i = numberHighscores - 1 ; i >= newHighscorePosition ; i-- ) { // for the number of highscores
			//8
			
			if (i == newHighscorePosition) {
				// highscore enter code
				PlayerPrefs.SetString("highscore" + i + "name" , score[i].name); // ask the player for name
				score[i].name = score[i].name;
				PlayerPrefs.SetInt("highscore" + i + "rounds" , curRounds);
				score[i].rounds = curRounds;
				PlayerPrefs.SetInt("highscore" + i + "kills" , curKills);
				score[i].kills = curKills;				
			} else {
				PlayerPrefs.SetString("highscore" + i + "name" , score[i-1].name);
				score[i].name = score[i-1].name;
				PlayerPrefs.SetInt("highscore" + i + "rounds" , score[i-1].rounds);
				score[i].rounds = score[i-1].rounds;
				PlayerPrefs.SetInt("highscore" + i + "kills" , score[i-1].kills);
				score[i].kills = score[i-1].kills;
			}
		}
	}
	
	
	
	// add it into our data and save it.


}
	
function SyncPlayerPrefs() {
	// our assumption is that the data in player prefs should over-ride the local data
	// need this to see if we have player prefs keys and if we do, copy into our local
	// if the key does not exist, we need to populate it with the local data
	
	for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores
	
		if (PlayerPrefs.HasKey("highscore" + i + "name" )) {
			//copy Player preferences value to local highscore class array
			score[i].name = PlayerPrefs.GetString("highscore" + i + "name");
		} else {
			//set that player prefs to local data
			PlayerPrefs.SetString("highscore" + i + "name" , score[i].name);
		}
		
		if (PlayerPrefs.HasKey("highscore" + i + "rounds" )) {
			//copy Player preferences value to local highscore class array
			score[i].rounds = PlayerPrefs.GetInt("highscore" + i + "rounds");
		} else {
			//set that player prefs to local data
			PlayerPrefs.SetInt("highscore" + i + "rounds" , score[i].rounds);
		}
		
		if (PlayerPrefs.HasKey("highscore" + i + "kills" )) {
			//copy Player preferences value to local highscore class array
			score[i].kills = PlayerPrefs.GetInt("highscore" + i + "kills");
		} else {
			//set that player prefs to local data
			PlayerPrefs.SetInt("highscore" + i + "kills" , score[i].kills);
		}
	}	
}





你可能感兴趣的:([Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名)