俄罗斯方块游戏设计
2010-03-12 13:03 Tedi 阅读(300) 评论(0) 编辑 收藏 举报我花了些时间用c#写了一个应用程序--俄罗斯方块游戏。增加了一些新的功能,基于xml的应用,可以自己配置砖块样式和快捷键,让你随心所欲,挑战自己的极限。此外我还在游戏中添加了默认的3首歌,当然你也可以自己添加你自己电脑上的歌曲,创建播放列表,让游戏不再单调。我自己玩了一下,非常的难,我还没通关过,自知水平不够。惭愧惭愧!~~~通关以后你会得到很大的奖励(暂时保密)。可惜我不知道博客上怎么传附件。如果有意者,可留言~~~~。
以下是一个文件的源代码,仅供参考:
using System;
using System.Drawing;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using System.Media;
namespace 俄罗斯方块
{
class Palette
{
private int _width = 15;//画板宽度
private int _height = 25;//画板高度
private Color[,] coorArr;//固定砖块数组
private Color disappearColor;//背景色
private Graphics gpPalette;//砖块活动画板
private Graphics gpReady;//下一个砖块样式画板
private BlockGroup bGroup;//砖块生产机
private Block runBlock;//正在活动的砖块
private Block readyBlock;//下一个砖块
private int rectPix;//单元格像素
private System.Timers.Timer timerBlock;//定时器
private int timeSpan = 800;//定时器间隔
private int score = 0;
private bool[] flag = { true, true,true,true,true,true };
public Palette(int x, int y, int pix, Color dcolor, Graphics gp, Graphics gr)
{
_width = x;
_height = y;
coorArr = new Color[_width, _height];
disappearColor = dcolor;
gpPalette = gp;
gpReady = gr;
rectPix = pix;
}
public void Settime(int time)
{
//初始化并启动定时器
timerBlock = new System.Timers.Timer(time);
timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
timerBlock.AutoReset = true;
timerBlock.Start();
}
public void Start()
{
bGroup = new BlockGroup();
runBlock = bGroup.GetABlock();
runBlock.XPos = _width / 2;
int y = 0;
for (int i = 0; i < runBlock.Lenght; i++)
{
if (runBlock[i].Y > y)
{
y = runBlock[i].Y;
}
}
runBlock.YPos =y;
gpPalette.Clear(disappearColor);
runBlock.Paint(gpPalette);
Thread.Sleep(20);
readyBlock = bGroup.GetABlock();//取另一个砖块赋给readyblock
readyBlock.XPos = 2; //5*5矩阵的中心点
readyBlock.YPos = 2;
gpReady.Clear(disappearColor);//清空画板
readyBlock.Paint(gpReady);
Settime(timeSpan);
//初始化并启动定时器
//timerBlock = new System.Timers.Timer(timeSpan);
// timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
//timerBlock.AutoReset = true;
//timerBlock.Start();
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
CheckAndOverBlock();
Down();
}
public bool Down()
{
int xPos = runBlock.XPos;
int yPos = runBlock.YPos+1;
for (int i = 0; i < runBlock.Lenght; i++)
{
if (yPos - runBlock[i].Y > _height-1 ) //如果超出下边界则失败
return false;
if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果下边有东西挡则失败
return false;
}
runBlock.erase(gpPalette);//擦除原来的砖块
runBlock.YPos++;
runBlock.Paint(gpPalette);//在新的位置上画砖块
return true;
}
public void Drop()
{
timerBlock.Stop();
while (Down())
timerBlock.Start();
}
public void MoveLeft()
{
int xPos = runBlock.XPos-1;
int yPos = runBlock.YPos ;
for (int i = 0; i < runBlock.Lenght; i++)
{
if (xPos+runBlock[i].X<0) //如果超出左边界则失败
return ;
if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果有东西挡则失败
return ;
}
runBlock.erase(gpPalette);//擦除原来的砖块
runBlock.XPos--;
runBlock.Paint(gpPalette);//在新的位置上画砖块
}
public void MoveRight()
{
int xPos = runBlock.XPos + 1;
int yPos = runBlock.YPos;
for (int i = 0; i < runBlock.Lenght; i++)
{
if (xPos + runBlock[i].X >_width-1) //如果超出右边界则失败
return;
if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果下边有东西挡则失败
return;
}
runBlock.erase(gpPalette);//擦除原来的砖块
runBlock.XPos++;
runBlock.Paint(gpPalette);//在新的位置上画砖块
}
public void DeasilRotate()
{
for (int i = 0; i < runBlock.Lenght; i++)
{
int x = runBlock.XPos + runBlock[i].Y;
int y = runBlock.YPos + runBlock[i].X;
if (x < 0||x>_width-1) //如果超出左右边界则失败
return;
if (y < 0 || y > _height - 1)//如果超出上下边界则失败
return;
if (!coorArr[x,y].IsEmpty)//如果旋转后有东西挡则失败
return;
}
runBlock.erase(gpPalette);//擦除原来的砖块
runBlock.DeasilRotate();
runBlock.Paint(gpPalette);//在新的位置上画砖块
}
public void ContraRotate()
{
for (int i = 0; i < runBlock.Lenght; i++)
{
int x = runBlock.XPos - runBlock[i].Y;
int y = runBlock.YPos - runBlock[i].X;
if (x < 0 || x > _width - 1) //如果超出左右边界则失败
return;
if (y < 0 || y > _height - 1)//如果超出上下边界则失败
return;
if (!coorArr[x, y].IsEmpty)//如果旋转后有东西挡则失败
return;
}
runBlock.erase(gpPalette);//擦除原来的砖块
runBlock.ContraRotate();
runBlock.Paint(gpPalette);//在新的位置上画砖块
}
private void PaintBackground(Graphics gp)//重画画板背景
{
gp.Clear(Color.Black);//首先清空画板
for (int i = 0; i < _height; i++)
{
for (int j = 0; j < _width; j++)
{
if (!coorArr[j, i].IsEmpty)
{
SolidBrush sb = new SolidBrush(coorArr[j, i]);
gp.FillRectangle(sb, j * rectPix + 1, i * rectPix, rectPix - 2, rectPix - 2);
}
}
}
}
public void PaintPalette(Graphics gp)//重画整个画板
{
PaintBackground(gp);//先画背景
if (runBlock != null)
{
runBlock.Paint(gp);//再画活动砖块
}
}
public void PaintReady(Graphics gp)//重画下一个砖块
{
if (readyBlock != null)
{
readyBlock.Paint(gp);//再画活动砖块
}
}
public void CheckAndOverBlock()//检查砖块是否到底,如果到底则归入corrarr数组中并产生新的砖块
{
bool over = false;//设置当前运行砖块是否到底的标志
for (int i = 0; i < runBlock.Lenght; i++)//遍历当前运行的所有小方块
{
int x = runBlock.XPos + runBlock[i].X;
int y = runBlock.YPos - runBlock[i].Y;
if (y == _height - 1)//如果达到下界则结束
{
over = true;
break;
}
if (!coorArr[x, y + 1].IsEmpty)//如果下面有其他砖块,则结束
{
over = true;
break;
}
}
if (over)
{
for (int i = 0; i < runBlock.Lenght; i++)//把当前砖块归入coorArr数组中
{
coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y] = runBlock.BlockColor;
}
CheckAndDelFullRow();
//产生新的砖块
runBlock = readyBlock;//新的砖块为准备好的砖块
runBlock.XPos = _width / 2;//确定当前砖块产生位置
int y = 0;
for (int i = 0; i < runBlock.Lenght; i++)
{
if (runBlock[i].Y > y)
{
y = runBlock[i].Y;
}
}
runBlock.YPos = y;
//检查新的砖块是否还有位置,如果没有则游戏结束
for (int i = 0; i < runBlock.Lenght; i++)
{
if (!coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y].IsEmpty)
{ //游戏结束
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
gpPalette.DrawString("GAME OVER", new Font("Arial Black", 25f), new SolidBrush(Color.White),
new RectangleF(0, _height * rectPix/2 - 100, _width * rectPix, 100), drawFormat);
timerBlock.Stop();
return;
}
}
runBlock.Paint(gpPalette);
//获取新的准备砖块
readyBlock = bGroup.GetABlock();//取另一个砖块赋给readyblock
readyBlock.XPos = 2;
readyBlock.YPos = 2;
gpReady.Clear(Color.Black);//清空画板
readyBlock.Paint(gpReady);
}
}
private void CheckAndDelFullRow()//检查并删除满行
{
//找出当前砖块所在行的范围
int lowRow = runBlock.YPos - runBlock[0].Y;//lowRow表示当前砖块y轴最小值
int highRow = lowRow;//highRow表示最大值
for (int i = 1; i < runBlock.Lenght; i++)//找出当前砖块所在行的范围,放入low,high变量中
{
int y = runBlock.YPos - runBlock[i].Y;
if (y < lowRow)
lowRow = y;
if (y > highRow)
highRow = y;
}
bool repaint = false;//判断是否重画标志
int sum = 0;
for (int i = lowRow; i <= highRow; i++)//检查满行,如果有就删除它
{
bool rowFull = true;
{
for (int j = 0; j < _width; j++)//判断是否满行
{
if (coorArr[j, i].IsEmpty)
{
rowFull = false;
break;
}
}
if (rowFull)//如果满行则删除这一行
{
sum++;
repaint = true;//如果有删除的行则需要重画
for (int k = i; k > 0; k--)
{
for (int j = 0; j < _width; j++)
{
coorArr[j, k] = coorArr[j, k - 1];
}
}
for (int j = 0; j < _width; j++)
{
coorArr[j, 0] = Color.Empty;//清空第0行
}
}
}
if (repaint)//重画
PaintBackground(gpPalette);
}
int sum_score = 1;
for (int j = 0; j < sum - 1; j++)
{
sum_score = sum_score * 2;
}
if (repaint)
{
score = score + 100 * sum_score;
if (score >= 20000)
{
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
gpPalette.DrawString("恭喜你通关了,全世界人向你致敬!", new Font("Arial Black", 25f), new SolidBrush(Color.Red),
new RectangleF(0, _height * rectPix / 2 - 100, _width * rectPix, 100), drawFormat);
timerBlock.Stop();
}
else if (flag[0])
{
if (score >= 2000&& score <= 2700)
{
flag[0] = false;
timerBlock.Dispose();
Settime(timeSpan - 300);
}
}
else if (flag[1])
{
if (score >= 4000 && score <= 4700)
{
flag[1] = false;
timerBlock.Dispose();
Settime(timeSpan - 400);
}
}
else if (flag[2])
{
if (score >= 6000 && score <= 6700)
{
flag[2] = false;
timerBlock.Dispose();
Settime(timeSpan - 500);
}
}
else if (flag[3])
{
if (score >= 8000 && score <= 8700)
{
flag[3] = false;
timerBlock.Dispose();
Settime(timeSpan - 600);
}
}
else if (flag[4])
{
if (score >= 12000 && score <= 12700)
{
flag[4] = false;
timerBlock.Dispose();
Settime(timeSpan - 700);
}
}
else if (flag[5])
{
if (score >= 16000 && score <= 16700)
{
flag[5] = false;
timerBlock.Dispose();
Settime(timeSpan - 800);
}
}
}
}
public void Pause()//暂停
{
if (timerBlock.Enabled == true)
timerBlock.Enabled = false;
}
public void EndPause()
{
if (timerBlock.Enabled == false)
timerBlock.Enabled = true;
}
public void Close()//关闭
{
timerBlock.Close();
gpPalette.Dispose();
gpReady.Dispose();
}
public int Score()
{
return score;
}
}
}
“七”乐无穷,尽在新浪新版博客,快来体验啊~~~请点击进入~