flex 聯機游戲開發 - 四國軍棋游戲:(二)棋盤棋子
玩了太多年的四國游戲,現在,我打算做個四國游戲的flex版,下面的文章與代碼是邊做邊寫的,所以,當我貼出來的時候,說不定我已經將代碼進行重構了,但是,如果你也是一名開發者,我想,設計思路總是對你有參考意義的。
想知道我愛四國的多深,看看引子里的那個文章就知道了。你也可以點擊這兒查看這些文章的全部。中途島之戰 深圳mm.活著viva&&冷血雅雅 。
老規矩,先畫棋盤,一般的軍棋游戲棋盤都利用的圖片做背景,然后判斷鼠標的點擊來定位棋子,現在,我決定不用圖片,直接用flex繪制棋盤,源于兩個方面的原因,一是adobe是做美術出身的,所以,用flex繪制的棋盤基本上在ui上比java,c#繪制的要好看得多,同時,你可以很方便地對棋盤,棋子使用各種濾鏡效果。二是繪制出來的棋盤,本身會減小相當多的開發工作,因為你點擊的如果是棋子,他本身就可以實現事件觸發。將細節處理放到了元部件中。
一,單人棋盤 Layout
public function createBoard():void
{
for (var row:int = 0; row <=xsize; row++) {
var tempArray:Array=new Array(ysize);
gameControl.boardArray[row] =tempArray;
}
//y 軸的線條
for (var i:int=0;i<=ysize;i++)
{
var line:Line=new Line();
line.xFrom=0+padding;
line.xTo=board.width-padding;
line.y=i*(board.height-2*padding)/ysize+padding;
line.stroke=DEFAULT_STROKE;
board.addElement(line);
}
//x 軸的線條
for (var j:int=0;j<=xsize;j++)
{
var line2:Line=new Line();
line2.yFrom=0+padding;
line2.yTo=board.height-padding;
line2.x=j*(board.width-2*padding)/xsize+padding;
line2.stroke=DEFAULT_STROKE;
board.addElement(line2);
}
//營里的線條
for (var x1:int=0;x1<=xsize;x1++)
{
for (var y1:int=0;y1<=ysize;y1++)
{
if ((x1==1&&y1==1)||(x1==3&&y1==3)||(x1==2&&y1==2)||(x1==1&&y1==3)||(x1==3&&y1==1))
{
//畫四個方向的線
board.addElement(drawLine(x1*(board.width-2*padding)/xsize+padding,(x1+1)*(board.width-2*padding)/xsize+padding,y1*(board.height-2*padding)/ysize+padding,(y1+1)*(board.height-2*padding)/ysize+padding));
board.addElement(drawLine(x1*(board.width-2*padding)/xsize+padding,(x1+1)*(board.width-2*padding)/xsize+padding,y1*(board.height-2*padding)/ysize+padding,(y1-1)*(board.height-2*padding)/ysize+padding));
board.addElement(drawLine(x1*(board.width-2*padding)/xsize+padding,(x1-1)*(board.width-2*padding)/xsize+padding,y1*(board.height-2*padding)/ysize+padding,(y1+1)*(board.height-2*padding)/ysize+padding));
board.addElement(drawLine(x1*(board.width-2*padding)/xsize+padding,(x1-1)*(board.width-2*padding)/xsize+padding,y1*(board.height-2*padding)/ysize+padding,(y1-1)*(board.height-2*padding)/ysize+padding));
}
}
}
//默認的棋盤填充,
for (var x:int=0;x<=xsize;x++)
{
for (var y:int=0;y<=ysize;y++)
{
if ((x==1&&y==5)||(x==3&&y==5))
//畫大本營
board.addElement(drawDaBenYing(x,y));
else if ((x==1&&y==1)||(x==3&&y==3)||(x==2&&y==2)||(x==1&&y==3)||(x==3&&y==1))
//畫營
board.addElement(drawYing(x,y));
else
//其它
board.addElement(drawQizhi(x,y));
}
}
}
現在我對決定在每個地方加一個默認的棋子,默認是不可見的,但在棋盤的實際情況應該是這樣的。在測試的時候加入一種顏色,實際情況中應該是選擇alpha為0,這樣,棋子是不可見的,同樣,這個函數也需要傳入用戶的位置,這樣,每個玩家就可以選擇不同顏色的棋子。

