⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cs

📁 C#开发的运行于windows mobile PDA上的游戏
💻 CS
📖 第 1 页 / 共 2 页
字号:
			GenerateNextBalls();
			NextStep();

			// Reset step counter
			stepCount = 0;
			// Reset score
			score = 0;

			// New game
			isGameOver = false;

			// Unlock in any case
			UnlockBoard();
		}

		/// <summary>
		/// Saves the current player score in a hi score list.
		/// </summary>
		/// <param name="player">The player name.</param>
		public void SaveResults(string player)
		{
			// Save in the high score table
			if (IsRecord)
			{
				Records.AddRecord(player, score, stepCount);
				Records.Save(RecordsFilename);
			}
		}

		/// <summary>
		/// Generates balls (position, colors) that will apper on the board at next step.
		/// </summary>
		public void GenerateNextBalls()
		{
			virtualBalls = board.GenerateVirtualBalls(ballsPerStep);
		}

		/// <summary>
		/// Performs operation to go for the next step.
		/// </summary>
		/// <returns><c>true</c> if operations are succeeded, <c>false</c> if the game is over.</returns>
		public bool NextStep()
		{
			// Remove lines that have reached a limit ballsInLine
			if (!DestroyLines())
			{
				// Materialize virtual balls :)
				for (int i = 0; i < virtualBalls.Length; i++)
				{
					Ball ball = virtualBalls[i];
					if (board.GetBallAt(ball.X, ball.Y) != null)
					{
						Point newPos = board.GetRandomEmptySquare();
						ball.MoveTo(newPos.X, newPos.Y);
					}
					board.SetBallAt(ball, ball.X, ball.Y);
					FireBallAdd(ball);
				}

				virtualBalls = null;
				
				// Collapse those that appeared after materializing virtual balls
				DestroyLines();
				
				// Generate following up set of balls
				GenerateNextBalls();
			}
			
			// Increment step counter
			stepCount++;

			// Each step gives one point to score
			score++;

			if (virtualBalls == null)
			{
				// Game over
				isGameOver = true;
				return false;
			}

			return true;
		}

		/// <summary>
		/// Moves currently selected ball to a new position.
		/// <seealso cref="MoveBall(Point, Point)"/>
		/// </summary>
		/// <param name="pos">The position to move selected ball to.</param>
		/// <returns><c>true</c> if the specified posion is free and reachable, <c>false</c> otherwise.</returns>
		/// <remarks>
		/// Moves currently selected ball to a certain position if possible. The animation of a 
		/// ball movement is started in a separate thread if this method has returned <c>true</c>.
		/// </remarks>
		public bool MoveTo(Point pos)
		{
			Ball destination = board.GetBallAt(pos.X, pos.Y);
			Ball ball = board.GetSelectedBall();
			if ((destination == null) && (ball != null))
			{
				Point[] route = board.CreateRoute(ball.Position, pos);
				if (route != null)
				{
					// Fire move event and then move the ball to appropriate pos.
					ball.Select(false);
					AnimateMove(ball, route);
					// ball.MoveTo(pos.X, pos.Y);
					return true;
				}
			}

			return false;
		}

		/// <summary>
		/// Animates ball movement.
		/// </summary>
		/// <param name="ball">The ball to move.</param>
		/// <param name="route">The ball's route.</param>
		/// <remarks>
		/// Launches an instance of <see cref="MoveBallWorker"/> in a separate thread to animate ball
		/// movement.
		/// </remarks>
		protected void AnimateMove(Ball ball, Point[] route)
		{
			MoveBallWorker worker = new MoveBallWorker(this, ball, route);
			Thread moveThread = new Thread(new ThreadStart(worker.Execute));
			moveThread.Start();
		}

		/// <summary>
		/// Moves a ball from one position to another.
		/// <seealso cref="MoveTo(Point)"/>
		/// </summary>
		/// <param name="from">The initial ball lacation.</param>
		/// <param name="to">The ball destination.</param>
		/// <remarks>
		/// <p>Moves a ball from position defined by <c>from</c> to posion <c>to</c>. Unlike <see cref="MoveTo(Point)"/>
		/// method this one does not calculate a route to move the ball and does not start a separate thread to animate
		/// movement, instead it simply transfers the ball and fires <see cref="BallMove"/> event.</p>
		/// <p>This method is used by <see cref="MoveBallWorker"/> to move a ball for one step.</p>
		/// </remarks>
		public void MoveBall(Point from, Point to)
		{
			Ball ball = board.GetBallAt(from.X, from.Y);
			if (ball != null)
			{
				board.MoveBall(from, to);
				FireBallMove(ball, from, to);
			}
		}

		/// <summary>
		/// Removes all lins that were found by <see cref="DestroyFinder"/>.
		/// </summary>
		/// <returns><c>true</c> if <see cref="DestroyFinder"/> has found something to destroy and balls 
		/// were removed from the <see cref="Board"/>, <c>false</c> otherwise.</returns>
		/// <remarks>
		/// Removes all balls that compose lines which were found by <see cref="DestroyFinder"/>. Depending 
		/// on <see cref="OneByOneDestruction"/> flag it either removes balls from the 
		/// <see cref="Board"/> all at once and fires <see cref="BallsDelete"/> event or destroys balls
		/// one by one with <see cref="DestroyBallPause"/> interval and fires <see cref="BallDelete"/> event
		/// each time the ball is about to be removed from the <see cref="Board"/>.
		/// </remarks>
		public bool DestroyLines()
		{
			Ball[] ballsToDestroy = board.FindBallsToDestroy(ballsInLine);
			bool hasBallsToDestroy = ballsToDestroy.Length > 0 ? true : false;
			UpdateScore(ballsToDestroy.Length);

			if (oneByOneDestruction)
			{
				foreach (Ball ball in ballsToDestroy)
				{
					FireBallDelete(ball);
					board.DeleteBallAt(ball.X, ball.Y);
					Thread.Sleep(destroyBallPause);
				}
			}
			else if (hasBallsToDestroy)
			{
				FireBallsDelete(ballsToDestroy);
				foreach (Ball ball in ballsToDestroy)
				{
					board.DeleteBallAt(ball.X, ball.Y);
				}
			}

			return hasBallsToDestroy;
		}

		/// <summary>
		/// Updates player's score.
		/// </summary>
		/// <param name="destroyedBalls">The amount of balls that were destroyed.</param>
		/// <remarks>
		/// <p>Updates player's score according to the amount of balls that were removed at one step.</p>
		/// <p>The score is calculated according to following rules:</p>
		/// <list type="bullet">
		///		<item>
		///			<description>For all mandatory amount of balls in line to be destroyed player receive
		///			corresponding amount of points. So each ball weighs 1 point.</description>
		///		</item>
		///		<item>
		///			<description>For the first extra-ball player receive 2 points.</description>
		///		</item>
		///		<item>
		///			<description>Each farther extra-ball is rewarded with weight of previous
		///			extra-ball plus 2 points.</description>
		///		</item>
		/// </list>
		/// <p>For instance if <see cref="BallsInLine"/> is equal to 5 and player has hit 8 
		/// balls at one step he will be awarded with 
		/// <c>score = 5 (5 required balls) + 2 (1st extra-ball) + 4 (2nd extra-ball) + 6 (3rd extra-ball) = 17 points.</c></p>
		/// </remarks>
		public void UpdateScore(int destroyedBalls)
		{
			if (destroyedBalls >= ballsInLine)
			{
				// Give one for each ball from minimum
				score += ballsInLine;

				// Each extra ball is valued with weight of previous + 2 starting from 2
				int extraValue = 2;
				destroyedBalls -= ballsInLine;
				while (destroyedBalls > 0)
				{
					score += extraValue;
					extraValue += 2;
					destroyedBalls--;
				}
			}
		}

		/// <summary>
		/// Fires <see cref="BallAdd"/> event with a reference to this game.
		/// </summary>
		/// <param name="ball">The ball that has been added.</param>
		public void FireBallAdd(Ball ball)
		{
			BallAdd(this, ball);
		}
		
		/// <summary>
		/// Fires <see cref="BallDelete"/> event with a reference to this game.
		/// </summary>
		/// <param name="ball">The ball that is about to be deleted.</param>
		public void FireBallDelete(Ball ball)
		{
			BallDelete(this, ball);
		}
		
		/// <summary>
		/// Fires <see cref="BallsDelete"/> event with a reference to this game.
		/// </summary>
		/// <param name="balls">The balls that are about to be deleted.</param>
		public void FireBallsDelete(Ball[] balls)
		{
			BallsDelete(this, balls);
		}
		
		/// <summary>
		/// Fires <see cref="BallMove"/> event with a reference to this game.
		/// </summary>
		/// <param name="ball">The ball to move.</param>
		/// <param name="oldPos">The old position of ball.</param>
		/// <param name="newPos">The destination of ball.</param>
		public void FireBallMove(Ball ball, Point oldPos, Point newPos)
		{
			BallMove(this, ball, oldPos, newPos);
		}
		
		/// <summary>
		/// Fires <see cref="BallMoved"/> event with a reference to this game.
		/// </summary>
		/// <param name="ball">The ball that has been moved.</param>
		public void FireBallMoved(Ball ball)
		{
			BallMoved(this, ball);
		}

		/// <summary>
		/// Locks an access to the <see cref="Board"/>.
		/// <seealso cref="UnlockBoard"/>
		/// </summary>
		/// <returns><c>true</c> if the <see cref="Board"/> were locked, <c>false</c>
		/// in case the board were already locked by another process.</returns>
		/// <remarks>
		/// Trys to lock an access to the <see cref="Board"/>. It is a simple way to resolve 
		/// problems of concurrency access to the <see cref="Board"/> so that a player cannot 
		/// move another ball untill the first one didn't finished its movement.
		/// </remarks>
		public bool LockBoard()
		{
			if (isLocked)
				return false;

			isLocked = true;
			return true;
		}

		/// <summary>
		/// Unlocks an access to the <see cref="Board"/>.
		/// <seealso cref="LockBoard"/>
		/// </summary>
		public void UnlockBoard()
		{
			isLocked = false;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -