• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
Maker Hacks

Maker Hacks

Ideas, news & tutorials for makers and hackers – Arduino/Raspberry Pi, 3D printing, robotics, laser cutting, and more

  • Home
  • About
  • YouTube
  • Recommendations
  • Contact

Programming the Amiga with AMOS BASIC: A Playable “Shoot ’em up” Game

You are here: Home / Hacks, Tips, and Tutorials / Programming the Amiga with AMOS BASIC: A Playable “Shoot ’em up” Game
FacebookTweetPin
Author: Chris Garrett

In the final (for now, at least) entry in this series, we are going to pull everything together into a playable “Shoot the Invaders from Space” game that has keyboard and joystick control, killable enemies, moving bullets, and a scrolling star field backdrop …

Previous AMOS Basic Tutorials in this series:

  1. Loading images and configuring AMOS screens
  2. “Dual Playfield”
  3. Bobs and Sprites
  4. Maps and Scrolling
  5. Better Tile Scrolling
  6. Animation & Scrolling with AMAL

The “Finished” Game

OK, it’s not exactly going to set Steam alight, and I am sure you can improve my code, but the game demonstrates enough that it is playable and has the major elements 🙂

Game Structure

To start, we are going to need a plan of attack.

In most games there will be a structure something like this:

  1. Load
  2. Show the start screen
  3. Do the setup
  4. Get player input
  5. Move the enemies
  6. Anything collide?
  7. Player still alive?
  8. Update the screen
  9. Loop back to 4 or go on to end screen
  10. End screen
  11. Loop back to 2 or end

Some items might shuffle around and you might have extra stuff, but essentially we need to fulfill all of those tasks if we are going to get a playable game.

This is more than a straight list of instructions so we will definitely need to break the game down into procedures.

As a reminder, your procedures are set up like so:

Procedure Procname
    Statements
End Proc

Once you have set up your procedures, you can call them just by using it’s name (in the above example it would be Procname).

Checking for our Sprite File

Previously we have just trusted that the sprites were there in the local directory. Instead we should check for the existence of the file:

' Load the sprites,  
' but first we check the file is there 
If Exist("invaders4.abk")
   Load "invaders4.abk",1
   
   ' Assuming our sprites loaded, get the colours 
   Get Bob Palette 
   
   
   ' Set some specific colours
   ' for the enemy bullet sprite
   Colour 17,$FF0
   Colour 18,$FFF
   Colour 20,$FA0
   
Else 
   
   ' If no sprite file, show an error 
   Paper 0 : Cls : Pen 4
   Print "Sprites not found"
   ' quit out 
   End 
   
End If 

Generating Bobs

As well as loading a sprite bank, we can generate bobs on the fly.

Let’s make a “scrolling” background of a star field!

' Set up starfield   
For Y=1 To 200 Step 2
   Plot Rnd(320),Y,SC(Rnd(6))
Next Y
' Get a bob for the stars
Get Bob 0,10,0,0 To 320,200
' Blank the screen 
Ink 0 : Bar 0,0 To 320,200

Animating the Background and Bullets

Both our star field and the player/enemy fire work the same way:

  
   ' Enemy and player fire
   ' One set to move down,
   ' other upwards
   _ZAP$="L: M 0,200,50; J L;"
   _PFIRE$="L: M 0,-200,50; J L;"
   Amal 5,_ZAP$
   Amal 6,_PFIRE$
   
   ' Starfield "scrolling"
   Amal 10,"L: Let Y=0; M 0,-200,200; J L;"
   Amal 11,"L: Let Y=200; M 0,-200,200; J L;"

The main difference is the bullets will only need to move all the way up or down the screen; their start positions reset when next fired, whereas in the “scrolling” bobs we loop round and round so there are always stars on screen.

One bob starts at 0 and the other at 200, and when they have moved 200 pixels they reset positions.

Reading the Joystick or Gamepad

Up to now we have used just keyboard control, either with Inkey$ or Key State. Here we have a simple way to also grab the joystick/gamepad control (in port 1 in this case)

