日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十)

發(fā)布時(shí)間:2025/7/25 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

在線(xiàn)演示地址:Silverlight+WCF 新手實(shí)例 象棋 在線(xiàn)演示

?

上上一節(jié),就是二十八節(jié):Silverlight+WCF 新手實(shí)例 象棋 該誰(shuí)下棋-A下B停(二十八)

?

我們實(shí)現(xiàn)了“開(kāi)始”游戲后,對(duì)棋子的限制,A下B停

這節(jié),我們要實(shí)現(xiàn):B下A停,[同時(shí),傳遞棋步,對(duì)方收到棋步,要反轉(zhuǎn)棋步坐標(biāo),自動(dòng)移動(dòng)棋子]

所以呢,這節(jié)我們要實(shí)現(xiàn)的東西是比上上一節(jié)相對(duì)多一點(diǎn)。

?

少?gòu)U話(huà),開(kāi)始了:

按流程來(lái)了,A移動(dòng)棋子之后,要干點(diǎn)什么事呢?

//-------這是一個(gè)AB同樣的循環(huán)流程-----

1:自己不能再動(dòng)了,IsCanMove=false;

2:要記錄移動(dòng)坐標(biāo)

3:傳遞坐標(biāo)給對(duì)方

4:對(duì)方要接收坐標(biāo)->反轉(zhuǎn)坐標(biāo)[對(duì)方的坐標(biāo)對(duì)自己來(lái)說(shuō),肯定是相反的啦,自己把頭反過(guò)來(lái)看下棋盤(pán)就有點(diǎn)清楚了]

5:對(duì)方系統(tǒng)自動(dòng)移動(dòng)棋子

6:對(duì)方的IsCanMove=true

7:然后到對(duì)方下棋了。

8:對(duì)方下棋之后呢?Go to 1

//-----又回到開(kāi)始,不斷的循環(huán)------

我們先來(lái)增加一個(gè)用于傳遞棋步類(lèi),既然是傳遞的,當(dāng)然得在WCF端新建了,回到和Player一樣位置[就是DataContract文件夾下了]:

添加文件類(lèi)名:MoveStep.cs

namespace ?GameService
{
????
/// ? <summary>
????
/// ?WCF?傳遞的棋步?by?路過(guò)秋天
????
/// ? http://cyq1162.cnblogs.com
????
/// ? </summary>
???? public ? class ?MoveStep
????{

????}
}

?

當(dāng)了棋步傳遞使者,自然得屬性加身了,看看加了什么屬性:

ID:這個(gè)用于標(biāo)識(shí)是第幾步,好像沒(méi)怎么用到

Name:名稱(chēng),是馬還是炮

ColorValue:什么顏色的

下面四個(gè)一看就知,為什么不用Point傳遞,和那個(gè)ColorValue一樣,WCF的Point和Silverlight客戶(hù)端的名稱(chēng)空間不一樣[馬走一下]

FromX

FromY

ToX

ToY

于是一個(gè)一個(gè)的敲完就像下面這樣了:


using ?System.Runtime.Serialization;
namespace ?GameService {
????
/// ? <summary>
????
/// ?WCF?傳遞的棋步?by?路過(guò)秋天
????
/// ? http://cyq1162.cnblogs.com
????
/// ? </summary>
???? public ? class ?MoveStep
????{
????????
/// ? <summary>
????????
/// ?棋的步數(shù)
????????
/// ? </summary>
????????[DataMember]
????????
public ? int ?ID
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的原始X位置
????????
/// ? </summary>
????????[DataMember]
????????
public ? double ?FromX
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的原始Y位置
????????
/// ? </summary>
????????[DataMember]
????????
public ? double ?FromY
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的移動(dòng)X位置
????????
/// ? </summary>
????????[DataMember]
????????
public ? double ?ToX
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的移動(dòng)X位置
????????
/// ? </summary>
????????[DataMember]
????????
public ? double ?ToY
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的名稱(chēng)
????????
/// ? </summary>
????????[DataMember]
????????
public ? string ?Name
????????{
????????????
get ;
????????????
set ;
????????}
????????
/// ? <summary>
????????
/// ?棋的移顏色值
????????
/// ? </summary>
????????[DataMember]
????????
public ? int ?ColorValue
????????{
????????????
get ;
????????????
set ;
????????}
????}
}

