WPF C#でテトリスを作ってみた(ソースのみ)

  • 5
    いいね
  • 0
    コメント
Gamemaking.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
//自己記録用です。XAML上で若干弄らないと動きません

namespace Gamemaking
{
    public class Board  //テトリスの画面レイアウトの実装
    {
        private int Rows;
        private int Cols;
        private int Score;
        private int LinesFilled;
        private Tetramino currTetramino;
        private Label[,] BlockControls;


        static private Brush NoBrush = Brushes.Transparent; //静的変数に格納する
        static private Brush SilverBrush = Brushes.Gray;// 上に同じ

        public Board(Grid TetrisGrid)
        {
            Rows = TetrisGrid.RowDefinitions.Count;
            Cols = TetrisGrid.ColumnDefinitions.Count;
            Score = 0;
            LinesFilled = 0;

            BlockControls = new Label[Cols, Rows];
            for (int i = 0; i < Cols; i++)
            {
                for (int j = 0; j < Rows; j++)
                {
                    BlockControls[i, j] = new Label();
                    BlockControls[i, j].Background = NoBrush;
                    BlockControls[i, j].BorderBrush = SilverBrush;
                    BlockControls[i, j].BorderThickness = new Thickness(1, 1, 1, 1);
                    Grid.SetRow(BlockControls[i, j], j);
                    Grid.SetColumn(BlockControls[i, j], i);
                    TetrisGrid.Children.Add(BlockControls[i, j]);
                }
            }
            currTetramino = new Tetramino();
            currTetraminoDraw();
        }
        public int getScore()
        {
            return Score;
        }
        public int getLines()
        {
            return LinesFilled;
        }
        private void currTetraminoDraw()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            Brush Color = currTetramino.getCurrColor();
            foreach (Point S in Shape)
            {
                BlockControls[(int)(S.X + Position.X) + ((Cols / 2) - 1),
                (int)(S.Y + Position.Y) + 2].Background = Color;
            }
        }
        private void currTetraminoErase()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            foreach (Point S in Shape)
            {
                BlockControls[(int)(S.X + Position.X) + ((Cols / 2) - 1),
                (int)(S.Y + Position.Y) + 2].Background = NoBrush;
            }
        }
        private void CheckRows()
        {
            bool full;
            for (int i = Rows - 1; i > 0; i--)
            {
                full = true;
                for (int j = 0; j < Cols; j++)
                {
                    if (BlockControls[j, i].Background == NoBrush)
                    {
                        full = false;
                    }
                }
                if (full)
                {
                    RemoveRow(i);
                    Score += 100;
                    LinesFilled += 1;
                }
            }
        }
        private void RemoveRow(int row)
        {
            for (int i = row; i > 2; i--)
            {
                for (int j = 0; j < Cols; j++)
                {
                    BlockControls[j, i].Background = BlockControls[j, i - 1].Background;
                }
            }
        }
        public void currTetraminoMovLeft()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            bool move = true;
            currTetraminoErase();
            foreach (Point S in Shape)
            {
                if (((int)(S.X + Position.X) + ((Cols / 2) - 1) - 1) < 0)
                {
                    move = false;
                }
                else if (BlockControls[((int)(S.X + Position.X) + ((Cols / 2) - 1) - 1),
                             (int)(Position.Y) + 2].Background != NoBrush)
                {
                    move = false;
                }
            }
            if (move)
            {
                currTetramino.movLeft();
                currTetraminoDraw();
            }
            else
            {
                currTetraminoDraw();
            }
        }
        public void currTetraminoMovRight()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            bool move = true;
            foreach (Point S in Shape)
            {
                if (((int)(S.X + Position.X) + ((Cols / 2) - 1) + 1) >= Cols)
                {
                    move = false;
                }
                else if (BlockControls[((int)(S.X + Position.X) + ((Cols / 2) - 1) + 1),
                             (int)(Position.Y) + 2].Background != NoBrush)
                {
                    move = false;
                }
            }
            if (move)
            {
                currTetramino.movRight();
                currTetraminoDraw();
            }
            else
            {
                currTetraminoDraw();
            }
        }

        public void currTetraminoMovDown()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            bool move = true;
            foreach (Point S in Shape)
            {
                if (((int)(S.Y + Position.Y) + 2 + 1) >= Rows)
                {
                    move = false;
                }
                else if (BlockControls[((int)(S.X + Position.X) + ((Cols / 2) - 1)),
                             (int)(Position.Y) + 2 + 1].Background != NoBrush)
                {
                    move = false;
                }
            }
            if (move)
            {
                currTetramino.movDown();
                currTetraminoDraw();
            }
            else
            {
                CheckRows();
                currTetramino = new Tetramino();
                currTetraminoDraw();
            }
        }

        public void currTetraminoMovRotate()
        {
            Point Position = currTetramino.getCurrPosition();
            Point[] Shape = currTetramino.getCurrShape();
            Point[] S = new Point[4];
            bool move = true;
            Shape.CopyTo(S, 0);
            currTetraminoErase();
            for (int i = 0; i < S.Length; i++)
            {
                double x = S[i].X;
                S[i].X = S[i].Y * -1;
                S[i].Y = x;
                if (((int)((S[i].Y + Position.Y) + 2)) >= Rows)
                {
                    move = false;
                }
                else if (((int)(S[i].X + Position.X) + ((Cols / 2) - 1)) < 0)
                {
                    move = false;
                }
                else if (((int)(S[i].X + Position.X) + ((Cols / 2) - 1)) >= Rows)
                {
                    move = false;
                }
                else if (BlockControls[((int)(S[i].X + Position.X) + ((Cols / 2) - 1)),
                        (int)(S[i].Y + Position.Y) + 2].Background != NoBrush)
                {
                    move = false;
                }
            }
            if (move)
            {
                currTetramino.movRotate();
                currTetraminoDraw();
            }
            else
            {
                currTetraminoDraw();
            }
        }
        public class Tetramino//ブロックの生成など
        {
            private Point currPosition; //ブロックの位置
            private Point[] currShape;//ブロックの形
            private Brush currColor;//ブロックの色指定
            private bool rotate; //ブロックの回転?
            public Tetramino()
            {//上四つの設定
                currPosition = new Point(0, 0);
                currColor = Brushes.Transparent;
                currShape = setRandomShape();
            }
            public Brush getCurrColor()//色
            {
                return currColor;
            }
            public Point getCurrPosition()//位置
            {
                return currPosition;
            }
            public Point[] getCurrShape()//形
            {
                return currShape;
            }
            public void movLeft()//以下4つ動きのための関数
            {
                currPosition.X -= 1;
            }
            public void movRight()
            {
                currPosition.X += 1;
            }

            public void movDown()
            {
                currPosition.Y += 1;
            }
            public void movRotate()//ブロックの回転
            {
                if (rotate)
                {
                    for (int i = 0; i < currShape.Length; i++)
                    {
                        double x = currShape[i].X;
                        currShape[i].X = currShape[i].Y * -1;
                        currShape[i].Y = x;
                    }
                }
            }
            private Point[] setRandomShape()
            {//ブロックの形と色のパターンをswtich文で実装。
                Random rand = new Random();
                switch (rand.Next() % 7)
                {
                    case 0:
                        rotate = true;
                        currColor = Brushes.Cyan;
                        return new Point[] {
                        new Point(0,0),
                        new Point(-1,0),
                        new Point(1,0),
                        new Point(2,0)
            };
                    case 1:
                        rotate = true;
                        currColor = Brushes.Blue;
                        return new Point[] {
                        new Point(1,-1),
                        new Point(-1,0),
                        new Point(0,0),
                        new Point(1,0)
            };
                    case 2:
                        rotate = true;
                        currColor = Brushes.Yellow;
                        return new Point[] {
                        new Point(0,0),
                        new Point(-1,0),
                        new Point(1,0),
                        new Point(1,-1)
            };
                    case 3:
                        rotate = false;
                        currColor = Brushes.Orange;
                        return new Point[] {
                        new Point(0,0),
                        new Point(0,1),
                        new Point(1,0),
                        new Point(1,1)
            };
                    case 4:
                        rotate = true;
                        currColor = Brushes.Green;
                        return new Point[] {
                        new Point(0,0),
                        new Point(-1,0),
                        new Point(0,-1),
                        new Point(1,0)
            };
                    case 5:
                        rotate = true;
                        currColor = Brushes.Purple;
                        return new Point[] {
                        new Point(0,0),
                        new Point(-1,0),
                        new Point(0,-1),
                        new Point(1,1)
            };
                    case 6:
                        rotate = true;
                        currColor = Brushes.Red;
                        return new Point[] {
                        new Point(0,0),
                        new Point(-1,0),
                        new Point(0,1),
                        new Point(1,1)
            };
                    default:
                        return null;
                }
            }
        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DispatcherTimer Timer;
        Board myBoard;
        public MainWindow()
        {
            InitializeComponent();
        }
        void MainWindow_Initialized(object sender, EventArgs e)
        {
            Timer = new DispatcherTimer();
            Timer.Tick += new EventHandler(GameTick);
            Timer.Interval = new TimeSpan(0, 0, 0, 0, 400);
            GameStart();
        }
        private void GameStart()
        {
            MainGrid.Children.Clear();
            myBoard = new Board(MainGrid);
            Timer.Start();
        }
        void GameTick(object sender, EventArgs e)
        {
            Scores.Content = myBoard.getScore().ToString("0000000000");
            Lines.Content = myBoard.getLines().ToString("00000000000");
            myBoard.currTetraminoMovDown();
        }
        private void GamePause()
        {
            if (Timer.IsEnabled) Timer.Stop();
            else Timer.Start();
        }
        private void HandleKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Left:
                    if (Timer.IsEnabled) myBoard.currTetraminoMovLeft();
                    break;
                case Key.Right:
                    if (Timer.IsEnabled) myBoard.currTetraminoMovRight();
                    break;
                case Key.Down:
                    if (Timer.IsEnabled) myBoard.currTetraminoMovDown();
                    break;
                case Key.Up:
                    if (Timer.IsEnabled) myBoard.currTetraminoMovRotate();
                    break;
                case Key.F2:
                    GameStart();
                    break;
                case Key.F3:
                    GamePause();
                    break;
            }
        }
        }
}