用flash as3.0软件写的一个游戏,也是我的第一个成品吧。
其中难点主要是两点,一是如何实现鼠标点击后准确下棋至棋盘的交点上,二是判断胜负的逻辑。以下主要记录这两点。
一.下棋点一种方式是在每一个交点处布置一个按钮,点击按钮时获取按钮坐标,在该坐标处显示棋子。一开始我觉得此方法有点木讷,后来想想这方法有一极大的好处,当鼠标出现在下棋点时,按钮可改变样式提示此处可下棋,这种交互功能我自己写的算法实现不了。
我自己的算法是用相对坐标来计算。每一格子是正方形,算出一格宽度,获得鼠标点击处坐标,除以格宽,得到相对坐标。再设置一相对敏感值e,设置e=0.2,那么鼠标点击处相对坐标为2.8与3.2时即取整到3处。
二.胜负逻辑
最终采用的逻辑,创建二维数组初始值为0,下黑棋时相应坐标的值为1,白棋为-1。每下一个棋检查,检查某个方向两头与该棋子颜色相同棋子的数目,相加大于等于5即可判断获胜。
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class ChessBoard extends MovieClip
{
var board:Array = new Array(); //棋盘二维数字
var numx :int; // 棋盘长度
var numy :int; //棋盘宽度
var gridWidth:Number ; //一格的宽度
var e_range:Number ; //鼠标点击位置与交点的位置的相对距离误差
var keyColor:Boolean ; //棋子的颜色 true为黑色,false为白色
public function ChessBoard()
{
init(); //初始化函数
}
public function init():void
{
gridWidth = 400/14;
e_range = 0.2;
keyColor = true;
numx = 15;
numy = 15;
for(var i=0;i<numx;i++) //数组初始化为0
{
board[i] = new Array();
for(var j=0;j<numy;j++)
{
board[i][j] = 0;
}
}
addEventListener(MouseEvent.CLICK, addChess);
}
function addChess(event:MouseEvent):void
{
if(event.stageX>=100&&event.stageX<=500&&event.stageY>=100&&event.stageY<=500)
{
var re_dx:Number = (event.stageX-100) / gridWidth; //鼠标点击位置的相对坐标,即 有多少格
var re_dy:Number = (event.stageY-100) / gridWidth;
var sign_x:int = 0; //x,y标记----决定是否出棋子
var sign_y:int = 0;
var sign1:int = 0; //决定在哪里出棋子的标记
var sign2:int = 0;
var x:Number; //棋子最终坐标
var y:Number;
if ( Math.abs(re_dx-int(re_dx))<e_range ) //x相对坐标,例如为3.1
{
sign_x = 1;
sign1 = 1;
}
if ( Math.abs(re_dx-Math.ceil(re_dx))<e_range) //x相对坐标,例如为3.9
{
sign_x = 1;
sign1 = -1;
}
if ( Math.abs(re_dy-int(re_dy))<e_range )
{
sign_y = 1;
sign2 = 1;
}
if (Math.abs(re_dy-Math.ceil(re_dy))<e_range)
{
sign_y = 1;
sign2 = -1;
}
if ( sign_x && sign_y ) //出现棋子
{
var chess:Chess;
if (sign1==1) //决定x坐标
{
x = int(re_dx) * gridWidth;
}
else
{
x = Math.ceil(re_dx) * gridWidth;
}
if (sign2==1) //决定y坐标
{
y = int(re_dy) * gridWidth;
}
else
{
y = Math.ceil(re_dy) * gridWidth;
}
if(!board[int(x/gridWidth)][int(y/gridWidth)]) //如果交点为空点,即可以下棋
{
if (keyColor) //决定棋子颜色
{
chess = new BlackKey();
keyColor = ! keyColor;
board[int(x/gridWidth)][int(y/gridWidth)]=1;
}
else
{
chess = new WhiteKey();
keyColor = ! keyColor;
board[int(x/gridWidth)][int(y/gridWidth)]=-1;
}
chess.x = x;
chess.y = y;
addChild(chess);
WinCheck( int(x/gridWidth) , int(y/gridWidth) ,keyColor );
}
}
function WinCheck (t:int,m:int,color:Boolean):void //color 为 false 下的是黑棋子
{ //color 为 true 下的是白棋子
var i:int ;
var winOrLost :Boolean = false;
var count1:int =0;
var count2:int =0;
/*检查水平方向*/
for(i=1;i<5;i++)
{
if(board[t-i][m]==board[t][m])
count1++;
else
break;
}
for(i=1;i<5;i++)
{
if(board[t+i][m]==board[t][m])
count2++;
else
break;
}
if( count1+count2+1 >= 5 )
winOrLost=true;
else
{
count1=0;
count2=0;
}
/*检查竖直方向*/
for(i=1;i<5;i++)
{
if(board[t][m-i]==board[t][m])
count1++;
else
break;
}
for(i=1;i<5;i++)
{
if(board[t][m+i]==board[t][m])
count2++;
else
break;
}
if( count1+count2+1 >= 5 )
winOrLost=true;
else
{
count1=0;
count2=0;
}
/*检查"/"方向*/
for(i=1;i<5;i++)
{
if(board[t+i][m-i]==board[t][m])
count1++;
else
break;
}
for(i=1;i<5;i++)
{
if (board[t-i][m+i]==board[t][m])
count2++;
else
break;
}
if( count1+count2+1 >= 5 )
winOrLost=true;
else
{
count1=0;
count2=0;
}
/*检查"\"方向*/
for(i=1;i<5;i++)
{
if(board[t-i][m-i]==board[t][m])
count1++;
else
break;
}
for(i=1;i<5;i++)
{
if (board[t+i][m+i]==board[t][m])
count2++;
else
break;
}
if( count1+count2+1 >= 5 )
winOrLost=true;
else
winOrLost=false;
if(winOrLost) //有玩家胜利
{
var win:Win = new Win();
win.x = 200;
win.y = 300;
if(color) //白色胜利
win.wintext.text ="WhiteKey Win" ;
else //黑色胜利
win.wintext.text ="BlackKey Win" ;;
removeEventListener(MouseEvent.CLICK,addChess);
addChild(win);
playAgain.addEventListener(MouseEvent.CLICK,onPlayAgainClick);
}
function onPlayAgainClick():void
{
removeChild(win);
var num=numChildren;
for(var i:uint=0;i<num;i++)
{
removeChildAt(2);
init();
}
}
}
}
}
}
}