Monday Snaps: Cheese Lander Game Reset

Welcome back to our weekly Snaps session, which has the ultimate aim of creating the awesome gaming experience that is Cheese Lander . Last week we got the bread, cheese and background screen drawing nicely, this week we are going to place the bread and cheese at their starting positions. So, if someone asks you "Who moved the cheese?" you can say it was you.

We're going to start with a bit of gentle re-factoring. Re-factoring is a posh word for "putting things in the place that they should have been from the start". Computer programmers are lucky in this respect. Doing "refactoring" in other professions means moving physical things around. Refactoring a brick wall is hard. But with code it's easy. What I want to do is create some methods that will deal with my game objects. To do this I'm going to have to move the game objects into the enclosing class, so that they are visible to all the methods in that class. 

public class MyProgram
{
    ImageSprite cheese, bread, background;

    void setupSprites()
    {
        SnapsEngine.StartGameEngine(fullScreen: false, framesPerSecond: 60);
        background = new ImageSprite(imageURL: "ms-appx:///Images/Background.png");
        background.Height = SnapsEngine.GameViewportHeight;
        background.Width = SnapsEngine.GameViewportWidth;

        cheese= new ImageSprite(imageURL: "ms-appx:///Images/cheese.png");
       
cheese.ScaleSpriteWidth(SnapsEngine.GameViewportWidth / 20);

        bread = new ImageSprite(imageURL: "ms-appx:///Images/bread.png");
        bread.ScaleSpriteWidth(SnapsEngine.GameViewportWidth / 8);

        SnapsEngine.AddSpriteToGame(background);
        SnapsEngine.AddSpriteToGame(bread);
        SnapsEngine.AddSpriteToGame(
cheese);
    }

    void gameLoop()
    {
        while (true)
        {
            SnapsEngine.DrawGamePage();
        }
    }

    public void StartProgram()
    {
        setupSprites();

        gameLoop();

    }
}

