Empty Your Mind Tutorial 2
From SwinGame
This tutorial will teach you how to use the SwinGameSDK to develop a simple danmaku game which looks cool. At the end of this tutorial you should be able to use pascal to implement your own space invaders or scrolling shooter style game which makes use of Vectors, animated Sprites, SoundEffects, and Music.
Contents |
Creating A Sprite
We need to create our ship so we can shoot bullets. To create an animating sprite, you will be using:
function CreateSprite(image : Bitmap; framesPerCell, frames, width, height: Integer): Sprite;
Frames per cell will define the number of frames per cell. The animation image is a single image file which contains animation. Sample image can be found in here. The game resources management is explained in here.
Steps I have taken to create the player's ship is:
- Create a sprite from the ship's image (multi-bitmap animation)
- Set the ship's x position to the middle of the screen
- Set the ship's y position (150 pixel offset from the bottom of the screen)
- Set the ship's speed
The following code is an implementation of the steps above.
procedure LoadGame(var game : GameData); const PLAYEROFFSET = 150; begin //Create the player ship game.player.theSprite := CreateSprite(GameImage('Ship'), 2, 2, 40, 43); game.player.theSprite.xPos := Round(ScreenWidth / 2 - game.player.theSprite.width / 2); game.player.theSprite.yPos := ScreenHeight - PLAYEROFFSET; game.player.speed := 4; end;
Make sure that the LoadGame procedure is called from the MainGame procedure.
Drawing A Sprite
We have created a sprite but we cannot see it yet because we are not drawing. Drawing and updating the animation can be done very easily. Drawing and animation update can be done by:
DrawSprite(player.theSprite); UpdateSpriteAnimation(player.theSprite);
Call these procedures in your loop before the RefreshScreen(). I highly recommend you to create a procedure which is dedicated to process everything related to the player to simplify the program.
Screenshot of working animation sprite:
Moving A Sprite
We have got the ship to display but we haven't got the ship to move. I'm going to show how to move a ship properly in three steps.
- Move left and right
- Move up and down
- Move up-right, up-left, down-right and down-left
Moving left and right is the first step to move a player's ship. In order to move a player's ship, we need to…
- Check the key input
- Move the ship according to the input
We can the ship left and right by using the following code.
procedure MovePlayerShip(var player : ShipData); begin if IsKeyPressed(VK_LEFT) then //if the left arrow key is the only key being pressed player.theSprite.xPos := player.theSprite.xPos - player.speed else if IsKeyPressed(VK_RIGHT) then //if the right key is the only key being pressed player.theSprite.xPos := player.theSprite.xPos + player.speed; end;
Execute this procedure before drawing the player's ship and the ship will react to your key inputs. Now we are going to implement the up and down movement. This is very easy if you understand the left and right movement. The following code will extend the last procedure to detect the up and down movement.
procedure MovePlayerShip(var player : ShipData); begin if IsKeyPressed(VK_LEFT) then //if the left arrow key is the only key being pressed player.theSprite.xPos := player.theSprite.xPos - player.speed else if IsKeyPressed(VK_RIGHT) then //if the right key is the only key being pressed player.theSprite.xPos := player.theSprite.xPos + player.speed else if IsKeyPressed(VK_DOWN) then //if the only key being pressed is the down arrow key player.theSprite.yPos := player.theSprite.yPos + player.speed else if IsKeyPressed(VK_UP) then //if the only key being pressed is the up arrow key player.theSprite.yPos := player.theSprite.yPos - player.speed; end;
We now have a basic movement but we cannot go right-up, left-up and so on. This is the hardest part of the player's ship movement. To move right-up, we need to move the ship by the player's speed. Let's say the player's speed is 4. In this case, we need to move the ship by 4 pixel diagonally. To calculate the movement of X and Y from an angle, we need to come up with a formula. This can be done very easily by using Cos and Sin.
procedure UpdateEntityPosition(speed, angle : Single; var target : Sprite); begin target.xPos := target.xPos + speed * SGSDK_Core.Cos(angle); target.yPos := target.yPos + speed * SGSDK_Core.Sin(angle); end;
This procedure will directly modify the sprite's position. The usage of this procedure is…
UpdateEntityPosition(player.speed, 225, player.theSprite);
This example code will move the sprite to up-left by 4 pixel. Finally, we can implement the complete movement code by using the UpdateEntityPosition procedure.
procedure MovePlayerShip(var player : ShipData); begin if IsKeyPressed(VK_LEFT) then begin //if the left arrow key is being pressed if IsKeyPressed(VK_UP) then //if the up arraw key is also being pressed UpdateEntityPosition(player.speed, 225, player.theSprite) else if IsKeyPressed(VK_DOWN) then //if the up down key is also being pressed UpdateEntityPosition(player.speed, 135, player.theSprite) else if not IsKeyPressed(VK_RIGHT) then //if the left arrow key is the only key being pressed player.theSprite.xPos := player.theSprite.xPos - player.speed end else if IsKeyPressed(VK_RIGHT) then begin //if the right arrow key is being pressed if IsKeyPressed(VK_UP) then //if the up arrow key is also being pressed UpdateEntityPosition(player.speed, 315, player.theSprite) else if IsKeyPressed(VK_DOWN) then //if the down arrow key is also being pressed UpdateEntityPosition(player.speed, 45, player.theSprite) //if the right key is the only key being pressed else player.theSprite.xPos := player.theSprite.xPos + player.speed end else if IsKeyPressed(VK_DOWN) and (not IsKeyPressed(VK_UP)) then //if the only key being pressed is the down arrow key player.theSprite.yPos := player.theSprite.yPos + player.speed else if IsKeyPressed(VK_UP) and (not IsKeyPressed(VK_DOWN)) then //if the only key being pressed is the up arrow key player.theSprite.yPos := player.theSprite.yPos - player.speed; end;
We now have a ship movement in any direction! You might notice that the ship can go out of the screen. The procedure that limits the ship's movement can be written very easily.
procedure FixPosition(var theSprite : Sprite); begin if theSprite.xPos < 0 then theSprite.xPos := 0; if theSprite.yPos < 0 then theSprite.yPos := 0; if theSprite.xPos > ScreenWidth() - theSprite.Width then theSprite.xPos := ScreenWidth() - theSprite.Width; if theSprite.yPos > ScreenHeight() - theSprite.Height then theSprite.yPos := ScreenHeight() - theSprite.Height; end;
The FixPlayerPosition procedure will check if the player's ship has gone out of the screen and fix the position if it has.
Summary
In this tutorial, I have gone through:
- Creating a sprite
- Directly manipulating a sprite coordinate
- Keyboard input processing
The current project files can be downloaded from here.