?

我們習(xí)慣了一直都傳遞Player,所以,為Player加個(gè)屬性了:

namespace ?GameService
{
????
/// ? <summary>
????
/// ?游戲玩家?by?路過(guò)秋天
????
/// ? </summary>
????[DataContract]
????
public ? class ?Player
????{
????????
// ...省略其它屬性...
????????[DataMember]
????????
public ?MoveStep?Step
????????{
????????????
get ;
????????????
set ;
????????}
???????
????}
}

?

同時(shí)啊,同時(shí)啊,剛剛想起來(lái)-_-...,我們要為房間添加一個(gè)棋子列表,記錄每步棋步,不然剛進(jìn)房間的人看西北風(fēng)的啊。

同時(shí)添加了構(gòu)造函數(shù),初始化一下List,不然Null魂就會(huì)老跟著你。

namespace ?GameService
{
????[DataContract]
????
public ? class ?Room
????{
????????
public ?Room()
????????{
????????????StepList?
= ? new ?List < MoveStep > ();
????????}
????????
/// ? <summary>
????????
/// ?房間的棋譜
????????
/// ? </summary>
????????[DataMember]
????????
public ?List < MoveStep > ?StepList
????????{
????????????
get ;
????????????
set ;
????????}
????????
// ...省略下面N個(gè)屬性...
??????}
}

?

?

OK,傳遞使者和兩個(gè)XX都有了,那我們要在WCF端建立傳遞和接收的接口了,這下我們只要傳遞Player來(lái)來(lái)去去的就行了:

IService.cs添加接口:


namespace ?GameService
{
????[ServiceContract(CallbackContract?
= ? typeof (ICallBack))] // 頭頂上這里寫(xiě)明了回調(diào)是ICallBack
???? public ? interface ?IService
????{
???????
// ...省略上面N個(gè)接口...
????????[OperationContract(IsOneWay? = ? true )]
????????
void ?MoveStep(Player?player);

????}
}

?

ICallBack.cs添加接口:

namespace ?GameService
{
????
interface ?ICallBack
????{
????????
// ...省略上面N個(gè)接口...
????????[OperationContract(IsOneWay? = ? true )]
????????
void ?NotifyMoveStep(Player?player); // 通知接收棋步
????}
}

?

OK,接著我們一如既往的實(shí)現(xiàn)MoveStep接口方法

Service.svc.cs,輕輕松松就完工,四行代碼搞定。

? public ? void ?MoveStep(Player?player)
????????{
????????????Room?room?
= ?roomList[player.RoomID];
????????????player.Step.ID?
= ?room.StepList.Count? + ? 1 ;
????????????room.StepList.Add(player.Step);
????????????Notify.Game(player,?GameType.Move);
????????}

?

那個(gè)Notify.Game我們上節(jié)都有的了,我們回到Notify里補(bǔ)一個(gè)Switch里的Case GameType.Move的方法就行了:

? internal ? static ? void ?Game(Player?player,?GameType?type)
????????{
????????????
switch ?(type)
????????????{
????????????????
case ?GameType.Start: // 通知對(duì)方玩家開(kāi)始游戲
????????????????????
// ...上上節(jié)實(shí)現(xiàn)了...
???????????????????? break ;
????????????????
case ?GameType.Move: // 通知移動(dòng)了,房間內(nèi)人手一份
???????????????????? foreach ?(KeyValuePair < Guid,?Player > ?item? in ?Service.playerList[player.RoomID])
????????????????????{
???????????????????????item.Value.CallBack.NotifyMoveStep(player);
????????????????????}
????????????????????
break ;
????????????????
case ?GameType.End:
????????????????????
break ;
????????????}
????????}

?

OK,到此,服務(wù)端完成了,編繹,更新引用:

接著我們回到客戶(hù)端,要開(kāi)始發(fā)送和接收了:

哪里加發(fā)送呢?我們棋步在哪里移動(dòng),就在哪里發(fā)送了

哪里移動(dòng)呢?想啦啦找啦啦:棋子移動(dòng)類(lèi)ChessAction里的MoveTo方法,我們要在里面添加一個(gè)移動(dòng)后觸發(fā)的事件