This is my re-factored game class. It now has two methods. One is called setupSprites, and it sets the sprites up. The other is called gameLoop. This runs the game loop (remember that a game is all about repeatedly drawing and updating. I've also renamed the ball object to cheese. It seemed the right thing to do.

Now things are all tidy I can start building up my methods that will make the game work. When the game resets (i.e. at the start of a new game) I want the bread to be placed somewhere on the bottom of the screen. The aim of the game is then to steer the cheese onto the bread. A method called resetBread would seem to make sense. If you're asking why I'm not calling it setupBread, then I hear you. The answer is that I'm being careful with my names here. setup is something that you do once in the lifetime of the program. Reset is something you do at the start of each game. This is just my standard, yours is allowed to be different, as long as you have a standard.

Moving the bread to the bottom of the screen is easy. We just set the bottom of the bread to the height of the screen:

 bread.Bottom = SnapsEngine.GameViewportHeight;

Moving the bread to a random position across the screen is a bit harder. For a start we'll need a random number. We can get random numbers from the Random class in the System namespace. I can create an instance of this in the class for the game to use:

System.Random breadRandom = new System.Random();

I'm going to use a different random number generator for each object that needs random behaviour. This is because that way I can convert any of them to produce the same sequence (simply by adding a seed):

System.Random breadRandom = new System.Random(1);

Now my bread would be placed at the same sequence of positions when the game is played. This is a good idea because it helps the player learn how the game plays, and encourages them to come back and have another go. In the case of the bread, I'll probably make it completely random.

Anyhoo, once I've got my random number generator I can place the bread somewhere random across the width of the screen:

 bread.Left = breadRandom.Next((int)(SnapsEngine.GameViewportWidth - bread.Width));

This code is a bit of a mess to be honest. The Next method of the Random class can generate an integer in a range from 0 to an upper limit. The upper limit I want is the width of the screen minus the width of the bread. I can calculate this, but Snaps graphics work with double precision numbers. So I have to convert the result of this calculation into an integer. 

void resetBread()
{
    bread.Bottom = SnapsEngine.GameViewportHeight;
    bread.Left = breadRandom.Next((int)(SnapsEngine.GameViewportWidth - bread.Width));

}

This is my resetBread method. It places the bread nicely at the bottom of the screen. I can now steal this technology (ooooh, that sounds so cool) to position the cheese at a random position on the top of the screen:

void resetCheese()
{
    cheese.Top = 0;
    cheese.Left = cheeseRandom.Next((int)(SnapsEngine.GameViewportWidth - cheese.Width));
}

After these reset behaviours I have a game screen that looks like this:

The entire program is here:

 using SnapsLibrary;

public class MyProgram
{
    ImageSprite cheese, bread, background;

    void setupSprites()
    {
        SnapsEngine.StartGameEngine(fullScreen: false, framesPerSecond: 60);
        background = new ImageSprite(imageURL: "ms-appx:///Images/Background.png");
        background.Height = SnapsEngine.GameViewportHeight;
        background.Width = SnapsEngine.GameViewportWidth;

        cheese = new ImageSprite(imageURL: "ms-appx:///Images/cheese.png");
        cheese.ScaleSpriteWidth(SnapsEngine.GameViewportWidth / 20);

        bread = new ImageSprite(imageURL: "ms-appx:///Images/bread.png");
        bread.ScaleSpriteWidth(SnapsEngine.GameViewportWidth / 8);

        SnapsEngine.AddSpriteToGame(background);
        SnapsEngine.AddSpriteToGame(bread);
        SnapsEngine.AddSpriteToGame(cheese);
    }

    System.Random breadRandom = new System.Random();

    void resetBread()
    {
        bread.Bottom = SnapsEngine.GameViewportHeight;
        bread.Left = breadRandom.Next((int)(SnapsEngine.GameViewportWidth - bread.Width));

    }
    System.Random cheeseRandom = new System.Random();

    void resetCheese()
    {
        cheese.Top = 0;
        cheese.Left = cheeseRandom.Next((int)(SnapsEngine.GameViewportWidth - cheese.Width));
    }

    void gameLoop()
    {
        while (true)
        {
            SnapsEngine.DrawGamePage();
        }
    }

    public void StartProgram()
    {
        setupSprites();

        resetBread();

        resetCheese();

        gameLoop();

    }
}

Come back next week for more. And remember that you can get the full details of gaming with Snaps from my book:

 

 

 

 

 

 

Monday Games Snap

You might have heard of my Snaps framework. Then again you might not. I created it for my Begin to Code with C# book

The idea behind Snaps is that learning to create Windows 10 Universal Applications is hard because it takes a while to get to the point where you understand enough to have a bit of fun writing C#. 

So I created a bunch of helper functions that grew into an entire library for app and game development. 

As a celebration of being awarded another year as an MVP (thanks Microsoft) I thought I'd put the whole Snaps framework up on GitHub and then people can download and play with it, and maybe even take it further. 

Every week I'll take a Snaps function and explain how to use it, along with a bit of detail about how it works. Monday is now officially "Snaps Day". I'm going to start with the games creation framework and go on from there. 

This week I'm going to tell you how to get started and make your first sprite. You need Visual Studio 2015 or Visual Studio 2017 (it works with either). You'll also need to be running Windows 10 64 bit edition.

You can download the entire framework from GitHub. It's a single Visual Studio Solution that you just have to open. You might get warnings about the dangers of loading projects downloaded from the internet. Ignore those in this case. 

If you run the solution you'll get the Snaps main menu:

On the left you can select the book chapter. On the right you can pick an exercise from the book to run. Pick the one you can see above (Ch15_04_CompleteGame from Chapter 15). It's a complete game with moving sprites and all sorts. Click "Run and App" and the game will start. 

The graphics aren't the best to be honest. But you can control the game by the cursor keys, or mouse/touch on the cursor pad on the lower right hand edge. One sprite will chase you while the others look on. Everything is running under WPF and I'm very impressed with the performance. 

If you want to get ahead of the game you can grab the book and see exactly how the code works. For now though, use Visual Studio to stop the game (go back to VS and press the red Stop button), and take a look at the Solution Explorer on the top right. If you open up the Chapters folder you can find a folder for each chapter:

Open up a chapter and you can find all the sample code. The names of the samples are keyed to the ones you can find when you run the program. Take a look in Chapter 15:

Open up the one indicated (Ch12_02_BallSprite) It creates a single ball sprite and displays it.:

    public void StartProgram()
    {
        SnapsEngine.StartGameEngine(fullScreen: false, framesPerSecond: 60);

        ImageSprite ball = new ImageSprite(imageURL: "ms-appx:///Images/ball.png");

        SnapsEngine.AddSpriteToGame(ball);

        while (true)
        {
            SnapsEngine.DrawGamePage();
        }
    }

All the action takes place in the StartProgram method. It starts the game engine, creates a sprite and adds it to the game. Then, once we've made the sprites, we start a game loop which continuously draws the game page. It does this 60 times a second, because that is the frame rate requested at the start. The image for the ball is an asset which is in the Images folder in the project:

You can use your own images if you like. Drag them to the images folder and make sure that their build action is set to Content (as below). Then use the appropriate name to draw them.

If you run the framework and select this example (Ch12_02_BallSprite) you can see the ball on the screen. If you change the above code and use the handy "Run That Again" button you can see your changes. Don't worry about breaking the examples. You can always download a fresh set from GitHub if it all goes horribly wrong.

You might like to add more sprites, or fiddle with the properties of the existing sprite, in which case Intellisense is your friend:

See what adding :

ball.CenterX++;

.. to the while loop does. You should have:

while (true)
 {
        ball.CenterX++;
        SnapsEngine.DrawGamePage();
 }

If you make anything especially impressive take a video of it, send me the link and I'll start a hall of fame on this page. Because this is a Universal Application it can run on any Windows 10 device, including Xbox One and Raspberry Pi (although it is not as fast on the Pi)

Of course the best way to find out all these things (and learn to program as well) is to buy my book. 

But if you don't want to do that, then I'll have another Monday Snap for you next week.

Snaps.Rocks goes live

snaps.PNG

I bought a domain name today. I do this every now and then. I say that getting a domain name is cheaper than getting a tattoo, and much easier to get rid of when you get bored with it. 

I now have snaps.rocks (it was cheap) and at the moment it points to a holding page on these hallowed pages. The latest version, with the Snaps gaming framework built in, will be going live in a few days. Such excitements. 

Snaps now has a 2D Game Engine

If  you've not heard much about Snaps (my library that's designed to make it easy to learn to program C# which I'm using in a forthcoming book) then that's because I've been too busy writing the book (and the Snaps) to tell anyone about it. But today I built some Snaps that I'm really quite proud of. I've now got a tiny sprite library and a gamepad which you can use to make 2D games.  I'm going to use it in the chapter where we talk about class hierarchies. 

It's not a particularly fancy engine really. It runs inside a Windows 10 Universal application and uses all the XAML display elements. Having said that, I can get reasonable performance on my machine which has no graphics acceleration and it even runs on a Raspberry Pi. 

For learning to program (and of course for Cheese Lander) it's absolutely perfect. 

Windows 10 on Raspberry Pi - Snaps secrets of the LogoBlaster

Spent a lot of today working on the presentation for Future Decoded tomorrow. I'm showing off my Snaps framework for creating simple applications. It's almost ready for release. If I hadn't just decided to renumber all the chapters of the book that it is linked too, thereby breaking all the sample code, it would be available now.....

Anyhoo, I dropped Snaps onto a Raspberry Pi (which is really easy to do) and built a bunch of embedded snaps.  I'm going to show how easy it is to use Snaps with embedded code and show of my LogoBlaster device.

This is the code that reads from a pin and changes to the next logo if the pin has been pressed. All that displayNextImage does is fetch the next picture. No need to set up an GPIO, just use the snaps engine methods. I'm really looking forward to the talk tomorrow.