Code updated now, only two problems left until I'm happy to feel I've completed it.
When the player hits a wall the counter goes down at 2 lifes per hit.
When the game starts the sound I have(beep.wav) which should only sound when the player hits a wall, is sounding each time I begin the game and the sound which should play throughout the game(onestop.wav) isn't playing at all.
public partial class Form1 : Form
{
// This SoundPlayer plays a song when the game begins.
System.Media.SoundPlayer onestop = new System.Media.SoundPlayer(#"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\onestop.wav");
// This SoundPlayer plays a sound whenever the player hits a wall.
System.Media.SoundPlayer beepSound = new System.Media.SoundPlayer(#"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\beep.wav");
// This SoundPlayer plays a sound when the player finishes the game.
System.Media.SoundPlayer clapSound = new System.Media.SoundPlayer(#"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\winningApplause.wav");
public Form1()
{
InitializeComponent();
timer1.Interval = (1000) * (1);
timer1.Enabled = true;
timer1.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
begin();
}
private void begin()
{
onestop.Play();
livesTextBox.Text = lives.ToString();
Point startingPoint = panel1.Location;
startingPoint.Offset(10, 10);
Cursor.Position = PointToScreen(startingPoint);
}
int lives = 5;
private void MoveToStart()
{
if ( lives > 0)
{
lives--;
}
if (lives == 0)
{
MessageBox.Show("You Lose!!");
Close();
}
else if (lives < 0)
{
MessageBox.Show("You Lose!!");
Close();
}
}
private void wall_MouseEnter(object sender, EventArgs e)
{
// When the mouse pointer hits a wall or enters the panel,
// call the MoveToStart() method.
beepSound.Play();
MoveToStart();
lives--;
livesTextBox.Text = lives.ToString();
}
private void finishLabel_MouseEnter(object sender, EventArgs e)
{
// Play a sound, show a congratulatory MessageBox, then close the form.
clapSound.Play();
MessageBox.Show("Congratulations! You've beaten the maze!");
Close();
}
int gameElapsed = 0;
private void timer1_Tick(object sender, EventArgs e)
{
gameElapsed++;
textBox1.Text = "" + gameElapsed.ToString();
}
}
You haven't posted the code very clearly, but I'll try and help.
Not sure about your sound issues. But: to 'call in your timer', I presume you want to put a number in the text box? You are half-way there. The Timer object simply calls the tick event every second, so you need to do the displaying part.
place the text box on your form, assume it is called textBox1.
put before the begin() method:
Stopwatch stopWatch = new Stopwatch();
Put inside the begin() method
stopWatch.Start();
inside the timer1_Tick method:
TimeSpan ts = stopWatch.Elapsed;
textBox1.Text = String.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds);
for your 'lives' bit, you'll need to put, before begin() method,
int lives = 0;
inside the begin(), put
int lives = 5;
livesTextBox.Text = lives.toString();
and inside wall_MouseEnter(), put
lives--;
livesTextBox.Text = lives.toString();
(assuming you have drawn a livesTextBox on your form)
Just Create a Timer on your form with interval 1000 and make it enable and then define game_elpased as integer as private field in the class and in timer_tick write :
void Timer1_Tick(object Sender,EventArgs e)
{
game_elapsed++;
textBox1.Text = "Elapsed Seconds : " + game_elapsed.ToString();
}
For the live times , You need to control the public variable like lives, when the player fails :
if(fails && lives>0){
lives--;
}
else if (lives<0)
{
MessageBox.Show("You are a looser ...");
}
The lives can be a property of the player class.
public class Player
{
int lives = 5;
public bool Kill()
{
this.lives--;
return this.lives <= 0;
}
public void run()
{
Player player = new Player();
// do stuff
// Check whether the player needs to die
if ("player fails".Contains("fail"))
{
if (player.Kill())
{
// restart level.
}
else
{
// Game over.
}
}
}
}
Related
Purpose of this code was to move a title(label) first rightwards until it hits the 600th pixel on the X axis and then leftwards until it hits the 27th pixel on the X axis of the form by using 2 timer tools and the Point class. One timer for going right and the other timer for going left. They should've work by swithing on and off consecutively after one another, however it does not work.
The label is stuck at 600th X location and does not move back to where it was.
The timer interval is 100 so it moves with a decent speed that allows us to see it moving.
namespace AlanCevreHesabiUygulamasi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
if (label11Point.X == 27)
{
timer2.Stop();
timer1.Start();
}
if (label11Point.X == 599)
{
timer1.Stop();
timer2.Start();
}
}
Point label11Point = new Point(27, 32);
private void timer1_Tick(object sender, EventArgs e)
{
while (label11Point.X <= 600)
{
label12.Text = label11Point.X.ToString();
label11Point.X += 1;
label11.Location = label11Point;
break;
}
}
private void timer2_Tick(object sender, EventArgs e)
{
while (label11Point.X >= 27)
{
label12.Text = label11Point.X.ToString();
label11Point.X -= 1;
label11.Location = label11Point;
break;
}
}
}
}
Label is stuck at 600th pixel of the form, does not move back. How to make it work?
I'm surprised you see movement resulting from a while loop in a timer tick handler. Why have a timer if your are going to do it that way.
In this solution, I have a timer, and the movements happen during a timer tick. I also have three possible directions, Right, Left and Stopped (in case you want to have a start/stop button).
In the Windows Forms designer, I dropped both a label and a timer on the form. I left their properties alone except for the timer's Interval property (that I set to 10 (ms))
Then I added an enum and an instance of the enum as a field to the Form class:
public partial class Form1 : Form
{
private enum Direction { MoveRight, MoveLeft, Stopped }
Direction _direction;
public Form1()
{
InitializeComponent();
}
}
I double-clicked the Caption area of the form in the designer to create a form Load handler, and added a call to start the timer:
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
Finally, I double-clicked the timer to get a timer Tick handler and added some code:
private void timer1_Tick(object sender, EventArgs e)
{
var curLocation = label1.Location;
if (_direction == Direction.MoveRight && curLocation.X > 600)
{
_direction = Direction.MoveLeft;
}
else if (_direction == Direction.MoveLeft && curLocation.X < 27)
{
_direction = Direction.MoveRight;
}
int offset = _direction switch
{
Direction.MoveRight => 1,
Direction.MoveLeft => -1,
_ => 0,
};
curLocation.X += offset;
label1.Location = curLocation;
}
The _direction field determines if the label is moving to the right or the left.
How can you write the code without a timer?"
You asked "How can you write the code without a timer?" I'm still flabbergasted that your label moves as the result of a while loop in an event handler - something must have changed from my good-old understanding of Win32 processing.
Anyways, I cheat and await a call to Task.Delay instead of using a timer. Take my existing code and do the following:
Add two buttons to your form (One labeled Start (named StartBtn) and the other labeled Stop (named StopBtn).
Add another Direction-typed field to the class: Direction _previousDirection;
Comment out the call to timer1.Start(); in the Form1_Load handler
Comment out all the code in the timer1_Tick method (at this point, you could remove the timer from the form if you want)
Select both buttons (Start and Stop) and press <Enter>. This will bring up click handlers for both buttons.
Change the StopBtn button's handler to look like:
New Stop Button code:
private void StopBtn_Click(object sender, EventArgs e)
{
_previousDirection = _direction;
_direction = Direction.Stopped;
}
Change the StartBtn's handler to look like the following. Note that nearly everything in the while loop (except the call to Task.Delay) is the same as the previous timer tick handler code. Also note that I made the handler async void to allow for the await keyword to do it's magic.
Start Button code:
private async void StartBtn_Click(object sender, EventArgs e)
{
_direction = _previousDirection;
while (_direction != Direction.Stopped)
{
var curLocation = label1.Location;
if (_direction == Direction.MoveRight && curLocation.X > 600)
{
_direction = Direction.MoveLeft;
}
else if (_direction == Direction.MoveLeft && curLocation.X < 27)
{
_direction = Direction.MoveRight;
}
int offset = _direction switch
{
Direction.MoveRight => 1,
Direction.MoveLeft => -1,
_ => 0,
};
curLocation.X += offset;
label1.Location = curLocation;
await Task.Delay(10);
}
}
I solved it, I don't know why but in my opening post the Form1() function only makes one of the if() conditions work. However, putting the if() statements into the timers solved the problem. Now, the title goes back and forth in the specified x axis intervals.
namespace AlanCevreHesabiUygulamasi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
Point label11Point = new Point(27, 32);
private void timer1_Tick(object sender, EventArgs e)
{
while (label11Point.X >= 27)
{
label12.Text = label11Point.X.ToString();
label11Point.X += 1;
label11.Location = label11Point;
break;
}
if (label11Point.X == 600)
{
timer2.Start();
timer1.Stop();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
while (label11Point.X <= 600)
{
label12.Text = label11Point.X.ToString();
label11Point.X -= 1;
label11.Location = label11Point;
break;
}
if (label11Point.X == 27)
{
timer1.Start();
timer2.Stop();
}
}
I have two forms, form1 and credentials. I want the data in my textbox (can be filled by user) to be transferred to the data grid view in form1.
Also, in form1, I want the data in my labels to be also transferred into the data grid view, which is also in form1. The labels I want to be transferred are: score, timer, level
I have tried and research for multiple solutions, yet none can really solve my problem. however, I tried to combine the solutions from websites and here is what i can do that kind of make sense to me. following are the codes for form1 and credentials.
form1 source code:
public partial class Form1 : Form
{
Snake mySnake;
Board mainBoard;
Rewards apples;
string mode;
Timer clock;
int duration; //How long the game has been running
int speed = 500; //500ms
int score;
int highscore;
int level;
public Form1()
{
InitializeComponent();
//button2.Text = Char.ConvertFromUtf32(0x2197);
//You don't have to worry about the auto-size
this.AutoSize = true; //The size of the Form will autoadjust.
boardPanel.AutoSize = true; //The size of the panel grouping all the squares will auto-adjust
//Set up the main board
mainBoard = new Board(this);
//Set up the game timer at the given speed
clock = new Timer();
clock.Interval = speed; //Set the clock to tick every 500ms
clock.Tick += new EventHandler(refresh); //Call the refresh method at every tick to redraw the board and snake.
duration = 0;
score = 0;
highscore = 0;
level = 1;
modeLBL.Text = mode;
gotoNextLevel(level);
scoresDGV.ColumnCount = 4;
scoresDGV.Columns[0].HeaderText = "Name";
scoresDGV.Columns[1].HeaderText = "Level";
scoresDGV.Columns[2].HeaderText = "Score";
scoresDGV.Columns[3].HeaderText = "Timer";
scoresDGV.AllowUserToAddRows = false;
scoresDGV.AllowUserToDeleteRows = false;
scoresDGV.MultiSelect = false;
scoresDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
scoresDGV.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void refresh(Object myObject, EventArgs myEventArgs)
{
//increment the duration by amount of time that has passed
//this method is called every speed millisecond
duration += speed;
timerLBL.Text = Convert.ToString(duration / 1000); //Show time passed
//Check if snke is biting itself. If so, call GameOver.
if (mySnake.checkEatItself() == true)
{
GameOver();
}
else if (apples.checkIFSnakeHeadEatApple( mySnake.getHeadPosition()) == true)
{
score += apples.eatAppleAtPostion(mySnake.getHeadPosition());
scoreLBL.Text = Convert.ToString(score);
if (apples.noMoreApples() == true)
{
clock.Stop();
level++;
levelLBL.Text = Convert.ToString(level);
gotoNextLevel(level);
MessageBox.Show("Press the start button to go to Level " + level, "Congrats");
}
else
{
//Length the snake and continue with the Game
mySnake.extendBody();
}
}
if (score > highscore)
{
highscoreLBL.Text = Convert.ToString(highscore);
}
}
private void startBTN_Click(object sender, EventArgs e)
{
clock.Start();
}
private void pauseBTN_Click(object sender, EventArgs e)
{
clock.Stop();
}
private void restartBTN_Click(object sender, EventArgs e) //snapBTN
{
duration = 0;
mySnake.draw();
}
private void backBTN_Click(object sender, EventArgs e)
{
// hides the form from the user. in this case, the program hides the HowToPlay form
this.Hide();
MainMenu mM = new MainMenu();
mM.ShowDialog();
this.Close();
}
private void GameOver()
{
clock.Stop();
MessageBox.Show("Your time taken is " + duration/1000 + " seconds. Bye Bye", "Game Over");
this.Close();
addCurrentScoresToDatabase();
//updateScoreBoard();
}
private void modeLBL_Click(object sender, EventArgs e)
{
}
private void addCurrentScoresToDatabase()
{
Credentials c = new Credentials();
c.ShowDialog();
}
}
credentials source code:
public partial class Credentials : Form
{
public static string SetValueForName = "";
public Credentials()
{
InitializeComponent();
}
private void saveBTN_Click(object sender, EventArgs e)
{
SetValueForName = enternameTB.Text;
Form1 frm1 = new Form1();
frm1.Show();
}
private void cancelBTN_Click(object sender, EventArgs e)
{
}
}
Because part of your code is made in the designer (and not shown here in your post) it is difficult to understand how it works. I assume you have a simple dialog form which is shown in your form1
Credentials is shown modal. So if you have some properties in your credentials dialog, you may data transfer via the properties.
private void addCurrentScoresToDatabase()
{
Credentials c = new Credentials();
// initialize c here
c.ShowDialog();
// read data from c here
}
If you want get data from the credential dialog while it is shown, you should use events.
https://learn.microsoft.com/en-us/dotnet/standard/events/
If you want to transfer score, timer, level to datagridview and transfer Name from credentials to datagridview, you can refer to the following code:
Code in Form1:
int index;
public void AddScore_Click(object sender, EventArgs e)
{
index = scoresDGV.Rows.Add();
scoresDGV.Rows[index].Cells[1].Value = label1.Text;
scoresDGV.Rows[index].Cells[2].Value = label2.Text;
scoresDGV.Rows[index].Cells[3].Value = label3.Text;
Credentials c = new Credentials();
c.FormClosed += c_FormClosed;
c.Show();
}
void c_FormClosed(object sender, FormClosedEventArgs e)
{
scoresDGV.Rows[index].Cells[0].Value = Credentials.SetValueForName;
}
Code in Credentials:
public partial class Credentials : Form
{
public static string SetValueForName = "";
public Credentials()
{
InitializeComponent();
}
private void saveBTN_Click(object sender, EventArgs e)
{
SetValueForName = enternameTB.Text;
this.Close();
}
}
Here is the test result:
so I have a list class called SąrašasList and it has string item called vardas, which contains a path name to a song, I have few songs in this list, and also GUI with AX Windows Media player, but when I write :
private void axWindowsMediaPlayer1_Enter(object sender, EventArgs e)
{
foreach (SąrašasList d in atrinktas)
{
axWindowsMediaPlayer1.URL = d.getVardas();
}
}
It only plays the last song, but does not go to another, what should I do?
I want this player to play all songs, one after the other.
Basically, what you're doing is iterating through all of your songs, and loading each one into the player. Of course, your player can only handle one of them, so the last one of your collection is effectively playing.
What you should do is loading your first song, and at the end of each media, you have to load the n + 1 song.
private System.Timers.Timer Timer; // Used to introduce a delay after the MediaEnded event is raised, otherwise player won't chain up the songs
private void ScheduleSongs() {
var count = 0;
var firstSong = atrinktas.FirstOrDefault(); // using Linq
if(firstSong == null) return;
axWindowsMediaPlayer1.URL = firstSong.getVardas();
// PlayStateChange event let you listen your player's state.
// https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd562460(v=vs.85).aspx
axWindowsMediaPlayer1.PlayStateChange += delegate(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e) {
if(e.newState == 8 && count < atrinktas.Count()) {
count++;
var nextSong = atrinktas[count];
axWindowsMediaPlayer1.URL = nextSong.getVardas();
Timer = new System.Timers.Timer() { Interval = 100 };
Timer.Elapsed += TimerElapsed; // Execute TimerElapsed once 100ms is elapsed
}
};
}
private void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Timer.Stop();
Timer.Elapsed -= TimerElapsed;
Timer = null;
axWindowsMediaPlayer1.Ctlcontrols.play(); // Play the next song
}
I have 4 dogs who're racing, I need to move them across the form but they don't move gradually, they start out at the starting line and immediately teleport to the finish line, without moving in between. With every timer tick, their location.X is incremented.
Do I need one timer or 4? I currently have one, and its interval is set to 400.
This is the relevant code:
private void btnRace_Click(object sender, EventArgs e)
{
btnBet.Enabled = false;
timer1.Stop();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{ while (!isWon)
{
for (i = 0; i < Dogs.Length; i++) // there are four dogs
{
if (Dogs[i].Run()) // Run() returns true if full racetrack is covered by this dog
{
Winner = i + 1;
isWon = true;
MessageBox.Show("We have a winner! Dog #" + Winner);
break;
}
}
}
And in the Dog class:
public bool Run()
{
Distance = 10 + Randomizer.Next(1, 4);
p = this.myPictureBox.Location;
p.X += Distance ;
this.myPictureBox.Location = p;
//return true if I won the game
if (p.X >= raceTrackLength)
{
return true ;
}
else
{
return false ;
}
}
The dogs only appear to move one step and then immediately show up on the finish line. What am I doing wrong?
Remove While loop from timer1_Tick method.
This method runs every 400 ms, but in your case at first launch it waits until one dog wins.
Also you should stop the timer after one of dogs win.
private void timer1_Tick(object sender, EventArgs e)
{
for (i = 0; i < Dogs.Length; i++) // there are four dogs
{
if (Dogs[i].Run()) // Run() returns true if full racetrack is covered by this dog
{
Winner = i + 1;
isWon = true;
timer1.Stop();
MessageBox.Show("We have a winner! Dog #" + Winner);
break;
}
}
}
Your timer goes off just once and is stuck in this loop;
while (!isWon)
{
}
Remove the loop and let the Timer do it's work
Add at the end
if (isWon) timer1.Stop();
My problem is very simple but I can't figure it out, so I need your help.
The problem is that I have a button and a label in a form, I simply want to click the button and see the label countdown from 10 to 0 and after that happens the form closes, that simple, can someone help me with this?
BTW, my real app is a form that shows video in real time from my webcam and the idea is to click the button, see the count down and when it finishes the appp saves the current frame as an image.
Thanks in advice!
It sounds like you probably just need three things:
A counter in your class as an instance variable
A timer (System.Windows.Forms.Timer or a DispatcherTimer depending on what UI framework you're using)
A method handling the timer's Tick even which decrements the counter, updates the UI, and stops the timer + takes a snapshot if the counter reaches 0
You can do all of this without any other threads.
Using WindowsFormsApplication u can do it like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Enabled = false; // Wait for start
timer1.Interval = 1000; // Second
i = 10; // Set CountDown Maximum
label1.Text = "CountDown: " + i; // Show
button1.Text = "Start";
}
public int i;
private void button1_Click(object sender, EventArgs e)
{
// Switch Timer On/Off
if (timer1.Enabled == true)
{ timer1.Enabled = false; button1.Text = "Start"; }
else if (timer1.Enabled == false)
{ timer1.Enabled = true; button1.Text = "Stop"; }
}
private void timer1_Tick(object sender, EventArgs e)
{
if (i > 0)
{
i = i - 1;
label1.Text = "CountDown: " + i;
}
else
{ timer1.Enabled = false; button1.Text = "Start"; }
}
}
You only need a label, a button and a timer.
use this code. put one timer,label and button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Tick += new EventHandler(timer1_Tick);
}
private static int i = 10;
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "10";
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = (i--).ToString();
if (i < 0)
{
timer1.Stop();
}
}
}