可是怎么觸發(fā)?單獨(dú)的類(lèi)里,是拿不到App.Client對(duì)象,更別說(shuō)傳遞了到WCF了,于是,大哥啊,代理快出來(lái):

還記得以前Silverlight+WCF 新手實(shí)例 象棋 主界面-控件消息傳遞(二十六),不記得回去看看了。

?

我們?cè)贑hessAction里添加一個(gè)代理事件:

看,我們定義代理事件之后只增加一句代碼,在移動(dòng)后直接調(diào)用,至于怎么實(shí)現(xiàn)的,我們?nèi)焕?#xff0c;反正有人幫我干這事。

? /// ? <summary>
????
/// ?棋子動(dòng)作類(lèi)?by?路過(guò)秋天
????
/// ? </summary>
???? public ? class ?ChessAction
????{
????????
public ? delegate ? void ?HelpMoveStep(Chessman?chessman,?Point?movePoint);
????????
public ? event ?HelpMoveStep?HelpMoveStepEvent;
???????
????????
????????
public ? bool ?MoveTo(Chessman?chessman,?Point?moveTo)
????????{
????????????
if ?(Rule.IsCanMove(chessman,?moveTo))
????????????{
????????????????chessman.ReadyMove?
= ? false ;
????????????????chessman.chessman.Background?
= ? null ;
????????????????PlayMove(chessman,?moveTo);
????????????????chessman.MovePoint?
= ?moveTo;
????????????????HelpMoveStepEvent(chessman,?moveTo);
// 這里增加一句
???????????????? return ? true ;
????????????}
????????????
return ? false ;
????????}
?????????
// ...?其它省略N多...
?}

?

OK,我們回到Chess.xaml.cs里,我們要實(shí)現(xiàn)做下代理人:

public ?Chess()
????????{
???????????
// ..省略N行...
????????????chess.Action.HelpMoveStepEvent? += ? new ?ChessNewInstance.ChessAction.HelpMoveStep(Action_HelpMoveStepEvent);
????????????App.chess?
= ?chess; // 為全局對(duì)象賦值
????????}

????????
void ?Action_HelpMoveStepEvent(ChessNewInstance.Chessman?chessman,?Point?moveTo)
????????{
????????????MoveStep?step?
= ? new ?MoveStep();
????????????step.FromX?
= ?chessman.MovePoint.X;
????????????step.FromY?
= ?chessman.MovePoint.Y;
????????????step.ToX?
= ?moveTo.X;
????????????step.ToY?
= ?moveTo.Y;
????????????step.ColorValue?
= ?chessman.Color? == ?Colors.Red? ? ? 1 ?:? 2 ;
????????????step.Name?
= ?chessman.Name;
????????????App.player.Step?
= ?step; // 附加棋步
????????????App.client.MoveStepAsync(App.player);
????????????chess.IsCanMove?
= ? false ;
????????}

?

設(shè)置完雜七雜八的參數(shù)后,把Step放到Player身上,就傳遞到服務(wù)端了,然后設(shè)置一下IsCanMove=false;

?

發(fā)送棋步就搞完了,接下來(lái)要接收棋步了,不過(guò)在接收棋上之前,我們要先完成一個(gè)函數(shù),反轉(zhuǎn)坐標(biāo):

我們回到Chess.cs象棋類(lèi)里,添加方法,"馬走一步",太簡(jiǎn)單了:

? /// ? <summary>
????????
/// ?反轉(zhuǎn)棋子坐標(biāo)
????????
/// ? </summary>
???????? public ?Point?ReverseArray(Point?point)
????????{
????????????point.X?
= ? 8 ? - ?point.X;
????????????point.Y?
= ? 9 ? - ?point.Y;
????????????
return ?point;
????????}

?

別急,我們還要添加一個(gè)自動(dòng)移動(dòng)的方法:

回到ChessAction.cs里:

需要解釋代碼么?不需要吧

解釋:既然是系統(tǒng)自動(dòng)移動(dòng),就不用判斷什么規(guī)則了,直接把棋子移過(guò)去,如果移動(dòng)到的另一個(gè)點(diǎn)有棋子,就移掉,然后設(shè)置一下坐標(biāo)。

