Diddy Tutorials - Simple Shoot 'em Up
Monkey Archive Forums/Monkey Tutorials/Diddy Tutorials - Simple Shoot 'em Up
| ||
Following on from the Screen Based Framework tutorial, let’s create a game with Diddy :) Diddy has a Sprite class which has basic sprite based functionality to make coding games faster. To load resources such as images and sounds, Diddy has a resource manager so you can store your images/sounds and retrieve them quickly and easily. Let’s start by creating the folder structure for our new game: DiddyShootEmUp\ main.data\ graphics\ sounds\ When using the resource managers Diddy expects graphics to be in a graphics folder and sounds in a sounds folder. Create the main file in DiddyShootEmUp called “main.monkey”, this file is the entry point for your game: main.monkey Strict Import diddy Function Main:Int() MyGame.GetInstance() Return True End Class MyGame Extends DiddyApp Global instance:MyGame = Null Method Create:Void() ' set the virtual resolution SetScreenSize(800, 450, True) End Function GetInstance:MyGame() If instance = Null instance = New MyGame() End Return instance End End I’m using the Singleton Pattern again for the MyGame class, in the future you could declare a font or something in here and refer to it via the GetInstance function. The SetScreenSize takes in the virtual resolution you want for your game, width and height. Set the Boolean to be True if you want Diddy to look after the aspect ratio for you. Let’s load some resources: Strict Import diddy Function Main:Int() MyGame.GetInstance() Return True End Class MyGame Extends DiddyApp Global instance:MyGame = Null Method Create:Void() ' set the virtual resolution SetScreenSize(800, 450, True) ' 16:9 ratio ' load the resources LoadImages() LoadSounds() End Function GetInstance:MyGame() If instance = Null instance = New MyGame() End Return instance End Method LoadImages:Void() ' load in an animation 64x64 with 7 frames images.LoadAnim("ship.png", 64, 64, 7) ' load in a background image images.Load("background.png", "", false) End Method LoadSounds:Void() ' load the sounds sounds.Load("boom3.ogg") sounds.Load("lazer.ogg") End End The “images” and “sounds” are resource managers within Diddy. When loading images Diddy will auto midhandle them, we don’t want the background to be midhandled so we set the Boolean to false. The resource managers are a hashmap with the name of the file as the key, but you can override the key if you want. Copy the following files into the graphics folder: ![]() ![]() Copy the following files into the sounds folder: https://dl.dropboxusercontent.com/u/35103024/tutorials/boom3.ogg https://dl.dropboxusercontent.com/u/35103024/tutorials/lazer.ogg Time for some screens, create a new file called “titlescreen.monkey” and one called “gamescreen.monkey” – remember case is important in MonkeyX! main.monkey Strict Import diddy Import titlescreen Function Main:Int() MyGame.GetInstance() Return True End Class MyGame Extends DiddyApp Global instance:MyGame = Null Method Create:Void() ' set the virtual resolution SetScreenSize(800, 450, True) ' 16:9 ratio ' load the resources LoadImages() LoadSounds() Start(TitleScreen.GetInstance()) End Function GetInstance:MyGame() If instance = Null instance = New MyGame() End Return instance End Method LoadImages:Void() ' load in an animation 64x64 with 7 frames images.LoadAnim("ship.png", 64, 64, 7) ' load in a background image images.Load("background.png", "", false) End Method LoadSounds:Void() ' load the sounds sounds.Load("boom3.ogg") sounds.Load("lazer.ogg") End End titlescreen.monkey Strict Import main Import gamescreen Class TitleScreen Extends Screen Global instance:TitleScreen = Null Function GetInstance:TitleScreen() If instance = Null instance = New TitleScreen() End Return instance End Method New() name = "TitleScreen" End Method Start:Void() End Method Update:Void() If KeyHit(KEY_SPACE) FadeToScreen(GameScreen.GetInstance()) End End Method Render:Void() Cls DrawText("Diddy Shoot'em Up!", SCREEN_WIDTH2, SCREEN_HEIGHT2, 0.5, 0.5) DrawText("Press Space to Play!", SCREEN_WIDTH2, SCREEN_HEIGHT2 + 50, 0.5, 0.5) End End Notice the SCREEN_WIDTH2 and SCREEN_HEIGHT2 variables, Diddy calculates half the screen dimensions and stores them in these variables for fast access. gamescreen.monkey Strict Import main Import titlescreen Class GameScreen Extends Screen Global instance:GameScreen = Null Field backgroundImage:GameImage Function GetInstance:GameScreen() If instance = Null instance = New GameScreen() End Return instance End Method New() name = "GameScreen" End Method Start:Void() ' set the background image backgroundImage = diddyGame.images.Find("background") End Method Update:Void() If KeyHit(KEY_ESCAPE) FadeToScreen(TitleScreen.GetInstance()) End End Method Render:Void() Cls backgroundImage.Draw(0, 0) End End Run the game, you will have a title screen and a game screen. Now for sprites :) Create a new file called “gameobjects.monkey”, you can of course create multiple files with only one class in each, but for ease of reading I’m going to add them to this one file: gameobjects.monkey Strict Import diddy Class Player Extends Sprite Field score:Int = 0 Method New(img:GameImage, x:Float, y:Float) Self.image = img Self.x = x Self.y = y Self.alpha = 1 Self.SetHitBox(-img.image.HandleX(), -img.image.HandleY(), img.w, img.h) Self.visible = True Self.speedX = 8 End Method Update:Void() ' controls If KeyDown(KEY_LEFT) Self.x -= Self.speedX * dt.delta End If KeyDown(KEY_RIGHT) Self.x += Self.speedX * dt.delta End ' boundary check If Self.x < Self.image.w2 Then Self.x = Self.image.w2 If Self.x > SCREEN_WIDTH - Self.image.w2 Then Self.x = SCREEN_WIDTH - Self.image.w2 End End The “dt” variable is a global within Diddy so that you can access the built in Delta Timing class, this is to ensure that your movement is the same on all devices. Better update gamescreen.monkey: gamescreen.monkey Strict Import main Import titlescreen Import gameobjects Class GameScreen Extends Screen Global instance:GameScreen = Null Field backgroundImage:GameImage Field player:Player Function GetInstance:GameScreen() If instance = Null instance = New GameScreen() End Return instance End Method New() name = "GameScreen" End Method Start:Void() ' set the background image backgroundImage = diddyGame.images.Find("background") player = New Player(diddyGame.images.Find("ship"), SCREEN_WIDTH2, SCREEN_HEIGHT - 50) player.frame = 3 End Method Update:Void() player.Update() If KeyHit(KEY_ESCAPE) FadeToScreen(TitleScreen.GetInstance()) End End Method Render:Void() Cls backgroundImage.Draw(0, 0) player.Draw() End End Now run the code, you should see your player’s ship on the screen and be able to move it using the cursor keys. For bullets, alter gameobjects.monkey: gameobjects.monkey Strict Import diddy Class Player Extends Sprite Field score:Int = 0 Field lazerSnd:GameSound Method New(img:GameImage, x:Float, y:Float) Self.image = img Self.x = x Self.y = y Self.alpha = 1 Self.SetHitBox(-img.image.HandleX(), -img.image.HandleY(), img.w, img.h) Self.visible = True Self.speedX = 8 Self.lazerSnd = diddyGame.sounds.Find("lazer") End Method Update:Void() ' controls If KeyDown(KEY_LEFT) Self.x -= Self.speedX * dt.delta End If KeyDown(KEY_RIGHT) Self.x += Self.speedX * dt.delta End If KeyHit(KEY_SPACE) Self.lazerSnd.Play() New Bullet(x, y) End ' boundary check If Self.x < Self.image.w2 Then Self.x = Self.image.w2 If Self.x > SCREEN_WIDTH - Self.image.w2 Then Self.x = SCREEN_WIDTH - Self.image.w2 End End Class Bullet Extends Sprite Global list:List<Bullet> = New List<Bullet> Field w:Int Field h:Int Method New(x:Float, y:Float) Self.x = x Self.y = y Self.w = 10 Self.h = 10 Self.alpha = 1 Self.SetHitBox(-w, -h, w, h) Self.speedY = 10 list.AddLast(Self) End Method Draw:Void() DrawOval(x - w / 2, y - h / 2, w, h) End Method Update:Void() y -= speedY * dt.delta If y < - h Kill() End End Method Kill:Void() list.Remove(Self) End Function DrawAll:Void() For Local b:Bullet = EachIn list b.Draw() End End Function UpdateAll:Void() For Local b:Bullet = EachIn list b.Update() End End End And alter gamescreen.monkey: Strict Import main Import titlescreen Import gameobjects Class GameScreen Extends Screen Global instance:GameScreen = Null Field backgroundImage:GameImage Field player:Player Function GetInstance:GameScreen() If instance = Null instance = New GameScreen() End Return instance End Method New() name = "GameScreen" End Method Start:Void() ' set the background image backgroundImage = diddyGame.images.Find("background") player = New Player(diddyGame.images.Find("ship"), SCREEN_WIDTH2, SCREEN_HEIGHT - 50) player.frame = 3 End Method Update:Void() player.Update() Bullet.UpdateAll() If KeyHit(KEY_ESCAPE) FadeToScreen(TitleScreen.GetInstance()) End End Method Render:Void() Cls backgroundImage.Draw(0, 0) Bullet.DrawAll() player.Draw() End End That’ll do for now, you have a ship which can move and a bullet which you can fire. |
| ||
Thank you for these diddy tutorials. I hope this will get you a lot of new users for the Diddy framework. |
| ||
Nice tutorials |
| ||
Hi, just trying out this demo but get an error in main.monkey at approx line 32 ---> Unable to find overload for LoadAnim(String,Int,Int,Int) images.LoadAnim("ship.png", 64, 64, 7) |
| ||
Unable to find overload for LoadAnim(String,Int,Int,Int) Works fine for me. Is it possible that you have a typo, a point instead of a comma? Something like images.LoadAnim("ship.png", 64, 64.7) |
| ||
mate you should think about doing that again as a video tut on youtube. |
| ||
Hi, I'm new to Monkey and therefore to Diddy. I have a couple of questions! 1. Do I need to use the Pro version of Monkey to run Diddy? 2. Does it replace Mojo or does it run alongside it? 3. What targets can my code run in when using Diddy? Thanks a lot! |
| ||
No No - Yes All There may be some compatibility issues if your using an older version of the Free monkey, just update both to the latest and you should be good to go. not a lot of time to do a proper reply, if you need more clarification just shout. |