Maker Hacks

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

  • Home
  • About Maker Hacks
  • Blog
  • YouTube Channel
  • Recommendations
  • Contact
You are here: Home / Hacks, Tips, and Tutorials / Programming the Amiga with AMOS BASIC: Maps & Scrolling

Programming the Amiga with AMOS BASIC: Maps & Scrolling

Chris Garrett

FacebookTweetPin

Up until now, our AMOS BASIC programming has relied on loading quite large full-screen images as our backgrounds. That is not memory efficient, plus creating maps and levels this way would be quite cumbersome.

The go-to solution is to create a tiled map. We will look at loading and drawing Icons, and how we can display and even scroll our maps, to offer massive game worlds at a fraction of the memory requirement.

Previous AMOS Basic Tutorials in this series:

  1. Loading images and configuring AMOS screens
  2. “Dual Playfield”
  3. Bobs and Sprites

Tile Based Maps

While the Amiga back in the day boasted a lot of memory for the time (most at least had 512kb, although at launch 256kb was standard), unless you are going to only have a couple of screens (title screen, high score screen, one or two backgrounds), loading IFF images, even compressed, will take up a bunch of room.

Instead, what most games implement is a system of maps or levels created out of tiles selected from a tile set.

Check out this famous set of tiles, recognise them?

Tiles
Super Mario tiles ripped by Jdaster64

This is how an NES game can be absolutely amazing fun and only take up 8kb!

AMOS Icons versus Blocks

In AMOS, our tiles are made out of Icons.

Unlike Bobs and Sprites, an Icon is not expected to move or have transparency. It’s simply pasted onto the screen as almost like a paint package brush.

Of course, given the name, one of the use-cases is for clickable icon buttons, but we will use it to build up a graphical environment for our game players!

AMOS also has a feature called Blocks. They are similar to Icons except are created and destroyed in memory by programmatically grabbing an area of screen.

We will use Icons so that we can work in the object editor ahead of time.

Creating Amiga Tile Sets in AMOS with Icons

AMOS provides us with an Object Editor. While so far we used it to create bobs and sprites, in this case we will create icons.

AMOS object editor, Edit Icons menu

Use the basic graphics tools to create some simple tiles. You could also load in an IFF picture and grab parts of that image to create your tiles too.

AMOS object editor creating icons on Amiga

When you save your .ABK it will ask if your objects are bobs or icons, tell it we need icons.

Save AMOS object data bank as icons or bobs

Loading Icons with AMOS

Now to load the tile data we just saved.

For simplicity, ensure your AMOS Basic file is saved in the same location as your .ABK file, then use:

Load "TILE.ABK"

Once we have it in memory, we can also pull the colours out of the file:

Get Icon Palette

Now we can draw our icons on screen. The icons in the file are numbered from 1.

Paste Icon X,Y,Icon_Number

paste icon in amos

Creating and Displaying a Tile Map

Now we can paste our icons, creating a map is a simple case of expanding into a grid of icons.

As we saw in a previous tutorial, the way we commonly create a grid or table in AMOS Basic is to use an Array.

Think of our map array as being like a table of spreadsheet cells. Rather than using letters to indicate the column, however, arrays use numbers for both row and column.

To make populating this array easier for ourselves, we will first create our map in text, using a String, and then fill the array from that.

Dim TILE_MAP(20,12)
ROWS$=ROWS$+"33333333333333333332"
ROWS$=ROWS$+"32222222222222222132"
ROWS$=ROWS$+"32111132111111321332"
ROWS$=ROWS$+"33333332111111333332"
ROWS$=ROWS$+"32222222111111222332"
ROWS$=ROWS$+"32111113333333211332"
ROWS$=ROWS$+"32111112222222211332"
ROWS$=ROWS$+"32111111111111111332"
ROWS$=ROWS$+"33333332111111333332"
ROWS$=ROWS$+"32222232111111322332"
ROWS$=ROWS$+"32111122111111221332"
ROWS$=ROWS$+"33333333333333333332"
ROWS$=ROWS$+"22222222222222222222"

Here we have told AMOS that we want to store 20 by 12 cells. We then create a text string containing the tile numbers that need to go into each cell.

Once we have that set up, we simply loop through the text string and insert the next entry into the appropriate array location.

I=0
' Loop through the rows  
For Y=0 To 12
   
   ' Loop through the columns 
   For X=0 To 19

      ' Incremement the counter  
      ' (AMOS weirdly counts from 1 with Mid$  
      ' BUT 0 will ALSO give the first char) 
      Inc I

      ' Fill the map array with the values 
      TILE_MAP(X,Y)=Val(Mid$(ROWS$,I,1))

      ' Paste the graphic
      Paste Icon X*16,Y*16,TILE_MAP(X,Y)
      
   Next X
   
Next Y

Wait Key 

Two functions help us here:

  • Val() takes a string and converts it into the number it represents because “1” otherwise would be interpreted as text instead of a numeric value.
  • Mid$() grabs the text at a given location within a string for you. We also provide a length of 1 to say that we want one character at the given location.

Strangely, while AMOS Arrays use 0 as the first slot, the Mid$ function seems to accept 0 but expects 1. I spent hours chasing down the cause of my maps being offset … This kind of thing can really make debugging frustrating!

Full Map Code

  
' Set up our low res screen
Screen Open 0,320,200,32,Lowres
Flash Off : Curs Off : Hide On 

' Load our tileset into the databank 
Load "TILE.ABK"

' Get the palette from our tileset 
Get Icon Palette 

