this tutorial will work with borland kylix
In the last tutorial we covered getting the tiled map on the screen. In this tutorial we'll cover moving a character around the map by using the mouse and also how to tell what section of the map the character is on. You've already done the difficult part in the last tutorial, in comparison to the last tutorial this should be more relaxing! As was the case in the last tutorial, the source code is available in case you have problems.
Creating our character
By now you should be familiar with setting up your own characters to move round, but here's a quick re-cap. Once you've added a new TImage component, load in a suitable image that will fit in a tile (so in this case make your image 60 * 60). In my program I've got a picture of Santa Claus seeing as this (was, and depending on when you read this, may very well be again) the season to be jolly. I've named my image SantaImg. If you want you can set the Height and Width properties to 60 or if your image is definitely 60 by 60 then you can always just set AutoSize to true. Also, remember to set Transparent to true and if you decide to shrink down a bigger image by providing the height and width properties, remember to set Stretch to true as well. In my program, however my picture is the correct size so I'll just leave AutoSize as true.
Clicking with the mouse
The first thing we need to do is set up the OnMouseDown procedure. To do this, select your Paintbox, head to the Events tab on the Object Inspector and double-click beside the line that says OnMouseDown. The starting code will now be created and whatever you put in here will happen whenever the mouse button is pushed down. You may wonder why we don't use the OnClick procedure as this carries out an action whenever the mouse is clicked. The reason is quite simple however. With the OnMouseDown procedure the command will return the exact coordinates at which the mouse has been clicked, as can be seen in the first one or two lines created:
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X,Y:Integer);
Here, the letters X and Y are being used to represent the X and Y coordinates of the mouse click (funny that). If you were to try and create an OnClick procedure you'd get the line:
procedure TForm1.PaintBox1Click(Sender: TObject);
This clearly is of no use as it will return no coordinates and will only know the mouse has been clicked. So, now we have that, we can start writing some code. If you remember, our tiles were 60 by 60 pixels in size. What we want to do though is have it so that we can tell which tile the mouse has been clicked inside of, then move our character into it. What we don't want though is for the character just to simply move to the mouse coordinates. We want it to move inside the tile. To do this we'll first need to set up a couple of new variables which we'll call mousex and mousey. Add the following lines before the begin line:
One thing to remember here is that because the variables are integers, if we divide them by 60 to get the number of the tile, we'll instead of getting a decimal, get a whole number. With that in mind, add the following two lines after the begin line.
mousex := X div 60;
mousey := Y div 60;
This means that if the user clicks, on the form at the coordinates (224,156) mousex will be 3 (because 224 divided by 60 is 3.73 with the whole number given being 3 rather than 4), and mousey will be 2 (as 156 divided by 60 is 2.6). Once we've done that we can simply times the result by 60 again to achieve the correct coordinates for the tile. These two lines placed after the last will do the trick:
SantaImg.Left := mousex * 60;
SantaImg.Top := mousey * 60;
So, in the case of the previous coordinates of (224,156), the final result at which the image will move to will be (180,120) (which is at the tile position of (3,2)). That's all you really need to know for using the mouse with a tiled map. Obviously if you've got a tiled map all on one screen, you don't need to worry about your character going off the edge of the screen as you can't actually click off the side of the screen! We'll be covering the use of the MouseDown, MouseUp and MouseMove procedures in more detail in the mouse tutorial soon.
Checking the location of the character
To check whether your character is on water, on grass or in the forest is very simple indeed, and needs very little explanation. What we'll do is have it so that whenever you click on the water to move your character into it, the Santa image will turn into one of him sinking into the water. First add a new TImage component called SantaSinking and insert the relevant image. Again, set Transparency and AutoSize to true. Next all we need to do is add a couple of lines to our MouseDown procedure:
if arr[mousex,mousey] = 2 then SantaImg.Picture := SantaSinking.Picture;
This checks to see if the current tile we are at (mousex,mousey), has an array value of 2. If it has then that tile must be water, as tile 2 is water, and the picture of the Santa will change to that of Santa sinking. That's all there is to it. You could of course in a real game introduce penalties for those who tread on difficult terrain. For example if the character you control is moving up a hill he could get one less move turn or could use valuable extra energy while climbing the hill. Whatever you want really.
Fiddle about with this code to make it to your liking, and if you have any problems or questions please e-mail me or leave a message on the board.