五子连珠,在民间俗称”五子棋”,是一种流传很广的益智棋类游戏,游戏规则非常简单,适合各个年龄段的朋友玩,相信大家以前也一定玩过此游戏,传统的玩法是两玩家在围棋棋盘上进行比赛,这里玩家的对手将变成电脑,想不想和电脑过过招呢?下面我们就来学习使用Flash制作五子连珠这个游戏。
游戏的主界面如图1所示:

图1
游戏玩法:
五子连珠这个游戏需要由两位选手一起来完成,其中一位是电脑,电脑在游戏中使用黑棋比赛,您在游戏中使用白棋进行比赛,游戏的目的是尽量将自己的棋在棋盘上排列成五颗棋子连在一起的直线,水平方向,垂直方向或者斜向都可以,但是不能有拐点,必须是一条直线,哪一方先连好,则胜利。玩家在游戏中一方面要尽量将自己的棋子连起来,另一方面也需要阻碍对手进行连子,不让对手轻易的将棋子连起来,直到有一方先连好五颗棋子,则游戏结束。游戏中为了防止一方没有看清对方上一步的落子位置,在棋盘的右上角将显示上一步的落子位置,棋子的位置根据棋盘上的横纵标识来决定(横向为1-15,纵向为A-O)。
游戏制作思路:
本游戏制作起来有一定的难度,难度的关键在于玩家中有一方是电脑,如何合理的控制电脑走棋是最关键的部分。如果要实现电脑的自动计算棋局和决定落子位置,就需要用到一些Ai(人工智能)方面的知识,在游戏制作中会详细讲解。
棋类游戏一般都会在一个二维的棋盘上进行,所以自然的就会使用二维数组来记录棋子的位置和决定落子的位置,数组在棋类游戏中也是应用非常的广泛。
游戏制作步骤:
下面我们就来开始具体的游戏制作步骤:
游戏素材的准备:
1. 棋子的准备:棋类游戏当然少不了棋子,本游戏中需要两类棋子,一种为黑色棋子,一种为白色棋子,默认情况下电脑使用黑色棋子,我们可以从外部导入两副棋子图片,也可以在Flash中进行手工绘制。本实例中我们就来自己制作两个棋子。
新建一个Graphic组件,并命名为black graphic,使用椭圆工具绘制一个圆形,并填充上黑色,这样一个简单的黑色棋子就做好了,如图2所示:

图2
因为我们需要在游戏中使用Action对棋子进行控制,所以需要将上面做好的Graphic组件转换为Movie clip类型的组件。所以新建一个movie clip组件,命名为black,将组件black graphic拖到组件black的编辑区即可。
按照同样的方法制作一个white graphic组件,并绘制一个白色的棋子,然后在建立相应的white movie clip组件,绘制好的白色棋子如图3所示:

图3
2. 控制按钮的制作:游戏中需要使用鼠标将棋子落到棋盘上,所以需要使用按钮结合棋子的方法,因为游戏中我们看到的实际是棋子,但是控制的是按钮,所以这里我们只需要制作一个简单的隐形按钮即可,按钮大小和棋子大小相似,如图4所示:

图4
当游戏结束后还需要有一个Replay按钮允许玩家重玩游戏,所以可以建立一个简单的按钮,用来控制游戏的再次运行,Replay按钮如图5所示:

