版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
騰訊云游戲應(yīng)用開發(fā)騰訊云游戲應(yīng)用開發(fā)實(shí)現(xiàn)登錄功能01任務(wù)實(shí)現(xiàn)獲取自身數(shù)據(jù)功能02任務(wù)實(shí)現(xiàn)注冊功能03任務(wù)實(shí)現(xiàn)業(yè)務(wù)邏輯模塊項(xiàng)目6實(shí)現(xiàn)匹配功能04任務(wù)實(shí)現(xiàn)準(zhǔn)備功能05任務(wù)實(shí)現(xiàn)戰(zhàn)場管理功能06任務(wù)實(shí)現(xiàn)登錄功能01任務(wù)實(shí)現(xiàn)獲取自身數(shù)據(jù)功能02任務(wù)實(shí)現(xiàn)注冊功能學(xué)習(xí)目標(biāo)
實(shí)現(xiàn)游戲的幾個(gè)重要業(yè)務(wù)邏輯
掌握CS模式下協(xié)議的使用
掌握登錄注冊功能的基本實(shí)現(xiàn)方法學(xué)習(xí)目標(biāo)實(shí)現(xiàn)游戲的幾個(gè)重要業(yè)務(wù)邏輯1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法當(dāng)用戶在登錄界面中單擊“登錄”按鈕后,后臺(tái)嘗試與服務(wù)器建立連接,連接成功后發(fā)送登錄協(xié)議,協(xié)議格式為login;id;password;。修改LoginPanel.cs腳本中的OnLoginClick
方法,代碼如下。/*登錄按鈕事件*/
public
void
OnLoginClick
()
{
if
(idInput.text
==
""
||
pwInput.text
==
"")
{
/*打開提示框*/
PanelMgr.instance.OpenPanel<TipPanel>
("用戶名密碼不能為空!");
return;
}
//如果服務(wù)器沒有連接,連接服務(wù)器
if
(NetMgr.instance.status
!=
NetMgr.Status.Connected)
{
NetMto
=
new
ProtocolStr
();
/*連接*/
if
(!NetMgr.instance.Connect
())
PanelMgr.instance.OpenPanel<TipPanel>
("連接服務(wù)器失敗!");
}
1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法當(dāng)用戶在登錄界面中單1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法
//發(fā)送登錄協(xié)議
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("login");
protocol.AddString
(idInput.text);
protocol.AddString
(pwInput.text);
/*一次性監(jiān)聽*/
NetMgr.instance.Send
(protocol,
OnLoginBack);
}1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法
//發(fā)送登1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法在HandleConnMsg類中添加Msglogin方法,當(dāng)服務(wù)端收到login協(xié)議時(shí),分發(fā)給Mgslogin方法處理
public
void
Msglogin
(Conn
conn,
ProtocolBase
protoBase)
{
string
id,
pw;
ProtocolStr
protocol
=
(ProtocolStr)protoBase;
id
=
protocol.GetString
(1);
pw
=
protocol.GetString
(2);
/*構(gòu)建返回協(xié)議*/
ProtocolStr
protocolRet
=
new
ProtocolStr
();
protocolRet.AddString
("login");
/*數(shù)據(jù)庫校驗(yàn)*/
//如果用戶名密碼校驗(yàn)失敗
if
(!DataMgr.instance.CheckPassWord
(id,
pw))
{
Console.WriteLine
("[Msglogin]登錄失敗:用戶名和密碼錯(cuò)誤"
+
conn.GetAddress
());
protocolRet.AddInt
(-1);//返回失敗結(jié)果
conn.Send
(protocolRet);
return;
}
1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法在HandleC1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法
if
(!ServNet.instance.KickOff
(id))
{
//如果踢下線失敗
Console.WriteLine
("[Msglogin]登錄失敗:擠下線失敗"
+
conn.player.id);
//返回失敗結(jié)果
protocolRet.AddInt
(-1);
conn.Send
(protocolRet);
return;
}
PlayerData
playerData
=
DataMgr.instance.GetPlayerData
(id);
//獲取玩家數(shù)據(jù)
if
(playerData
==
null)
{
Console.WriteLine
("[Msglogin]登錄失敗:獲取賬戶信息失敗"
+
conn.player.id);
protocolRet.AddInt
(-1);
//返回失敗結(jié)果
conn.Send
(protocolRet);
return;
}
conn.player
=
new
Player
(id,
conn,
playerData);
//登入賬戶,加載數(shù)據(jù)
protocolRet.AddInt
(0);
//返回成功結(jié)果
conn.Send
(protocolRet);
}1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法
i1實(shí)現(xiàn)登錄功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法添加OnLoginBack方法
/*登錄協(xié)議回執(zhí)*/
public
void
OnLoginBack
(ProtocolBase
protocol)
{
/*構(gòu)建協(xié)議*/
ProtocolStr
proto
=
(ProtocolStr)protocol;
/*校驗(yàn)登錄結(jié)果*/
int
result
=
proto.GetInt
(1);
if
(result
==
0)
{
GameMgr.instance.id
=
idInput.text;
//保存賬號(hào)ID
PanelMgr.instance.OpenPanel<TipPanel>
("登錄成功!");
PanelMgr.instance.OpenPanel<LobbyPanel>
();
/*進(jìn)入游戲大廳*/
PanelMgr.instance.ClosePanel
(this);
}
else
{
NetMgr.instance.Close
();
//斷開連接
PanelMgr.instance.OpenPanel<TipPanel>
("登錄失敗,請檢查用戶名密碼!");
}
}1實(shí)現(xiàn)登錄功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法添加OnLogi1實(shí)現(xiàn)登錄功能4.實(shí)現(xiàn)踢下線模塊如果該角色在游戲中,則把它踢下線。并且發(fā)送Logout協(xié)議,向被踢下線的客戶端發(fā)送通知。在ServNet中添加KickOff方法,代碼如下。
/*如果某id已經(jīng)在線就踢下線*/
public
bool
KickOff
(string
id)
{
for
(int
i
=
0;
i
<
conns.Length;
i++)
{
if
(conns
[i]
==
null)
continue;
if
(!conns
[i].isUse)
continue;
if
(conns
[i].player
==
null)
continue;
/*如果該玩家已經(jīng)在線*/
if
(conns
[i].player.id
==
id)
{
lock
(conns[i].player)
{
Console.WriteLine
("檢查到"+id+"已在線,踢下線");
/*通知客戶端下線*/
ProtocolStr
protocolLogout
=
new
ProtocolStr
();
protocolLogout.AddString
("logout");
conns[i].Send
(protocolLogout);
return
conns
[i].player.Logout
();
}
}
}
return
true;
}1實(shí)現(xiàn)登錄功能4.實(shí)現(xiàn)踢下線模塊如果該角色在游戲中,則把它踢2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能1.實(shí)現(xiàn)客戶端發(fā)送請求方法在LobbyPanel.cs腳本的OnShowing方法的最后添加相關(guān)代碼,如下?!?/p>
/*請求加載自身數(shù)據(jù)*/
ProtocolStr
proto
=
new
ProtocolStr
();
proto.AddString
("getachieve");//發(fā)送協(xié)議,并注冊接收方法
NetMgr.instance.Send
(proto,RecvGetAchieve);
}2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能1.實(shí)現(xiàn)客戶端發(fā)送請求方法在Lobby2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能2.實(shí)現(xiàn)服務(wù)端處理協(xié)議的方法當(dāng)服務(wù)端接收到協(xié)議時(shí),分發(fā)給對(duì)應(yīng)的方法,將玩家的勝負(fù)場次寫入?yún)f(xié)議返回給玩家。在HandlePlayerMsg類中添加協(xié)議處理方法Msggetachieve方法,代碼如下。/*獲取玩家自身數(shù)據(jù)*/
/*返回協(xié)議"getachieve,win,lost,"*/
public
void
Msggetachieve
(Player
player,
ProtocolBase
protoBase)
{
ProtocolStr
protocolRet
=
new
ProtocolStr
();
protocolRet.AddString
("getachieve");
protocolRet.AddString
(player.id);
protocolRet.AddInt
(player.playerData.win);
protocolRet.AddInt
(player.playerData.fail);
player.conn.Send
(protocolRet);
return;
}2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能2.實(shí)現(xiàn)服務(wù)端處理協(xié)議的方法當(dāng)服務(wù)端接2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果客戶端收到返回協(xié)議并更新到UI上,代碼如下。
/*個(gè)人信息協(xié)議接收*/
public
void
RecvGetAchieve
(ProtocolBase
protocol)
{
/*解析協(xié)議*/
ProtocolStr
proto
=
(ProtocolStr)protocol;
IDtext.text
=
"玩家:";
IDtext.text
+=
proto.GetString
(1);
IDtext.text
+=
",勝場:";
IDtext.text
+=
proto.GetInt
(2);
IDtext.text
+=
",負(fù)場:";
IDtext.text
+=
proto.GetInt
(3);
}2實(shí)現(xiàn)獲取自身數(shù)據(jù)功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果客戶端收到返3實(shí)現(xiàn)注冊功能1.實(shí)現(xiàn)客戶端請求注冊方法當(dāng)用戶在注冊界面中單擊“注冊”按鈕后,后臺(tái)嘗試與服務(wù)器建立連接,連接成功后發(fā)送注冊協(xié)議,協(xié)議格式為register;id;password;。修改RegPanel.cs腳本中的OnRegClick方法,代碼如下。
/*注冊按鈕事件*/
public
void
OnRegClick
()
{
/*本地校驗(yàn)*/
//用戶名密碼為空
if
(idInput.text
==
""
||
pwInput.text
==
"")
{
PanelMgr.instance.OpenPanel<TipPanel>
("用戶名密碼不能為空!");
return;
}
//兩次密碼不同
if
(pwInput.text
!=
repInput.text)
{
PanelMgr.instance.OpenPanel<TipPanel>
("兩次輸入的密碼不同!");
return;
}
3實(shí)現(xiàn)注冊功能1.實(shí)現(xiàn)客戶端請求注冊方法當(dāng)用戶在注冊界面中3實(shí)現(xiàn)注冊功能1.實(shí)現(xiàn)客戶端請求注冊方法
//連接服務(wù)器
if
(NetMgr.instance.status
!=
NetMgr.Status.Connected)
{
NetMto
=
new
ProtocolStr
();
if
(!NetMgr.instance.Connect
())
PanelMgr.instance.OpenPanel<TipPanel>
("連接服務(wù)器失敗!");
}
//構(gòu)建協(xié)議
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("register");
protocol.AddString
(idInput.text);
protocol.AddString
(pwInput.text);
//發(fā)送
NetMgr.instance.Send
(protocol,
OnRegBack);
}3實(shí)現(xiàn)注冊功能1.實(shí)現(xiàn)客戶端請求注冊方法
//連接3實(shí)現(xiàn)注冊功能2.實(shí)現(xiàn)服務(wù)端注冊協(xié)議處理方法當(dāng)服務(wù)端收到register
協(xié)議時(shí),分發(fā)給Msgregister
方法處理。該方法首先解析協(xié)議中的用戶名和密碼。調(diào)用GetXXX是獲取協(xié)議數(shù)值的一種方法。然后調(diào)用DataMgr.instance.Register向user中表添加數(shù)據(jù),如果添加失敗,則通過protocol.AddInt(0)構(gòu)造參數(shù)為0的返回協(xié)議。最后通過CreatePlayer創(chuàng)建角色,并返回協(xié)議給客戶端,代碼如下。/*注冊協(xié)議*/
public
void
Msgregister
(Conn
conn,
ProtocolBase
protoBase)
{
/*解析協(xié)議*/
string
id,
pw;
ProtocolStr
protocol
=
(ProtocolStr)protoBase;
id
=
protocol.GetString
(1);
pw
=
protocol.GetString
(2);
Console.WriteLine
("[Msgregister]處理注冊協(xié)議:"
+
conn.GetAddress
()
+
"
用戶名:"
+
id
+
"
密碼:"
+
pw);
/*注冊*/
bool
result
=
DataMgr.instance.Register
(id,
pw);
3實(shí)現(xiàn)注冊功能2.實(shí)現(xiàn)服務(wù)端注冊協(xié)議處理方法當(dāng)服務(wù)端收到r3實(shí)現(xiàn)注冊功能2.實(shí)現(xiàn)服務(wù)端注冊協(xié)議處理方法
//構(gòu)建返回協(xié)議
ProtocolStr
protocolRet
=
new
ProtocolStr
();
protocolRet.AddString
("register");
if
(result)
{
Console.WriteLine
("[Msgregister]注冊成功"
+
conn.GetAddress
());
protocolRet.AddInt
(0);
}
else
{
Console.WriteLine
("[Msgregister]注冊失敗"
+
conn.GetAddress
());
protocolRet.AddInt
(-1);
}
//返回協(xié)議給客戶端
conn.Send
(protocolRet);
}3實(shí)現(xiàn)注冊功能2.實(shí)現(xiàn)服務(wù)端注冊協(xié)議處理方法
//構(gòu)3實(shí)現(xiàn)注冊功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法服務(wù)端處理協(xié)議后,會(huì)返回處理結(jié)果,格式為register;result;。result為0表示成功,-1表示失敗??蛻舳耸盏椒祷貐f(xié)議再做出響應(yīng)。注冊成功則關(guān)閉注冊界面。注冊失敗則提示注冊失敗。添加OnRegBack
方法,代碼如下。
/*注冊協(xié)議回執(zhí)*/
public
void
OnRegBack
(ProtocolBase
protocol)
{
/*解析協(xié)議*/
ProtocolStr
proto
=
(ProtocolStr)protocol;
int
result
=
proto.GetInt
(1);
if
(result
==
0)
{
PanelMgr.instance.OpenPanel<TipPanel>
("注冊成功!");
/*返回登錄界面*/
PanelMgr.instance.ClosePanel
(this);
}
else
{
NetMgr.instance.Close
();
PanelMgr.instance.OpenPanel<TipPanel>
("注冊失敗,請更換用戶名!");
}
}3實(shí)現(xiàn)注冊功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法服務(wù)端處理協(xié)議4實(shí)現(xiàn)匹配功能1.實(shí)現(xiàn)客戶端的匹配請求①單擊“匹配”按鈕,發(fā)送相關(guān)協(xié)議。在LobbyPanel.cs中添加新字段,代碼如下。
/*匹配狀態(tài)*/
enum
MatchState{
Matching,None
}
MatchState
state=MatchState.None;4實(shí)現(xiàn)匹配功能1.實(shí)現(xiàn)客戶端的匹配請求①單擊“匹配”按鈕4實(shí)現(xiàn)匹配功能1.實(shí)現(xiàn)客戶端的匹配請求修改LobbyPanel.cs中的OnMatchClick方法,代碼如下。
//匹配按鈕事件
public
void
OnMatchClick(){
if
(state
==
MatchState.None)
{
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("matchin");
NetMgr.instance.Send
(protocol);
state
=
MatchState.Matching;
btnText.text
=
"匹配中…\n(點(diǎn)擊取消)";
}
else
{
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("matchout");
NetMgr.instance.Send
(protocol);
state
=
MatchState.None;
btnText.text
=
"匹配\n(點(diǎn)擊開始)";
}
}4實(shí)現(xiàn)匹配功能1.實(shí)現(xiàn)客戶端的匹配請求修改LobbyPan4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgrMatchMgr類主要負(fù)責(zé)以下工作:①定義匹配隊(duì)列。當(dāng)匹配隊(duì)列滿足人數(shù)要求時(shí),創(chuàng)建房間,并將這些玩家添加到房間的玩家列表里。②定義游戲開始要求的人數(shù)。當(dāng)隊(duì)列滿足人數(shù)要求的時(shí)候,將隊(duì)列最前面的幾個(gè)人放到一個(gè)新建的房間類里。③控制隊(duì)列的進(jìn)入與離開。添加MatchMgr匹配管理類,代碼如下。using
System;
/*匹配管理*/
using
System.Collections.Generic;
public
class
MatchMgr
{
//單例
public
static
MatchMgr
instance;
//匹配列表
public
List<Player>
list
=
new
List<Player>();
//開始游戲需要的人數(shù)
public
int
beginNum=4;4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgrMa4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgr
/*構(gòu)造方法*/
public
MatchMgr
()
{
instance
=
this;
}
/*判斷匹配隊(duì)列中是否已經(jīng)足夠開局*/
public
void
CanBegin(){
if
(list.Count
>=
beginNum)
{
Console.WriteLine
("匹配成功,創(chuàng)建房間");
Room
room
=
new
Room
();
for(int
i=0;i<beginNum;i++){
room.AddPlayer
(list
[0]);
list.Remove
(list[0]);
}
/*通知所有匹配上的玩家進(jìn)入房間*/
room.MatchOK();
}
}4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgr
4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgr
public
void
AddPlayer(Player
player){
lock
(list)
{
if
(list.Contains
(player))
return;
list.Add
(player);
player.tempData.status
=
PlayerTempData.Status.Matching;
Console.WriteLine
("[Msgmatchin]進(jìn)入匹配隊(duì)列"+player.id);
CanBegin
();
}
}
/*將玩家移出匹配隊(duì)列*/
public
void
RemovePlayer(Player
player){
lock
(list)
{
if
(!list.Contains
(player))
return;
player.tempData.status
=
PlayerTempData.Status.None;
list.Remove
(player);
Console.WriteLine
("[Msgmatchout]離開匹配隊(duì)列"+player.id);
}
}
}4實(shí)現(xiàn)匹配功能2.創(chuàng)建服務(wù)端匹配管理類MatchMgr
4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類RoomRoom類主要負(fù)責(zé)以下工作:①當(dāng)匹配隊(duì)列滿足人數(shù)要求時(shí),創(chuàng)建房間,并將這些玩家添加到房間的玩家列表里。②創(chuàng)建房間時(shí),向房間中所有玩家發(fā)送匹配成功協(xié)議。③分配隊(duì)伍,以錯(cuò)開的方式,比如135是紅隊(duì)、246是藍(lán)隊(duì)。添加Room房間類,代碼如下。using
System;
using
System.Collections.Generic;
using
System.Linq;
//房間
public
class
Room{
//狀態(tài)
public
enum
Status
{
/*準(zhǔn)備中*/
Prepare
=
1,
/*游戲中*/
Fight
=
2,
}4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類RoomRoom類主要負(fù)4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
public
Status
status
=
Status.Prepare;
public
int
maxPlayers
=
2;
//玩家
/*已準(zhǔn)備的玩家*/
int
readyNum
=
0;
/*玩家列表*/
public
Dictionary<string,Player>
playerlist
=
new
Dictionary<string,Player>
();
/*座位數(shù)組*/
public
Room
()
{
maxPlayers
=
MatchMgr.instance.beginNum;
}
public
bool
AddPlayer
(Player
player)
{
//添加玩家
lock
(playerlist)
{
if
(playerlist.Count
>=
maxPlayers)
return
false;
/*修改玩家臨時(shí)數(shù)據(jù)*/
player.tempData.room
=
this;
player.tempData.team
=
SwitchTeam
();
player.tempData.status
=
PlayerTempData.Status.Room;
/*寫入*/
playerlist.Add
(player.id,
player);
}
return
true;
}4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
public4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
/*分配隊(duì)伍*/
/*返回一個(gè)隊(duì)伍的ID*/
public
int
SwitchTeam
()
{
int
count1
=
0;
int
count2
=
0;
foreach
(Player
player
in
playerlist.Values)
{
if
(player.tempData.team
==
1)
count1++;
if
(player.tempData.team
==
2)
count2++;
}
if
(count1
<=
count2)
return
1;
else
return
2;
}
4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
/*分配隊(duì)伍4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
//廣播
public
void
Broadcast
(ProtocolBase
protocol)
{
lock
(playerlist)
{
foreach
(Player
player
in
playerlist.Values)
{
player.conn.Send
(protocol);
}
}
}
/*匹配成功*/
/*通知所有玩家進(jìn)入房間,并廣播房間中所有玩家的信息*/
public
void
MatchOK
()
{
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("enterroom");
Broadcast
(protocol);
}
}4實(shí)現(xiàn)匹配功能3.創(chuàng)建服務(wù)端房間類Room
//廣播
4實(shí)現(xiàn)匹配功能4.創(chuàng)建服務(wù)端協(xié)議處理方法添加HandleMatchMsg.cs文件用來處理匹配協(xié)議,它有兩個(gè)協(xié)議處理方法Msgmatchin和Msgmatchout,代碼如下。using
System;
using
System.Collections.Generic;
public
partial
class
HandlePlayerMsg
{
//進(jìn)入匹配隊(duì)列
public
void
Msgmatchin
(Player
player,
ProtocolBase
protoBase)
{
MatchMgr.instance.AddPlayer
(player);
}
//離開匹配隊(duì)列
public
void
Msgmatchout
(Player
player,
ProtocolBase
protoBase)
{
MatchMgr.instance.RemovePlayer
(player);;
}
}4實(shí)現(xiàn)匹配功能4.創(chuàng)建服務(wù)端協(xié)議處理方法添加HandleM4實(shí)現(xiàn)匹配功能5.客戶端響應(yīng)匹配結(jié)果當(dāng)匹配成功后,服務(wù)端會(huì)發(fā)送enterroom協(xié)議,客戶端接收協(xié)議后進(jìn)入到房間。在OnShowing方法的最后注冊進(jìn)入房間的協(xié)議,代碼如下?!?*添加事件監(jiān)聽,匹配成功進(jìn)入房間*/
NetMgr.instance.msgDist.AddListener("enterroom",
RecvEnterRoom);}添加回調(diào)方法,代碼如下。
/*協(xié)議回發(fā)*/
public
void
RecvEnterRoom(ProtocolBase
protocol)
{
Debug.Log
("RecvEnterRoom");
PanelMgr.instance.OpenPanel<RoomPanel>
();
PanelMgr.instance.ClosePanel
(this);
}4實(shí)現(xiàn)匹配功能5.客戶端響應(yīng)匹配結(jié)果當(dāng)匹配成功后,服務(wù)端會(huì)5實(shí)現(xiàn)準(zhǔn)備功能1.客戶端發(fā)送準(zhǔn)備通知當(dāng)玩家單擊“確認(rèn)”按鈕(也就是游戲中常說的準(zhǔn)備)后,向服務(wù)端發(fā)送choosedhero協(xié)議。修改確認(rèn)按鈕的點(diǎn)擊事件,代碼如下。//確認(rèn)選擇按鈕事件
public
void
OnYesClick
()
{
/*通知服務(wù)器*/
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("choosedhero");
protocol.AddString
("Archer");
NetMgr.instance.Send
(protocol);
/*點(diǎn)擊一次準(zhǔn)備按鈕后,按鈕就失效*/
yesBtn.onClick.RemoveAllListeners
();
}5實(shí)現(xiàn)準(zhǔn)備功能1.客戶端發(fā)送準(zhǔn)備通知當(dāng)玩家單擊“確認(rèn)”按鈕5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果在HandleMatchMsg中添加處理choosedhero協(xié)議的方法,代碼如下。
//選擇英雄
public
void
Msgchoosedhero(Player
player,ProtocolBase
protoBase){
/*解析協(xié)議*/
ProtocolStr
protocol
=
(ProtocolStr)protoBase;
string
heroName
=
protocol.GetString
(1);
/*檢查是否可以開始*/
player.tempData.room.ChoosedHero
(player,heroName);
}5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果在HandleMatc5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果每當(dāng)有一個(gè)玩家提交選擇英雄協(xié)議時(shí)進(jìn)行判斷,是否可以開始戰(zhàn)斗。在Room類中添加相關(guān)方法,代碼如下。/*選擇英雄*/
public
void
ChoosedHero
(Player
player,
string
heroName)
{
//修改玩家臨時(shí)數(shù)據(jù)
player.tempData.heroName
=
heroName;
//當(dāng)前房間中準(zhǔn)備的玩家數(shù)量+1
readyNum++;
/*是否可以開始游戲*/
int
beginNum
=
playerlist.Count;
Console.WriteLine
(readyNum+"位玩家已選擇英雄");
//如果準(zhǔn)備的玩家>=所有玩家,則可以開始
if
(readyNum
>=
beginNum)
{
Console.WriteLine
("所有玩家選擇完畢,開始戰(zhàn)斗!");
StartFight
();
}
}5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果每當(dāng)有一個(gè)玩家提交選擇5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果當(dāng)所有玩家都準(zhǔn)備完畢時(shí),向所有玩家發(fā)送游戲開始協(xié)議.在Room類中添加方法,代碼如下。
/*開始游戲*/
public
void
StartFight
()
{
/*構(gòu)建fight協(xié)議*/
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("fight");
status
=
Status.Fight;
int
teamPos1
=
1;
int
teamPos2
=
1;
lock
(playerlist)
{
protocol.AddInt
(playerlist.Count);
/*將每一個(gè)玩家的信息逐一添加到協(xié)議中*/
foreach
(Player
p
in
playerlist.Values)
{
/*玩家ID*/
protocol.AddString
(p.id);5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果當(dāng)所有玩家都準(zhǔn)備完畢時(shí)5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果
/*選擇的英雄*/
protocol.AddString
(p.tempData.heroName);
/*所在隊(duì)伍*/
protocol.AddInt
(p.tempData.team);
/*隊(duì)伍位置*/
if
(p.tempData.team
==
1)
protocol.AddInt
(teamPos1++);
else
protocol.AddInt
(teamPos2++);
/*修改所有玩家的臨時(shí)數(shù)據(jù)*/
p.tempData.status
=
PlayerTempData.Status.Fight;
p.tempData.isAlive
=
true;
}
/*廣播*/
Broadcast
(protocol);
}
}5實(shí)現(xiàn)準(zhǔn)備功能2.服務(wù)端處理準(zhǔn)備結(jié)果
/*選5實(shí)現(xiàn)準(zhǔn)備功能3.客戶端處理回發(fā)協(xié)議當(dāng)服務(wù)端確定可以開始游戲時(shí),會(huì)向房間中每一個(gè)玩家發(fā)送一個(gè)fight協(xié)議,客戶端接收fight協(xié)議,開始處理戰(zhàn)場。添加協(xié)議監(jiān)聽并在關(guān)閉面板時(shí)注銷,代碼如下。……
/*添加監(jiān)聽*/
NetMgr.instance.msgDist.AddListener
("fight",
RecvFight);
}在OnClosing方法中刪除監(jiān)聽,代碼如下。
public
override
void
OnClosing
()
{
NetMgr.instance.msgDist.DelListener
("fight",
RecvFight);
}5實(shí)現(xiàn)準(zhǔn)備功能3.客戶端處理回發(fā)協(xié)議當(dāng)服務(wù)端確定可以開始游5實(shí)現(xiàn)準(zhǔn)備功能3.客戶端處理回發(fā)協(xié)議實(shí)現(xiàn)RecvFight方法,代碼如下。/*處理fight協(xié)議*/
public
void
RecvFight
(ProtocolBase
protocol)
{
ProtocolStr
proto
=
(ProtocolStr)protocol;
/*開始戰(zhàn)斗*/
PanelMgr.instance.OpenPanel<FightPanel>
();
PanelMgr.instance.ClosePanel
(this);
//初始化戰(zhàn)場,稍后實(shí)現(xiàn)
//
BattleManager.instance.StartBattle
(proto);
}5實(shí)現(xiàn)準(zhǔn)備功能3.客戶端處理回發(fā)協(xié)議實(shí)現(xiàn)RecvFight6實(shí)現(xiàn)戰(zhàn)場管理功能1.創(chuàng)建BattleManager戰(zhàn)場管理類添加BattleManager.cs腳本用來處理戰(zhàn)場布置,代碼如下。using
System.Collections;
using
System.Collections.Generic;
using
UnityEngine;
public
class
BattleManager
:
MonoBehaviour
{
/*角色的預(yù)制體*/
public
GameObject
archerPre;
/*戰(zhàn)場中的所有玩家*/
public
Dictionary<string,BattleArcher>
list
=
new
Dictionary<string,
BattleArcher>
();
/*單例*/
public
static
BattleManager
instance;
/*皮膚*/
public
Material
mat1,mat2;
void
Awake
()
{
instance
=
this;
}
}6實(shí)現(xiàn)戰(zhàn)場管理功能1.創(chuàng)建BattleManager戰(zhàn)場管6實(shí)現(xiàn)戰(zhàn)場管理功能2.添加初始化戰(zhàn)場的方法用StartBattle
方法解析fight協(xié)議,實(shí)例化協(xié)議中的每個(gè)玩家,代碼如下。
/*開始戰(zhàn)斗*/
/*處理一切戰(zhàn)斗準(zhǔn)備和預(yù)設(shè)*/
public
void
StartBattle
(ProtocolStr
proto)
{
/*解析協(xié)議*/
string
protoName
=
proto.GetString
(0);
int
count
=
proto.GetInt
(1);
//玩家總數(shù)
//清理場景
ClearBattle
();
//實(shí)例化每一個(gè)玩家
for
(int
i
=
0;
i
<
count;
i++)
{
string
id
=
proto.GetString
(4
*
i
+
2);
string
heroName
=
proto.GetString
(4
*
i
+
3);
int
team
=
proto.GetInt
(4
*
i
+
4);
/*出生點(diǎn)ID*/
int
swopID
=
proto.GetInt
(4
*
i
+
5);
//實(shí)例化角色
GenerateBattleHero
(id,
heroName,
team,
swopID);
}
}6實(shí)現(xiàn)戰(zhàn)場管理功能2.添加初始化戰(zhàn)場的方法用StartBa6實(shí)現(xiàn)戰(zhàn)場管理功能3.添加清理戰(zhàn)場方法每次開啟新戰(zhàn)斗之前需要清理戰(zhàn)場,包括清空玩家列表,恢復(fù)主攝像機(jī)的跟隨狀態(tài),銷毀所有角色和輔助物體(如準(zhǔn)心)。添加ClearBattle方法,代碼如下。public
void
ClearBattle
()
{
//清除玩家列表
list.Clear
();
//恢復(fù)主攝像機(jī)父級(jí)
Camera.main.transform.SetParent
(transform);
/*銷毀所有的角色*/
GameObject[]
heros
=
GameObject.FindGameObjectsWithTag
("Archer");
for
(int
i
=
0;
i
<
heros.Length;
i++)
Destroy
(heros
[i]);
/*銷毀所有的輔助物體*/
foreach(GameObject
g
in
GameObject.FindGameObjectsWithTag
("Helper"))
GameObject.Destroy(g);
}6實(shí)現(xiàn)戰(zhàn)場管理功能3.添加清理戰(zhàn)場方法每次開啟新戰(zhàn)斗之前需6實(shí)現(xiàn)戰(zhàn)場管理功能4.創(chuàng)建角色名稱由于是多人對(duì)戰(zhàn),為了更好地識(shí)別隊(duì)友和敵人,可以在角色的頭上增加一個(gè)3Dtext模型,并且讓模型始終面向主攝像機(jī)。在Archer中添加子物體3DText,重命名為ID,Text字體大小設(shè)置為0.3,Position設(shè)為(0,1.32,0)6實(shí)現(xiàn)戰(zhàn)場管理功能4.創(chuàng)建角色名稱由于是多人對(duì)戰(zhàn),為了更好6實(shí)現(xiàn)戰(zhàn)場管理功能4.創(chuàng)建角色名稱為了讓名稱一直面向玩家,需要給ID添加一個(gè)腳本FaceToCamera.cs,代碼如下。using
System.Collections;
using
System.Collections.Generic;
using
UnityEngine;
public
class
FaceToCamera
:
MonoBehaviour
{
void
Update
()
{
transform.rotation
=
Camera.current.transform.rotation;
}
}6實(shí)現(xiàn)戰(zhàn)場管理功能4.創(chuàng)建角色名稱為了讓名稱一直面向玩家,6實(shí)現(xiàn)戰(zhàn)場管理功能5.創(chuàng)建出生點(diǎn)游戲設(shè)定有兩組隊(duì)伍,每隊(duì)兩人。地圖上需要預(yù)先設(shè)置好玩家的出生點(diǎn),在場景中新建空游戲?qū)ο骃pawn,如圖6-6-2所示。具體位置玩家可以自己設(shè)置,注意出生點(diǎn)不可以放到地形的下面,不然角色出生的時(shí)候會(huì)掉出地圖。6實(shí)現(xiàn)戰(zhàn)場管理功能5.創(chuàng)建出生點(diǎn)游戲設(shè)定有兩組隊(duì)伍,每隊(duì)兩6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家GenerateBattleHero
主要實(shí)現(xiàn)以下幾點(diǎn):①實(shí)例化角色模型,并將模型放到對(duì)應(yīng)出生點(diǎn)的位置。②為角色添加控制組件,為主角添加PlayerCtrl,為其他角色添加NetCtrl。③為主角設(shè)置相機(jī)跟隨。④為其他角色設(shè)置剛體。⑤針對(duì)不同隊(duì)伍,設(shè)置材質(zhì)和ID的顏色。添加GenerateBattleHero方法,代碼如下。
/*實(shí)例化戰(zhàn)場角色*/
void
GenerateBattleHero
(string
id,
string
heroName,
int
team,
int
swopID)
{
/*獲取出生點(diǎn)*/
Transform
sp
=
GameObject.Find
("Spawn").transform;
Transform
swopTrans;
if
(team
!=
1
&&
team
!=
2)
{
Debug.LogError
("team的格式不正確");
return;
}6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家GenerateBattl6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
if
(swopID
<
1
||
swopID
>
5)
{
Debug.LogError
("swopID的格式不正確");
return;
}
//查找出生點(diǎn)對(duì)象
swopTrans
=
sp.GetChild
(team
-
1).GetChild
(swopID
-
1);
if
(swopTrans
==
null)
{
Debug.LogError
("GenerateBattleHero出生點(diǎn)錯(cuò)誤!");
return;
}
if
(archerPre
==
null)
{
Debug.LogError
("GenerateBattleHero找不到預(yù)制體!");
return;
}
6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
if
(swopI6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
/*實(shí)例化角色*/
//實(shí)例化模型
GameObject
heroObj
=
(GameObject)Instantiate
(archerPre);
//名稱
heroO
=
id;
/*位置*/
heroObj.transform.localPosition
=
Vector3.zero;
heroObj.transform.position
=
swopTrans.position;
heroObj.transform.rotation
=
swopTrans.rotation;
/*添加組件*/
//如果這個(gè)是玩家自身
if
(id
==
GameMgr.instance.id)
{
//添加玩家控制器
PlayerCtrl
pc=
heroObj.AddComponent<PlayerCtrl>
();
pc.aimPoint=Resources.Load("Prefabs/AimMark",typeof(GameObject))as
GameObject;
pc.arrowPrefab=Resources.Load("Prefabs/Arrow",typeof(GameObject))as
GameObject;
6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
/*實(shí)例化角色*/6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
//附著主攝像機(jī)
Camera.main.GetComponent<CameraTracePlayer>
().SetTarget
(heroObj.transform);
}
else
{
//添加網(wǎng)絡(luò)控制器
NetCtrl
nc=
heroObj.AddComponent<NetCtrl>
();
nc.arrowPrefab=Resources.Load("Prefabs/Arrow",typeof(GameObject))as
GameObject;
/*設(shè)置剛體*/
Rigidbody
rrb
=
heroObj.GetComponent<Rigidbody>
();
rrb.useGravity
=
false;
rrb.isKinematic
=
true;
}
/*根據(jù)隊(duì)伍處理材質(zhì)*/
//如果是隊(duì)伍1
if
(team
==
1)
{
6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
//附著主6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
Renderer[]
rs
=
heroObj.GetComponentsInChildren<Renderer>
();
//設(shè)置ID之外模型的材質(zhì)
foreach
(Renderer
r
in
rs)
{
if(!="ID")
r.material
=
mat1;
}
/*設(shè)置ID的顏色*/
TextMesh
tm
=
heroObj.transform.Find
("ID").GetComponent<TextMesh>();
tm.color
=
Color.red;
tm.text
=
id;
}
else
{
Renderer[]
rs
=
heroObj.GetComponentsInChildren<Renderer>
();
//設(shè)置ID之外模型的材質(zhì)
foreach
(Renderer
r
in
rs)
{
if(!="ID")
r.material
=
mat2;
}
6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
Rendere6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
/*設(shè)置ID的顏色*/
TextMesh
tm
=
heroObj.transform.Find
("ID").GetComponent<TextMesh>();
tm.color
=
Color.blue;
tm.text
=
id;
}
//列表處理
BattleArcher
ba
=
new
BattleArcher
();
ba.archer
=
heroObj.GetComponent<Archer>
();
ba.team
=
team;
list.Add
(id,
ba);
}6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家
/*設(shè)置ID的6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家using
System.Collections;
using
System.Collections.Generic;
using
UnityEngine;
public
class
NetCtrl
:
MonoBehaviour
{
}NerCtrl是網(wǎng)絡(luò)同步控制腳本,被添加在非玩家控制的其他角色身上。腳本具體的內(nèi)容會(huì)在項(xiàng)目7中實(shí)現(xiàn),本任務(wù)中只創(chuàng)建NerCtrl腳本,代碼如下。6實(shí)現(xiàn)戰(zhàn)場管理功能6.實(shí)例化玩家using
System.6實(shí)現(xiàn)戰(zhàn)場管理功能7.添加相機(jī)動(dòng)態(tài)跟隨腳本using
System.Collections;
using
System.Collections.Generic;
using
UnityEngine;
public
class
CameraTracePlayer
:
MonoBehaviour{
public
int
type
=
0;
public
Transform
player;
public
void
SetTarget
(Transform
target)
{
Transform
head
=
target.Find
("Body").Find
("Head");
transform.SetParent
(head);
transform.localPosition
=
new
Vector3
(0,
0.075f,
0.115f);
transform.localRotation
=
Quaternion.identity;
}
void
Start
()
{
if
(type
>
0)
SetTarget
(player);
}
}為了讓相機(jī)動(dòng)態(tài)地變成新建角色的子物體,不能再用以前直接拖動(dòng)的方式,而是用腳本去實(shí)現(xiàn),新建CameraTracePlayer腳本,并添加到主相機(jī)上,代碼如下。6實(shí)現(xiàn)戰(zhàn)場管理功能7.添加相機(jī)動(dòng)態(tài)跟隨腳本using
SyThankYOU!Thank騰訊云游戲應(yīng)用開發(fā)騰訊云游戲應(yīng)用開發(fā)實(shí)現(xiàn)登錄功能01任務(wù)實(shí)現(xiàn)獲取自身數(shù)據(jù)功能02任務(wù)實(shí)現(xiàn)注冊功能03任務(wù)實(shí)現(xiàn)業(yè)務(wù)邏輯模塊項(xiàng)目6實(shí)現(xiàn)匹配功能04任務(wù)實(shí)現(xiàn)準(zhǔn)備功能05任務(wù)實(shí)現(xiàn)戰(zhàn)場管理功能06任務(wù)實(shí)現(xiàn)登錄功能01任務(wù)實(shí)現(xiàn)獲取自身數(shù)據(jù)功能02任務(wù)實(shí)現(xiàn)注冊功能學(xué)習(xí)目標(biāo)
實(shí)現(xiàn)游戲的幾個(gè)重要業(yè)務(wù)邏輯
掌握CS模式下協(xié)議的使用
掌握登錄注冊功能的基本實(shí)現(xiàn)方法學(xué)習(xí)目標(biāo)實(shí)現(xiàn)游戲的幾個(gè)重要業(yè)務(wù)邏輯1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法當(dāng)用戶在登錄界面中單擊“登錄”按鈕后,后臺(tái)嘗試與服務(wù)器建立連接,連接成功后發(fā)送登錄協(xié)議,協(xié)議格式為login;id;password;。修改LoginPanel.cs腳本中的OnLoginClick
方法,代碼如下。/*登錄按鈕事件*/
public
void
OnLoginClick
()
{
if
(idInput.text
==
""
||
pwInput.text
==
"")
{
/*打開提示框*/
PanelMgr.instance.OpenPanel<TipPanel>
("用戶名密碼不能為空!");
return;
}
//如果服務(wù)器沒有連接,連接服務(wù)器
if
(NetMgr.instance.status
!=
NetMgr.Status.Connected)
{
NetMto
=
new
ProtocolStr
();
/*連接*/
if
(!NetMgr.instance.Connect
())
PanelMgr.instance.OpenPanel<TipPanel>
("連接服務(wù)器失敗!");
}
1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法當(dāng)用戶在登錄界面中單1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法
//發(fā)送登錄協(xié)議
ProtocolStr
protocol
=
new
ProtocolStr
();
protocol.AddString
("login");
protocol.AddString
(idInput.text);
protocol.AddString
(pwInput.text);
/*一次性監(jiān)聽*/
NetMgr.instance.Send
(protocol,
OnLoginBack);
}1實(shí)現(xiàn)登錄功能1.實(shí)現(xiàn)客戶端請求登錄方法
//發(fā)送登1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法在HandleConnMsg類中添加Msglogin方法,當(dāng)服務(wù)端收到login協(xié)議時(shí),分發(fā)給Mgslogin方法處理
public
void
Msglogin
(Conn
conn,
ProtocolBase
protoBase)
{
string
id,
pw;
ProtocolStr
protocol
=
(ProtocolStr)protoBase;
id
=
protocol.GetString
(1);
pw
=
protocol.GetString
(2);
/*構(gòu)建返回協(xié)議*/
ProtocolStr
protocolRet
=
new
ProtocolStr
();
protocolRet.AddString
("login");
/*數(shù)據(jù)庫校驗(yàn)*/
//如果用戶名密碼校驗(yàn)失敗
if
(!DataMgr.instance.CheckPassWord
(id,
pw))
{
Console.WriteLine
("[Msglogin]登錄失敗:用戶名和密碼錯(cuò)誤"
+
conn.GetAddress
());
protocolRet.AddInt
(-1);//返回失敗結(jié)果
conn.Send
(protocolRet);
return;
}
1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法在HandleC1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法
if
(!ServNet.instance.KickOff
(id))
{
//如果踢下線失敗
Console.WriteLine
("[Msglogin]登錄失敗:擠下線失敗"
+
conn.player.id);
//返回失敗結(jié)果
protocolRet.AddInt
(-1);
conn.Send
(protocolRet);
return;
}
PlayerData
playerData
=
DataMgr.instance.GetPlayerData
(id);
//獲取玩家數(shù)據(jù)
if
(playerData
==
null)
{
Console.WriteLine
("[Msglogin]登錄失敗:獲取賬戶信息失敗"
+
conn.player.id);
protocolRet.AddInt
(-1);
//返回失敗結(jié)果
conn.Send
(protocolRet);
return;
}
conn.player
=
new
Player
(id,
conn,
playerData);
//登入賬戶,加載數(shù)據(jù)
protocolRet.AddInt
(0);
//返回成功結(jié)果
conn.Send
(protocolRet);
}1實(shí)現(xiàn)登錄功能2.實(shí)現(xiàn)服務(wù)端登錄協(xié)議處理方法
i1實(shí)現(xiàn)登錄功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法添加OnLoginBack方法
/*登錄協(xié)議回執(zhí)*/
public
void
OnLoginBack
(ProtocolBase
protocol)
{
/*構(gòu)建協(xié)議*/
ProtocolStr
proto
=
(ProtocolStr)protocol;
/*校驗(yàn)登錄結(jié)果*/
int
result
=
proto.GetInt
(1);
if
(result
==
0)
{
GameMgr.instance.id
=
idInput.text;
//保存賬號(hào)ID
PanelMgr.instance.OpenPanel<TipPanel>
("登錄成功!");
PanelMgr.instance.OpenPanel<LobbyPanel>
();
/*進(jìn)入游戲大廳*/
PanelMgr.instance.ClosePanel
(this);
}
else
{
NetMgr.instance.Close
();
//斷開連接
PanelMgr.instance.OpenPanel<TipPanel>
("登錄失敗,請檢查用戶名密碼!");
}
}1實(shí)現(xiàn)登錄功能3.實(shí)現(xiàn)客戶端處理回發(fā)結(jié)果方法添加OnLogi1實(shí)現(xiàn)登錄功能4.實(shí)現(xiàn)踢下線模塊如果該角色在游戲中,則把它踢下線。并且發(fā)送Logout協(xié)議,向被踢下線的客戶端發(fā)送通知。在ServNet中添加KickOff方法,代碼如下。
/*如果某id已經(jīng)在線就踢下線*/
public
bool
KickOff
(string
id)
{
for
(int
i
=
0;
i
<
conns.Length;
i++)
{
if
(conns
[i]
==
null)
continue;
if
(!conns
[i].isUse)
continue;
if
(conns
[i].player
==
null)
continue;
/*如果該玩家已經(jīng)在線*/
if
(conns
[i].player.id
==
id)
{
lock
(conns[i].player)
{
Console.WriteLine
("檢查到"+id+"已在線,踢下線");
/*通知客戶端下線*/
ProtocolStr
protocolLogout
=
new
ProtocolStr
()
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 規(guī)上工業(yè)調(diào)研報(bào)告5篇
- 《保險(xiǎn)與理財(cái)》課件
- 期末考前動(dòng)員會(huì)的講話稿(35篇)
- 《銷售語言技巧培訓(xùn)》課件
- 國共關(guān)系的歷史反思與現(xiàn)實(shí)走向分析
- 【大學(xué)課件】單片機(jī)原理與接口技術(shù)課件 單片機(jī)系統(tǒng)模擬量及其他擴(kuò)展技術(shù)
- 植物的無性生殖課件用
- 2025屆福建省福州市羅源縣第一中學(xué)高考臨考沖刺數(shù)學(xué)試卷含解析
- 2025屆甘肅省涇川縣第三中學(xué)高考全國統(tǒng)考預(yù)測密卷語文試卷含解析
- 來賓市重點(diǎn)中學(xué)2025屆高三第二次聯(lián)考數(shù)學(xué)試卷含解析
- GB/T 15900-1995化學(xué)試劑偏重亞硫酸鈉(焦亞硫酸鈉)
- GB/T 15686-2008高粱單寧含量的測定
- GB/T 12615.3-2004封閉型平圓頭抽芯鉚釘06級(jí)
- 拒收紅包、表揚(yáng)信等登記表
- 《血糖儀POCT臨床操作規(guī)范》考試題及答案
- GB 16715.4-2010瓜菜作物種子第4部分:甘藍(lán)類
- GA/T 1105-2013信息安全技術(shù)終端接入控制產(chǎn)品安全技術(shù)要求
- 成年依戀量表
- 中石化至烏茲別克斯坦車用潤滑油項(xiàng)目分析
- KTV管理培訓(xùn)課件(共48張)
- 全科醫(yī)學(xué)的臨床思維【-】課件
評(píng)論
0/150
提交評(píng)論