Dim TILE_MAP(20,12)
ROWS$=ROWS$+"33333333333333333332"
ROWS$=ROWS$+"32222222222222222132"
ROWS$=ROWS$+"32111132111111321332"
ROWS$=ROWS$+"33333332111111333332"
ROWS$=ROWS$+"32222222111111222332"
ROWS$=ROWS$+"32111113333333211332"
ROWS$=ROWS$+"32111112222222211332"
ROWS$=ROWS$+"32111111111111111332"
ROWS$=ROWS$+"33333332111111333332"
ROWS$=ROWS$+"32222232111111322332"
ROWS$=ROWS$+"32111122111111221332"
ROWS$=ROWS$+"33333333333333333332"
ROWS$=ROWS$+"22222222222222222222"


I=0
' Loop through the rows  
For Y=0 To 12
   
   ' Loop through the columns 
   For X=0 To 19

      ' Incremement the counter  
      ' (AMOS weirdly counts from 1 with Mid$  
      ' BUT 0 will ALSO give the first char) 
      Inc I

      ' Fill the map array with the values 
      TILE_MAP(X,Y)=Val(Mid$(ROWS$,I,1))

      ' Paste the graphic
      Paste Icon X*16,Y*16,TILE_MAP(X,Y)
      
   Next X
   
Next Y

Wait Key 


Tiled Map Scrolling in AMOS

If we can create a static map or level, why not then scroll it?

The trick to scrolling a screen made up of tiles is to backfill the next set of tiles you have scrolled. You can scroll horizontally, vertically, or both using this technique.

Previously we used a screen offset but we can also use a powerful screen copy feature of AMOS that allows us to copy a portion of a screen and paste it wherever we want:

Screen Copy 0,1,0,352,200 To 0,0,0

As you can see, we grab the part of the screen that is one pixel over to the right, and paste it at the top left of the screen, giving the impression of the screen moving.

This will leave a mess at the far right of the screen so we put the far right of our screen off of the visible area

Screen Open 0,353,200,32,Lowres

Rather than 320 pixels wide, we have made it 353 pixels wide. Really that is overkill, but it serves to illustrate the idea 🙂

When the screen has moved a whole 32 pixel tile distance, we paste a fresh column from the map on the right and start over until a key is pressed.

See the full scroller in action

Full AMOS Icon Scroller Code

' Set up our low res screen
Screen Open 0,353,200,32,Lowres
Screen Display 0,135,40,320,200
Flash Off : Curs Off : Hide On 

' Load our tileset into the databank 
Load "TILE.ABK"

' Get the palette from our tileset 
Get Icon Palette 

' Load space invader 
Load "INVADER.ABK"

' Screen background from orange to black 
Colour 1,$0

' Sprite colour
Colour 17,$A00

' Initial blank background ready to overwrite
' Loop through the rows in 32pixel increments
For Y=0 To 168 Step 32

   ' Loop through the columns 
   For X=0 To 352 Step 32

      ' Paste the graphic
      Paste Icon X,Y,1

   Next X

Next Y

' Set up the map
Dim TILE_MAP(70,5)
ROW1$="1211121122221211112111122221121111121222212222212111112222211122111111"
ROW2$="1211121121111211112111121121121111121211212111112111111211121122111111"
ROW3$="1222221122111211112111121121121121121211212111112111111211121122111111"
ROW4$="1211121121111211112111121121121121121211212111112111111211121111111111"
ROW5$="1211121122221222212222122221112212211222212111112222212122211122111111"

' Set up the initial map in memory
For THIS_COL=0 To 69

   ' Doing the same command multiple times is
   ' faster than a loop, it's called unrolling
   TILE_MAP(THIS_COL,0)=Val(Mid$(ROW1$,THIS_COL,1))
   TILE_MAP(THIS_COL,1)=Val(Mid$(ROW2$,THIS_COL,1))
   TILE_MAP(THIS_COL,2)=Val(Mid$(ROW3$,THIS_COL,1))
   TILE_MAP(THIS_COL,3)=Val(Mid$(ROW4$,THIS_COL,1))
   TILE_MAP(THIS_COL,4)=Val(Mid$(ROW5$,THIS_COL,1))
   TILE_MAP(THIS_COL,5)=1

Next THIS_COL


' Loop until a key is pressed  
While Inkey$=""

   Inc THIS_COLUMN
   If THIS_COLUMN=70 Then THIS_COLUMN=0

   ' Replace missing blocks
   For Y=0 To 5
      Paste Icon 320,Y*32,TILE_MAP(THIS_COLUMN,Y)
   Next Y

   ' Scroll the screen over the original  
   For I=0 To 31

      ' Copy and paste the screen to 
      ' give the impression of movement
      Screen Copy 0,1,0,352,200 To 0,0,0

      ' Place our space invader 
      Sprite 1,X Hard(SPX),Y Hard(SPY),1

      ' Bounce math!
      If SPX>=288 Then SPX_DIR=-2
      If SPX<=0 Then SPX_DIR=2

      If SPY>=168 Then SPY_DIR=-2
      If SPY<=0 Then SPY_DIR=2
      SPX=SPX+SPX_DIR
      SPY=SPY+SPY_DIR



   Next I


Wend 



Related

FacebookTweetPin

by Chris Garrett Filed Under: Hacks, Tips, and Tutorials Tagged With: amiga, amos, basic programming, retrocomputing

About Chris Garrett

StudioPress Marketing Director at WP Engine. Co-author of the Problogger Book with Darren Rowse. Maker of things. 🇨🇦 Canadian

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

« Programming the Amiga with AMOS BASIC: Bobs and Sprites
Programming the Amiga with AMOS BASIC: Better Tile Scrolling »

The website for makers and hackers – Arduino, Raspberry Pi, 3D Printing and more

Get fresh makes, hacks, news, tips and tutorials directly to your inbox, plus access to the 30 Days to Arduino course

Recently Popular

  • 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 © 2021 Maker Hacks