? /// ? <summary>
????????
/// ?系統(tǒng)自動(dòng)移動(dòng)棋子
????????
/// ? </summary>
???????? public ? void ?AutoMoveTo(Point?from,?Point?to)
????????{
????????????Chessman?chessman?
= ?Parent.FindChessman(from);
????????????Chessman?eatchessman?
= ?Parent.FindChessman(to);
????????????
if ?(chessman? != ? null )
????????????{
????????????????PlayMove(chessman,?to);
????????????????chessman.MovePoint?
= ?to;
????????????????
if ?(eatchessman? != ? null )
????????????????{
????????????????????eatchessman.GoToDead();
????????????????}
????????????}
????????}

?

?

好了,可以接收了,要實(shí)現(xiàn)了,眼睛睜大點(diǎn),回到Chess.xaml.cs:

? public ? partial ? class ?Chess?:?UserControl
????{
????????ChessNewInstance.Chess?chess;
// 這里我們同時(shí)把它提到全局對(duì)象
???????? public ?Chess()
????????{
???????????
// ...省略N行...
????????????App.client.NotifyMoveStepReceived? += ? new ?EventHandler < NotifyMoveStepReceivedEventArgs > (client_NotifyMoveStepReceived);
????????????App.chess?
= ?chess; // 為全局對(duì)象賦值

??????????
????????}

????????
void ?client_NotifyMoveStepReceived( object ?sender,?NotifyMoveStepReceivedEventArgs?e)
????????{
????????????
if ?(App.player.ID? != ?e.player.ID) // 非自己
????????????{
????????????????GameService.MoveStep?step?
= ?e.player.Step;
????????????????Point?from?
= ? new ?Point(step.FromX,?step.FromY);
????????????????Point?to?
= ? new ?Point(step.ToX,?step.ToY);
????????????????
// 轉(zhuǎn)換坐標(biāo)
???????????????? if ?(e.player.ColorValue? == ? 2 ? || ?App.player.ColorValue? != ? 3 ) // 旁觀(guān)者?黑色棋子
????????????????{
????????????????????from?
= ?chess.ReverseArray(from);
????????????????????to?
= ?chess.ReverseArray(to);
????????????????}
????????????????chess.Action.AutoMoveTo(from,?to);
????????????????
if ?(App.player.ColorValue? != ? 3 ) // 下棋者
????????????????{
????????????????????chess.IsCanMove?
= ? true ;
????????????????}
????????????}
????????}
????????
// ....省略N行...
????}

?

看清楚,就是轉(zhuǎn)換坐標(biāo),然后移動(dòng)棋子,設(shè)置一下IsCanMove。

OKOKOK,代碼終于全部寫(xiě)完了,可以F5運(yùn)行看效果了:

“馬再走一步”,上面代碼棋子沒(méi)有自動(dòng)移動(dòng),又要調(diào)試了,不截圖先:

斷點(diǎn)一調(diào)試,發(fā)現(xiàn)接收的點(diǎn)都是一樣的,一步步回去查,終于發(fā)現(xiàn)在MoveTo方法里添加的一行事件位置不對(duì):

看有位置的那兩行,看清楚了。

public ? bool ?MoveTo(Chessman?chessman,?Point?moveTo)
????????{
????????????
if ?(Rule.IsCanMove(chessman,?moveTo))
????????????{
????????????????chessman.ReadyMove?
= ? false ;
????????????????chessman.chessman.Background?
= ? null ;
????????????????PlayMove(chessman,?moveTo);
????????????????HelpMoveStepEvent(chessman,?moveTo);
// 這一行要在上
????????????????chessman.MovePoint? = ?moveTo; // 這一行要在下
????????????????
????????????????
return ? true ;
????????????}
????????????
return ? false ;
????????}

?

OK,現(xiàn)在可以F5看效果了,截圖:

?

OK,本節(jié)到此,打完收工!

順?lè)曛芪?#xff0c;打包源碼:第六階段源碼:點(diǎn)擊下載

?

?

轉(zhuǎn)載于:https://my.oschina.net/secyaher/blog/274172

總結(jié)

以上是生活随笔為你收集整理的Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。