⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cs

📁 中文名:Windows Forms 程序设计 英文名:Windows Forms Programming in c# 作者: Chris Sells 翻译: 荣耀 蒋贤哲 出版社:人民
💻 CS
字号:
using System;
using System.Drawing;
using System.Collections;
using System.Diagnostics;

namespace WahooControlLibrary {

  class Game {

    Size size;
    int rows;
    int cols;
    int cellPadding;
    bool isOver;
    int linesRemoved;
    Shape currentShape;
    Random rnd = new Random();
    Color[,] cellColors;
    
    public void Tick() {
      // When the current shape gets to the bottom...
      if( !this.currentShape.Down() ) {
        // If we collide on the first line, game over
        if( this.currentShape.Row == 0 ) {
          this.isOver = true;
          return;
        }

        // Move current shape to set of filled cells
        AcquireCurrentShape();

        // Remove the filled lines (and update the score)
        int fillsFound = CheckFills(this.currentShape.Row, this.currentShape.Height);
        this.linesRemoved += fillsFound;

        // Create a new shape
        this.currentShape = GetRandomShape();
      }
    }

    public void Draw(Graphics g) {
      // Draw the board background
      Rectangle topLeftCell = GetCellRectangle(this.size, this.rows, this.cols, this.cellPadding, 0, 0);
      Rectangle bottomRightCell = GetCellRectangle(this.size, this.rows, this.cols, this.cellPadding, this.rows - 1, this.cols - 1);
      Rectangle gameRect = new Rectangle(topLeftCell.Left, topLeftCell.Top, bottomRightCell.Right - topLeftCell.Left, bottomRightCell.Bottom - topLeftCell.Top);
      gameRect.Inflate(this.cellPadding, this.cellPadding);
      g.DrawRectangle(Pens.Black, gameRect);

      // Draw the current shape
      if( this.currentShape != null ) this.currentShape.Draw(g);

      // Draw the colored cells left behind by old shapes
      for( int row = 0; row != this.rows; ++row ) {
        for( int col = 0; col != this.cols; ++col ) {
          if( CellFilled(row, col) ) DrawCell(g, this.cellColors[row, col], row, col);
        }
      }
    }

    public bool CellFilled(int row, int col) {
      // If we're out of bounds, report that as filled
      // That will cause the edges to act as a boundary
      // and prevent turning a shape out of bounds
      if( row < 0 || row >= this.rows ) return true;
      if( col < 0 || col >= this.cols ) return true;

      // Check the visible cells
      return !this.cellColors[row, col].IsEmpty;
    }

    public bool Drop() {
      // Drop as far as we can
      while( this.currentShape.Down() ) ;
      return true;
    }

    public bool Left() {
      return this.currentShape.Left();
    }

    public bool Right() {
      return this.currentShape.Right();
    }

    public bool RotateRight() {
      return this.currentShape.RotateRight();
    }

    public bool RotateLeft() {
      return this.currentShape.RotateLeft();
    }

    public void Reset() {
      this.isOver = false;
      this.linesRemoved = 0;
      ResetRowCol();
      this.currentShape = GetRandomShape();
    }

    protected Shape GetRandomShape() {
      Shape shape = null;

      switch( this.rnd.Next(0, 7) ) {
        case 0: shape = new ShapeT(this); break;
        case 1: shape = new ShapeCrook1(this); break;
        case 2: shape = new ShapeCrook2(this); break;
        case 3: shape = new ShapeL1(this); break;
        case 4: shape = new ShapeL2(this); break;
        case 5: shape = new ShapeLine(this); break;
        case 6: shape = new ShapeBox(this); break;
        default: Debug.Assert(false, "Check your random usage"); return null;
      }

      int colCentered = (this.cols - shape.Width) / 2;
      while( colCentered-- != 0 ) shape.Right();
      return shape;
    }

    protected void FillCell(int row, int col, Color color) {
      this.cellColors[row, col] = color;
    }

    protected void ClearCell(int row, int col) {
      this.cellColors[row, col] = new Color();
    }

