I tried two different way to collect coins and both didn't work. I don't know what I'm doing wrong. I'm coding in c#. Is there something I'm missing or is there something I'm supposed to do beforehand?
Here is method number 1:
//collecting coins
foreach(Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "coin")
{
if (((PictureBox)x).Bounds.IntersectsWith(pacman.Bounds))
{
this.Controls.Remove(x); //remove that point
score++; // add to the score
}
}
}
and Here is method number 2:
//collecting coins
foreach(Control x in this.Controls)
{
if (x is PictureBox)
{
if ((string)x.Tag == "coin" && x.Visible == true)
{
if (pacman.Bounds.IntersectsWith(x.Bounds))
{
score += 1;
x.Visible = false;
}
}
}
}
This is work in progress so the code is still missing some parts. Here is a bit of the source code:
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 Pac_Man_Game_Clone
{
public partial class Form1 : Form
{
bool goup, godown, goright, goleft, isGameOver;
int score, playerSpeed, redGhostSpeed, yellowGhostSpeed, pinkGhostX, pinkGhostY;
public Form1()
{
InitializeComponent();
restGame();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void keyisdown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Up)
{
goup= true;
}
if(e.KeyCode == Keys.Down)
{
godown= true;
}
if(e.KeyCode == Keys.Left)
{
goleft= true;
}
if(e.KeyCode == Keys.Right)
{
goright= true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
goup = false;
}
if (e.KeyCode == Keys.Down)
{
godown = false;
}
if (e.KeyCode == Keys.Left)
{
goleft = false;
}
if (e.KeyCode == Keys.Right)
{
goright = false;
}
}
private void mainGameTimer(object sender, EventArgs e)
{
txtScore.Text = "Score: " + score;
//moving pacman
if(goleft == true)
{
pacman.Left -= playerSpeed;
pacman.Image = Properties.Resources.left;
}
if(goright == true)
{
pacman.Left += playerSpeed;
pacman.Image = Properties.Resources.right;
}
if(godown == true)
{
pacman.Top += playerSpeed;
pacman.Image = Properties.Resources.down;
}
if(goup == true)
{
pacman.Top -= playerSpeed;
pacman.Image = Properties.Resources.Up;
}
//leaving the parameters
//left and right
if (pacman.Left < -10)
{
pacman.Left = 680;
}
if (pacman.Left > 680)
{
pacman.Left = -10;
}
//up and down
if (pacman.Top < -10)
{
pacman.Top = 550;
}
if (pacman.Top > 550)
{
pacman.Top = -10;
}
//collecting coins
foreach(Control x in this.Controls)
{
if (x is PictureBox)
{
if ((string)x.Tag == "coin" && x.Visible == true)
{
if (pacman.Bounds.IntersectsWith(x.Bounds))
{
score += 1;
x.Visible = false;
}
}
}
//runs through wall
if ((string)x.Tag == "wall")
{
if (pacman.Bounds.IntersectsWith(x.Bounds))
{
// run game over
}
}
//bumps to ghost
if ((string)x.Tag == "ghost")
{
if (pacman.Bounds.IntersectsWith(x.Bounds))
{
// run game over
}
}
}
//moving ghosts
redGhost.Left += redGhostSpeed;
if (redGhost.Bounds.IntersectsWith(pictureBox1.Bounds || redGhost.Bounds.IntersectsWith(pictureBox2.Bounds))
{
redGhost += redGhostSpeed;
}
if (score == int.MaxValue)
{
//run game over
}
}
private void restGame()
{
txtScore.Text = "Score: 0";
score= 0;
redGhostSpeed = 5;
yellowGhostSpeed = 5;
pinkGhostX = 5;
pinkGhostY = 5;
playerSpeed = 8;
isGameOver= false;
pacman.Left = 7;
pacman.Top= 35;
redGhost.Left = 219;
redGhost.Top = 56;
yellowGhost.Left = 450;
yellowGhost.Top = 447;
pinkGhost.Left = 521;
pinkGhost.Top = 227;
foreach(Control x in this.Controls)
{
if(x is PictureBox)
{
x.Visible= true;
}
}
gameTimer.Start();
}
private void gameOver(string message)
{
}
}
}
Without having the full source code and the visual tree, I can only try to understand why this isn't working. To me looks like the pacman object isn't defined in the same parent as the coins.
The bounds property is relative to the parent control as coordinate origin.
It works well if each element in the collection of controls are in at the same level of the visual tree, with the same parent. If not, intersect will hardly be true because it is checking against two different coordinate origins, and even if returns true, the position on screen could not match.
As your pacman seems to be referred somewhere else than your collection, maybe your control does not have the same parent and will unlikely have the same origin for your pacman and the coin, and the IF...ELSE will never hit. Please be sure to use the same parent for the pacman and the coins.
Another solution is to draw the game objects on a canvas using the drawing primitives, and create ad hoc objects to store the drawing rectangles. This is the preferred solution as using GDI+ objects to draw game elements doesn't perform well. If you use the canvas instead, all you must do is to update the canvas on each drawing loop with the images of your game objects. This way, you will have no issues with the visual tree of the controls.
Edit: as stated in other comments, if you succeed to hit the intersection condition, in the first version of your code you will also face exception for removing items from the collection while iterating it using foreach. In this case, the solution is to iterate the list first and add the items to a new "removedItemsList" and then iterate this new list to remove the items from the controls collection without iterate it.
It's not so efficient, your second solution with visibility in my opinion is far better. It's not efficient for at least two motives: one because every time you remove a control the visual tree updated for each remaining control. Second, you must allocate a new list, and reiterate it every time you hit a coin. Visibility instead only invalidate the control render rectangle, and on the next draw routing it will be draw invisible.
Related
I can't seem to figure out how to make this simple animation work, where i have user control over a red square, and it shouldn't overlap/intersect with a black square (e.g. a wall sprite)
My best effort is to have stack data structure of keys pressed and if there is an intersection, then we look at (peek) last key pressed and assign a speed of -1. (See line 67 of code) But this doesn't prevent an overlap. Is there a way that I can make it so the user's red rectangle can't overlap with black?
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;
using System.Collections;
namespace Movement
{
public partial class Form1 : Form
{
bool moveRight, moveLeft, moveUp, moveDown;
Keys currentInput;
Keys lastInput;
Stack pressedKeys = new Stack();
int speed = 5;
bool collision = false;
public Form1()
{
InitializeComponent();
this.CenterToScreen();
}
private void pbRed_Click(object sender, EventArgs e)
{
}
private void moveTimeEvent(object sender, EventArgs e)
{
currentInput = Keys.KeyCode;
//moving left
if (moveLeft == true && pbRed.Left > 7 )
{
pbRed.Left -= speed;
}
//moving right
if (moveRight == true && pbRed.Left < 750)
{
pbRed.Left += speed;
}
//moving up
if(moveUp == true && pbRed.Top > 7)
{
pbRed.Top -= speed;
}
//moving down
if(moveDown == true && pbRed.Top < 400)
{
pbRed.Top += speed;
}
if (moveLeft == true || moveRight == true || moveUp == true || moveDown == true)
{
pressedKeys.Push(currentInput);
}
Collision();
}
private void Collision()
{
//collision detection
if(pbRed.Bounds.IntersectsWith(pbBlack.Bounds))
{
collision = true;
if(collision)
{
lastInput = (Keys)pressedKeys.Peek();
if(currentInput == lastInput)
{
speed = -1;
}
}
}
}
private void keyisdown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Left)
{
moveLeft = true;
}
if (e.KeyCode == Keys.Right)
{
moveRight = true;
}
if (e.KeyCode == Keys.Up)
{
moveUp = true;
}
if (e.KeyCode == Keys.Down)
{
moveDown = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = false;
}
if (e.KeyCode == Keys.Right)
{
moveRight = false;
}
if (e.KeyCode == Keys.Up)
{
moveUp = false;
}
if (e.KeyCode == Keys.Down)
{
moveDown = false;
}
}
}
}
When your speed is 5, don't apply a movement of 5 pixels in one go, but apply the 5 steps separately. Before each step, so before actually moving the rectangle, decide whether that one step movement is allowed.
Also look at vertical and horizontal movement separately.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Movement
{
public partial class Form1 : Form
{
bool moveRight, moveLeft, moveUp, moveDown;
int speed = 5;
public Form1()
{
InitializeComponent();
this.CenterToScreen();
}
private void moveTimeEvent(object sender, EventArgs e)
{
// Get movement vector
Point movement = new Point(0, 0);
if (moveLeft) movement.X -= 1;
if (moveRight) movement.X += 1;
if (moveUp) movement.Y -= 1;
if (moveDown) movement.Y += 1;
// Speed defines how many steps we move
for (int i=1; i<= speed; i++)
{
// Check vertical movement allowed
if (movement.X != 0)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
if (!CheckCollision(newPosition))
{
movement.X = 0;
}
}
// Check horizontal movement allowed
if (movement.Y != 0)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
newPosition.Y += movement.Y;
if (!CheckCollision(newPosition))
{
movement.Y = 0;
}
}
// Apply Actual movement
if (!movement.IsEmpty)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
newPosition.Y += movement.Y;
pbRed.Bounds = newPosition;
}
}
}
// Returns true when movingRecht is allowed position
private bool CheckCollision(Rectangle movingRect)
{
bool lResult = true;
//collision detection
lResult = lResult && !pbBlack.Bounds.IntersectsWith(movingRect);
// Check we remain inside the form
lResult = lResult && movingRect.Left >= 0;
lResult = lResult && movingRect.Top >= 0;
lResult = lResult && movingRect.Right <= ClientRectangle.Right;
lResult = lResult && movingRect.Bottom <= ClientRectangle.Bottom;
return lResult;
}
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = true;
}
if (e.KeyCode == Keys.Right)
{
moveRight = true;
}
if (e.KeyCode == Keys.Up)
{
moveUp = true;
}
if (e.KeyCode == Keys.Down)
{
moveDown = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = false;
}
if (e.KeyCode == Keys.Right)
{
moveRight = false;
}
if (e.KeyCode == Keys.Up)
{
moveUp = false;
}
if (e.KeyCode == Keys.Down)
{
moveDown = false;
}
}
}
}
I'm a beginner using Visual Studio to make a C# Windows Form. So I have a brick game (like the classic block game with ball and bricks) where if the player doesn't bounce the ball back, it's basically game over. However when this happens, the timer is just stopped and there's no way to restart. The code I have now just says to create a message box with "You lose" and you have to exit the program to play again. If you reach score 30 then that's a win and to play again you have to exit also.
I've tried googling this and the suggestions I see is if it's all set up already in their cases so implementing it to mine without having to re-do it all in someway is hard. I would like to make a simple implementation (or edit) where there is a play again function. How can I modify existing code to do this? Thank you dearly for any help.
This is the section of code that accounts for game-over if statement.
EDIT= Entire code provided.
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;
using System.Media;
using System.Reflection;
using System.IO;
namespace FinalProjectGame
{
public partial class FrmGame : Form
{
bool goLeft;
bool goRight;
int speed = 10;
int pBallx = 5;
int pBally = 5;
int score = 0;
public FrmGame()
{
InitializeComponent();
}
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left && btnGamer.Left > 0)
{
goLeft = true;
}
if (e.KeyCode == Keys.Right && btnGamer.Left + btnGamer.Width < 920)
{
goRight = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goLeft = false;
}
if (e.KeyCode == Keys.Right)
{
goRight = false;
}
}
private void TmrMainTimer_Tick(object sender, EventArgs e)
{
pBall.Left += pBallx;
pBall.Top += pBally;
lblScore.Text = "Score: " + score; //keeping score
if (goLeft) { btnGamer.Left -= speed; } //izquierda
if (goRight) { btnGamer.Left += speed; } //derecha
if (btnGamer.Left < 1)
{
goLeft = false; //disables "no-clip"
}
else if (btnGamer.Left + btnGamer.Width > 920)
{
goRight = false;
}
if (pBall.Left + pBall.Width > ClientSize.Width || pBall.Left < 0)
{
pBallx = -pBallx; //left, right wall bounce
}
if (pBall.Top < 0 || pBall.Bounds.IntersectsWith(btnGamer.Bounds))
{
pBally = -pBally; //top, bottom wall bounce
}
foreach (Control x in this.Controls)
//main code brickies subtraction
{
if (x is PictureBox && x.Tag == "blockies")
{
if (pBall.Bounds.IntersectsWith(x.Bounds))
{
this.Controls.Remove(x);
pBally = -pBally;
score++;
} //end of main
//ALT method foreach (Control x in this.Controls)
//{
if (!(x is PictureBox))
continue;
//this is needed if some specific property of the PictureBox is needed.
PictureBox ctl = (PictureBox)x;
if (ctl.Tag.ToString() != "blockies")
continue;
if (!pBall.Bounds.IntersectsWith(ctl.Bounds))
continue;
//this.Controls.Remove(x);
x.Visible = false;
pBally = -pBally;
score++;
//}
}
}//----
//This accounts for user score. Upon completing the game, the user wins. If the user does not capture the ball, it is automatically a game over.
if (score == 30)
{
gameOver();
MessageBox.Show("YES! WINNER!");
}
if (pBall.Top + pBall.Height > ClientSize.Height)
{
gameOver();
MessageBox.Show("SORRY YOU LOSE!");
}
//======
}
private void gameOver()
{
TmrMainTimer.Stop();
}
private void FrmGame_Load(object sender, EventArgs e) //main form load
{
//load the splash screen form that was made with design view
SplashScreen splash = new SplashScreen();
splash.Show();
//using system media to play the audio which is played upon start of the main form
SoundPlayer Sndplayr = new SoundPlayer(Properties.Resources.RoleMusic);
Sndplayr.Play();
}
}
}
If you want to restart that WinForms application, use Application.Restart(). You may close your game form and call restart in your static Main() method afterwards.
private void TmrMainTimer_Tick(object sender, EventArgs e)
{
...
if (pBall.Top + pBall.Height > ClientSize.Height)
{
gameOver();
MessageBox.Show("SORRY YOU LOSE!");
// close the game form
this.Close();
}
}
And in your startup code:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmGame());
// restart application
Application.Restart();
}
}
Edit:
The example above ist the easiest way to play that game from start. Of course, there are many other options:
As an extension, you can start your game form from a (maybe hidden) program startup form. If you register an event handler on the FrmGame.FormClosed event, you can restart that form again after the previous game was lost.
As many other guys suggested, a StartAgain() method, that resets your logic, is also an option.
Separate drawing logic (View) from game logic (Controller). For a such a simple game it is not necessary and overkill. But it is always a good idea to keep the things simple and clear. See the MVC pattern for your next project...
Basically,I am a beginner in C# and I just started working on a simple platformer game following a basic Visual Studio 2015 tutorial.This is the code:
public partial class Form1 : Form
{
bool goleft = false;
bool goright = false;
bool jumping = false;
int JumpSpeed = 10;
int force = 8;
int score = 0;
public Form1()
{
InitializeComponent();
}
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goleft = true;
}
if (e.KeyCode == Keys.Right)
{
goright = true;
}
if (e.KeyCode == Keys.Space && !jumping)
{
jumping = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goleft = false;
}
if (e.KeyCode == Keys.Right)
{
goright = false;
}
if (jumping)
{
jumping = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
player.Top += JumpSpeed;
if (jumping && force < 0)
{
jumping = false;
}
if (goleft)
{
player.Left -= 5;
}
if (goright)
{
player.Left += 5;
}
if (jumping)
{
JumpSpeed = -12;
force -= 1;
}
else
{
JumpSpeed = 12;
}
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "p")
{
if (player.Bounds.IntersectsWith(x.Bounds) && !jumping)
{
force = 8;
player.Top = x.Top - player.Height;
}
}
if (player.Bounds.IntersectsWith(Door.Bounds))
{
timer1.Stop();
MessageBox.Show("You Won!");
this.Close();
}
}
}
}
The gravity force and everything works great EXCEPT for one big problem with the player that I definitely can't solve without some help.
The problem is: the player is completely glitched and it keeps going up and down. I realised that this is because of two lines in private void timer1_Tick(object sender, EventArgs e):
player.Top += JumpSpeed;
and
player.Top = x.Top - player.Height;
Both of these try to change player.Top and interfere with each other. The trouble is that I can't just cut one of the two without destroying the gravity force code. What I think might work is applying player.Top += JumpSpeed; ONLY if(player.Bounds.IntersectsWith(x.Bounds) && !jumping) = false but I don't know how to write the code this way at all (previous tries always ended up with errors).
Thanks in advance for any help and please forgive any grammar errors that I made because I am not a native english speaker.
I don't know how your Form looks like, but with what you provided I would change the code like that:
public partial class Form1 : Form
{
bool goleft = false;
bool goright = false;
int JumpSpeed = 0; //current vertical speed
int force = 8; //initial jump speed
int score = 0;
public Form1()
{
InitializeComponent();
}
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goleft = true;
}
if (e.KeyCode == Keys.Right)
{
goright = true;
}
if (e.KeyCode == Keys.Space && JumpSpeed==0) //JumpSpeed==0 to prevent "double jump"
{
JumpSpeed = force; //start jumping with full power
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goleft = false;
}
if (e.KeyCode == Keys.Right)
{
goright = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (goleft)
{
player.Left -= 5;
}
if (goright)
{
player.Left += 5;
}
JumpSpeed -= 1; //decrement the vertical speed = gravity -> choose higher value to bring him back on the ground quicker
player.Top -= JumpSpeed;
if (player.Bounds.IntersectsWith(Door.Bounds))
{
timer1.Stop();
MessageBox.Show("You Won!");
this.Close();
}
foreach (PictureBox x in this.Controls.OfType<PictureBox>())
{
if (x.Tag == "p")
{
if (player.Bounds.IntersectsWith(x.Bounds)) //if the player should be able to jump/walk on something the code is
{
player.Top = x.Top - player.Height;
JumpSpeed = 0; //the player stops falling
}
}
}
}
}
To make sure to player does not fall out of the window place PictureBoxes with tag == p on the floor!
PS:
Feel free to leave a comment!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Game1
{
public partial class Form1 : Form
{
Graphics g;
Rectangle Player;
Rectangle Enemy;
Boolean left;
Boolean right;
Boolean up;
Boolean down;
int Playerx, Playery, Playerw, Playerh;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Playerx = 0;
Playery = 0;
Playerw = 32;
Playerh = 32;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
g = e.Graphics;
//Draw Player
Player = new Rectangle(Playerx, Playery, Playerw, Playerh);
g.FillRectangle(Brushes.Blue, Player);
//Draw Enemy
Enemy = new Rectangle(100, 100, 32, 32);
g.FillRectangle(Brushes.Red, Enemy);
if (Player.IntersectsWith(Enemy.Left))
{
left = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (left == true)
{
Playerx -= 5;
}
if (right == true)
{
Playerx += 5;
}
if (up == true)
{
Playery -= 5;
}
if (down == true)
{
Playery += 5;
}
Invalidate();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
left = true;
right = false;
up = false;
down = false;
}
if (e.KeyCode == Keys.D)
{
right = true;
left = false;
up = false;
down = false;
}
if (e.KeyCode == Keys.W)
{
up = true;
down = false;
left = false;
right = false;
}
if (e.KeyCode == Keys.S)
{
down = true;
up = false;
left = false;
right = false;
}
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
left = false;
}
if (e.KeyCode == Keys.D)
{
right = false;
}
if (e.KeyCode == Keys.W)
{
up = false;
}
if (e.KeyCode == Keys.S)
{
down = false;
}
}
}
}
I want to make the player stop moving when it touches the left side of the enemy but i keep getting an error, and it highlights
if (Player.IntersectsWith(Enemy.Left)) and says Can't convert int into System.Drawing.Rectangle any ideas?
I have tried to see if this works
if (Player.IntersectsWith(Enemy))
{
left = false;
right = false;
up = false;
down = false;
}
but of course it keeps the player in place.
You seem to want a specific collision.
You should try:
if(Player.X + Player.Width >= Enemy.X && Player.X < Enemy.X)
{
right = false;
}
This way you are checking if the right side of the player intersects the left side of the enemy and the left side of the players position is less than the left side of the enemy's position (the player is to the left of the enemy)
You will have to add in heights and stuff to that collision to make it so you can pass the enemy but I think for what you have posted it should work ok.
NOTE: Code is untested, let me know how you get on.
I'm trying to write a tetris clone, and after doing some research I've come across an example that uses small user controls to form the block and a bigger user control that contains the grid.
Everything I've written already seems to work just fine (blocks are being generated and placed on the grid, i can even place them somewhere else if I change the code), but I can't seem to get the blocks to move while the program is running. The example I use does this by changing the control.left property of each of the blocks. I've tried this, debugged it and while the property changes, the block doesn't move.
I've searched around for about 4 hours now. I'm a novice programmer, so I know it's probably something stupid, but I cant find what it is.
Here's the methods I've written:
//Class TetrisGame.cs
public void MoveRight()
{
blok.MoveBlock("x", 1);
}
//Class Shape.cs
public void MoveBlock(string pos, int Amount)
{
if (pos == "x")
{
for (int i = 0; i < this.Shape().Count; i++)
{
((Blokje)this.Shape()[i]).MoveSide(1);
}
}
if (pos == "y")
{
for (int i = 0; i < this.Shape().Count; i++)
{
((Blokje)this.Shape()[i]).MoveDown(1);
}
}
//And, the code that should actually move the block in Block.cs:
public void MoveSide(int Step)
{
this.Left += (Step * 20);//Blocks are 20*20 pixels so should move in steps of 20 pixels
}
Shape is actually an arraylist which just contains the 4 Blocks. Block.cs is a partial class since it's the code behind the usercontrol that is the small squares, Shape.cs makes the shapes out of the blocks and tetrisgame is just the gamelogic
the Keypress event:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
try
{
if (e.KeyChar == 'q')//left
{
if (!paused)
{
Game.MoveLeft();
}
}
else if (e.KeyChar == 'd')//right
{
if (!paused)
{
Game.MoveRight();
}
}
else if (e.KeyChar == 'p')//pause
{
if (paused)
{
tmrGame.Start();
}
else
{
tmrGame.Stop();
}
}
else if (e.KeyChar == 'z')//rotate
{
if (!paused)
{
Game.Rotate();
}
}
else if (e.KeyChar == 'h')//help
{
Help.Show();
}
else if (e.KeyChar == 'f')//save
{
}
else if (e.KeyChar == 's')//Drop
{
if (!paused)
{
Game.Drop();
}
}
}
catch
{
//no error message has to be displayed, this is just to prevent runtime Errors when pressing keys before the game has started
}
}
It seems that the "bigger user control that contains the grid" with it's children is not redrawn.
Change MoveSide to:
public void MoveSide(int Step)
{
this.Left += (Step * 20);
Update();
}
so everything is redrawn correctly.