大学时候做绘图和键盘练习的例子,俄罗斯方块游戏,分享出来给winform学习。
下载链接:
https://download.csdn.net/download/zhanglianzhu_91/11055683
示例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;
namespace RussianGrid
{
/// <summary>
/// 格子类
/// </summary>
public class Gride
{
public int rowCount; //行数
public int colCount; //列数
public int cellWidth; //单元格宽度
public int cellHeight; //单元格高度
Rectangle gridRect; //表格区域
Image bmp; //单元格位图
Image bkBmp; //表格背景位图
Bitmap bit; //内存画布
public Cell [,] cellGrid; //单元格几集合
/// <summary>
/// 构造函数
/// </summary>
/// <param name="rc"></param>
public Gride(Rectangle rc,int row,int col)
{
gridRect = rc;
rowCount = row;
colCount = col;
cellHeight = gridRect.Height / rowCount; //单元格高度
cellWidth = gridRect.Width / colCount; //单元格宽度
bmp=Bitmap.FromFile("1.bmp");
bkBmp=Bitmap.FromFile("bk.bmp");
bit = new Bitmap(rc.Width-4,rc.Height-16);
cellGrid = new Cell[rowCount, colCount];
InitCellGrid();
}
/// <summary>
/// 初始化表格
/// </summary>
private void InitCellGrid()
{
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
cellGrid[i, j] = new Cell();
cellGrid[i,j].rowIndex = i;
cellGrid[i,j].colIndex = j;
cellGrid[i,j].bUsed = false;
cellGrid[i,j].bFixed = false;
}
}
}
//绘制表格
public void DrawGrid(Graphics pDC)
{
Graphics graphi = Graphics.FromImage(bit);
graphi.Clear(Color.Gray);
//绘制单元格
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
//计算单元格区域
Rectangle rect = new Rectangle(gridRect.Left + j * cellWidth, gridRect.Top + i * cellHeight, cellWidth, cellHeight);
if (cellGrid[i, j].bUsed == true || cellGrid[i, j].bFixed == true)
{
graphi.DrawImage(bmp, rect);
}
else
{
graphi.DrawImage(bkBmp, rect);
}
Pen pen=new Pen(Color.Black);
graphi.DrawRectangle(pen, rect);
}
}
pDC.DrawImage(bit, 0, 0);
}
}
}
主要逻辑
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RussianGrid
{
public enum Drection {up,low,left,right };
public partial class Main : Form
{
public const int ROW_NUM=22;//格子行数
public const int COL_NUM=15;//格子列数
Gride gride; //格子对象
Drection drection; //方向
Piece piece; //方块
Random random; //产生随机数
int grade = 0; //记录分数
bool isEnd = false; //是否结束
bool stopping = false; //是否暂停
int Next; // 下一个方块
bool isFirst = true; //是否刚运行
bool isRuning = false;
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
random = new Random();
gride = new Gride(new Rectangle(0, 0, DrawPanel.Width, DrawPanel.Height),ROW_NUM,COL_NUM);
gride.DrawGrid(DrawPanel.CreateGraphics());
}
/// <summary>
/// 开始
/// </summary>
private void Start()
{
isRuning = true;
gride =new Gride(new Rectangle(0,0,DrawPanel.Width,DrawPanel.Height),ROW_NUM,COL_NUM);
piece = new Piece();
piece.SetPieceType(1);
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = true;
}
timer1.Enabled = true;
Next = random.Next(7) + 1;
Draw();
}
/// <summary>
/// Paint函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DrawPanel_Paint(object sender, PaintEventArgs e)
{
Draw();
}
/// <summary>
/// 判断能否下落
/// </summary>
/// <param name="piece"></param>
/// <returns></returns>
public bool CanPieceMove(Piece piece,Drection drection)
{
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
}
#region 下移
if (drection == Drection.low)
{
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y + 1 >= ROW_NUM)
{
for (int j = 0; j < 4; j++)
{
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
if (piece.imagesPoint[i].Y +1< 0)
{
continue;
}
if (gride.cellGrid[piece.imagesPoint[i].Y + 1, piece.imagesPoint[i].X].bUsed || gride.cellGrid[piece.imagesPoint[i].Y + 1, piece.imagesPoint[i].X].bFixed)
{
for (int j = 0; j < 4; j++)
{
if (piece.imagesPoint[j].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
}
}
#endregion
#region 左移
if (drection == Drection.left)
{
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].X<= 0)
{
for (int j = 0; j < 4; j++)
{
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
if (gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X-1].bUsed || gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X-1].bFixed)
{
for (int j = 0; j < 4; j++)
{
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
}
}
#endregion
#region 右移
if (drection == Drection.right)
{
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].X+1 >= 15)
{
for (int j = 0; j < 4; j++)
{
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
if (gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X + 1].bUsed || gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X + 1].bFixed)
{
for (int j = 0; j < 4; j++)
{
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return false;
}
}
}
#endregion
#region 旋转
if (drection == Drection.up)
{
for(int n=0;n<4;n++)
{
if (piece.imagesPoint[n].Y < 0)
{
return false;
}
}
//图像以左顶点为转点
if (piece.type == 33 || piece.type == 35 ||
piece.type == 44 || piece.type == 46 ||
piece.type == 11 || piece.type == 55 ||
piece.type == 57 || piece.type == 66 ||
piece.type == 77)
{
if (piece.leftIndex == 0)
{
return false;
}
else if (piece.leftIndex >= 13 &&
(piece.type == 11 || piece.type == 55 ||
piece.type == 57 || piece.type == 66 ||
piece.type == 77))//如果图像处于右边和右表弟二行,这些图形不能旋转
{
return false;
}
}
//定义一个临时的piece1,进行图像转换,判断转换后的图像是否合法,以决定当前图像是否允许变形
//图像是否合法的检测是通过该图像是否在表格中已被占用来决定的
Piece piece1 = new Piece ();
piece1.leftIndex = piece.leftIndex;
piece1.topIndex = piece.topIndex;
piece1.type = piece.type;
piece1.imagesPoint = new Point[4];
for (int i = 0; i < 4; i++)
{
piece1.imagesPoint[i] = piece.imagesPoint[i];
}
piece1.type = GetChangedType(piece.type);
piece1.SetPieceType(piece1.type);
for (int i = 0; i < 4; i++)
{
int nColIndex = piece.imagesPoint[i].X;
int nRowIndex = piece.imagesPoint[i].Y;
if (nColIndex <= 0 || nColIndex >= ROW_NUM || nRowIndex <= 0 || nRowIndex >= 15)
{
return false;
}
if (gride.cellGrid[nColIndex,nRowIndex].bFixed)//如果旋转后的图形有被填充的,则不能旋转
return false;
}
}
#endregion
for (int j = 0; j < 4; j++)
{
if (piece.imagesPoint[j].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
}
return true;
}
/// <summary>
/// 移动块
/// </summary>
/// <param name="drect"></param>
/// <param name="piece"></param>
public void MovePiece(Drection drect, Piece piece)
{
if (drect == Drection.left)
{
if (!CanPieceMove(piece, drect))
{
return;
}
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
}
for(int i=0;i<4;i++)
{
piece.imagesPoint[i].X--;
}
piece.leftIndex--;
}
if (drect == Drection.right)
{
if (!CanPieceMove(piece, drect))
{
return;
}
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
}
for (int i = 0; i < 4; i++)
{
piece.imagesPoint[i].X++;
}
piece.leftIndex++;
}
if (drect == Drection.low)
{
if (!CanPieceMove(piece, drect))
{
return;
}
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
}
for (int i = 0; i < 4; i++)
{
piece.imagesPoint[i].Y++;
}
piece.topIndex++;
}
if (drect == Drection.up)
{
if (CanPieceMove(piece, drect))
{
for (int i = 0; i < 4; i++)
{
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
}
piece.type = GetChangedType(piece.type);
piece.SetPieceType(piece.type);
}
}
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = true;
}
}
/// <summary>
/// 更改类型
/// </summary>
/// <param name="nSrcType"></param>
/// <returns></returns>
public int GetChangedType(int nSrcType)//获得改变后的图像类型,图像顺时针旋转
{
if (nSrcType == 1)
{
return 11;
}
else if (nSrcType == 11)
{
return 1;
}
else if (nSrcType == 3)
{
return 33;
}
else if (nSrcType == 33)
{
return 34;
}
else if (nSrcType == 34)
{
return 35;
}
else if (nSrcType == 35)
{
return 3;
}
else if (nSrcType == 4)
{
return 44;
}
else if (nSrcType == 44)
{
return 45;
}
else if (nSrcType == 45)
{
return 46;
}
else if (nSrcType == 46)
{
return 4;
}
else if (nSrcType == 5)
{
return 55;
}
else if (nSrcType >= 55 && nSrcType <= 57)
{
if (nSrcType == 57)
return 5;
else
return ++nSrcType;
}
else if (nSrcType == 6)
{
return 66;
}
else if (nSrcType == 66)
{
return 6;
}
else if (nSrcType == 7)
{
return 77;
}
else if (nSrcType == 77)
{
return 7;
}
else if (nSrcType == 2)
{
return 2;
}
else return 1;
}
/// <summary>
/// 按键事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Main_KeyDown(object sender, KeyEventArgs e)
{
if (!isRuning)
{
return;
}
if (e.KeyCode == Keys.Left)
{
MovePiece(Drection.left,piece);
}
if (e.KeyCode == Keys.Right)
{
MovePiece(Drection.right, piece);
}
if (e.KeyCode == Keys.Up)
{
MovePiece(Drection.up, piece);
}
if (e.KeyCode == Keys.Down)
{
timer1.Interval = 1;
MovePiece(Drection.low, piece);
}
Draw();
}
/// <summary>
/// 绘图
/// </summary>
public void Draw()
{
gride.DrawGrid(DrawPanel.CreateGraphics());
}
/// <summary>
/// 产生新块
/// </summary>
/// <returns></returns>
public Piece CreateNewPiece()
{
Piece p = new Piece();
p.SetPieceType(Next);
Next = random.Next(7) + 1;
return p;
}
/// <summary>
/// 时间事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
Running();
}
/// <summary>
/// 运行
/// </summary>
private void Running()
{
pictureBox1.ImageLocation = "type"+Next + ".bmp";
if (!CanPieceMove(piece, Drection.low))
{
#region 锁定
for (int i = 0; i < 4; i++)
{
if (piece.imagesPoint[i].Y < 0)
{
continue;
}
gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bFixed = true;
}
#endregion
#region 判断消失与计分
for (int i = ROW_NUM-1; i >= 0; i--)
{
int j = 0;
for (; j < COL_NUM; j++)
{
if (gride.cellGrid[i, j].bFixed == false)
{
break;
}
}
if (j == COL_NUM)
{
for (int n = 0; n < COL_NUM; n++)
{
for (int m =i; m>=1; m--)
{
gride.cellGrid[m, n].bFixed = gride.cellGrid[m - 1, n].bFixed;
gride.cellGrid[m, n].bUsed = gride.cellGrid[m - 1, n].bUsed;
}
}
i++;
grade += 10;
label1.Text = "分数:" + grade;
}
}
#endregion
#region 判断结束
for (int n = 0; n < COL_NUM; n++)
{
if (gride.cellGrid[0, n].bFixed == true)
{
if (isEnd == false)
{
isEnd = true;
isRuning = false;
Draw();
MessageBox.Show("游戏结束","结束提示");
}
timer1.Enabled = false;
return;
}
}
#endregion
//产生新块
piece = CreateNewPiece();
timer1.Interval = 500;
return;
}
MovePiece(Drection.low, piece);
Draw();
}
/// <summary>
/// 开始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labStart_Click(object sender, EventArgs e)
{
Start();
}
/// <summary>
/// 暂停
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labstop_Click(object sender, EventArgs e)
{
if (isRuning)
{
timer1.Enabled = false;
stopping = true;
}
}
/// <summary>
/// 继续
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labContinue_Click(object sender, EventArgs e)
{
if (isRuning)
{
if (stopping == true)
{
timer1.Enabled = true;
stopping = false;
}
}
}
}
}