[Home]  [Edit this page]  [Recent Changes]  [Special Pages]  [Help
Mouse-Pascal
The only thing you need to make use of this tutorial is this unit. I will base my article on it.

In the previous article, I showed how to apply graphics procedures to display the sprites in your games and how to detect collisions. The mouse is basically the same thing. The mouse is (in its own way) a sprite. It has its X and Y and booleans to tell you which button was pressed. What we need to do is in our main loop, add an If statement to see if the mouses position has changed and if a button was pressed. In order to see if it was moved, we need something to compare it with. Therefore, we will add a variable to store its position. We will also add variables to store the mouses current position - the hand is faster then the computer... (Or at least a few years ago )
{Before the main procedure}
Var MX, MY, OldMX, OldMY : Integer;

(Before the main loop)
OldMX := GetMouseX; {Initially, the old position iswhre the new one is}
OldMX := GetMouseY;
MX := OldMX;
MY := OldMY;

{In the main loop}
MX := GetMouseX;
My := GetMouseY;
If LeftPressed Do 
 Begin {On mouse click (Left button)}
 End;
If MX <> OldMX Or MY <> OldMY Do
 Begin {On mouse move}
  RedrawMouse;
 End;
OldMX := MX;
OldMy := MY;


This is the general format of our mouse code. But I still haven't mentioned the cursor and its being redrawn. The first thing we need is a type. We will make a small cursor - Six by Seven pixels.
 
 Icon = Array[1..7,1..6] of Byte;


As I mentioned as a footnote at the end of my graphics article, a picture is just an array of colours for Our loop to draw - look at this:
{I declared this mouse as a constant, so it doesn't need to be re-declared.}
{I hope you like my pic }
  MouseIcon : Icon = ((0,98,98,98,98,98), {Every number represents a colour}
                      (0,0,98,98,98,98),  {98 = Transparent. 0 = Black.
                                           31 = White}
                      (0,31,0,98,98,98),
                      (0,31,31,0,98,98),
                      (0,31,31,31,0,98),
                      (0,31,31,31,31,98),
                      (98,0,31,31,31,0));


You will notice, I put down colour 98 as transparent. How o I draw transparent? Easy, You don't!!! In the for loop that we use to draw our icon, we add an if statement that says that if pixel colour is not 98 then we draw, otherwise, skip it. Here is the drawing routine: (This routine is for anything that is declared as an icon.)
Procedure DrawIcon(X,Y : Integer;Var Ic : Icon);
Var i, j : Integer;
Begin
 For j := 1 to 7 do
   For i := 1 to 6 do
    If (Ic[j,i] <> 98) And (X+(i-1) < 320) And 
      (Y+(j-1) < 200) then PutPixel(X+(i-1),Y+(j-1),Ic[j,i],VGA);
End;


Now that we have our drawing routine, we need to be able to clear the mouse. We will do this based on how we cleared our other sprites in the previous article:
  1. Get what is behind the mouse before it is drawn the first time
  2. Draw the mouse
  3. On mouse move, redraw what was behind the mouse
  4. Repeat from number 2.
We will first need to declare another icon - one holding what was behind the mouse. We also need to declare a procedure that we can use to get from the screen what is behind the mouse. The only real difference is that we will use getpixel instead of putpixel. In code:
{Notice how I passed GetIcon by reference - 
  pascal doesn't support returning complex types}
Procedure GetIcon(X,Y : Integer; Var GetIcon : Icon);
Var i, j : integer;
Begin
 For j := 1 to 7 do
   For i := 1 to 6 do
    GetIcon[j,i] := GetPixel(X+(i-1),Y+(j-1),VGA);
End;


Add this to the declarations section:
OldIcon : Icon;


And after all that, we can finally come to our refresh mouse procedure:
Procedure RefreshMouse;
Begin
    DrawIcon(OldMX,OldMY,OldIcon); {Clean mouse at its old position}
    OldMX := MX; {Update the mouse's old position - it was moved}
    OldMY := MY;
    GetIcon(MX,MY, OldIcon); {Get its new "Background"}
    DrawIcon(MX,MY,MouseIcon); {And finally draw it.}
End;


But their are times that we don't want to show our mouse, for example, if we added a feature to write text to our code and want to hide the mouse while the user is using the keyboard to type. What we will do is add "MouseEnabled : Boolean" to our declarations section and only refresh mouse when it = true. But that means that we wont be calling anything to hide the mouse - only to not redraw it, so we need to add a small procedure to hide the mouse.
Procedure HideMouse;
Begin
 MouseEnabled := False;
 DrawIcon(OldMx,OldMy,OldIcon);
End;
And when we want to reshow it, we need to do one additional thing - get its new background - its no use drawing its old background that it had before it was hidden - it will draw glitches to your screen (Try the code without that line and then hide the mouse, change the colour of the screen and then show it - it will show the old background.).
Procedure ShowMouse;
Begin
 MouseEnabled := True;
 GetIcon(MX,MY, OldIcon);
 RefreshMouse;
End;


So far so good - we now have a mouse icon on the screen that can move, be redrawn, be hidden and shown. Now let us look at its On click event. What we basically need for it is a procedure that will check if the mouse is over another object - a sprite, button, or anything. So, for every new concept that we add to our program, we need to add a procedure that checks its co-ordinates relative to the mouse and say if the mouse is over it. If it is, and the mouse button was clicked then we know that the user clicked on it. We will later on add some for loops to run through every object in the game and check if the mouse was over it, but for now, here is the basic routine that checks to see if it was over it. (This routine is almost exactly the same as the routine that I added to check for a collision between the ball and the bricks in my arkanoid game.) Here is the routine:
{Lets say we have the type button that has X and Y CoOrdinates}
{A button is 48 by 18.}
Function CheckMOButton(Mx,My : Integer;Var Btn:Button) : Boolean;
Begin   {If (Btn.X < MX < Btn.X + 48) And (Btn.Y < MY < Btn.Y + 18)}
        {Then return true.} 
CheckMOButton := ((MX > Btn.X) And (MX < Btn.X+48)) And 
                      ((MY > Btn.Y) And (MY < Btn.Y+18));
End;
Now lets say that we had an array of 5 buttons, then in the main loop, we will add this under the on click event:
For i := 1 to 5 do
 If CheckMOButton(MX, MY, btn[i]) then 
       ButtonClick(i); {Which tells the procedure Button click that 
                        button i was pressed}


How to use all this information in games? Well get into your favourite game - see that picture that moves whenever you move the mouse? Well you can have that in your games.

Here is a program I made that include all this (My graphics article and this mouse one.) and more!! (You should read the article about using fonts first...)

last edited (September 28, 2005) by Relman, Number of views: 4673, Current Rev: 6 (Diff)

[Edit this page]  [Page history]  [What links here]  [Discuss this topic]  [Printer Friendly]  

Members

Username:

Password:


Register
Forgot Password?




Programmers Heaven - for .NET, Java, C/C++ and WEB Developers!
© 1996-2008 Community Networks Ltd. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Tore Nestenius at .NET Consultant - Synchron Data.