' Get the player movement
Procedure _PLAYER_INPUT
   
   ' What key was pressed?
   PRESSED$=Inkey$
   
   ' If cursor left or right then move player 
   If PRESSED$="o" and PLYER_X>0
      PLYER_X=PLYER_X-4
   End If 
   
   If PRESSED$="p" and PLYER_X<290
      PLYER_X=PLYER_X+4
   End If 
   
   ' If joystick left or right then move player 
   If(Joy(1)=4 or Joy(1)=20) and PLYER_X>0
      PLYER_X=PLYER_X-4
   End If 
   
   If(Joy(1)=8 or Joy(1)=24) and PLYER_X<290
      PLYER_X=PLYER_X+4
   End If 
   
   ' Fire button
   If(Joy(1)>10 or PRESSED$=" ") and Y Bob(5)=<0
      Bob 5,X Bob(4)+7,Y Bob(4)-16,8
      Amal On 6
      Shoot 
   End If 
   
End Proc

Collision Detection

We need to know when a collision happens, either detecting the player bob bullet or the enemy sprite bullet. AMOS has a couple of easy to use features for detecting this.

' Did anything collide?
Procedure _CHECK_COLLISIONS
   
   ' Make sure win/lose is zero   
   _YOU_WIN=0
   _YOU_DEAD=0
   
   ' Any enemies drop below the player? 
   ' if the enemies get past player then  
   ' player loses   
   If Y Bob(0)>160 or Y Bob(1)>160 or Y Bob(2)>160 or Y Bob(3)>160
      Boom 
      Sprite 1,X Hard(-100),Y Hard(220),5
      Bob 5,320,0,8
      _YOU_DEAD=1
      _YOU_WIN=0
      _KILLS=0
      
      ' Did the player get hit?
   Else If Spritebob Col(1,4 To 4)
      
      ' Explosion sound
      Boom 
      
      ' Move the bullets offscreen 
      Sprite 1,X Hard(-100),Y Hard(220),5
      Bob 5,320,0,8
      
      ' reduce player's lives
      _LIVES=_LIVES-1
      
      ' if out of lives they lose! 
      If _LIVES=0
         _YOU_DEAD=1
         _YOU_WIN=0
         _KILLS=0
      End If 
      
   End If 
   
   ' Check if any enemies got hit 
   For _THIS_ONE=0 To 3
      
      ' Determine which was killed       
      If Bob Col(5,_THIS_ONE To _THIS_ONE)
         
         ' The one killed was this one
         _KILLED=_THIS_ONE
         
         ' Increment player kills 
         _KILLS=_KILLS+1
         
         ' Turn off killed enemy          
         Amal Off _KILLED+1
         Bob 5,319,0,8
         Bob _KILLED,-32,20,1
         
         ' Make sound effect          
         Boom 
         
         ' Did they win?          
         If _KILLS=4
            
            ' You won! Pass go, collect points             
            _YOU_WIN=1
            _YOU_DEAD=0
            Exit 
            
         End If 
         
         ' Exit the loop, we know our loser         
         Exit 
         
      End If 
      
      ' Move on to the next enemy      
   Next _THIS_ONE
   
End Proc

Putting it all Together

' Global variables 
Global PLYER_X,PLYER_Y,_YOU_WIN,_YOU_DEAD,_KILLS,_KILLED,_LIVES
' Information screen 
Screen Open 1,320,200,16,Lowres
Flash Off : Curs Off : Hide 
' Game screen
Screen Open 0,320,200,16,Lowres
Flash Off : Curs Off : Hide 
Paper 0
Cls 
' Load the sprites,  
' but first we check the file is there 
If Exist("invaders4.abk")
   Load "invaders4.abk",1
   
   ' Assuming our sprites loaded, get the colours 
   Get Bob Palette 
   
   
   ' Set some specific colours
   ' for the enemy bullet sprite
   Colour 17,$FF0
   Colour 18,$FFF
   Colour 20,$FA0
   
Else 
   
   ' If no sprite file, show an error 
   Paper 0 : Cls : Pen 4
   Print "Sprites not found"
   ' quit out 
   End 
   
End If 

' Set up smooth moves
Double Buffer 
Autoback 1

' Selected star colours
Dim SC(6)
SC(0)=6
SC(1)=7
SC(2)=8
SC(3)=9
SC(4)=13
SC(5)=14
SC(6)=15
' Set up starfield   
For Y=1 To 200 Step 2
   Plot Rnd(320),Y,SC(Rnd(6))
Next Y
' Get a bob for the stars
Get Bob 0,10,0,0 To 320,200
' Blank the screen 
Ink 0 : Bar 0,0 To 320,200

' Initialize all values
' to their defaults
Procedure _INIT
   
   ' These values control program flow
   ' for example if you won or lost 
   _KILLS=0
   _YOU_WIN=0
   _YOU_DEAD=0
   _LIVES=3
   
   ' Set the screen to blank
   Paper 0
   Pen 4
   Cls 0
   
   ' The sprite will be the enemy fire
   ' It needs a mask so collision detection 
   ' can work and hotspot is where the x/y
   ' is counted from  
   'Amal Off  
   Sprite 1,X Hard(0),Y Hard(200),5
   Hot Spot 5,8,8
   Make Mask 5
   
   
   ' Starfield (because they ARE the background 
   ' we tell it not to bother replacing the background) 
   Bob 10,0,0,10
   Set Bob 10,-1,1,
   Bob 11,0,200,10
   Set Bob 11,-1,1,
   Limit Bob 10,0,0 To 320,160
   Limit Bob 11,0,0 To 320,160
   Priority Reverse On 
   
   ' Add our enemy and player bobs
   Bob 0,0,40,1
   Bob 1,40,40,1
   Bob 2,80,40,1
   Bob 3,120,40,1
   PLYER_X=160
   PLYER_Y=160
   Bob 4,160,160,7
   Bob 5,320,5,8
   
   ' Animation channels 
   Channel 1 To Bob 0
   Channel 2 To Bob 1
   Channel 3 To Bob 2
   Channel 4 To Bob 3
   Channel 5 To Sprite 1
   Channel 6 To Bob 5
   Channel 10 To Bob 10
   Channel 11 To Bob 11
   
   
   ' Animation and movement scripts 
   A1$="Anim 0,(1,20)(2,20)(3,20)(4,20)(3,20)(2,20)"
   A2$="Label:"
   A3$="M 200,0,280;M 0,32,80;M -200,0,280; M 0,32,80;"
   A4$="Jump Label"
   A$=A1$+A2$+A3$+A4$
   
   ' 4 enemies  
   Amal 1,A$
   Amal 2,A$
   Amal 3,A$
   Amal 4,A$
   
   ' Enemy and player fire
   ' One set to move down,
   ' other upwards
   _ZAP$="L: M 0,200,50; J L;"
   _PFIRE$="L: M 0,-200,50; J L;"
   Amal 5,_ZAP$
   Amal 6,_PFIRE$
   
   ' Starfield "scrolling"
   Amal 10,"L: Let Y=0; M 0,-200,200; J L;"
   Amal 11,"L: Let Y=200; M 0,-200,200; J L;"
   
   ' Start animating
   Amal On 
   
End Proc
' Information screens
' in an actual game they would 
' have graphics and stuff! 
Procedure _DO_SCREEN
   
   ' Set the info screen as the 
   ' visible screen 
   Screen 1
   Screen To Front 1
   Sprite Off 
   Amal Off 
   
   ' Set the message to blank 
   MESS$=""
   
   ' Which message to display?
   If _YOU_WIN=1
      MESS$="YOU WON. YAY."
   End If 
   
   If _YOU_DEAD=1
      MESS$="YOU DIED. SORRY."
   End If 
   
   If _YOU_WIN=0 and _YOU_DEAD=0
      MESS$="Alien types are invading. From Space!"
   End If 
   
   _YOU_WIN=0
   _YOU_DEAD=0
   _KILLS=0
   
   Paper 0
   Pen 4
   Cls 
   Clear Key 
   
   ' This loop makes the text 
   ' change colour real fast    
   Repeat 
      
      ' Wait for screen refresh
      Wait Vbl 
      
      ' Text to random colour
      Pen Rnd(8)
      Locate 10,5
      Centre MESS$
      Locate 10,15
      Centre "Press Fire/Space to continue"
      
   Until Inkey$=" " or Joy(1)>10
   
   ' After a keypress, switch 
   ' to the game screen   
   Screen 0
   Screen To Front 0
   
   
End Proc
' In-Game kills and lives stats
Procedure _UPDATE_HUD
   
   Locate 5,0
   Print "KILLS: ",_KILLS," LIVES: ",_LIVES
   
End Proc
' Get the player movement
Procedure _PLAYER_INPUT
   
   ' What key was pressed?
   PRESSED$=Inkey$
   
   ' If cursor left or right then move player 
   If PRESSED$="o" and PLYER_X>0
      PLYER_X=PLYER_X-4
   End If 
   
   If PRESSED$="p" and PLYER_X<290
      PLYER_X=PLYER_X+4
   End If 
   
   ' If joystick left or right then move player 
   If(Joy(1)=4 or Joy(1)=20) and PLYER_X>0
      PLYER_X=PLYER_X-4
   End If 
   
   If(Joy(1)=8 or Joy(1)=24) and PLYER_X<290
      PLYER_X=PLYER_X+4
   End If 
   
   ' Fire button
   If(Joy(1)>10 or PRESSED$=" ") and Y Bob(5)=<0
      Bob 5,X Bob(4)+7,Y Bob(4)-16,8
      Amal On 6
      Shoot 
   End If 
   
End Proc
' Did anything collide?
Procedure _CHECK_COLLISIONS
   
   ' Make sure win/lose is zero   
   _YOU_WIN=0
   _YOU_DEAD=0
   
   ' Any enemies drop below the player? 
   ' if the enemies get past player then  
   ' player loses   
   If Y Bob(0)>160 or Y Bob(1)>160 or Y Bob(2)>160 or Y Bob(3)>160
      Boom 
      Sprite 1,X Hard(-100),Y Hard(220),5
      Bob 5,320,0,8
      _YOU_DEAD=1
      _YOU_WIN=0
      _KILLS=0
      
      ' Did the player get hit?
   Else If Spritebob Col(1,4 To 4)
      
      ' Explosion sound
      Boom 
      
      ' Move the bullets offscreen 
      Sprite 1,X Hard(-100),Y Hard(220),5
      Bob 5,320,0,8
      
      ' reduce player's lives
      _LIVES=_LIVES-1
      
      ' if out of lives they lose! 
      If _LIVES=0
         _YOU_DEAD=1
         _YOU_WIN=0
         _KILLS=0
      End If 
      
   End If 
   
   ' Check if any enemies got hit 
   For _THIS_ONE=0 To 3
      
      ' Determine which was killed       
      If Bob Col(5,_THIS_ONE To _THIS_ONE)
         
         ' The one killed was this one
         _KILLED=_THIS_ONE
         
         ' Increment player kills 
         _KILLS=_KILLS+1
         
         ' Turn off killed enemy          
         Amal Off _KILLED+1
         Bob 5,319,0,8
         Bob _KILLED,-32,20,1
         
         ' Make sound effect          
         Boom 
         
         ' Did they win?          
         If _KILLS=4
            
            ' You won! Pass go, collect points             
            _YOU_WIN=1
            _YOU_DEAD=0
            Exit 
            
         End If 
         
         ' Exit the loop, we know our loser         
         Exit 
         
      End If 
      
      ' Move on to the next enemy      
   Next _THIS_ONE
   
End Proc
' Make sure win/lose info is reset 
_YOU_WIN=0
_YOU_DEAD=0
' Show welcome screen
_DO_SCREEN
' Start of the infinite loop 
Do 
   
   ' Set everything up
   ' with default values    
   _INIT
   
   ' Game loop    
   Repeat 
      
      ' Turn off sprite drawing temporarily      
      Bob Update Off 
      Sprite Update Off 
      
      ' Update the screen info       
      _UPDATE_HUD
      
      ' Anything collided?       
      _CHECK_COLLISIONS
      
      ' Update player movement 
      _PLAYER_INPUT
      Bob 4,PLYER_X,PLYER_Y,7
      
      ' If enemy fiire goes past the player .. 
      If Y Sprite(1)>Y Hard(160)
         
         ' Choose a random enemy
         _SHOOTER=Rnd(3)
         
         ' If the enemy is on screen .. 
         If X Bob(_SHOOTER)>0
            
            ' Enemy shoots!            
            Sprite 1,X Hard(X Bob(_SHOOTER)+8),Y Hard(Y Bob(_SHOOTER)+32),5
            Amal On 5
            
         End If 
         
      End If 
      
      ' Update sprite and bob drawing      
      Bob Update On 
      Sprite Update On 
      Wait Vbl 
      
      ' Keep looping until you win/lose    
   Until _YOU_WIN=1 or _YOU_DEAD=1
   
   ' Display the information screen 
   _DO_SCREEN
   
   ' Outside loop goes on indefinitely  
Loop 

Bonus: Play in your browser!

Wait, there’s more!

If you are running Chrome, you can play the AOZ.studio version of the game in your web browser!

Launch the Game

AOZ is still in beta development, so it’s not fully ready, but eventually you will be able to take your Amiga AMOS knowledge and build cross-platform games for everything from Windows/Mac/Linux through to iOS and Android.

Find out more at AOZ.Studio

Related

Category: Hacks, Tips, and Tutorials, Retro ProgrammingTag: amiga, amos, basic programming, retro, retrocomputing
FacebookTweetPin

About Chris Garrett

Marketing Director by day, maker, retro gaming, tabletop war/roleplaying nerd by night. Co-author of the Problogger Book with Darren Rowse. Husband, Dad, 🇨🇦 Canadian.

Check out Retro Game Coders for retro gaming/computing.

☕️ Support Maker Hacks on Ko-Fi and get exclusive content and rewards!

Previous Post:amal-scrollingProgramming the Amiga with AMOS BASIC: Animation & Scrolling with AMAL
Next Post:Ultrasonic Rangefinding with the Wio Terminal and Grove Ultrasonic SensorGrove Ultrasonic Rangefinder Sensor

Sidebar

  • Facebook
  • Twitter
  • Instagram
  • YouTube

Recently Popular

  • Gweike Cloud Review
  • How to choose the right 3D printer for you
  • Glowforge Review – Glowforge Laser Engraver Impressions, Plus Glowforge Versus Leading Laser Cutters
  • Original Prusa i3 Mk3S Review
  • Best 3D Printing Facebook Groups
  • Elegoo Mars Review – Review of the Elegoo Mars MSLA Resin 3D Printer
  • Glowforge ‘Pass-Through’ Hack: Tricking the Front Flap of the Glowforge with Magnets to Increase Capacity
  • How to Make a DIY “Internet of Things” Thermometer with ESP8266/Arduino
  • Wanhao Duplicator i3 Review
  • IKEA 3D Printer Enclosure Hack for Wanhao Di3
  • Creality CR-10 3d printer review – Large format, quality output, at a low price!
  • 3D Printed Tardis with Arduino Lights and Sounds
  • Anet A8 Review – Budget ($200 or less!) 3D Printer Kit Review
  • Make your own PEI 3D printer bed and get every print to stick!
  • Upgrading the Wanhao Di3 from Good to Amazing
  • How to Install and Set Up Octopi / Octoprint
  • Creality CR-10 S5 Review

Copyright © 2023 · Maker Hacks · All Rights Reserved · Powered by Mai Theme