
Hello,
I am working on a tetris game for the XBox 360 in my console development class. I have the code running good, with all the collision working along with the pieces falling at the right pace. I also have the movement working. The only thing I am having trouble with is the shape rotation. I was wondering if maybe someone can help me out. Here is my solution: Did I mention that I am working with XNA 4.0 game studio in C#.
Thanks,
bigdawg
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
namespace Tetris
{
// class
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D Shape1;
Texture2D Jellyfish;
int shapeColor;
Color[] colors;
Texture2D blank;
Vector2 position = new Vector2(0, 0); //
//int numOfFrames = 0;
//double FPS = 0;
int[,] bottomBlocks;
KeyboardState keyboardState; //Keyboard class
List<Vector2> fallingBlocks;
// Regulates the falling block speed
int fallSpeedFast = 15;
int fallSpeedRegular = 30;
int fallSpeedState = 30;
//private SpriteFont font;
Random random;
public Game1()
{
graphics = new GraphicsDeviceManager(this); // map
graphics.PreferredBackBufferWidth = 480; //
graphics.PreferredBackBufferHeight = 640; //
graphics.ApplyChanges();
Content.RootDirectory = "Content"; //
}
protected override void Initialize()
{
random = new Random();
keyboardState = Keyboard.GetState();
colors = new Color[] { Color.Red, Color.Blue, Color.Green, Color.Yellow, Color.Orange, Color.Purple }; // Tetris shape colors
bottomBlocks = new int[10, 20]; // bottom of screen
for (int countX = 0; countX < bottomBlocks.GetLength(0); countX++) //
{
for (int countY = 0; countY < bottomBlocks.GetLength(1); countY++) //
{
bottomBlocks[countX, countY] = -1; //
}
}
ResetFalling(); // Resets the falling blocks
base.Initialize(); //
}
void ResetFalling() // Deals with the falling shapes
{
shapeColor = random.Next(0, 6); // For dropping the shapes at random
fallingBlocks = new List<Vector2>();
if (shapeColor == 0) // If statements that put the tetris shapes together
{
fallingBlocks.Add(new Vector2(4, 0)); // Red
fallingBlocks.Add(new Vector2(5, 0));
fallingBlocks.Add(new Vector2(4, 1));
fallingBlocks.Add(new Vector2(5, 1));
}
else if (shapeColor == 1)
{
fallingBlocks.Add(new Vector2(4, 0)); // Blue
fallingBlocks.Add(new Vector2(3, 0));
fallingBlocks.Add(new Vector2(5, 0));
fallingBlocks.Add(new Vector2(6, 0));
}
else if (shapeColor == 2)
{
fallingBlocks.Add(new Vector2(4, 0)); // Green
fallingBlocks.Add(new Vector2(3, 0));
fallingBlocks.Add(new Vector2(5, 0));
fallingBlocks.Add(new Vector2(3, 1));
}
else if (shapeColor == 3)
{
fallingBlocks.Add(new Vector2(4, 0)); // Yellow
fallingBlocks.Add(new Vector2(4, 1));
fallingBlocks.Add(new Vector2(3, 1));
fallingBlocks.Add(new Vector2(5, 0));
}
else if (shapeColor == 4)
{
fallingBlocks.Add(new Vector2(4, 0)); // Orange
fallingBlocks.Add(new Vector2(3, 0));
fallingBlocks.Add(new Vector2(4, 1));
fallingBlocks.Add(new Vector2(5, 1));
}
else if (shapeColor == 5)
{
fallingBlocks.Add(new Vector2(4, 0)); // Purple
fallingBlocks.Add(new Vector2(3, 0));
fallingBlocks.Add(new Vector2(4, 1));
fallingBlocks.Add(new Vector2(5, 0));
}
}
void ClearRows() // This function clears a complete row when a row is completeted
{
for (int countY = bottomBlocks.GetLength(1) - 1; countY >= 0; countY--)
{
bool clearRow = true;
for (int countX = 0; countX < bottomBlocks.GetLength(0); countX++)
{
clearRow &= bottomBlocks[countX, countY] != -1;
}
if (clearRow)
{
for (int countX = 0; countX < bottomBlocks.GetLength(0); countX++)
{
bottomBlocks[countX, countY] = -1;
}
for (int y = countY; y > 0; y--)
{
for (int countX = 0; countX < bottomBlocks.GetLength(0); countX++)
{
bottomBlocks[countX, y] = bottomBlocks[countX, y - 1];
}
}
countY++;
}
}
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
blank = Content.Load<Texture2D>("blank"); // This is a filling shape
Shape1 = Content.Load<Texture2D>("Shape1"); // This is the Tetris shape design
Jellyfish = Content.Load<Texture2D>("Jellyfish"); // The background of the playing area
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
KeyboardState keyboardCurrent = Keyboard.GetState();
if (keyboardCurrent.IsKeyDown(Keys.Left) & keyboardState.IsKeyUp(Keys.Right))
{
bool clear = true;
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.X--;
int x = (int)block.X;
int y = (int)block.Y;
clear &= (block.X >= 0) && bottomBlocks[x, y] == -1;
}
if (clear)
{
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.X --;
fallingBlocks[count] = block;
}
}
}
else if (keyboardCurrent.IsKeyDown(Keys.Right) & keyboardState.IsKeyUp(Keys.Right))
{
bool clear = true;
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.X++;
int x = (int)block.X;
int y = (int)block.Y;
clear &= (block.X <= 9) && bottomBlocks[x, y] == -1;
}
if (clear)
{
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.X++;
fallingBlocks[count] = block;
}
}
}
if (keyboardCurrent.IsKeyDown(Keys.Up) & keyboardState.IsKeyUp(Keys.Up)) // Turns the shape
{
if (shapeColor == 0)
{
}
else if (shapeColor == 1)
{
shapeColor1();
}
}
if (keyboardCurrent.IsKeyDown(Keys.Down) & keyboardState.IsKeyUp(Keys.Down)) // This speeds the shape decent when you press the down button
{
fallSpeedState = 0; //
}
else if (keyboardCurrent.IsKeyUp(Keys.Down) & keyboardState.IsKeyDown(Keys.Down)) //
{
fallSpeedState = fallSpeedRegular; //
}
// Block falling and collision
if (fallSpeedState <= 0)
{
if (keyboardCurrent.IsKeyDown(Keys.Down))
{
fallSpeedState = fallSpeedFast;
}
else
{
fallSpeedState = fallSpeedRegular;
}
bool clear = true;
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.Y++;
int x = (int)block.X;
int y = (int)block.Y;
clear &= (block.Y <= 19) && bottomBlocks[x, y] == -1;
}
if (clear)
{
for (int count = 0; count < fallingBlocks.Count; count++)
{
var block = fallingBlocks[count];
block.Y++;
fallingBlocks[count] = block;
}
}
else
{
while (fallingBlocks.Count > 0)
{
int x = (int)fallingBlocks[0].X;
int y = (int)fallingBlocks[0].Y;
bottomBlocks[x, y] = shapeColor;
fallingBlocks.RemoveAt(0);
}
ClearRows();
ResetFalling();
}
}
else
{
fallSpeedState--;
}
keyboardState = keyboardCurrent;
//
base.Update(gameTime);
}
// This is my rotation
bool shapeColor1()
{
bool rotate = true;
if (rotate)
{
fallingBlocks.Add(new Vector2(4, 0)); // Blue
fallingBlocks.Add(new Vector2(4, 1));
fallingBlocks.Add(new Vector2(4, 2));
fallingBlocks.Add(new Vector2(4, 3));
}
{
fallingBlocks.Remove(new Vector2(4, 0));
fallingBlocks.Remove(new Vector2(3, 0));
fallingBlocks.Remove(new Vector2(5, 0));
fallingBlocks.Remove(new Vector2(6, 0));
}
return rotate;
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Blue); // Color for the non-playing area
spriteBatch.Begin();
spriteBatch.Draw(Jellyfish, new Rectangle(0, 0, bottomBlocks.GetLength(0) * 32, bottomBlocks.GetLength(1) * 32), Color.DarkGray); //Draws the background to the playing area
for (int countX = 0; countX < bottomBlocks.GetLength(0); countX++)
{
for (int countY = 0; countY < bottomBlocks.GetLength(1); countY++)
{
int currentColor = bottomBlocks[countX, countY];
if (currentColor != -1)
{
spriteBatch.Draw(Shape1, new Rectangle(countX * 32, countY * 32, 32, 32), colors[currentColor]); // This draws the design on the tetris shapes
}
}
}
for (int count = 0; count < fallingBlocks.Count; count++)
{
int x = (int)fallingBlocks[count].X;
int y = (int)fallingBlocks[count].Y;
spriteBatch.Draw(Shape1, new Rectangle(x * 32, y * 32, 32, 32), colors[shapeColor]); // This also draws the design on shapes
}
8)
spriteBatch.End();
//
base.Draw(gameTime);
}
public int x { get; set; } // Not sure why but if this is deleted I get an error
public int y { get; set; } // Not sure why but if this is deleted I get an error
public bool rotate { get; set; }
}
}