//默認的棋盤填充,
for (var x:int=0;x<=xsize;x++)
{
for (var y:int=0;y<=ysize;y++)
{
if ((x==1&&y==5)||(x==3&&y==5))
//畫大本營
board.addElement(drawDaBenYing(x,y));
else if ((x==1&&y==1)||(x==3&&y==3)||(x==2&&y==2)||(x==1&&y==3)||(x==3&&y==1))
//畫營
board.addElement(drawYing(x,y));
else
//其它
board.addElement(drawRect(x,y));
//放一個默認的棋子
board.addElement(drawQizhi(x,y));
}
}
//默認的棋盤填充,
for (var x:int=0;x<=xsize;x++)
{
for (var y:int=0;y<=ysize;y++)
{
if ((x==1&&y==5)||(x==3&&y==5))
//畫大本營
board.addElement(drawDaBenYing(x,y));
else if ((x==1&&y==1)||(x==3&&y==3)||(x==2&&y==2)||(x==1&&y==3)||(x==3&&y==1))
//畫營
board.addElement(drawYing(x,y));
else
//其它
board.addElement(drawRect(x,y));
//放一個默認的棋子
board.addElement(drawQizhi(x,y));
}
}
對不同顏色的棋子,我們再加入一個默認的數組來填充不同用戶的顏色,同樣,我們可以設置這個數組是可變的,當你的上家說,要吃紅子時,實際上紅子對不同位置的玩家是完全不一樣的,有一定的迷惑作用,當然,他可以說,人吃上家或下家,總歸是道高一,魔高一章啊。
//玩家填充
private const TURNARRAY:Array=[new SolidColor(0xff0000,1),new SolidColor(0x00ff00,1),new SolidColor(0x0000ff,1),new SolidColor(0xffcc00,1),new SolidColor(0xffffff,0)];
哦,差點忘了,在游戲中還有另外一種狀態,那就是棋子是覆蓋著的,不可見的。我們也得把這個加上。
二 四人棋盤 Board
現在,每個人的棋盤已經畫好,我們現在需要四個棋盤+一個中間部分來完成整個棋盤的初始化工作,flex對效果的支持現在開始發威,我們只要把這個棋盤放上四份,一份為原始,一份旋轉90,一份旋轉-90,一份旋轉180度,就可以完成4個棋盤的工作,
<s:Group width="660" height="660" left="20" top="20">
<ns1:Layout x="425" y="220" rotation="180">
</ns1:Layout>
<ns1:Layout x="220" y="235" rotation="90">
</ns1:Layout>
<ns1:Layout x="235" y="440">
</ns1:Layout>
<ns1:Layout x="440" y="425" rotation="-90">
</ns1:Layout>
<ns1:CenterGroup x="220" y="220">
</ns1:CenterGroup>
</s:Group>
下面的工作就是畫中間那個部分了。
protected function init(event:FlexEvent):void
{
// TODO Auto-generated method stub
// TODO Auto-generated method stub
//y 軸的線條
BOARD_IMG.source=BoardChess;
BOARD_IMG.fillMode = BitmapFillMode.REPEAT;
for (var i:int=0;i<=2;i++)
{
var line:Line=new Line();
line.xFrom=0;
line.xTo=center.width;
line.y=i*(center.height-2*padding)/2+padding;
line.stroke=DEFAULT_TEDAO_STROKE;
center.addElement(line);
}
//x 軸的線條
for (var j:int=0;j<=2;j++)
{
var line2:Line=new Line();
line2.yFrom=0;
line2.yTo=center.height;
line2.x=j*(center.width-2*padding)/2+padding;
line2.stroke=DEFAULT_TEDAO_STROKE;
center.addElement(line2);
}
//邊角的弧
center.addElement(drawArc(-padding,-padding));
center.addElement(drawArc(-padding,2*(center.height-2*padding)/2+padding));
center.addElement(drawArc(2*(center.height-2*padding)/2+padding,-padding));
center.addElement(drawArc(2*(center.height-2*padding)/2+padding,2*(center.height-2*padding)/2+padding));
//填充,
for (var x:int=0;x<=2;x++)
{
for (var y:int=0;y<=2;y++)
{
var rect:Rect=new Rect();
rect.width=15;
rect.height=15;
rect.x=x*(center.width-2*padding)/2-15/2+padding;
rect.y=y*(center.height-2*padding)/2-15/2+padding;
rect.radiusX=3;
rect.radiusY=3;
rect.stroke=DEFAULT_STROKE;
rect.fill=BOARD_IMG;
center.addElement(rect);
}
}
}
這樣,所有的部分已經完成,我們現在稍微改變一下邏輯,將底紋填充放到主類,在layout類不進行填充。生成的棋局應該就是這樣子的。

三,最終布局
最后,我們將用戶的信息傳入棋盤,并加入一些控制鍵,最終形成的棋盤應該如下
<s:BorderContainer id="board" width="880" height="670" top="20" left="150" horizontalCenter="0">
<ns1:CenterGroup x="320" y="198">
</ns1:CenterGroup>
<ns1:Layout x="530" y="219" rotation="180">
</ns1:Layout>
<ns1:Layout x="341" y="218" rotation="90">
</ns1:Layout>
<ns1:Layout x="340" y="407">
</ns1:Layout>
<ns1:Layout x="529" y="408" rotation="-90">
</ns1:Layout>
<ns1:UserInfo x="221" y="17">
</ns1:UserInfo>
<ns1:UserInfo x="550" y="433">
</ns1:UserInfo>
<ns1:UserInfo x="10" y="228">
</ns1:UserInfo>
<mx:Button id="btnlose" label="投降" enabled="false" x="669" y="465" width="70" height="21"/>
<mx:Button id="btnstart" label="開始" enabled="true" x="669" y="435" width="70" height="21"/>
<mx:Button id="btnsave" label="調入布局" enabled="true" x="669" y="525" width="70" height="21"/>
<mx:Button id="btnopen" label="保存布局" enabled="true" x="669" y="495" width="70" height="21"/>
<ns1:UserInfo x="763" y="228">
</ns1:UserInfo>
</s:BorderContainer>
浙公網安備 33010602011771號