Reputation: 137
I am making Tetris in C#. I have now created a playfield and the figures with their possible rotations. I am making it in Winforms. The playfield has a 2d-array and the figures too. The playfield is standard filled with the values 0, what means that it is empty. The figures are filled with the values 1 what means it is filled and 0. In this way I can create figures. The labels are the visual part of the game. This is my code so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TetrisTest
{
public partial class Form1 : Form
{
private Label label;
public Form1()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
int[,] figureI = {{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0}};
int[,] figureL = {{1, 0, 0},
{1, 0, 0},
{1, 1, 0}};
int[,] figureJ = {{0, 1, 0},
{0, 1, 0},
{1, 1, 0}};
int[,] figureT = {{1, 1, 1},
{0, 1, 0},
{0, 0, 0}};
int[,] figureO = {{1, 1},
{1, 1}};
int[,] figureS = {{0, 1, 1},
{1, 1, 0},
{0, 0, 0}};
int[,] figureZ = {{1, 1, 0},
{0, 1, 1},
{0, 0, 0}};
var figureI2 = RotateRight(figureI);
var figureL2 = RotateRight(figureL);
var figureL3 = RotateRight(figureL2);
var figureL4 = RotateRight(figureL3);
var figureJ2 = RotateRight(figureJ);
var figureJ3 = RotateRight(figureJ2);
var figureJ4 = RotateRight(figureJ3);
var figureT2 = RotateRight(figureT);
var figureT3 = RotateRight(figureT2);
var figureT4 = RotateRight(figureT3);
var figureS2 = RotateRight(figureS);
var figureS3 = RotateRight(figureS2);
var figureS4 = RotateRight(figureS3);
var figureZ2 = RotateRight(figureZ);
var figureZ3 = RotateRight(figureZ2);
var figureZ4 = RotateRight(figureZ3);
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 20; j++)
{
label = new Label();
label.AutoSize = false;
label.Name = "label" + j.ToString() + i.ToString();
label.TabIndex = 0;
label.Text = "[" + j.ToString() + "]" + "[" + i.ToString() + "]";
label.Visible = true;
this.Controls.Add(label);
label.Location = new Point(Size.Width / 2 - (5 - i) * 50, Size.Height / 2 - (11 - j) * 30);
label.Size = new Size(50, 30);
label.BackColor = Color.White;
if (i % 2 == 0)
{
label.BackColor = Color.Blue;
}
}
}
int valueNone = 0;
int[,] playField = new int[10, 20];
foreach (int b in playField)
{
playField[b, b] = valueNone;
Console.WriteLine(playField[b, b]);
}
}
static int[,] RotateRight(int[,] arr)
{
int size = arr.GetLength(0);
int[,] rotated = new int[size, size];
for (int j = 0; j < size; j++)
for (int i = size - 1; i >= 0; i--)
rotated[j, size - i - 1] = arr[i, j];
return rotated;
}
private void startGame_Click(object sender, EventArgs e)
{
}
}
}
I am a bit stuck now. I know I need a timer, because the figures need to move down automatically over time. But what I don't know is firstly: how I can get the figures in the playfield. And secondly: make sure the figures stop as soon as the value 1 in the figures-array hits the value 1 in the playfield-array. In this way I can create the game. I hope someone can help me with this, because I have no idea.
Upvotes: 0
Views: 109
Reputation: 2371
Well, this is a whole project. I'm going to give you my impressions and some keys about how I do a project like this. First of all, you need do a previous review of the entire project and try to get all your actors.
For example, you need a class for the Board with the array and properties like Width/Height. If you need some statistics (like number of figures...) you can have a list of Figures. If not, you may use a byte value, with the index of color or directly the color itself. We choose the last option, the easier one. The board has an array of Colors, black at first.
You need also a Figure, with an array like your example and a Color. It has also an X, Y property (position of upper left array). This class can have methods like Rotate, GetWidth and GetHeight because the array may be bigger than the figure (figureI in vertical, for example, has 1 of width but 4 in the array to allow the rotation) and you need work with the figure when you move in the board and check collision with other figures.
Add a Game class with a Board and a Figure (the current figure). Add a TryMoveFigure(bool right) that return true if you can move the current figure in that direction. You have access to the board and the current figure. Simply check if values of figure (filtering black positions) moved in that direction are inside the board and not overlap previous figures (the color in the board is black in this zone). If figure may move, you update it's X property.
Add a TryMoveDown() to try move figure down (update Y property).
And you need a method to know when the figure can't move anymore. IsFigureStopped return true in this case.
The game may have a Draw method (Draw(Graphics g)) in which you invoke Draw of board and draw of current figure. In all cases you are going to invoke g.FillRectangle with each cell of the board. The board has the color of any cell, simply get the coordinates and draw it. The figure is similar: you know the position of its array and (filtering blacks items) draw each position.
And for the logic:
You can draw everything using a Panel, for example, in the Paint event. Remember invoke Invalidate of your Panel each time that your image change (you move a figure, for example) to indicate to Windows that you want redraw the panel.
Let me know if you want to develop it in this way and need some help.
Upvotes: 2