private void elementMove(object obj) { TetrisElement telement = obj as TetrisElement; while (isRunning && telement != null) { if (!isMove) { telement = TetrisFactory.move(tcontainer, telement, TetrisDirection.DEFAULT); } Thread.Sleep(500); } element = telement; }
/// <summary> /// 后台线程执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BgWorker_DoWork(object sender, DoWorkEventArgs e) { while (isRunning) { if (element == null) { //如果元素为空,则创建元素,并启动新线程 element = TetrisFactory.generate(); Thread t = new Thread(new ParameterizedThreadStart(elementMove)); t.Start(element); } else { //暂停1秒钟 Thread.Sleep(1000); } } }
/// <summary> /// 更新tetris /// </summary> /// <param name="element"></param> private void updateTetris(TetrisElement element) { Point location = element.location; Point[] content = element.content; int minX = element.getMinX(element.style); int maxX = element.getMaxX(element.style); int minY = element.getMinY(element.style); int maxY = element.getMaxY(element.style); foreach (Point p in content) { if (location.Y + p.Y < 20 && location.Y + p.Y >= 0 && location.X + p.X >= 0 && location.X + p.X < 10) { this.tetris[location.X + p.X, location.Y + p.Y] = 1; } } }
/// <summary> /// 静态函数,生成Tetris元素对象 /// </summary> /// <returns></returns> public static TetrisElement generate() { Random r = new Random(0); //随机生成形状 int tstyle = getRandom(); tstyle = tstyle % 7; TetrisStyle style = TetrisStyle.I; style = (TetrisStyle)Enum.Parse(typeof(TetrisStyle), tstyle.ToString()); //随机生成起始坐标 int x = getRandom(); x = x % 10; int y = 0; //根据形状生成位置信息 TetrisElement element = new TetrisElement(style); //内容由四个点组成,顺序:先上后下,先左后右 Point[] content = element.getContent(style); //获取最小坐标和最大坐标,防止越界 int minX = element.getMinX(style); int minY = element.getMinY(style); int maxX = element.getMaxX(style); int maxY = element.getMaxY(style); //修正起始坐标 x = (x <= minX) ? minX : x; x = (x >= maxX) ? maxX : x; y = minY; Point location = new Point(x, y); element.location = location; element.content = content; return(element); }
/// <summary> /// 移动元素 /// </summary> /// <param name="container"></param> /// <param name="element"></param> /// <param name="direction"></param> /// <returns></returns> public static TetrisElement move(TetrisContainer container, TetrisElement element, TetrisDirection direction) { return(container.change(element, direction)); }
/// <summary> /// 判断是否可以向右移动 /// </summary> /// <param name="element"></param> /// <returns></returns> private bool checkRight(TetrisElement element) { Point location = element.location; Point[] content = element.content; int maxY = element.getMaxY(element.style); int maxX = element.getMaxX(element.style); int minX = element.getMinX(element.style); int minY = element.getMinY(element.style); bool flag = false; if (location.Y >= 0) { switch (element.style) { case TetrisStyle.I: if (location.X <= maxX) { //I形状,如果没有到最左边,且左边一排元素为空,则返回true if (location.X + content[0].X + 1 < 10 && this.tetris[location.X + content[0].X + 1, location.Y + content[0].Y] == 0 && this.tetris[location.X + content[1].X + 1, location.Y + content[1].Y] == 0 && this.tetris[location.X + content[2].X + 1, location.Y + content[2].Y] == 0 && this.tetris[location.X + content[3].X + 1, location.Y + content[3].Y] == 0) { flag = true; } } break; case TetrisStyle.J: if (location.X <= maxX) { //J形状,如果没有到底,且第1,2,3个元素的左面都为空,则返回true if (location.X + content[0].X + 1 < 10 && this.tetris[location.X + content[0].X + 1, location.Y + content[0].Y] == 0 && this.tetris[location.X + content[1].X + 1, location.Y + content[1].Y] == 0 && this.tetris[location.X + content[2].X + 1, location.Y + content[2].Y] == 0) { flag = true; } } break; case TetrisStyle.L: //L形状,如果没有到底,且第1,2,4个元素的左面都为空,则返回true if (location.X <= maxX) { if (location.X + content[0].X + 1 < 10 && this.tetris[location.X + content[0].X + 1, location.Y + content[0].Y] == 0 && this.tetris[location.X + content[1].X + 1, location.Y + content[1].Y] == 0 && this.tetris[location.X + content[3].X + 1, location.Y + content[3].Y] == 0) { flag = true; } } break; case TetrisStyle.O: case TetrisStyle.Z: //O形状,如果没有到底,且第2,4个元素的左面都为空,则返回true if (location.X <= maxX) { if (location.X + content[1].X + 1 < 10 && this.tetris[location.X + content[1].X + 1, location.Y + content[1].Y] == 0 && this.tetris[location.X + content[3].X + 1, location.Y + content[3].Y] == 0) { flag = true; } } break; case TetrisStyle.S: //S形状,如果没有到底,且第1,3个元素的左面都为空,则返回true if (location.X <= maxX) { if (location.X + content[0].X + 1 < 10 && this.tetris[location.X + content[0].X + 1, location.Y + content[0].Y] == 0 && this.tetris[location.X + content[2].X + 1, location.Y + content[2].Y] == 0) { flag = true; } } break; case TetrisStyle.T: //T形状,如果没有到底,且第3,4个元素的左面都为空,则返回true if (location.X <= maxX) { if (location.X + content[3].X + 1 < 10 && this.tetris[location.X + content[2].X + 1, location.Y + content[2].Y] == 0 && this.tetris[location.X + content[3].X + 1, location.Y + content[3].Y] == 0) { flag = true; } } break; default: if (location.X <= maxX) { //I形状,如果没有到最左边,且左边一排元素为空,则返回true if (location.X + content[0].X + 1 < 10 && this.tetris[location.X + content[0].X + 1, location.Y + content[0].Y] == 0 && this.tetris[location.X + content[1].X + 1, location.Y + content[1].Y] == 0 && this.tetris[location.X + content[2].X + 1, location.Y + content[2].Y] == 0 && this.tetris[location.X + content[3].X + 1, location.Y + content[3].Y] == 0) { flag = true; } } break; } } return(flag); }
/// <summary> /// 状态发生改变 /// </summary> /// <param name="element"></param> /// <param name="direction"></param> /// <returns></returns> public TetrisElement change(TetrisElement element, TetrisDirection direction) { TetrisElement tmp = null; //判断不同的方向 switch (direction) { case TetrisDirection.DEFAULT: //如果可以向下移动 if (checkDefault(element)) { //向下移动一个元素 element.move(element.location.X, element.location.Y + 1); tmp = element; } else { //如果不可以向下移动,则更新容器 updateTetris(element); tmp = null; } break; case TetrisDirection.DOWN: break; case TetrisDirection.UP: break; case TetrisDirection.LEFT: if (checkLeft(element)) { //判断是否可以向左移动 //向下移动一个元素 element.move(element.location.X - 1, element.location.Y); tmp = element; } break; case TetrisDirection.RIGHT: if (checkRight(element)) { //判断是否可以右左移动 //向下移动一个元素 element.move(element.location.X + 1, element.location.Y); tmp = element; } break; } //局部变更 if (onPartialChanged != null) { Point location = element.location; Point[] content = new Point[4]; element.content.CopyTo(content, 0); for (int i = 0; i < content.Length; i++) { content[i].X = location.X + content[i].X; content[i].Y = location.Y + content[i].Y; } onPartialChanged(location, content, direction); } //判断游戏是否结束 if (onCompleted != null) { if (checkComplete()) { onCompleted(); } } //全部变更 if (onFullChanged != null) { //判断是是否有权为1的行,如果有则消掉 int[] rows = checkAllTetris(); if (rows.Length > 0) { updateAllTetris(rows);//消掉行 onFullChanged(tetris); } } return(tmp); }
/// <summary> /// 判断默认情况:下方是否有元素 /// </summary> /// <returns></returns> private bool checkDefault(TetrisElement element) { Point location = element.location; Point[] content = element.content; int maxY = element.getMaxY(element.style); int maxX = element.getMaxX(element.style); int minX = element.getMinX(element.style); int minY = element.getMinY(element.style); bool flag = false; switch (element.style) { case TetrisStyle.I: if (location.Y > minY) { //I形状,如果没有到底,且最下面一个元素为空,则返回true if (location.Y + content[3].Y + 1 < 20 && this.tetris[location.X, location.Y + content[3].Y + 1] == 0) { flag = true; } } else { flag = true; } break; case TetrisStyle.J: case TetrisStyle.L: case TetrisStyle.O: if (location.Y > minY) { //J,L,O形状,如果没有到底,且第3,4个元素的下面都为空,则返回true if (location.Y + content[3].Y + 1 < 20 && this.tetris[location.X + content[2].X, location.Y + content[2].Y + 1] == 0 && this.tetris[location.X + content[3].X, location.Y + content[3].Y + 1] == 0) { flag = true; } } else { flag = true; } break; case TetrisStyle.S: case TetrisStyle.T: case TetrisStyle.Z: if (location.Y > minY) { //S,T,Z形状如果没有到底,且第1,3,4个元素的下面都为空,则返回true if (location.Y + content[3].Y + 1 < 20 && this.tetris[location.X + content[0].X, location.Y + content[0].Y + 1] == 0 && this.tetris[location.X + content[2].X, location.Y + content[2].Y + 1] == 0 && this.tetris[location.X + content[3].X, location.Y + content[3].Y + 1] == 0) { flag = true; } } else { flag = true; } break; default: if (location.Y > minY) { //默认I形状,如果没有到底,且最下面一个元素为空,则返回true if (location.Y + content[3].Y + 1 < 20 && this.tetris[location.X, location.Y + content[3].Y + 1] == 0) { flag = true; } } else { flag = true; } break; } return(flag); }