timy created page: ProgramDesign

Tim Young 2017-10-03 03:10:53 +02:00
parent b449fd9ad5
commit afb10ebb97

86
ProgramDesign.md Normal file

@ -0,0 +1,86 @@
# Program design
This section is geared towards helping describe how you may want to design a game that is built with SpriteLibrary. This is a suggestion only. It will probably help you to read this section, as it does contain a fair bit of hard-won thought. BUT, every developer must make a lot of their own decisions. There is nothing magical about this.
## One Form
It is a lot simpler to program a game if it is all within one form. While you can develop games using multiple forms, things can get very messy. The SpriteLibrary was designed for use with one form, and bouncing between different forms can result in some very strange behavior. In my [AdventureDemo](http://www.codeproject.com/Articles/1110409/Using-SpriteLibrary-to-develop-a-Role-Playing-Game), I used multiple forms. That was a bad idea. If I closed the main game window during a battle, the game exited and the game-menu popped up. Then, the sprites continued to fight, even though they were technically gone. The party continued to take damage, and sometimes die. It was a little disconcerting.
The game is a lot simpler to deal with if you only have one form. This means you draw your menu on the same PictureBox that you have your game running on. You can change the PictureBox background, so you have a different looking window when the window is up, or you can leave it be. It does not really matter too much. But, please, try using putting it all in one Form if possible.
Having multiple PictureBoxes works fairly well, particularly with linked sprite-controllers and / or a SpriteDatabase. Both of those allow you to define a sprite once but use it on multiple picture boxes.
## Enum for Game Mode
To get everything to run in one PictureBox, it is usually easiest to have an Enum, which tells you which mode you are in. The enum might be something like:
```c#
public enum GameMode { Menu, Menu_Settings, Menu_HighScores, Playing, Won, Lost }
```
You will have a “Tick” function (more information below), and the first thing in your tick function is to determine what mode you are in, and process things accordingly.
## Instantiate Named Sprites (or instantiate on demand)
You often want to load your sprites at the beginning. Sometimes, you will want to make a function, called “GetSprite”, which will find a named sprite. If the named sprite does not exist, it will load it and name it. If you do that, you can load and name the sprite the first time you need it. This only works in a few cases; if the process of instantiating a sprite is quick enough that it can be done in the middle of action. Otherwise, you will want to pause long enough at the beginning of the game to load all your sprites.
## Function to change mode
You should create a function to change the game mode. We will place a call for this in a moment, but for now, we do something like:
* Clear all sprites: The sprite controller has a process for clearing all sprites that are duplicates of named sprites. Basically, anything on the screen gets removed.
* Start Game: Change the background to whatever the game background is. Duplicate all the sprites you need for the game and place them in their starting positions.
* Start Menu: Change the background to whatever the menu background image is. Duplicate all the menu sprite buttons and place them in their respective menu spots. (You should have menu buttons for things like “play”, “settings”, “high-scores”, and “exit”)
* Start Settings: This is usually a special “menu” that has items like: “volume”, “speed”, etc.
* Start Game Won: This is usually a special menu that shows you a “you have won!” message, as well as your score, and any special “win” message. You usually have a “next” button or something to go on to the menu from there.
* Start Game Lost: This is usually a special menu that shows you a “you have Lost!” message, as well as your score, and any special “lost” message. You usually have a “next” button or something to go on to the menu from there.
## Game Tick
The Game Tick function is where most of the work on your game goes. The Tick happens every few milliseconds. When you create your SpriteController, you need to add your Tick function with something like: MyController.DoTick += GameTick;
You usually check first to see if you are switching your mode to something else:
```c#
If(newmode != currentmode) ChangeMode(newmode);
And then, you have an if (or switch) block to process things depending on which mode you are in:
If(currentmode == GameMode.Playing) {
CheckForKeypresses();
CheckForChangeInLevel();
}
```
## Making a Game Menu
Your Menu is usually set up by creating a bunch of functions, one for each MenuButtonSprite. A MenuButtonSprite is basically a sprite that does something when you click it.
For an example, we will use an “exit” sprite button. This button will look something like the one on the left. We load the sprite as three different animations. The first one, at the top, we will use for when we show the menu. The second menu item is just a little bit lighter in color, and we will use that when we mouse-over the menu item. And we will use the green one when we click on it.
We will want to have some functions for this button. Lets call them ExitClick, ExitMouseOver, and ExitMouseLeave.
When we instantiate this menu button, we will do something like the following:
```c#
Sprite ExitButton = Sprite(new Point(0, 0), MyController, Properties.Resources.Exit, 100, 100, 1000, 1);
ExitButton.AddAnimation(new Point(0, 50), Properties.Resources.Exit, 100, 100, 1000, 1);
ExitButton.AddAnimation(new Point(0, 100), Properties.Resources.Exit, 100, 100, 1000, 1);
ExitButton.Click += ExitClick;
ExitButton.MouseOver = ExitMouseOver;
ExitButton.MouseLeave = ExitMouseLeave;
ExitButton.SetName(“ExitButton”);
Now, lets make our different functions.
public void ExitClick(object sender, SpriteEventArgs e)
{
If(sender is Sprite)
{
Sprite ExitSprite = (Sprite)sender;
Sender.ChangeAnimation(2);
NewGameMode = GameMode.Exiting;
}
}
public void ExitMouseOver(object sender, SpriteEventArgs e)
{
If(sender is Sprite)
{
Sprite ExitSprite = (Sprite)sender;
Sender.ChangeAnimation(1);
}
}
public void ExitMouseLeave(object sender, SpriteEventArgs e)
{
If(sender is Sprite)
{
Sprite ExitSprite = (Sprite)sender;
Sender.ChangeAnimation(0);
}
}
```