在个人电脑日益普及的今天,一些有趣的桌面游戏已经成为人们在使用计算机进行工作或学习之余休闲娱乐的首选,而俄罗斯方块游戏是人们最熟悉的小游戏知益,它趣味性极强,变化无穷,易上手等诸多特点得到了大众的认可,此外对运动的方块进行组合,可以训练玩家的反应能力。
????????此款游戏的总设计,需求分析和内部数据的具体处理和计算进行了详细的阐述。并对游戏的具体设计与实现进行了简要的说明。本系统基于C#语言下,应用了Visuai Studio 2022开发环境而发出的“俄罗斯方块”这款游戏。
1 功能概述
2 总体设计
2.1总体设计
2.2?功能设计(含界面设计、算法设计、代码)?
3?测试?
功能概述
我们开发的俄罗斯方块游戏,主要实现了以下几种功能:
1.可以灵活控制方块在图形框中运动。
2.游戏过程中方块可以自由旋转。
3.当某一行的方块排列满时,将自动将这一行方块消除,然后将上面所有方块向下移动,可以支持连续消行。
4.游戏前可以选择游戏的速度和游戏的等级,游戏速度既为方块下落速度,游戏等级为初始游戏时在基层随机生成一定行数的无规律方块,生成的行数由你来选择,每行至少产生5个以上的无规律方块,这样增加了游戏难度,对于游戏高手来说,无疑不是一个新的挑战。
5.游戏的得分支持积分
总体设计
游戏设计目的熟悉C#运行环境,会简单的程序调试,熟悉C语言各种类型数据的输入和输出,以及各种函数的使用方法,掌握顺序结构程序设计。
游戏设计内容按照经典的俄罗斯方块游戏设计方案、用C语言编写程序主要设计3个类。
设计游戏类(Game)
设计方块类(Block)
设计窗体类(From)
+背景音乐
功能设计基本功能实现
1、小方块
每个俄罗斯方块由四、五个小方块组成,定义小方块组合即俄罗斯方块类,实现俄罗斯方块的绘制,移动,擦除功能。
2、定时机制
建立计时器后,根据参数定义的时间步长触发定时处理时间,直到杀死计时器为止。通过计时器实现,每隔固定时间,检测方块状态以及方块下落,预览下一方块。当游戏结束或暂停时杀死计时器。
3、绘图实现
游戏开始时初始化界面,绘制俄罗斯方块的分数、等级、开始游戏、暂停游戏和结束游戏显示。
4、边界判断
通过键盘响应消息处理函数,响应键盘操作,判断俄罗斯方块是否与边界或者下方方块碰撞。
5、方块旋转功能
将小方块组合的位置基点作为旋转中心点,通过旋转各个小方块中心位置到小方块组合的位置基点的x与y边实现俄罗斯方块的旋转。
6、满行消除功能
将俄罗斯方块运动的主要界面看作一个二维数组,存储颜色。当某行满时,消除该行的方块,并且将该行上方的方块颜色向下移一行。
7、方块预览功能
将下一个方块画到游戏面板右侧的提示信息去中。
页面设计:
?
代码:
设计游戏类(Game)
????internal?class?Game
????{
????????public?const?int?BlockImageWidth = 21;//方砖中每个小方格的大小
????????public?const?int?BlockImageHeight = 21;
????????public?const?int?PlayingFieldWidth = 10;//游戏面板大小
????????public?const?int?PlayingFieldHeight = 20;
????????private?int[,] pile; //存储在游戏面板中的所有方砖;
????????private?Block currentBlock;//当前的俄罗斯方块
????????private?Block nextBlock;//下一个的俄罗斯方块
????????public?int?score = 0, lines = 0;
????????public?bool?over = false;//游戏是否结束
????????public?Game()//Game类构造函数
????????{
????????????pile = new?int[PlayingFieldWidth, PlayingFieldHeight];
????????????ClearPile();//清空游戏面板中的所有方砖
????????????CreateNewBlock();//产生新的俄罗斯方块
????????}
????????private?void?ClearPile()//清空游戏面板中的所有方砖
????????{
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????for?(int?j = 0; j < PlayingFieldHeight; j++)
????????????????{
????????????????????pile[i, j] = 0;
????????????????}
????????????}
????????}
????????private?void?CreateNewBlock()//产生新的俄罗斯方块
????????{
????????????if?(this.nextBlock != null)
????????????{
????????????????currentBlock = nextBlock;
????????????}
????????????else
????????????{
????????????????currentBlock = new?Block();
????????????}
????????????nextBlock = new?Block();
????????}
????????public?void?DrawPile(Graphics g)//将pile存储的所有固定画到游戏面板中
????????{
????????????Image brickImage = Image.FromFile(@"C:\Users\lenovo1\Desktop\俄罗斯方块\block2.gif");//方砖的图形
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????for?(int?j = 0; j < PlayingFieldHeight; j++)
????????????????{
????????????????????if?(pile[i, j] == 1)
????????????????????{
????????????????????????Rectangle rect = new?Rectangle(i * BlockImageWidth, j * BlockImageHeight, BlockImageWidth, BlockImageHeight);//(j - 1)
????????????????????????g.DrawImage(brickImage, rect);
????????????????????}
????????????????}
????????????}
????????}
????????internal?void?DrawCurrentBlock(object?graphics)
????????{
????????????throw?new?NotImplementedException();
????????}
????????public?void?DrawCurrentBlock(Graphics g)//将当前方块画到游戏面板中
????????{
????????????if?(currentBlock != null)//检查当前块是否为空
????????????{
????????????????currentBlock.Draw(g);
????????????}
????????}
????????public?void?DrawNextBlock(Graphics drawingSurface)//将下一个方块画到游戏面板右侧的提示信息去中
????????{
????????????if?(nextBlock != null)
????????????{
????????????????short?currentLeft = nextBlock.Left;
????????????????short?currentTop = nextBlock.Top;
????????????????nextBlock.Left = (short)((6 - nextBlock.Width) / 2);
????????????????nextBlock.Top = (short)((6 - nextBlock.Height) / 2);
????????????????nextBlock.Draw(drawingSurface);
????????????????nextBlock.Left = currentLeft;
????????????????nextBlock.Top = currentTop;
????????????}
????????}
????????public?bool?DownCurrentBlock()//判断方块下落
????????{
????????????bool?hit = false;
????????????currentBlock.Top++;
????????????if?((currentBlock.Top + currentBlock.Height) > PlayingFieldHeight)
????????????{
????????????????hit = true;//当前块触游戏面板底
????????????}
????????????else//检查是否接触到下一行其他已落方块
????????????{
????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????{
????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????{
????????????????????????int?fx, fy;
????????????????????????fx = currentBlock.Left + i;
????????????????????????fy = currentBlock.Top + j;
????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[fx, fy] == 1))//(fy + 1)
????????????????????????{
????????????????????????????hit = true;
????????????????????????}
????????????????????}
????????????????}
????????????}
????????????if?(hit)//触到其他已落方块或游戏面板底
????????????{
????????????????currentBlock.Top--;
????????????????MoveBlockToPile();//固定到游戏面板上 ???????????
????????????????CreateNewBlock(); //产生新的俄罗斯方块
????????????}
????????????return?hit;
????????}
????????private?void?MoveBlockToPile()//固定到游戏面板上
????????{
????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????{
????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????{
????????????????????int?fx, fy;
????????????????????fx = currentBlock.Left + i;
????????????????????fy = currentBlock.Top + j;
????????????????????if?(currentBlock.shape[i, j] == 1)
????????????????????{
????????????????????????pile[fx, fy] = 1;//将当前块的信息存储到二维数组pile中
????????????????????}
????????????????}
????????????}
????????????CheckForLines();
????????????if?(CheckForGameOver())//检查游戏是否结束
????????????????over = true;
????????}
????????private?int?CheckForLines()//检查是否满行并消去
????????{
????????????int?numLines = 0;
????????????int[] completeLines = new?int[PlayingFieldHeight];
????????????for?(int?j = PlayingFieldHeight - 1; j > 0; j--)
????????????{
????????????????bool?fullLine = true;
????????????????for?(int?i = 0; i < PlayingFieldWidth; i++)//PlayingFieldHeight游戏面板宽度
????????????????{
????????????????????if?(pile[i, j] == 0)
????????????????????{
????????????????????????fullLine = false;
????????????????????????break;
????????????????????}
????????????????}
????????????????if?(fullLine)
????????????????{
????????????????????numLines++;
????????????????????completeLines[numLines] = j;
????????????????}
????????????}
????????????if?(numLines > 0)
????????????{
????????????????for?(int?i = 1; i <= numLines; i++)
????????????????{
????????????????????ClearLine((completeLines[i] + (i - 1)));
????????????????}
????????????????score += 5 * (numLines * (numLines + 1));
????????????????lines += numLines;
????????????}
????????????return?numLines;
????????}
????????public?void?RotateCurrentBlock()//旋转方块
????????{
????????????bool?canRotate = true;
????????????short?newWidth = 0;
????????????short?newHeight = 0;
????????????int[,] newShape;
????????????newWidth = currentBlock.Height;
????????????newHeight = currentBlock.Width;
????????????newShape = new?int[newWidth, newHeight];
????????????int?x, y;
????????????//将某方块存储的形状信息shape二维数组进行转置
????????????if?(((currentBlock.Left + newWidth) <= Game.PlayingFieldWidth)
????????????????&& ((currentBlock.Top + newHeight) < Game.PlayingFieldHeight))
????????????{
????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????{
????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????{
????????????????????????x = ((currentBlock.Height - 1) - j);
????????????????????????y = i;
????????????????????????newShape[x, y] = currentBlock.shape[i, j];
????????????????????????//将转置后的方块形状信息shape数组与游戏面板所对应的数组进行比较,判断是否有重叠的地方
????????????????????????if?(newShape[x, y] == 1 && pile[x + currentBlock.Left, y + currentBlock.Top] == 1)
????????????????????????{
????????????????????????????canRotate = false; return;//不能旋转 }
????????????????????????}
????????????????????}
????????????????}
????????????????if?(canRotate)
????????????????{
????????????????????currentBlock.Width = newWidth;
????????????????????currentBlock.Height = newHeight;
????????????????????currentBlock.shape = newShape;
????????????????}
????????????}
????????}
????????public?void?MoveCurrentBlockSide(bool?left)//左右移动
????????{
????????????bool?canMove = true;
????????????if?(left)//左移动
????????????{
????????????????if?(currentBlock.Left > 0)
????????????????{
????????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????????{
????????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????????{
????????????????????????????int?fx, fy;
????????????????????????????fx = currentBlock.Left + i;
????????????????????????????fy = (currentBlock.Top + 1) + j;
????????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[(fx - 1), fy] == 1))
????????????????????????????{
????????????????????????????????canMove = false;//保证左右移动时和pile中存储的固定方块不重叠
????????????????????????????}
????????????????????????}
????????????????????}
????????????????????if?(canMove)
????????????????????{
????????????????????????currentBlock.Left--;
????????????????????}
????????????????}
????????????}
????????????else//右移动
????????????{
????????????????if?((currentBlock.Left + currentBlock.Width) < PlayingFieldWidth)
????????????????{
????????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????????{
????????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????????{
????????????????????????????int?fx, fy;
????????????????????????????fx = currentBlock.Left + i;
????????????????????????????fy = (currentBlock.Top + 1) + j;
????????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[(fx + 1), fy] == 1))
????????????????????????????{
????????????????????????????????canMove = false;
????????????????????????????}
????????????????????????}
????????????????????}
????????????????????if?(canMove)
????????????????????{
????????????????????????currentBlock.Left++;
????????????????????}
????????????????}
????????????}
????????}
????????private?void?ClearLine(int?lineNumber)//消去满行
????????{
????????????//将上方的行依次下移
????????????for?(int?j = lineNumber; j > 0; j--)
????????????{
????????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????????{
????????????????????pile[i, j] = pile[i, (j - 1)];
????????????????}
????????????}
????????????//将首行清空
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????pile[i, 0] = 0;
????????????}
????????}
????????public?bool?CheckForGameOver()//检查游戏是否结束
????????{
????????????if?(currentBlock.Top == 0)
????????????????return?true;
????????????else
????????????????return?false;
????????}
????}
代码:
设计游戏类(Game)
????internal?class?Game
????{
????????public?const?int?BlockImageWidth = 21;//方砖中每个小方格的大小
????????public?const?int?BlockImageHeight = 21;
????????public?const?int?PlayingFieldWidth = 10;//游戏面板大小
????????public?const?int?PlayingFieldHeight = 20;
????????private?int[,] pile; //存储在游戏面板中的所有方砖;
????????private?Block currentBlock;//当前的俄罗斯方块
????????private?Block nextBlock;//下一个的俄罗斯方块
????????public?int?score = 0, lines = 0;
????????public?bool?over = false;//游戏是否结束
????????public?Game()//Game类构造函数
????????{
????????????pile = new?int[PlayingFieldWidth, PlayingFieldHeight];
????????????ClearPile();//清空游戏面板中的所有方砖
????????????CreateNewBlock();//产生新的俄罗斯方块
????????}
????????private?void?ClearPile()//清空游戏面板中的所有方砖
????????{
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????for?(int?j = 0; j < PlayingFieldHeight; j++)
????????????????{
????????????????????pile[i, j] = 0;
????????????????}
????????????}
????????}
????????private?void?CreateNewBlock()//产生新的俄罗斯方块
????????{
????????????if?(this.nextBlock != null)
????????????{
????????????????currentBlock = nextBlock;
????????????}
????????????else
????????????{
????????????????currentBlock = new?Block();
????????????}
????????????nextBlock = new?Block();
????????}
????????public?void?DrawPile(Graphics g)//将pile存储的所有固定画到游戏面板中
????????{
????????????Image brickImage = Image.FromFile(@"C:\Users\lenovo1\Desktop\俄罗斯方块\block2.gif");//方砖的图形
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????for?(int?j = 0; j < PlayingFieldHeight; j++)
????????????????{
????????????????????if?(pile[i, j] == 1)
????????????????????{
????????????????????????Rectangle rect = new?Rectangle(i * BlockImageWidth, j * BlockImageHeight, BlockImageWidth, BlockImageHeight);//(j - 1)
????????????????????????g.DrawImage(brickImage, rect);
????????????????????}
????????????????}
????????????}
????????}
????????internal?void?DrawCurrentBlock(object?graphics)
????????{
????????????throw?new?NotImplementedException();
????????}
????????public?void?DrawCurrentBlock(Graphics g)//将当前方块画到游戏面板中
????????{
????????????if?(currentBlock != null)//检查当前块是否为空
????????????{
????????????????currentBlock.Draw(g);
????????????}
????????}
????????public?void?DrawNextBlock(Graphics drawingSurface)//将下一个方块画到游戏面板右侧的提示信息去中
????????{
????????????if?(nextBlock != null)
????????????{
????????????????short?currentLeft = nextBlock.Left;
????????????????short?currentTop = nextBlock.Top;
????????????????nextBlock.Left = (short)((6 - nextBlock.Width) / 2);
????????????????nextBlock.Top = (short)((6 - nextBlock.Height) / 2);
????????????????nextBlock.Draw(drawingSurface);
????????????????nextBlock.Left = currentLeft;
????????????????nextBlock.Top = currentTop;
????????????}
????????}
????????public?bool?DownCurrentBlock()//判断方块下落
????????{
????????????bool?hit = false;
????????????currentBlock.Top++;
????????????if?((currentBlock.Top + currentBlock.Height) > PlayingFieldHeight)
????????????{
????????????????hit = true;//当前块触游戏面板底
????????????}
????????????else//检查是否接触到下一行其他已落方块
????????????{
????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????{
????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????{
????????????????????????int?fx, fy;
????????????????????????fx = currentBlock.Left + i;
????????????????????????fy = currentBlock.Top + j;
????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[fx, fy] == 1))//(fy + 1)
????????????????????????{
????????????????????????????hit = true;
????????????????????????}
????????????????????}
????????????????}
????????????}
????????????if?(hit)//触到其他已落方块或游戏面板底
????????????{
????????????????currentBlock.Top--;
????????????????MoveBlockToPile();//固定到游戏面板上 ???????????
????????????????CreateNewBlock(); //产生新的俄罗斯方块
????????????}
????????????return?hit;
????????}
????????private?void?MoveBlockToPile()//固定到游戏面板上
????????{
????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????{
????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????{
????????????????????int?fx, fy;
????????????????????fx = currentBlock.Left + i;
????????????????????fy = currentBlock.Top + j;
????????????????????if?(currentBlock.shape[i, j] == 1)
????????????????????{
????????????????????????pile[fx, fy] = 1;//将当前块的信息存储到二维数组pile中
????????????????????}
????????????????}
????????????}
????????????CheckForLines();
????????????if?(CheckForGameOver())//检查游戏是否结束
????????????????over = true;
????????}
????????private?int?CheckForLines()//检查是否满行并消去
????????{
????????????int?numLines = 0;
????????????int[] completeLines = new?int[PlayingFieldHeight];
????????????for?(int?j = PlayingFieldHeight - 1; j > 0; j--)
????????????{
????????????????bool?fullLine = true;
????????????????for?(int?i = 0; i < PlayingFieldWidth; i++)//PlayingFieldHeight游戏面板宽度
????????????????{
????????????????????if?(pile[i, j] == 0)
????????????????????{
????????????????????????fullLine = false;
????????????????????????break;
????????????????????}
????????????????}
????????????????if?(fullLine)
????????????????{
????????????????????numLines++;
????????????????????completeLines[numLines] = j;
????????????????}
????????????}
????????????if?(numLines > 0)
????????????{
????????????????for?(int?i = 1; i <= numLines; i++)
????????????????{
????????????????????ClearLine((completeLines[i] + (i - 1)));
????????????????}
????????????????score += 5 * (numLines * (numLines + 1));
????????????????lines += numLines;
????????????}
????????????return?numLines;
????????}
????????public?void?RotateCurrentBlock()//旋转方块
????????{
????????????bool?canRotate = true;
????????????short?newWidth = 0;
????????????short?newHeight = 0;
????????????int[,] newShape;
????????????newWidth = currentBlock.Height;
????????????newHeight = currentBlock.Width;
????????????newShape = new?int[newWidth, newHeight];
????????????int?x, y;
????????????//将某方块存储的形状信息shape二维数组进行转置
????????????if?(((currentBlock.Left + newWidth) <= Game.PlayingFieldWidth)
????????????????&& ((currentBlock.Top + newHeight) < Game.PlayingFieldHeight))
????????????{
????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????{
????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????{
????????????????????????x = ((currentBlock.Height - 1) - j);
????????????????????????y = i;
????????????????????????newShape[x, y] = currentBlock.shape[i, j];
????????????????????????//将转置后的方块形状信息shape数组与游戏面板所对应的数组进行比较,判断是否有重叠的地方
????????????????????????if?(newShape[x, y] == 1 && pile[x + currentBlock.Left, y + currentBlock.Top] == 1)
????????????????????????{
????????????????????????????canRotate = false; return;//不能旋转 }
????????????????????????}
????????????????????}
????????????????}
????????????????if?(canRotate)
????????????????{
????????????????????currentBlock.Width = newWidth;
????????????????????currentBlock.Height = newHeight;
????????????????????currentBlock.shape = newShape;
????????????????}
????????????}
????????}
????????public?void?MoveCurrentBlockSide(bool?left)//左右移动
????????{
????????????bool?canMove = true;
????????????if?(left)//左移动
????????????{
????????????????if?(currentBlock.Left > 0)
????????????????{
????????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????????{
????????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????????{
????????????????????????????int?fx, fy;
????????????????????????????fx = currentBlock.Left + i;
????????????????????????????fy = (currentBlock.Top + 1) + j;
????????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[(fx - 1), fy] == 1))
????????????????????????????{
????????????????????????????????canMove = false;//保证左右移动时和pile中存储的固定方块不重叠
????????????????????????????}
????????????????????????}
????????????????????}
????????????????????if?(canMove)
????????????????????{
????????????????????????currentBlock.Left--;
????????????????????}
????????????????}
????????????}
????????????else//右移动
????????????{
????????????????if?((currentBlock.Left + currentBlock.Width) < PlayingFieldWidth)
????????????????{
????????????????????for?(int?i = 0; i < currentBlock.Width; i++)
????????????????????{
????????????????????????for?(int?j = 0; j < currentBlock.Height; j++)
????????????????????????{
????????????????????????????int?fx, fy;
????????????????????????????fx = currentBlock.Left + i;
????????????????????????????fy = (currentBlock.Top + 1) + j;
????????????????????????????if?((currentBlock.shape[i, j] == 1) && (pile[(fx + 1), fy] == 1))
????????????????????????????{
????????????????????????????????canMove = false;
????????????????????????????}
????????????????????????}
????????????????????}
????????????????????if?(canMove)
????????????????????{
????????????????????????currentBlock.Left++;
????????????????????}
????????????????}
????????????}
????????}
????????private?void?ClearLine(int?lineNumber)//消去满行
????????{
????????????//将上方的行依次下移
????????????for?(int?j = lineNumber; j > 0; j--)
????????????{
????????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????????{
????????????????????pile[i, j] = pile[i, (j - 1)];
????????????????}
????????????}
????????????//将首行清空
????????????for?(int?i = 0; i < PlayingFieldWidth; i++)
????????????{
????????????????pile[i, 0] = 0;
????????????}
????????}
????????public?bool?CheckForGameOver()//检查游戏是否结束
????????{
????????????if?(currentBlock.Top == 0)
????????????????return?true;
????????????else
????????????????return?false;
????????}
????}
设计方块类(Block)
????internal?class?Block
????{
????????private?short?width;//方块的高度
????????private?short?height;//方块的宽度
????????private?short?top;//方块位置的纵坐标
????????private?short?left;//方块位置的横坐标
????????private?int?ID; ??? //方块部件的ID
????????public?int[,] shape; ?//存储方块部件的形状,0为空白,1为有砖块
????????public?short?Width
????????{
????????????get
????????????{
????????????????return?width;
????????????}
????????????set
????????????{
????????????????width = value;
????????????}
????????}
????????public?short?Height
????????{
????????????get
????????????{
????????????????return?height;
????????????}
????????????set
????????????{
????????????????height = value;
????????????}
????????}
????????public?short?Top
????????{
????????????get
????????????{
????????????????return?top;
????????????}
????????????set
????????????{
????????????????top = value;
????????????}
????????}
????????public?short?Left
????????{
????????????get
????????????{
????????????????return?left;
????????????}
????????????set
????????????{
????????????????left = value;
????????????}
????????}
????????public?Block()
????????{
????????????Random randomGenerator = new?Random();
????????????int?randomBlock = randomGenerator.Next(1, 7);//产生1—4的数
????????????this.ID = randomBlock;
????????????switch?(this.ID)
????????????{
????????????????case?1: ??//横条形
????????????????????this.Width = 4;
????????????????????this.Height = 1;
????????????????????this.Top = 0;
????????????????????this.Left = 3;
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 0] = 1; shape[1, 0] = 1;
????????????????????shape[2, 0] = 1; shape[3, 0] = 1;
????????????????????break;
????????????????case?2: //正方形
????????????????????this.Width = 2;
????????????????????this.Height = 2;
????????????????????this.Top = 0;
????????????????????this.Left = 4;
????????????????????// Creates the new shape for this block.
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 0] = 1; shape[0, 1] = 1;
????????????????????shape[1, 0] = 1; shape[1, 1] = 1;
????????????????????break;
????????????????case?3: //T形
????????????????????this.Width = 3;
????????????????????this.Height = 3;
????????????????????this.Top = 0;
????????????????????this.Left = 4;
????????????????????// Creates the new shape for this block.
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 0] = 1; shape[1, 0] = 1;
????????????????????shape[2, 0] = 1; shape[1, 1] = 1;
????????????????????shape[1, 2] = 1;
????????????????????break;
????????????????case?4: //L形
????????????????????this.Width = 2;
????????????????????this.Height = 3;
????????????????????this.Top = 0;
????????????????????this.Left = 4;
????????????????????// Creates the new shape for this block.
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 0] = 1; shape[0, 1] = 1;
????????????????????shape[0, 2] = 1; shape[1, 2] = 1;
????????????????????break;
????????????????case?5: //新建
????????????????????this.Width = 2;
????????????????????this.Height = 3;
????????????????????this.Top = 0;
????????????????????this.Left = 4;
????????????????????// Creates the new shape for this block.
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 0] = 1; shape[0, 1] = 1;
????????????????????shape[0, 2] = 1; shape[1, 1] = 1;
????????????????????break;
????????????????case?6: //新建
????????????????????this.Width = 2;
????????????????????this.Height = 3;
????????????????????this.Top = 0;
????????????????????this.Left = 4;
????????????????????// Creates the new shape for this block.
????????????????????shape = new?int[this.Width, this.Height];
????????????????????shape[0, 2] = 1; shape[1, 0] = 1;
????????????????????shape[1, 2] = 1; shape[1, 1] = 1;
????????????????????break;
????????????}
????????}
????????public?void?Draw(Graphics g)//随机生成方块类型的编号(this.ID),该构造函数中Switch/Case语句段根据类型编号this.ID生成相应方块的形状
????????{
????????????Image brickImage = Image.FromFile(@"C:\Users\lenovo1\Desktop\俄罗斯方块\block2.gif");
????????????for?(int?i = 0; i < this.Width; i++)
????????????{
????????????????for?(int?j = 0; j < this.Height; j++)
????????????????{
????????????????????if?(this.shape[i, j] == 1)//黑色格子
????????????????????{
????????????????????????//得到绘制这个格子的在游戏面板中的矩形区域
????????????????????????Rectangle rect = new?Rectangle((this.Left + i) * Game.BlockImageWidth, (this.Top + j) * Game.BlockImageHeight, Game.BlockImageWidth, Game.BlockImageHeight);
????????????????????????g.DrawImage(brickImage, rect);
????????????????????}
????????????????}
????????????}
????????}
????}
设计窗体类(From)
public?partial?class?Form1?: Form
????{
????????public?Form1()
????????{
????????????InitializeComponent();
????????}
????????Game game = null;
????????private?void?button1_Click(object?sender, EventArgs e)//开始游戏,启动定时器
????????{
????????????game = new?Game();
????????????pictureBox1.Height = Game.BlockImageHeight * Game.PlayingFieldHeight + 3;
????????????pictureBox1.Width = Game.BlockImageWidth * Game.PlayingFieldWidth + 3;
????????????pictureBox1.Invalidate();//重画游戏面板区域
????????????timer1.Enabled = true;
????????????button1.Enabled = false;
????????}
????????private?void?button2_Click(object?sender, EventArgs e)//暂停游戏
????????{
????????????if?(button2.Text == "暂停游戏")
????????????{
????????????????timer1.Enabled = false; button2.Text = "继续游戏";
????????????}
????????????else
????????????{
????????????????timer1.Enabled = true; button2.Text = "暂停游戏";
????????????}
????????}
????????private?void?button3_Click(object?sender, EventArgs e)//结束游戏
????????{
????????????this.Close();
????????}
????????private?void?pictureBox1_Paint(object?sender, PaintEventArgs e)//刷新游戏面板屏幕,重画当前下落方块和pile存储的固定方块
????????{
????????????//重画游戏面板
????????????if?(game != null)
????????????{
????????????????game.DrawPile(e.Graphics);
????????????????game.DrawCurrentBlock(e.Graphics);
????????????}
????????}
????????private?void?pictureBox2_Paint(object?sender, PaintEventArgs e)//重画下一个方块
????????{
????????????if?(game != null) game.DrawNextBlock(e.Graphics);
????????}
????????private?void?comboBox1_SelectedIndexChanged(object?sender, EventArgs e)//设置下落速度,调整时间
????????{
????????????timer1.Interval = 550 - Convert.ToInt16(comboBox1.Text) * 50;
????????}
????????private?void?timer1_Tick(object?sender, EventArgs e)
????????{
????????????if?(!game.DownCurrentBlock())
????????????{
????????????????pictureBox1.Invalidate();//重画游戏面板区域
????????????????pictureBox2.Invalidate();//重画下一个方块
????????????}
????????????lblScore.Text = game.score.ToString();
????????????if?(game.over == true)
????????????{
????????????????timer1.Enabled = false;
????????????????MessageBox.Show("游戏结束,", "提示");
????????????????button1.Enabled = true;
????????????}
????????}
????????protected?override?bool?ProcessCmdKey(ref?Message msg, Keys e)
????????//重写ProcessCmdKey方法
????????{
????????????if?(button2.Text == "继续游戏") return?true;//暂停时不响应键盘
????????????if?(e == Keys.Up || e == Keys.Down || e == Keys.Space ||
?????????????????????e == Keys.Left || e == Keys.Right)
????????????{
????????????????MyKeyPress(this, new?KeyPressEventArgs((char)e)); //然后在MyKeyPress方法中处理 ??
????????????}
????????????return?true;
????????}
????????private?void?MyKeyPress(object?sender, KeyPressEventArgs e)
????????{
????????????switch?(e.KeyChar)
????????????{
????????????????case?(char)Keys.Up:
????????????????????game.RotateCurrentBlock();
????????????????????break;
????????????????case?(char)Keys.Down:
????????????????????if?(!game.DownCurrentBlock())
????????????????????????pictureBox1.Invalidate();//重画游戏面板区域
????????????????????break;
????????????????case?(char)Keys.Right:
????????????????????game.MoveCurrentBlockSide(false);
????????????????????break;
????????????????case?(char)Keys.Left:
????????????????????game.MoveCurrentBlockSide(true);
????????????????????break;
????????????????case?(char)Keys.Space:
????????????????????button2.PerformClick();
????????????????????break;
????????????}
????????????pictureBox1.Invalidate();
????????????pictureBox2.Invalidate();
????????}
}
背景音乐
?SoundPlayer sp = new?SoundPlayer(@"C:\Users\lenovo1\Desktop\音乐\清明上河图.wav");
?????????sp.PlayLooping();
测试
使用情况正常且逻辑清晰
?&用到的图片资源:
??
?
?
?
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。 |
标签: #C #游戏 #基于C语言下应用了Visuai #Studio