I'm about to show you) much better is:
-They're fast and don't have to be drawn every loop
-They return proper data
-They're numbered so you can change certain ones
I have uploaded a simple butotn sheet, which uses 4 button pictures in one bitmap.. going from top to bottom, and it doesn't
matter what size they are
, they are split automatically in the program..
We will start with a simple setup..
`Setup
sync on
Set display mode 1024,768,16
Set window on : maximize window
(please note to set the directory to where you saved the button image)
Now, to load, and split up the buttons.. We will load it as a bitmap, and grab each image, and there is no need to change the
size of the image you grab, because it always only grabs a quarter of the bitmap..
`Load button bitmaps and grab images
load bitmap "buttons5.bmp",1 : set current bitmap 1
get image 1, 0, 0, bitmap width(1), bitmap height(1)/4
get image 2, 0, bitmap height(1)/4, bitmap width(1), bitmap height(1)/2
get image 3, 0, bitmap height(1)/2, bitmap width(1) , (bitmap height(1)/4)*3
get image 4, 0, (bitmap height(1)/4)*3, bitmap width(1),bitmap height(1)
set current bitmap 0 : delete bitmap 1
This will load up the button images..
Now we need to create an array for the buttons, this array will take up to 20 buttons, but you can change it to as much as
you want (up to 65535 I believe), but we're only make 5 buttons..
`Button Data
dim Button_State(20)
for b=1 to 20
Button_state(b)=1
next b
(if you do not understand arrays then I made a tutorial about AI and arrays somewhere in this board)
Notice the "button_state", this will control the state of the button, depending of the actions of the mouse and whether the
button is active or not.. here is what each state means:
1~ Normal (not covered or clicked, just normal)
2~ covered (if the state is 2, then change the image to the 2nd one)
3~ Clicked (if the state is 3, change image to 3rd image)
4~ Inactive (you can't click it or anything)
so, if you wanted to say.. if you click button 1, then change button 5 to inactive:
if button_state(1)=3 then button_state(5)=4
I set them all to one to start them off...
You get it?
Now we will setup the text to look right, and the sprites, so the text shows above the sprites..
`Setup text
set text font "tahoma" : set text size 20
`Setup Sprites
draw sprites first
Next - simple, make the main loop..
`**Main Loop**
Do
`**End Loop**
Sync
Loop
Then, in the loop, we will call a function (which we will create soon, note that once youve put this bit in, and you don't
have the function, then the program won't work)
Let's call the function 5 times, to make 5 buttons
`**Main Loop**
Do
`Create Push Buttons
PushButton(1,10,10,150,40,"A Button")
PushButton(2,10,60,150,40,"Another")
PushButton(3,10,110,150,40,"Click me!")
PushButton(4,10,160,150,40,"You can't touch me!") : button_state(4)=4
PushButton(5,10,210,150,40,"Caption")
`**End Loop**
Sync
Loop
Notice, the first parameter increases as I go down, this is the butotn number, which is actually the sprite number, but you
control the button too from that number..
These are the parameters:
PushButton(number, posX, posY, sizeX, sizeY, Caption$)
Also notice, that on button number 4, I've changed it's state to 4, so it's inactive, this can be done inside OR before the
main loop .
Now, to make the function..
We will start with:
Function PushButton(num,x,y,sx,sy,caption$)
Endfunction
Notice, that there is no return value to return the data from the button, as I have already said, this will be done with
arrays, which are better
now, add this inside the Function:
Function PushButton(num,x,y,sx,sy,caption$)
`Change state
if button_state(num)<4 or button_state(num)>5
if mousex()>x and mousex()<x+sx and mousey()>y and mousey()<y+sy
if mouseclick()=0
button_state(num)=2
else
button_state(num)=3
endif
else
button_state(num)=1
endif
endif
Endfunction
What this does is: makes sure that the state isn't 4 (because 4 is the locked one), and if it isn't, check where the mouse
is, and if it's clicking, and change the data for that current button from there.. the drawinfor the button isn't done
depending on the positions and state of the mouse, but depending on the state of that current buttom.. ie. if
button_state(1)=1 then sprite 1,etc etc... you get my drift.
now add this:
Function PushButton(num,x,y,sx,sy,caption$)
`Change state
if button_state(num)<4 or button_state(num)>5
if mousex()>x and mousex()<x+sx and mousey()>y and mousey()<y+sy
if mouseclick()=0
button_state(num)=2
else
button_state(num)=3
endif
else
button_state(num)=1
endif
endif
`Change appearance...
if button_state(num)=1
if sprite exist(num)=0
sprite num,x,y,1 : size sprite num,sx,sy
else
set sprite image num,1
endif
endif
if button_state(num)=2
if sprite exist(num)=0
sprite num,x,y,2 : size sprite num,sx,sy
else
set sprite image num,2
endif
endif
if button_state(num)=3
if sprite exist(num)=0
sprite num,x,y,3 : size sprite num,sx,sy
else
set sprite image num,3
endif
endif
if button_state(num)=4
if sprite exist(num)=0
sprite num,x,y,4 : size sprite num,sx,sy
else
set sprite image num,4
endif
endif
Endfunction
This code checks the state of the button, and makes sure that the sprite for that button doesn't already exist, and if it
doesn't, it draws it as the number for that button... If the sprite for that button DOES exist, it just changes the imahge it
uses, so it is very efficient
Now, all we need to do is make the text..
This text will look like it's been etched into the button, but when you click, it will look like it sticks out, hence giving
it a 3D clickable look.
if button_state(num)=1 or button_state(num)=2
ink rgb(255,255,255),0 : center text x+(sx/2),(y+(sy/2))-12,caption$:ink rgb(0,0,0),0 : center text
(x+(sx/2))+1,((y+(sy/2))-12)+1,caption$
endif
if button_state(num)=3
ink rgb(200,200,200),0 : center text x+(sx/2)+1,(y+(sy/2))-11,caption$:ink rgb(128,128,128),0 : center text
(x+(sx/2))+2,((y+(sy/2))-12)+2,caption$
endif
if button_state(num)=4 then ink rgb(100,100,100),0 : center text x+(sx/2),(y+(sy/2))-12,caption$
Don't forget to add this inside the function..
And that's about it.. now some tips..
1- You can make your own functions such as "hide_button" etc.. that is what is so good, you can't do that when you draw boxes
to the screen.. and, you can even rotate the buttons etc.
2- Instead of checking the coordinates of the mouse, it would be wise to make a tiny little sprite and position it at the
mouse, and check if the sprites collide.. because then, you can have any shape of button you like, round, triangle, you name
it..
3- These buttons redraw what was last behind them because they are sprites, the other kinds where you draw boxes to the screen wouldn't unless you always refreshed the screen, which would slow it down.
4- Have fun
[edit]
Here is all my code that I use, just incase you need it.
`Setup
sync on
Set display mode 1024,768,16
set dir "C:\Program Files\The Game Creators\Dark Basic Professional\Projects\GUI\buttons"
Set window on : maximize window
`Load button bitmaps and grab images
load bitmap "buttons5.bmp",1 : set current bitmap 1
get image 1, 0, 0, bitmap width(1), bitmap height(1)/4
get image 2, 0, bitmap height(1)/4, bitmap width(1), bitmap height(1)/2
get image 3, 0, bitmap height(1)/2, bitmap width(1) , (bitmap height(1)/4)*3
get image 4, 0, (bitmap height(1)/4)*3, bitmap width(1),bitmap height(1)
set current bitmap 0 : delete bitmap 1
`Button Data
dim Button_State(20)
for b=1 to 20
Button_state(b)=1
next b
`Setup text
set text font "tahoma" : set text size 20
`Setup Sprites
draw sprites first
`*Main Loop*
Do
`PushButton(Number,X,Y,Size X,Size Y,"Caption")
PushButton(1,10,10,150,40,"A Button")
PushButton(2,10,60,150,40,"Another")
PushButton(3,10,110,150,40,"Click me!")
PushButton(4,10,160,150,40,"You can't touch me!") : button_state(4)=4
PushButton(5,10,210,150,40,"Caption")
`*End Loop*
sync
Loop
`Create Buttons
Function PushButton(num,x,y,sx,sy,caption$)
if button_state(num)<4 or button_state(num)>5
if mousex()>x and mousex()<x+sx and mousey()>y and mousey()<y+sy
if mouseclick()=0
button_state(num)=2
else
button_state(num)=3
endif
else
button_state(num)=1
endif
endif
if button_state(num)=1
if sprite exist(num)=0
sprite num,x,y,1 : size sprite num,sx,sy
else
set sprite image num,1
endif
endif
if button_state(num)=2
if sprite exist(num)=0
sprite num,x,y,2 : size sprite num,sx,sy
else
set sprite image num,2
endif
endif
if button_state(num)=3
if sprite exist(num)=0
sprite num,x,y,3 : size sprite num,sx,sy
else
set sprite image num,3
endif
endif
if button_state(num)=4
if sprite exist(num)=0
sprite num,x,y,4 : size sprite num,sx,sy
else
set sprite image num,4
endif
endif
if button_state(num)=1 or button_state(num)=2
ink rgb(255,255,255),0 : center text x+(sx/2),(y+(sy/2))-12,caption$:ink rgb(0,0,0),0 : center text (x+(sx/2))+1,((y+(sy/2))-12)+1,caption$
endif
if button_state(num)=3
ink rgb(200,200,200),0 : center text x+(sx/2)+1,(y+(sy/2))-11,caption$:ink rgb(128,128,128),0 : center text (x+(sx/2))+2,((y+(sy/2))-12)+2,caption$
endif
if button_state(num)=4 then ink rgb(100,100,100),0 : center text x+(sx/2),(y+(sy/2))-12,caption$
Endfunction