Handling input

In Blazor there are several attributes you can place on elements to handle events, for example:

  • @onkeydown
  • @onkeyup
  • @onmousedown
  • @onmouseup

On those attributes you can specify a method in your Blazor component that must be called when the event happens. This code can look like this:

1
2
3
4
5
6
7
<div id="canvasContainer" @onkeyup="OnKeyUp">
@code {
  private void OnKeyUp(KeyboardEventArgs args)
    {
        Console.WriteLine($"Key pressed: {args.Code}");
    }
}

In the example above the OnKeyUp method will be called every time a pressed key is released. From that code you can then of course implement your game logic and what needs to happen when you released a certain key.

There is only one more challenge here. Because the @onkeyup method is declared on a specific element this elements needs to have focus to handle the events. When this element does not have focus no events will happen and our code will not be called. In case of a game I assume you always want to have focus on the game and handle those input events. To realize this I added another small piece of javascript to my page:

1
2
3
4
5
// always keep focus
window.game.canvases[0].onblur = (e) => {
    window.game.canvases[0].focus();
};
window.game.canvases[0].focus();

Using this code I can make sure that as soon as the element loses its focus (onblur), focus is re-applied to it.

All the things I described above will work the same way if you want to handle mouse events. I have made some examples that can be found on: https://github.com/henthoven/BlazorFunExamples

Look for the project Example3 to see the input handling examples.

Using sprites

For a game it is of course also important to have some images/sprites to show. For my game my definition of a sprite is just an image that is used to display a certain object in the game. In this chapter I will explain how you can make sprites using Piskelapp and how you can use them in a game.

Piskelapp

I am not a designer and I am sure there are a lot of application available to make sprites. When I was looking for a good application I had 2 requirements in mind:

  • Support transparency
  • Support to store multiple sprites in one image

The second requirement is important to me because it will help making it more efficient to load images into the game. Next to that the HTML5 canvas has very good support for drawing images to a canvas from a certain part of an image.

While searching I ended up with an application named Piskelapp (https://www.piskelapp.com/). This is a web application that you can use with or without an account from your browser or you can download it and run it as a desktop application. I have used the web version without making an account for my examples. In Piskelapp you have a basic drawing set where you can draw your sprites and in the end save all your sprites to one image. The result can for example look as follows:

PiskelApp, example sprite

In this image you see 2 sprites which are each 32 pixels wide and 32 pixels in height. To use those sprites from our Blazor application we have to load our image from the server. We do this by simply adding an image tag with the hidden attribute on it. In that way the browser will not show the image to the user. Next to that we add the @ref attribute from Blazor to it so we have a reference to it from our Blazor component. It looks as follows:

1
2
3
4
<img  @ref="_demoSprites" src="Images/BlazorFunPiskelDemo.png" hidden/>
@code {
    ElementReference _demoSprites;
}

Now we have a reference in our Blazor component to the images with our sprites. To draw those sprites to the screen we can make use of the drawImage method of the HTML5 canvas. To this method you can pass in:

  • the reference to our _demoSprites image
  • the source X and Y position to get the sprite from in the image
  • the source width and height of the sprite in the image
  • the target X and Y position on the canvas
  • the target width and height on the canvas

To draw the second sprite of our image to the X,Y position 100,100 on the canvas the method call will look like this:

1
await _canvasContext.DrawImageAsync (_demoSprites, 32, 0, 32, 32, 100, 100, 32, 32);

I have made an example application using those sprites which can be found on: https://github.com/henthoven/BlazorFunExamples

Look for the Example5 project for loading sprites from 1 image. This example also show basic movement of the sprite over the screen.

In my next blog I will continue on this subject and we will talk about how we can add sound to our game and create a real snake game.