    protected Color CellColor(int row, int col) {
      return this.cellColors[row, col];
    }

    protected void AcquireCurrentShape() {
      // Make all currently set cells in the shape part of the cells of the game
      Color color = this.currentShape.Color;
      for( int row = 0; row != this.currentShape.Height; ++row ) {
        for( int col = 0; col != this.currentShape.Width; ++col ) {
          if( this.currentShape.CellFilled(row, col) ) {
            FillCell(row + this.currentShape.Row, col + this.currentShape.Column, color);
          }
        }
      }
    }

    protected void MoveLines(int bottomRow) {
      // Move bottomRow to not quite the top
      for( int row = bottomRow - 1; row > 0; --row ) {
        for( int col = 0; col != this.cols; ++col ) {
          FillCell(row + 1, col, CellColor(row, col));
        }
      }

      // Clear the top row
      for( int col = 0; col != this.cols; ++col ) {
        ClearCell(0, col);
      }
    }

    protected int CheckFills(int topRow, int height) {
      int filledLines = 0;

      for( int row = topRow; row != topRow + height; ++row ) {
        bool lineFilled = true;
        for( int col = 0; col != this.cols; ++col ) {
          if( !CellFilled(row, col) ) { lineFilled = false; break; }
        }

        if( lineFilled ) {
          ++filledLines;
          MoveLines(row);
          --row; // Check this line again
        }
      }

      return filledLines;
    }

    public bool IsOver {
      get { return this.isOver; }
    }

    public int LinesRemoved {
      get { return this.linesRemoved; }
    }

    public Size Size {
      get { return this.size; }
      set { this.size = value; }
    }

    public int Rows {
      get { return this.rows; }
      set { this.rows = value; ResetRowCol(); }
    }

    public int Columns {
      get { return this.cols; }
      set { this.cols = value; ResetRowCol(); }
    }

    public int CellPadding {
      get { return this.cellPadding; }
      set { this.cellPadding = value; }
    }

    protected void ResetRowCol() {
      this.cellColors = new Color[this.rows, this.cols];
    }

    internal void DrawCell(Graphics g, Color color, int row, int col) {
      // TODO: Cache brushes -- we're only using 7 colors!
      using( Brush brush = new SolidBrush(color) ) {
        Rectangle rect = GetCellRectangle(this.size, this.rows, this.cols, this.cellPadding, row, col);
        rect.Inflate(-1, -1);
        g.FillRectangle(brush, rect);
        g.DrawRectangle(Pens.Black, rect);
        rect.Inflate(1, 1);
        g.DrawRectangle(Pens.White, rect);
      }
    }

    // Calculate a cell rectangle given a game size, how many rows and cols in a game,
    // the amount of padding around each cell and the cell in question.
    // NOTE: This is more calculation than we strictly need to do, but it's
    // handy for drawing the design view as well as if these properties change on the fly.
    internal static Rectangle GetCellRectangle(Size size, int rows, int cols, int cellPadding, int row, int col) {
      // This algorithm fills the area defined by size, making each cell a rectangle
      //            int cx = (size.Width - cellPadding * (cols + 1))/cols;
      //            int cy = (size.Height - cellPadding * (rows + 1))/rows;
      //            int x = cellPadding + (cx + cellPadding) * col;
      //            int y = cellPadding + (cy + cellPadding) * row;
      //            return new Rectangle(x, y, cx, cy);

      // This algorithm fills the center of the area defined by size, making each cell a square
      int cx = (size.Width - cellPadding * (cols + 1)) / cols;
      int cy = (size.Height - cellPadding * (rows + 1)) / rows;
      int side = Math.Min(cx, cy);
      int cxTotal = (side + cellPadding) * cols + cellPadding;
      int cyTotal = (side + cellPadding) * rows + cellPadding;
      int leftOffset = (size.Width - cxTotal) / 2;
      int topOffset = (size.Height - cyTotal) / 2;
      int x = leftOffset + cellPadding + (side + cellPadding) * col;
      int y = topOffset + cellPadding + (side + cellPadding) * row;
      return new Rectangle(x, y, side, side);
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -