LoginSignup
5
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-12-26
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;
            }
        }
        }
}
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6