Working with Images

Bitmaps Pacman Image Mapping Masks

Working with Bitmaps.

This program loads a bitmap .bmp file to the current turtle position.
32 bit versions of MSW also have a GIF load command, which in our case we have not got.

to bmpload
ht
bitload "c:\\Programming\\logo\\bmps\\rocket.bmp
end

The \\ is necessary in the address of your bmp file. The first \ "escapes" the second so that it is read correctly by the computer.
You need to point the bitload command at an address which contains the bmp that you wish to load.

Making a Pacman Maze

Images.

First create your Pacman images and place them in a folder low in the directory structure.
Make sure that all filenames 8 letters or less long and don't contain wierd symbols.
The images must be bitmaps; bmp files.

Making the Maze.

This code generates a very basic maze.

to mazemaker
make "maze (ARRAY 120 0)
for [ x 0 11 1][
for [ y 0 9 1][
setitem :x+:y*12 :maze 5
]]
repeat 12 [
setitem repcount-1 :maze 10]
repeat 12 [ setitem (repcount-1)+108 :maze 10]
repeat 10 [ setitem (repcount-1)*12 :maze 10]
repeat 10 [ setitem (repcount-1)*12+11 :maze 10]
setitem 61 :maze 20
for [ x 0 11 1][
for [ y 0 9 1][
if (item :x+:y*12 :maze)=10 [
pu setxy (:x-6)*50 (:y-5)*50 pd
bitload "C:\\gameim\\wall.bmp]
if (item :x+:y*12 :maze)=5 [
pu setxy (:x-6)*50 (:y-5)*50 pd
bitload "C:\\gameim\\fruit.bmp]
if (item :x+:y*12 :maze)=20 [
pu setxy (:x-6)*50 (:y-5)*50 pd
bitload "C:\\gameim\\pacr.bmp]
]]
end

  1. Our maze will be made from a grid of tiles. The tiles are 50px square and we will have 12 across and 10 down.
  2. The contents of each tile are represented in an array of 120 numbers.
  3. Every tile at first is given the value 5 which stands for fruit.
  4. Logo can't generate 2D arrays so the y values are multiplied by 12 and added to the x values.
  5. We then draw the rock walls of the outsides of the maze. These are given by value 10.
  6. The pacman is inserted on tile 61 with value 20 for a right facing pacman.
  7. We then work through the array drawing the correct tile at each location. This is done by using a set of if statements for each tile type.
  8. This completes the start up for a game.
  9. To make this into a full game you need to be able to move the pacman around go to Input/Output to find out how to do this.
  10. It will help if you think about how you might remember where the pacman came from and how to keep score etc.
  11. To keep score you need to be able to write labels onto the screen. See logowords1 for advice on how to do this.

Image Mapping

Load the source image.

This program loads a bitmap .bmp file to the coordinate origin (0 0).

to loader
home
bitload "c:\\Programming\\logo\\bmps\\test1.bmp
end

The \\ is necessary in the address of your bmp file. The first \ "escapes" the second so that it is read correctly by the computer.
You need to point the bitload command at an address which contains the bmp that you wish to load.

Copying the image.

This doesn't achieve anything but it lays the foundation for all that follows.
You use two turtles, the first turtle scans the source image whilst the second draws a copy.

to copy :xSize :ySize
for [yCo 0 :ySize-1 1] [
for [xCo 0 :xSize-1 1] [
setturtle 0
pu setxy :xCo :yCo pd
setpencolor pixel
setturtle 1
pu setxy -200+:xCo 0+:yCo pd
fd 1
]]
end

  • The procedure takes two arguments. These are the dimensions of the image in pixels.
  • Two nested for loops scan across the image and then move up a line at a time.
  • setturtle 0 gains control of turtle 0.
  • This turtle reads the pixel at x,y and sets the pencolor to this value.
  • setturtle 1 gains control of turtle 1.
  • This turtle colors the pixel at x-200,y.

Enlarging the image.

Each axis can be enlarged by a different scale factor.
It is important to work from the target image to ensure that blank pixel rows are not created. The source image must be stretched to fill the target area.
This is achieved by making the outer loops larger by the appropriate factor.

to enlarge :xSize :ySize :xFac :yFac
for [yCo 0 :yFac*:ySize 1] [
for [xCo 0 :xFac*:xSize 1] [
setturtle 0
pu setxy int(:xCo/:xFac) int(:yCo/:yFac) pd
setpencolor pixel
setturtle 1
pu setxy int(-400+:xCo) :yCo pd
fd 1
]]
end

Working with masks

This enables you to map an image onto the coloured parts of a prexisting mask.
This is very useful for making tiles to perform tessellations with.
The mask must be smaller than the source image and it mustn't contain internal white pixels.

Load the mask

to maskload
pu setxy -200 0 pd
bitload "c:\\Programming\\logo\\bmps\\mask1.bmp
end

Run loader first to load the source image and then run maskload to load the mask.

Mapping onto the mask.

to mask :xSize :ySize
for [yCo 0 :ySize 1] [
for [xCo 0 :xSize 1] [
setturtle 0
pu setxy :xCo :yCo pd
setpencolor pixel
setturtle 1
pu setxy -200+:xCo 0+:yCo pd
if not(pixel=[255 255 255])[fd 1 ]
]]
end

The only new code here is the in the if statement. This reads the pixel at the drawing position and only colours it in if it isn't white.
This line could be modified to do all manner of interesting things!

Colour addition.

This code reads the pixel values from two source images and adds the colours together.

to addcol :xSize :ySize
make "cols1 {0 0 0}@0
make "cols2 {0 0 0}@0
for [yCo 0 :ySize-1 1] [
for [xCo 0 :xSize-1 1] [
setturtle 0
pu setxy :xCo :yCo pd
setitem 0 :cols1 (item 1 pixel)
setitem 1 :cols1 (item 2 pixel)
setitem 2 :cols1 (item 3 pixel)
setturtle 2
pu setxy :xCo+300 :yCo pd
setitem 0 :cols2 (item 1 pixel)
setitem 1 :cols2 (item 2 pixel)
setitem 2 :cols2 (item 3 pixel)
repeat 3 [
setitem repcount-1 :cols1 (remainder ((item repcount-1 :cols1)+(item repcount-1 :cols2)) 255)
]
setpencolor arraytolist :cols1
setturtle 1
pu setxy -200+:xCo 0+:yCo pd
fd 1
]]
end

Colour inversion.

This code reads the source image and inverts the colours.
255 255 255 is white. This inverts to 0 0 0, black.
0 0 255 is blue. This inverts to 255 255 0, yellow.

to invcol :xSize :ySize
make "cols {0 0 0}@0
for [yCo 0 :ySize-1 1] [
for [xCo 0 :xSize-1 1] [
setturtle 0
pu setxy :xCo :yCo pd
setitem 0 :cols (255-(item 1 pixel))
setitem 1 :cols (255-(item 2 pixel))
setitem 2 :cols (255-(item 3 pixel))
setpencolor arraytolist :cols
setturtle 1
pu setxy -200+:xCo 0+:yCo pd
fd 1
]]
end

cols is an array used for manipulating the RGB values.
The three setitem lines subtract the current RGB values from 255 abd store these values in the cols array.
The array is then converted to a list which setpencolor can recognise and use.

cols1 and cols2 are arrays used for holding the RGB values.
The setitem repeat line then adds the values and reduces them modulo 256 to give integers in the range 0-255 which Logo recognises as RGB codes.
The array is then converted to a list which setpencolor can recognise and use.

Last updated 23rd February 2010