图5
3. 控制游戏的MC:棋类游戏中少不了大量的Action程序控制,为了便于对游戏进行控制,一般将Action放在专门的Movie clip中,然后就可以在游戏的任何地方调用了。
A:新建一个Movie clip组件,命名为blk,进入组件编辑状态后,在第一关键桢添加如下AS:
stop();
function makelist(maker)
//自定义函数makelist,参数为maker,其作用是生成一个列表
{
if (maker =="white")
//如果传递进函数的参数是white
{
color = 2;
color_bad = 1;
//设置两变量值
}
else
//如果传递进函数的参数是black
{
color = 1;
color_bad = 2;
//设置两变量值
}
for (i=0; i<15; i++)
//外循环,循环变量为I,循环次数为15次
{
for (j=0; j<15; j++)
//外循环,循环变量为j,循环次数为15次,两次循环共15*15此,正好等于棋盘的大小,用来设//置棋盘
{
if (_root.table[i][j] <> 0)
//table数组用来检查棋盘是否为空,为空,相应的值为1,否则为0
{
for (k=0; k<4; k++)
{
if (maker =="white")
{
_root.computer[i*15+j][k] = 0;
}
else
{
_root.player[i*15+j][k] = 0;
}
}//若前一步的落子为白棋,则后一步计算机落子,否则玩家落子
} else {
//如果棋盘为空
for (k=0; k<4; k++) {
x = i;
y = j;
score = 5;
while ((_root.table[x+_root.dir[k][0]][y+_root.dir[k][1]] == color) and (x+_root.dir[k][0] < 15) and (y+_root.dir[k][1] >= 0) and (y+_root.dir[k][1] < 15) and (x+_root.dir[k][0] >= 0)) {
x = x + _root.dir[k][0];
y = y + _root.dir[k][1];
score = score * 2;
}
if ((_root.table[x+_root.dir[k][0]][y+_root.dir[k][1]] == color_bad) and (x+_root.dir[k][0] < 15) and (y+_root.dir[k][1] >= 0) and (y+_root.dir[k][1] < 15) and (x+_root.dir[k][0] >= 0)) {
score = score / 2;
}
x = i;
y = j;
while ((_root.table[x+_root.dir[k+4][0]][y+_root.dir[k+4][1]] == color) and (x+_root.dir[k+4][0] < 15) and (y+_root.dir[k+4][1] >= 0) and (y+_root.dir[k+4][1] < 15) and (x+_root.dir[k+4][0] >= 0)) {
x = x + _root.dir[k+4][0];
y = y + _root.dir[k+4][1];
score = score * 2;
}
if (score > 30) {
score = score * 2;
}
if ((_root.table[x+_root.dir[k+4][0]][y+_root.dir[k+4][1]] == color_bad) and (x+_root.dir[k+4][0] < 15) and (y+_root.dir[k+4][1] >= 0) and (y+_root.dir[k+4][1] < 15) and (x+_root.dir[k+4][0] >= 0)) {
score = score / 2;
}
if (maker =="white") {
_root.computer[i*15+j][k] = score;
} else {
_root.player[i*15+j][k] = score;
}
}//初始化棋盘,根据上一步落子的不同,来计算一下一步的落子
}
}
}
}
B:再新建一个Movie clip组件,命名为blk2,进入组件编辑状态后,在第一关键桢添加as:stop();
在第六桢插入一个关键桢,并添加如下AS:
if (_root.playnow == "computer") {
// 如果先落子的为电脑,则初始化棋盘
_root.func.makelist("white");
_root.func.makelist("black");
//分别调用前面定义的自定义函数,且传递不同的参数
max_computer = 0;
max_player = 0;
k = 0;
//定义三个变量
for (j=0; j<15; j++) {
for (i=0; i<15; i++) {
for (k=0; k<4; k++) {
if (_root.computer[j*15+i][k] == max_computer) {
rndnum = random ( 100 ) + 1;
if (rndnum > 50) {
max_computer = _root.computer[j*15+i][k] ;
xc = i;
yc = j;
}
}
if (_root.computer[j*15+i][k] > max_computer) {
max_computer = _root.computer[j*15+i][k] ;
xc = i;
yc = j;
}
if (_root.player[j*15+i][k] > max_player) {
max_player = _root.player[j*15+i][k] ;
xp = i;
yp = j;
}
}
}
}
if (max_computer > max_player) {
x = xc;
y = yc;
} else {
x = xp;
y = yp;
}
// 绘制棋子
num = y * 15 + x;
removeMovieClip(_root.b add num);
duplicateMovieClip(_root.white, "white" add num, num + 300);
setProperty(_root.white add num, _x, 34.7 + x * 20);
setProperty(_root.white add num, _y, 34.7 + y * 20);
_root.table[y][x] = 2;
// 显示棋子
_root.display = "Xpos : " + (x + 1);
temp = chr ( y + 65);
_root.display1 = "Ypos : " + temp;
_root.playnow = "player";
//判断是否获胜
xx = x;
yy = y;
for (k=0; k<4; k++) {
if (_root.a_result <> 6) {
_root.a_result = 0;
x = xx;
y = yy;
while ((_root.table[y][x] == 2) and (y+_root.dir[k][1] < 16) and (x+_root.dir[k][0] >= -1) and (x+_root.dir[k][0] < 16) and (y+_root.dir[k][1] >= -1)) {
x = x + _root.dir[k][0];
y = y + _root.dir[k][1];
// "_root.table["+y+"]["+x+"]="+_root.table[y][x]
_root.a_result = _root.a_result+1;
}
x = xx;
y = yy;
while ((_root.table[y][x] == 2) and (y+_root.dir[k+4][1] < 16) and (x+_root.dir[k+4][0] >= -1) and (x+_root.dir[k+4][0] < 16) and (y+_root.dir[k+4][1] >= -1)) {
x = x + _root.dir[k+4][0];
y = y + _root.dir[k+4][1];
_root.a_result = _root.a_result+1;
}
if (_root.a_result == 6) {
_root.playnow = "nobody";
}
}
}
if (_root.playnow =="nobody")
}
C:新建一个Movie clip组件,并命名为bb,此组件用来计算电脑如何走棋,进入组件编辑状态后,在图层layer1绘制一个有填充色的矩形,然后在第5桢插入一个关键桢,在同样位置绘制一个大小相同填充色不同的矩形。新建一个图层,在矩形里输入提示文字:电脑走棋,然后再新建一个图层Action,在第一桢添加AS: stop();,在第8桢插入一个关键桢,在此桢添加如下AS:
if (_root.playnow == "computer") {
//初始化棋盘
_root.func.makelist("white");
_root.func.makelist("black");
//调用自定义函数
max_computer = 0;
max_player = 0;
k = 0;
//定义三变量
for (j=0; j<15; j++) {
for (i=0; i<15; i++) {
for (k=0; k<4; k++) {
if (_root.computer[j*15+i][k] == max_computer) {
rndnum = random ( 100 ) + 1;
if (rndnum > 50) {
max_computer = _root.computer[j*15+i][k] ;
xc = i;
yc = j;
}
}
if (_root.computer[j*15+i][k] > max_computer) {
max_computer = _root.computer[j*15+i][k] ;
xc = i;
yc = j;
}
if (_root.player[j*15+i][k] > max_player) {
max_player = _root.player[j*15+i][k] ;
xp = i;
yp = j;
}
}
}
}
x = xc; y = yc; } else { x = xp; y = yp; } // 绘制棋子 num = y * 15 + x; removeMovieClip(_root.b add num); duplicateMovieClip(_root.white, "white" add num, num + 300); setProperty(_root.white add num, _x, 34.7 + x * 20); setProperty(_root.white add num, _y, 34.7 + y * 20); _root.table[y][x] = 2; // 显示棋子 _root.display = "Xpos : " + (x + 1); temp = chr ( y + 65); _root.display1 = "Ypos : " + temp; _root.playnow = "player"; // 判断是否获胜 xx = x; yy = y; for (k=0; k<4; k++) { if (_root.a_result <> 6) { _root.a_result = 0; x = xx; y = yy; while ((_root.table[y][x] == 2) and (y+_root.dir[k][1] < 16) and (x+_root.dir[k][0] >= -1) and (x+_root.dir[k][0] < 16) and (y+_root.dir[k][1] >= -1)) { x = x + _root.dir[k][0]; y = y + _root.dir[k][1]; // "_root.table["+y+"]["+x+"]="+_root.table[y][x] _root.a_result = _root.a_result+1; } x = xx; y = yy; while ((_root.table[y][x] == 2) and (y+_root.dir[k+4][1] < 16) and (x+_root.dir[k+4][0] >= -1) and (x+_root.dir[k+4][0] < 16) and (y+_root.dir[k+4][1] >= -1)) { x = x + _root.dir[k+4][0]; y = y + _root.dir[k+4][1]; _root.a_result = _root.a_result+1; } if (_root.a_result == 6) { _root.playnow = "nobody"; } } } // 游戏结束 if (_root.playnow =="nobody") } 最后的时间线如图6所示: ![]() 图6 D:再新建一个movie clip组件,命名为buttonclip,此组件用来控制双方的落子,进入组件编辑状态后,将前面做好的隐形按钮拖放到编辑区中,然后给第一桢添加AS:stop();. E:最后再制作一个movie clip,命名为gameover,此组件用来判断游戏是否结束,也就是判断是缶有一方已经连好了五颗棋子。进入组件编辑状态后,连续建立四个图层,分别为layer1,layer2,layer3和action,在layer1,layer2,layer3的第一桢插入空白,然后在第2桢绘制电脑获胜的提示信息,并将Replay按钮拖到编辑区中,给按钮添加As: on (release) 如图7所示: ![]() 图7 在layer1,layer2,layer3的第三桢按照同样的方法设置您胜利的提示信息,如图8所示: ![]() 图8 然后回到图层action,接下来就要添加具体的控制Action了,在此图层的前三个关键桢分别添加as: stop();,在第四关键桢添加如下AS: for (i=0; i<=225; i++) { removeMovieClip(_root.black add i); removeMovieClip(_root.white add i); removeMovieClip(_root.b add i); } //清除棋盘上的棋子 _root.gotoAndPlay("run"); //跳转到游戏的开始 最后的时间线如图9所示: ![]() 图9 布置主场景: 游戏的主要工作完成后,接下来需要布置主场景了。 首先使用绘图工具绘制出游戏中的棋盘,棋盘大小为15*15的矩阵,然后给棋盘标上横向和纵向的标识,如图10所示: ![]() 图10 分别将组件white,black,buttonclip,blk,bb和gameover拖到舞台的合适位置,如图11所示: ![]() 图11 组件white的实例名为:black 组件black的实例名为:white 组件buttonclip的实例名为:b 组件blk的实例名为:func 组件bb的实例名为:computerrun 组件gameover的实例名为:gameoverman 然后在棋盘上绘制两个Dynamic text动态文本框,用来显示上一步落子的位置,分别设置变量名为display和display1。 最后,给第一关键祯添加as: stop(); urls = "边城浪子-闪客帝国"; num = 0; table = new Array(); computer = new Array(); player = new Array(); a_result = 0; // Table array for (i=0; i<15; i++) { table[i] = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); } // Computer and player table list for (j=0; j<15; j++) { for (i=0; i<15; i++) { computer[j*15+i] = new Array(0,0,0,0); player[j*15+i] = new Array(0,0,0,0); } } // Make buttons count = 0; for (j=0; j<15; j++) { for (i=0; i<15; i++) { duplicateMovieClip(_root.b, "b"add count, count + 30); setProperty("b"add count, _x, 34.7 + i * 20); setProperty("b" add count, _y, 34.7 + j * 20 ); count++; } } // Eight directions var dir = new Array(); dir[0] = new Array(1,0); dir[1] = new Array(1,1); dir[2] = new Array(0,1); dir[3] = new Array(-1,1); dir[4] = new Array(-1,0); dir[5] = new Array(-1,-1); dir[6] = new Array(0,-1); dir[7] = new Array(1,-1); playnow = "player"; removeMovieClip(_root.b112); duplicateMovieClip(_root.white, "white112", 142); setProperty("white112", _x, 174.7); setProperty("white112", _y, 174.7); // The first black point table[7][7] = 2; 到此为止,五子连珠这个游戏就制作完成了,本游戏属于较高级的游戏制作,需要有一定的Action编程基础,不过如果您对Action不太了解,相信学完本实例后,可以在一定程度上提高您的Action水平。 |







