上篇博文已经介绍俄罗斯方块Demo的简单实现,鄙人在完成了弱弱的简单俄罗斯方块Demo后,想要对Demo进行优化和美化设置,使得俄罗斯的可玩性增强。本篇博文主要在将结构的优化、游戏的美化和可玩性的扩展性上进行改进,让我们的游戏变不那么单调,偶尔也要高端霸气上档次。
第一、算法的优化:
在Demo中,基本上都是用循环来完成向下、向左、向右的移动、检查是否存在可以得分的行等动作。在这些循环中我们使用了从0到最大值的循环。在检测是否满行和绘制背景的时候,之前采用了历边所有的背景数组。将遍历条件设为缩小到俄罗斯方块完成落下的最小高度,可以缩小循环的范围。从而提高执行效率。故声明一个全局变量
private int lowY = 19; //初始化的时候为到最下面一行。初始背景无任何砖块
第二、补全砖块类型:
俄罗斯方块一共有7种砖块类型,上篇博文鄙人只定义了四种类型,现在将其补齐
可能看过上一篇博文的童鞋可能不太懂这个怎么弄的,其实这个容易理解,把是1的连起来就知道是什么图形了。哈哈,简单吧。。。
/// <summary> /// 定义砖块int[i,j,y,x] /// 4种类型方块,每种方块的4种方位,4*4的位置矩阵 /// tricks:i为块砖类型,j为状态,x为行,y为列 /// </summary> private int[, , ,] tricks = {{ { {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} }, { {1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} }, { {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} }, { {1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} } }, { { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} } }, { { {1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0} }, { {0,1,1,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0} }, { {0,1,1,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} } }, { { {0,1,0,0}, {1,1,0,0}, {1,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0} }, { {0,1,0,0}, {1,1,0,0}, {1,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0} } }, { { {1,1,0,0}, {0,1,0,0}, {0,1,0,0}, {0,0,0,0} }, { {0,0,1,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} }, { {1,0,0,0}, {1,0,0,0}, {1,1,0,0}, {0,0,0,0} }, { {1,1,1,0}, {1,0,0,0}, {0,0,0,0}, {0,0,0,0} } },{{ {1,0,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} }, { {1,1,0,0}, {1,0,0,0}, {1,0,0,0}, {0,0,0,0} }, { {1,1,1,0}, {0,0,1,0}, {0,0,0,0}, {0,0,0,0} }, { {0,1,0,0}, {0,1,0,0}, {1,1,0,0}, {0,0,0,0} }}, {{ {0,1,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} }, { {0,1,0,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0} }, { {1,1,1,0}, {0,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {0,1,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0} }} };
第三、砖块的美化:
添加颜色
颜色表是一个7*3二维数组
tricksColor[type][color]tpye表示方块类型,
每一种类型指定一种颜色
每一个tpye中含有3个color值,
其中第一个为填充基本方块的颜色,第二个为填充方块上多边形的颜色,第三个为填充方块右多边形的颜色,这样做为了凸显出方块的立体感
#region 定义颜色表 /// <summary> /// 各个砖块对应的RGB信息 /// </summary> private Color[,] tricksColor = { {Color.FromArgb(0,0,255),Color.FromArgb(200,200,253),Color.FromArgb(98,98,140)}, {Color.FromArgb(255,0,0),Color.FromArgb(253,200,200),Color.FromArgb(140,98,98)}, {Color.FromArgb(0,255,20),Color.FromArgb(76,206,23),Color.FromArgb(65,206,45)}, {Color.FromArgb(255,0,255),Color.FromArgb(253,200,255),Color.FromArgb(189,84,255)}, {Color.FromArgb(255,255,0),Color.FromArgb(253,253,200),Color.FromArgb(189,189,84)}, {Color.FromArgb(255,128,0),Color.FromArgb(253,148,41),Color.FromArgb(189,108,17)}, {Color.FromArgb(128,64,64),Color.FromArgb(253,78,68),Color.FromArgb(189,68,68)} }; #endregion
将背景矩阵也添加颜色参数
初始默认为黑色,这样立体感更明显。
/// <summary> /// 定义背景 /// x:行,y:列,color:颜色 /// </summary> private int[, ,] bgGraoud ={ {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, };
最主要的就是绘制方块啦,之前只是填充了值为1基本的正方形,现在增加绘制上边和右边多边形,以增强立体感
/// <summary>
/// 绘制方块的方法
/// </summary>
private void DrawTetris()
{
Graphics g = Graphics.FromImage(myImage);
g.Clear(panel1.BackColor);
for (int bgy = 19; bgy > lowY - 1; bgy--)
{
for (int bgx = 0; bgx < 14; bgx++)
{
if (bgGraoud[bgy, bgx, 0] == 1)
{
//首先绘制一个基本方块
g.FillRectangle(new SolidBrush(tricksColor[bgGraoud[bgy, bgx, 1], 0]), bgx * 20, bgy * 20, 20, 20);
//绘制上边
g.DrawRectangle(new Pen(panel1.BackColor), bgx * 20, bgy * 20, 20, 20);
Point[] myPoints1 = { new Point(bgx * 20 + 5, bgy * 20 - 5), new Point(bgx * 20 + 25, bgy * 20 - 5), new Point(bgx * 20 + 20, bgy * 20), new Point(bgx * 20, bgy * 20) };
g.FillPolygon(new SolidBrush(tricksColor[bgGraoud[bgy, bgx, 1], 1]), myPoints1);
g.DrawPolygon(new Pen(panel1.BackColor), myPoints1);
//绘制右边
Point[] myPoints2 = { new Point(bgx * 20 + 20, bgy * 20), new Point(bgx * 20 + 25, bgy * 20 - 5), new Point(bgx * 20 + 25, bgy * 20 + 15), new Point(bgx * 20 + 20, bgy * 20 + 20) };
g.FillPolygon(new SolidBrush(tricksColor[bgGraoud[bgy, bgx, 1], 2]), myPoints2);
}
}
}
//绘制当前的图片
for (int y = 3; y >= 0; y--)
{
for (int x = 0; x < 4; x++)
{
if (currentTrick[y, x, 0] == 1)
{
//绘制基本方块
g.FillRectangle(new SolidBrush(tricksColor[currentTrick[y, x, 1], 0]), (x + currentX) * 20, (y + currentY) * 20, 20, 20);
g.DrawRectangle(new Pen(panel1.BackColor), (x + currentX) * 20, (y + currentY) * 20, 20, 20);
//绘制周围区域,增强立体感
if (x + 1 + currentX < 14)
{
if (bgGraoud[y + currentY, x + 1 + currentX, 0] == 0)
{
//绘制上边
Point[] myPoints1 = { new Point((x + currentX) * 20 + 5, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 25, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 20, (y + currentY) * 20), new Point((x + currentX) * 20, (y + currentY) * 20) };
g.FillPolygon(new SolidBrush(tricksColor[currentTrick[y, x, 1], 1]), myPoints1);
//绘制右边
g.DrawPolygon(new Pen(panel1.BackColor), myPoints1);
Point[] myPoints2 = { new Point((x + currentX) * 20 + 20, (y + currentY) * 20), new Point((x + currentX) * 20 + 25, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 25, (y + currentY) * 20 + 15), new Point((x + currentX) * 20 + 20, (y + currentY) * 20 + 20) };
g.FillPolygon(new SolidBrush(tricksColor[currentTrick[y, x, 1], 2]), myPoints2);
}
else
{
Point[] myPoints1 = { new Point((x + currentX) * 20 + 5, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 20, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 20, (y + currentY) * 20), new Point((x + currentX) * 20, (y + currentY) * 20) };
g.FillPolygon(new SolidBrush(tricksColor[currentTrick[y, x, 1], 1]), myPoints1);
g.DrawPolygon(new Pen(panel1.BackColor), myPoints1);
}
}
else
{
Point[] myPoints1 = { new Point((x + currentX) * 20 + 5, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 20, (y + currentY) * 20 - 5), new Point((x + currentX) * 20 + 20, (y + currentY) * 20), new Point((x + currentX) * 20, (y + currentY) * 20) };
g.FillPolygon(new SolidBrush(tricksColor[currentTrick[y, x, 1], 1]), myPoints1);
g.DrawPolygon(new Pen(panel1.BackColor), myPoints1);
}
}
}
}
Graphics gg = panel1.CreateGraphics();
gg.DrawImage(myImage, 0, 0);
}
第四、游戏提示等改进:
增加游戏控制的显示,增加游戏关卡。
改进后的游戏预览
C#俄罗斯方块游戏Demo的设计请猛戳: