📄 mainform.cs
字号:
/// <param name="e"></param>
private void MainForm_Load(object sender, System.EventArgs e)
{
// Redraw complete area, there was a certain problem encountered.
// This action doesn't seem to be much helpful though.
RefreshView();
}
/// <summary>
/// Handles <b>Resize</b> event of a form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Adjusts the size of located controls to the actual form size.
/// </remarks>
private void MainForm_Resize(object sender, System.EventArgs e)
{
// Working area
int width = this.Width - 2;
int height = this.Height - 2 * menuSize - 1;
this.indicatorCtrl.Width = width;
this.boardCtrl.Size = new System.Drawing.Size(width, height - this.indicatorCtrl.Height);
}
/// <summary>
/// Handles <b>Closing</b> event of a form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Saves the application settings and executes game over process.
/// </remarks>
private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
AppSettings.Instance.Save();
GameOver();
}
/// <summary>
/// Handles <see cref="menuItemExit"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Closes application.
/// </remarks>
private void menuItemExit_Click(object sender, System.EventArgs e)
{
Close();
}
/// <summary>
/// Handles <see cref="menuItemAbout"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Displays <see cref="AboutBox"/> dialog.
/// </remarks>
private void menuItemAbout_Click(object sender, System.EventArgs e)
{
Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
AboutBox dialog = new AboutBox();
dialog.Left = (workingArea.Width - dialog.Width) / 2;
dialog.Top = (workingArea.Height - dialog.Height) / 2;
dialog.ShowDialog();
//dialog.Show();
}
/// <summary>
/// Handles <see cref="menuItemNew"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Proceeds game over process and starts a new game.
/// </remarks>
private void menuItemNew_Click(object sender, System.EventArgs e)
{
GameOver();
}
/// <summary>
/// Handles <see cref="menuItemRecords"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Displays <see cref="HiScoreForm"/> dialog with players' records.
/// </remarks>
private void menuItemRecords_Click(object sender, System.EventArgs e)
{
Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
HiScoreForm dialog = new HiScoreForm();
dialog.Left = (workingArea.Width - dialog.Width) / 2;
dialog.Top = (workingArea.Height - dialog.Height) / 2;
dialog.UpdateRecordList(game.Records);
dialog.ShowDialog();
}
/// <summary>
/// Handles <see cref="menuItemSound"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Turns on/off the sound in the game. The user preffered settings for sound will be remembered
/// by <see cref="AppSettings"/> object.
/// </remarks>
private void menuItemSound_Click(object sender, System.EventArgs e)
{
menuItemSound.Checked = !menuItemSound.Checked;
if (menuItemSound.Checked)
{
game.DestroyBallPause = AppSettings.Instance.PauseDestroyBall;
}
else
{
game.DestroyBallPause = 0;
}
AppSettings.Instance.UseSound = menuItemSound.Checked;
}
/// <summary>
/// Handles <see cref="menuItemOneByOne"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Turns on/off the one-by-one ball destruction feature. The user preffered settings for this flag
/// will be remembered by <see cref="AppSettings"/> object.
/// </remarks>
private void menuItemOneByOne_Click(object sender, System.EventArgs e)
{
menuItemOneByOne.Checked = !menuItemOneByOne.Checked;
game.OneByOneDestruction = menuItemOneByOne.Checked;
AppSettings.Instance.OneByOneDestroy = menuItemOneByOne.Checked;
}
/// <summary>
/// Handles <see cref="menuItemRefresh"/>'s <b>Click</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Invokes redraw of complete form.
/// </remarks>
private void menuItemRefresh_Click(object sender, System.EventArgs e)
{
RefreshView();
}
/// <summary>
/// Handles <see cref="BoardCtrl.CellClick"/> event of board control.
/// </summary>
/// <param name="ctrl">The reference to a board control object that fired this event.</param>
/// <param name="cell">The coordinates of cell that has been clicked.</param>
/// <remarks>
/// If there is a selected ball on the board and game board is not locked then initiates
/// movement of selected ball direction to the clicked cell.
/// </remarks>
private void boardCtrl_CellClick(BoardCtrl ctrl, Point cell)
{
Ball ball = game.Board.GetSelectedBall();
if ((ball != null) && (game.LockBoard()))
{
// Move ball
if (!game.MoveTo(cell))
{
// Wasn't able to move
game.UnlockBoard();
PlaySound(soundBlocked);
}
}
}
/// <summary>
/// Handles <see cref="BoardCtrl.BallClick"/> event of board control.
/// </summary>
/// <param name="ctrl">The reference to a board control object that fired this event.</param>
/// <param name="ballCtrl">The ball control that has been clicked.</param>
/// <remarks>
/// Propagates this event further to the board and sets the status of clicked ball to selected.
/// </remarks>
private void boardCtrl_BallClick(BoardCtrl ctrl, BallCtrl ballCtrl)
{
game.Board.SelectBall(ballCtrl.Ball);
}
/// <summary>
/// Handles <see cref="Game.BallAdd"/> event of game object.
/// </summary>
/// <param name="game">The reference to a game object that fired this event.</param>
/// <param name="ball">The ball that has been added.</param>
/// <remarks>
/// Propagates this event further to the board control.
/// </remarks>
private void game_BallAdd(Game game, Ball ball)
{
boardCtrl.AddNewBall(ball);
}
/// <summary>
/// Handles <see cref="Game.BallDelete"/> event of game object.
/// </summary>
/// <param name="game">The reference to a game object that fired this event.</param>
/// <param name="ball">The ball that is going to be deleted.</param>
/// <remarks>
/// Plays appropriate sound and propagates this event further to the board control.
/// </remarks>
private void game_BallDelete(Game game, Ball ball)
{
PlaySound(soundDestroy);
boardCtrl.RemoveBall(ball);
}
/// <summary>
/// Handles <see cref="Game.BallsDelete"/> event of game object.
/// </summary>
/// <param name="game">The reference to a game object that fired this event.</param>
/// <param name="balls">The balls that are about to be deleted.</param>
/// <remarks>
/// Plays appropriate sound and propagates this event further to the board control.
/// </remarks>
private void game_BallsDelete(Game game, Ball[] balls)
{
PlaySound(soundDestroy);
boardCtrl.RemoveBalls(balls);
}
/// <summary>
/// Handles <see cref="Game.BallMove"/> event of game object.
/// </summary>
/// <param name="game">The reference to a game object that fired this event.</param>
/// <param name="ball">The ball to move.</param>
/// <param name="oldPos">The old position of ball.</param>
/// <param name="newPos">The ball destination.</param>
/// <remarks>
/// Plays appropriate sound and propagates this event further to the board control.
/// </remarks>
private void game_BallMove(Game game, Ball ball, Point oldPos, Point newPos)
{
PlaySound(soundMove);
boardCtrl.MoveBall(ball, oldPos, newPos);
}
/// <summary>
/// Handles <see cref="Game.BallMoved"/> event of game object.
/// </summary>
/// <param name="game">The reference to a game object that fired this event.</param>
/// <param name="ball">The ball that has been moved.</param>
/// <remarks>
/// Initiates the next step of the game (See <see cref="Game.NextStep()"/>) and performs
/// optimized invalidation of board control.
/// </remarks>
private void game_BallMoved(Game game, Ball ball)
{
// Diselect & Invalidate
boardCtrl.InvalidateCell(ball.Position);
// Next step
if (game.NextStep())
{
indicatorCtrl.Invalidate();
// For optimization purposes we will invalidate only new virtual balls positions
for (int i = 0; i < game.VirtualBalls.Length; i++)
{
boardCtrl.InvalidateCell(game.VirtualBalls[i].Position);
}
game.UnlockBoard();
}
else
{
// If failed then game is over
// !IMPORTANT! Cannot call dialog from the Thread :( !!!! (see watch dog implementation)
//GameOver();
}
}
/// <summary>
/// Handles <see cref="ballJump"/>'s <b>Tick</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Makes board control to redraw jumping ball if there is one.
/// </remarks>
private void ballJump_Tick(object sender, System.EventArgs e)
{
boardCtrl.DrawJumpingBall();
}
/// <summary>
/// Starts a new game.
/// </summary>
private void NewGame()
{
boardCtrl.RemoveAllBalls();
game.NewGame();
RefreshView();
}
/// <summary>
/// Finalizes the current game and starts a new one.
/// </summary>
/// <remarks>
/// Displays "Game Over!" message and requests the player's name if he or she scored the record.
/// </remarks>
private void GameOver()
{
MessageBox.Show("Game Over!", "Lines.NET", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
if ((game.StepCount > 0) && game.IsRecord)
{
InputBox dialog = new InputBox(AppSettings.Instance.IsPocketPC);
dialog.Text = "Hi Score Record!";
dialog.Message = "What is your name hero?";
dialog.DisplayCancelButton = false;
dialog.ShowDialog();
game.SaveResults(dialog.InputText);
}
NewGame();
}
/// <summary>
/// Invalidates both indicator control and board control and force them to redraw themselves.
/// </summary>
private void RefreshView()
{
boardCtrl.Invalidate();
indicatorCtrl.Invalidate();
}
/// <summary>
/// Plays sound if user settings allows sounds.
/// </summary>
/// <param name="sound">The sound object to play.</param>
private void PlaySound(Sound sound)
{
if (menuItemSound.Checked)
{
sound.Play();
}
}
/// <summary>
/// Handles <see cref="gameOverWatchDog"/>'s <b>Tick</b> event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// <p>That's an implementation of ad hoc solution for .NET Compact Framework thread problem. This
/// method is executed every 100 ms. from inside of main thread (therefor <see cref="Timer"/> object
/// is needed) and checks if game has set the "game over" flag (See
/// <see cref="Game.IsGameOverEvent"/>). If it appears to be the end of the game the appropriate logic
/// is executed.</p>
/// <p style="color:red">The ball movement is done in a separate thread. By the end of this movement
/// the next step for the game is executed and the check of the game over status is done. The call
/// of dialogs (to display "Game Over!" message and to request the player name) from this thread
/// causes exceptions when the application is closing.</p>
/// <p style="color:red"><b>It seems like the only solution is to display dialogs and forms
/// only from the main thread.</b></p>
/// <p style="color:red">It has something to do with initialization of SIP.</p>
/// </remarks>
private void gameOverWatchDog_Tick(object sender, System.EventArgs e)
{
// That's horrible, but let me know how the hell I can treat it in another way? :(
if (game.IsGameOverEvent)
{
GameOver();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -