以下是我过去做俄罗斯方块的全部思路,虽说每种语言实现的方式不一样,但是制作的思路是大体一样的
俄罗斯方块的思路
界面的搭建:游戏区域 panel控件
下一个方块的提示显示区域: panel 控件
其他控件有button,label,textBox等等
游戏实现的主要步骤:
方块的动态生成
方块的移动
方块的变化
当每一行填满的时候方块的清除
清除后方块的排列
方块动态生成的思路以及运用的知识点:
PictureBox p=new PictureBox();//动态生成方块
p.width=20;//设置方块的属性,对于其他方块必须的属性根据个人要求设置
p.height=20;
不同方块的生成:由小方块拼接而成
方块的移动:
当方块的下一个移动区域为空的时候,可以容许方块向下移动,
如果条件不成立,就停止方块移动
注意:没个方块的向下移动的情况都不相同,只需要根据每个方块的向下移动
的可行区域进行判断,如果方块可以往下移动,就容许移动。
方块的左右移动
判断方块最的左边和右边的方块的座标+左右移动的位置(像素)
y
移动条件:如果移动的区域为空的时候,就移动方块,否则不移动方块
注意:左右移动的最大区域不可以超过游戏区域,可以根据不同的判断来限定方块越界的问题
方块的直接向下移动:
只需要加快方块的移动速度就可以达到这个效果
方块的变化
两种长方形的变化条件
判断区域:变化范围=长方形的长*长方形的长的区域
如果变化范围条件都为空的时候,就变化
其它方块的变化条件:
主要思路:判断要变化方块,变化后的区域是否为空,
并且方块变化区域范围是否成立
注意:方块变化时的条件,不要忘记如果方块已经停止移动的时候,方块就不再容许变化
判断方块如何为填满:
可以根据不同的方法来限定:只需要判断当Y座标一行都为方块的时候,
说明这一行方块已经填满,那么就可以清除这一行方块
清除后的效果:
清除这一行以上的方块的位置都需要往下移动一行,
根据消除行数来判断向下移动的位置
建议:可以将每一个小方块保存在List<>集合中,
清除时候可以根据填满一行的下标和对象进行删除:
对于游戏等级和游戏加分制度可以根据不同的需求来进行设置,
最后希望这个方案能给你带来思路,能给你带来帮助,祝愿能早日完成!
个人代码提供以及实现步骤:
The First Point
运用二维数组定义整个游戏界面,定义数组
Int[,] arr=new int[21,12];
界面赋值
For(int i=0;i<22;i++)
{
For(int j=0;j<12;j++)
{
If( i==20 || j==0 || j==11)
Arr[i,j]=-2;//代表障碍
Else
Arr[i,j]=-1;//代表空格
}
}
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■■■■■■■■■■
地图大小为200 * 400
数组赋值后,值为-1的地方相对于地图界面的空白区域
The Second Point
//动态生成方块(■■■■)
//定义方块集合
list<PictureBox> ls=new list<PictureBox>();
PictureBox one =new pictureBox();
One.width=20;
One.height=20;
One.image=imagelist.images[0];//给图片空间赋值图片
One.location=new point(40,0);//给第一张图片定位
PictureBox two=new pictureBox();
Two.width=20;
Two.height=20;
Two.image=imagelist.images[0];
Two.location=new point(60,0);
pictureBox three =new pictureBox();
three.widht=20;
three.height=20;
three.image=imagelist.images[0];
three.location=new point(80,0);
pictureBox four=new pictureBox();
four.widht=20;
four.height=20;
four.image=imagelist.images[0];
four.location=new point(100,0);
//将四个设好的图片添加到游戏控件内
This.panel.controls.add(one);
This.panel.controls.add(two);
This.panel.controls.add(three); x 40
This.panel.controls.add(four); | 100
//将方块添加到集合中 | |
ls.add(one); ■□□■■■■□□■ ——y 0
ls.add(two); ■□□□□□□□□■
ls.add(three); ■□□□□□□□□■
ls.add(four); ■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
完成后大概图像 ■□□□□□□□□■
//定义变量记录方块下标 ■□□□□□□□□■
■□□□□□□□□■ __ y 380
■■■■■■■■■■
sumindex+=4;
//方块的移动
The Thrid Point
//注意判断四个方块同等X座标移动的Y位置是否为空
如:定义X和Y代表方块在panel中的座标值
方块1 x=40, y=0;
方块2 x=60,y=0;
方块3 x=80,y=0;
方块4 x=100,y=0;
如果方块每移动一次,Y座标加20pX的话
四个方块的向下移动条件是
每个方块同等X座标下Y+20的地方等于空
二维数组中行和列所对应的就是panel中的X和Y座标
只需判断数组中的相应位置来控件方块的移动
移动后的图解
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■赋值后index值■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□□□□□□□■ ■□□□□□□□□■
■□□■■■■□□■ __y 380 ■□□ 0 1 2 3□□■
■■■■■■■■■■ ■■■■■■■■■■
|
x 40
arr[19,4]=indexsum-4;
arr[19,5]=indexsum-3;
arr[19,6]=indexsum-2;
arr[19,7]=indexsum-1;
The Fourth Point
左移动
判断方块X座标减移动的20Px的地方是否为空,条件成立
向左移动4个方块
如图 x
| □■□ ------ y
□■■■□
x=20;
y=0;
//如果两个白正方块的地方为空的时候,方块可以向左移动一格,x+20,y不变
arr[1,1]=-1 对于的座标 x=0,y=20;
arr[0,3]=-1 x=40,y=0;
x
|
□■—y
□■■■
右则反之
x-1 x
变化 | | x
□■□--y |
y+1--□■□ ■■■ ---y
□■■ 变化后 ■
The Fifth Point
当一行填满的时候
清除这一行方块
for (int i =1; i <20; i++) //判断是哪一行已经填满 ■□□□□□□□□■
{ ■□□□□□□□□■
string see="已满"; ■□□□□□□□□■
for (int j = 1; j < 11; j++) ■■■■■■■■■■
{ ■□□□□□□□□■
if (arr[i, j] == -1)//判断是否有空格 ■□□■■■□■□■
{
see = "未满";
break;
}
}
if (see == "已满") //判断如果一行填满的时候
{
int start = lp.Count;
for (int b = 1; b < 11; b++)//隐藏消除该行
{
int index = arr[i, b];//得到消除方块在数组中的下标
lp.RemoveAt(index);//从数组中移除方块
this.panel.Controls.RamoveAt(index);//清除控件中的方块
for (int iy = 1; iy < 20; iy++)//消除后根据集合的动态维护进行相应的数组改变
{
for (int ix = 1; ix < 11; ix++)
{
if (GameHelp.Yarr[iy, ix] != -1 && GameHelp.Yarr[iy, ix] > index)
{
GameHelp.Yarr[iy, ix] = GameHelp.Yarr[iy, ix] - 1;
}
}
}
}
//注动态维护
{0,1,2,3,4,5,6,7} 删除 0 时候 1,2,3,4,5,6,7 index 为 0,1,2,3,4,5,6,
删除为2的时候 0,1,3,4,5,6,7, index 0,1,2,3,4,5,6
` 1
indexsum-= 10;//由于集合动态维护,将indexsum-消除行控件的个数
for (int b = 1; b < 11; b++)//将隐藏方块的区域赋值为空
GameHelp.Yarr[i, b] = -1;//将数组中消除的区域赋值
int indexof = 0;
this.panel1.Controls.Clear();//清除游戏区域的控件,可以不清除
x
| foreach (PictureBox pb in lp)//循环遍历整个集合,将集合中的控件重新确定位置
■□□□□□□□□■ {
■□□□□□□■□■ int lx = pb.Location.X;//获取方块的X座标
■□□□■□□□□■ int ly = pb.Location.Y;//获取方块的Y座标
■□■□■□□□□■ if (ly < i*20 )//如果方块小于消除行的Y座标,将方块Y+20,往下移动
■□□□□□□□□■ —y {
ly += 20;
pb.Location = new Point(lx, ly); 2
■2 this.panel1.Controls.Add(pb); 3
■3 int nexty=0;
int nextx=0;
移动2的时候 if (indexof > 0)//当是数组中第二个方块的时候
-1 {
2 nexty = lp[indexof - 1].Location.Y;//获取上一个方块的XY座标
移动3的时候 nextx = lp[indexof - 1].Location.X;
-1 }
2 if (lx == nextx && ly == nexty + 20)//如果上一个方块和这一个方块X相同,并且Y相差20的话
3 {
GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;//将方块移动到的地方赋值为集合下标值
}
■2 else
{
□2 index -1 GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;//方块移动的地方赋值为集合下标值
■3 2 GameHelp.Yarr[ly / 20 - 1, lx / 20 + 1] = -1;//方块的原始位置赋值为空
}
■3 //集合中3 }
else //消除方块一下的方块位置不变
■3 arr index 2 {
□-1 this.panel1.Controls.Add(pb);
移动后 GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;
■2 arr index 2 }
■3 arr index 3 indexof = indexof + 1;//集合数组下标加
}
i -= 1;//判断向下移动一格后,需要I-1重新判断
}
}