Author Topic: Is There a Mouse Equivalent of _KEYCLEAR?  (Read 8753 times)

0 Members and 1 Guest are viewing this topic.

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #15 on: January 04, 2019, 10:24:41 am »
Any code with a wild WHILE _MOUSEINPUT: WEND will miss clicks. It works as a _KEYCLEAR for the mouse, certainly, but you don't want to have it in a handling loop.

And since we're sharing mouse handling code, here's mine:
Code: QB64: [Select]
  1.     IF _MOUSEBUTTON(1) = mouse_down THEN 'Is the button still in the same position?
  2.         IF _MOUSEBUTTON(1) <> mouse_down THEN EXIT DO 'Process through the queue until the button changes state
  3.       LOOP
  4.     END IF
  5.     mouse_down = _MOUSEBUTTON(1)
  6.     'Do mouse click processing here
  7.   END IF
  8.   'Do other stuff
  9.   _LIMIT 30
Admittedly this doesn't bother trying to detect drag events, just clicks. Also, don't ask me to explain exactly how it works; it was written a long time ago.
« Last Edit: January 04, 2019, 10:28:24 am by luke »

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #16 on: January 05, 2019, 05:46:19 am »
From Steve:
The best practice is:  WHILE _MOUSEINPUT: WEND.    It truly is the equivalent to _KEYCLEAR, for the mouse. 

From Luke:
Any code with a wild WHILE _MOUSEINPUT: WEND will miss clicks. It works as a _KEYCLEAR for the mouse, certainly, but you don't want to have it in a handling loop.

Two of our Great Masters at complete loggerheads (and Fellippe's contributions were rather over my head).

I changed my project code back to Steve's simple loop and then the program set off unwanted mouse click events again, so I agree with Luke: WHILE _MOUSEINPUT: WEND will miss clicks which seems to be the case.  I have put back my original code and this prevents false mouse click events in my project.  I may also add Luke's code as a double-check.  I will shortly submit my project code and perhaps Steve would care to spend more of his valuable time to check it through.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #17 on: January 05, 2019, 07:10:07 am »
From Steve:
The best practice is:  WHILE _MOUSEINPUT: WEND.    It truly is the equivalent to _KEYCLEAR, for the mouse. 

From Luke:
Any code with a wild WHILE _MOUSEINPUT: WEND will miss clicks. It works as a _KEYCLEAR for the mouse, certainly, but you don't want to have it in a handling loop.

Two of our Great Masters at complete loggerheads (and Fellippe's contributions were rather over my head).

Not in disagreement.  Luke was saying that stray WHILE _MOUSEINPUT: WEND routines will cause you to miss events, and he’s right.  You only need the main mousepolling event ONCE, in your main loop.  As I said, think of it as a _KEYCLEAR for your mouse:

DO
   _DELAY 1
   k = _KEYHIT ‘get single byte from the keyboard buffer
   _KEYCLEAR ‘this keyclear will eliminate all the extra buffer events
   PRINT k
LOOP

With the above, you might bang out “ASDFG” on the keyboard and only print out “A” to the screen.  You put extra events into the buffer, but then used _KEYCLEAR to erase them before handling them once each second.

A stray/unneeded _KEYCLEAR causes keyboard input to be missed.  Unnecessary uses of WHILE _MOUSEINPUT: WEND do the same for the mouse.



I’d guess if you’re you’re getting unwanted events, it’s from simply detecting “mouse down” events instead of “mouse click” events.

A mouse down checker is as simple as:
   IF _MOUSEBUTTON(1) THEN....

A mouse click checker needs to be something a little more, like:
  CONST Up = 0, Down = -1
  IF OldState = Up THEN ‘if the mouse was up last pass
      IF _MOUSEBUTTON(1) = Down THEN ‘and it’s down now — We went from up to down
            ... do click stuff
      END IF
  END IF
  OldState = _MOUSEBUTTON(1) ‘store the state of this pass to compare next pass

******

You don’t want to just check to see that the mouse was down for your needs.  After all, holding it down for 10 seconds shouldn’t generate 1000 mouse clicks...  You want it to at least be counted as an, “It WAS up, but now it’s down” type event.

(And If you’re adding “hold events”, you basically need to check, “It WAS up, then down, then released back up” for a click; “Up, down, staying down” for a hold event.)

Feel free to share your actual code, and I’ll be more than happy to look over it.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #18 on: January 05, 2019, 08:01:43 am »
^ what Steve said.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #19 on: January 05, 2019, 08:16:16 am »
Thanks guys, you may find it perplexing that there are some of the very simplest things that I struggle to understand - dimwitted Qwerkey.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #20 on: January 05, 2019, 08:54:57 am »
Fellippe, we could do with a _MOUSECLEAR function, so that the dimwitted amongst us don't have to struggle (or even think!).

FellippeHeitor

  • Guest
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #21 on: January 05, 2019, 09:25:55 am »
Let's see what my peers have to say on that. My view is that it's unrequired, but I'm only one.
« Last Edit: January 05, 2019, 09:29:30 am by FellippeHeitor »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #22 on: January 05, 2019, 09:40:07 am »
Let's see what my peers have to say on that. My view is that it's unrequired, but I'm only one.

I think it’d be asking for trouble. 

We don’t really do a _MOUSECLEAR with a WHILE _MOUSEINPUT: WEND, as much as we do a _MOUSEUPDATE to update mouse x/y/button positions.  At *no* point do we ever actually return NULL (clear) values for the mouse.

_KEYCLEAR gives us a keyboard buffer of “”...

What exactly would a _MOUSECLEAR give us?  MouseX/Y of 0?  Mouse button of 0? 

Would _MOUSEINPUT even function properly after a _MOUSECLEAR, or would you lose too many events?  And would we be able to track wheel events?

Personally, I think it’d complicate things a lot more than it’d simplify them, in the long run.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #23 on: January 05, 2019, 11:13:58 am »
Here is the code of my project where I found it necessary to have a "Use Up Mouse Clicks" routine.

Code: QB64: [Select]
  1. ' Pelmanism (Pairs) Game version 2 by QWERKEY 2019-01-05
  2. ' Images from openclipart.org,clipartpng.com & pngimg.com
  3. ' Sounds from findsounds.com
  4.  
  5. CONST True = -1`, False = 0`
  6. CONST NoObjectsLess1%% = 67
  7. DIM SHARED ButtonNo%%
  8. DIM BestScore%(2), GameLevel%%(2, 1), NosImg&(9, 1), Images&(NoObjectsLess1%%)
  9. $EXEICON:'.\Balloons.ico'
  10. _TITLE "Pelmanism Game"
  11.  
  12. DATA 4,4
  13. DATA 6,6
  14. DATA 10,6
  15. FOR N%% = 0 TO 2
  16.     FOR M%% = 0 TO 1
  17.         READ GameLevel%%(N%%, M%%)
  18.     NEXT M%%
  19. NEXT N%%
  20. 'Create Images
  21. DATA Bananas,Cherry,Carrots,Pepper,Tomato,Cat,Egg,Beer,Acorn,Feather,Squirrel,IcedBun,LightBulb,GoldCup
  22. DATA Parrot,LadyMouse,Mushrooms,Pineapple,Balloons,Rose,CloverLeaf,Goose,Raccoon,Raspberry,Violin,TeddyBear
  23. DATA Clock,Shoes,Wrench,Hammer,Computer,Matches,Diamond,WineGlass,Frog,Chimp,Apricot,RollsRoyce,Knight,Bee
  24. DATA Fish,IceCream,SnowFlake,XmasTree,Butterfly,Rainbow,Penguin,Fox,Hummingbird,Cashews,Tulips,Matryoshka
  25. DATA Lion,Apple,Hat,Heart,Key1,Ladybird,Strawberry,TV,Dog,Dolphin,Koala,Earth,Olives,Einstein,Plane,Flag
  26. FOR N%% = 0 TO NoObjectsLess1%%
  27.     READ Dum$
  28.     Images&(N%%) = _LOADIMAGE(Dum$ + ".png", 33)
  29. NEXT N%%
  30. IF RND > 0.5 THEN
  31.     ObverseImg& = _LOADIMAGE("Back1.png", 33)
  32.     ObverseImg& = _LOADIMAGE("Back2.png", 33)
  33. FOR N%% = 0 TO 9
  34.     TempImg& = _NEWIMAGE(40, 40, 32)
  35.     _DEST TempImg&
  36.     UsedFont& = _LOADFONT("calibriz.ttf", 40)
  37.     _FONT UsedFont&
  38.     COLOR _RGB32(255, 0, 0), _RGB32(0, 0, 0)
  39.     _PRINTSTRING (5, 5), LTRIM$(STR$(N%%))
  40.     _FONT 16
  41.     _FREEFONT UsedFont&
  42.     NosImg&(N%%, 1) = MakeHardware&(TempImg&)
  43. NEXT N%%
  44. FOR N%% = 0 TO 9
  45.     TempImg& = _NEWIMAGE(40, 40, 32)
  46.     _DEST TempImg&
  47.     UsedFont& = _LOADFONT("calibriz.ttf", 40)
  48.     _FONT UsedFont&
  49.     COLOR _RGB32(0, 255, 0), _RGB32(0, 0, 0)
  50.     _PRINTSTRING (5, 5), LTRIM$(STR$(N%%))
  51.     _FONT 16
  52.     _FREEFONT UsedFont&
  53.     NosImg&(N%%, 0) = MakeHardware&(TempImg&)
  54. NEXT N%%
  55. TempImg& = _NEWIMAGE(110, 74, 32)
  56. _DEST TempImg&
  57. UsedFont& = _LOADFONT("calibriz.ttf", 40)
  58. _FONT UsedFont&
  59. COLOR _RGB32(255, 0, 0), _RGB32(0, 0, 0)
  60. _PRINTSTRING (5, 5), "Best"
  61. _PRINTSTRING (5, 45), "Score:"
  62. _FREEFONT UsedFont&
  63. BestImg& = MakeHardware&(TempImg&)
  64. 'Load/Set Initial Data
  65. IF _FILEEXISTS("pelman.dat") THEN
  66.     OPEN "pelman.dat" FOR INPUT AS #1
  67.     INPUT #1, ButtonNo%%
  68.     FOR N%% = 0 TO 2
  69.         INPUT #1, BestScore%(N%%)
  70.     NEXT N%%
  71.     CLOSE #1
  72.     SCREEN _NEWIMAGE(500, 500, 32)
  73.     _SCREENMOVE 100, 100
  74.     _DEST 0
  75.     CLS
  76.     Mousey& = _LOADIMAGE("Mouse.png", 33)
  77.     LOCATE 2, 7
  78.     PRINT "Click on the mouse below with your normal button";
  79.     LOCATE 3, 5
  80.     PRINT "Click (not double-click) to make this screen disappear";
  81.     CorrectButton` = False: ButtonNo%% = 1
  82.     WHILE NOT CorrectButton`
  83.         _LIMIT 60
  84.         _PUTIMAGE (50, 100), Mousey&
  85.         'Assumes hardware has mouse buttons, value <=5
  86.         WHILE _MOUSEINPUT
  87.             IF _MOUSEBUTTON(1) THEN
  88.                 CorrectButton` = True
  89.                 ButtonNo%% = 1
  90.             ELSEIF _MOUSEBUTTON(2) THEN
  91.                 CorrectButton` = True
  92.                 ButtonNo%% = 2
  93.             ELSEIF _MOUSEBUTTON(3) THEN
  94.                 CorrectButton` = True
  95.                 ButtonNo%% = 3
  96.             ELSEIF _MOUSEBUTTON(4) THEN
  97.                 CorrectButton` = True
  98.                 ButtonNo%% = 4
  99.             ELSEIF _MOUSEBUTTON(5) THEN
  100.                 CorrectButton` = True
  101.                 ButtonNo%% = 5
  102.             END IF
  103.         WEND
  104.         _DISPLAY
  105.     WEND
  106.     _FREEIMAGE Mousey&
  107. CALL UseUpMouse
  108. 'Perform Game
  109. Pelmanism` = True
  110. WHILE Pelmanism`
  111.     'Set Game Level
  112.     TempImg& = _NEWIMAGE(70, 90, 32)
  113.     _DEST TempImg&
  114.     COLOR _RGB32(100, 255, 100), _RGBA32(100, 100, 100, 0)
  115.     CLS
  116.     LINE (0, 0)-(69, 89), , B
  117.     Highlight& = MakeHardware&(TempImg&)
  118.     Img123& = _LOADIMAGE("Pelman123.png", 33)
  119.     ImgSkills& = _LOADIMAGE("SkillLevel.png", 33)
  120.     SCREEN _NEWIMAGE(500, 500, 32)
  121.     _SCREENMOVE 100, 100
  122.     _DEST 0
  123.     CLS
  124.     Skilled` = False
  125.     ValidMouse` = False
  126.     DoGrid` = True
  127.     DoMore` = True
  128.     WHILE NOT Skilled`
  129.         _LIMIT 30
  130.         _PUTIMAGE (70, 50), ImgSkills&
  131.         _PUTIMAGE (30, 300), Img123&
  132.         WHILE _MOUSEINPUT
  133.             XMouse% = _MOUSEX: YMouse% = _MOUSEY
  134.             ValidMouse` = False
  135.             IF YMouse% > 345 AND YMouse% < 405 THEN
  136.                 IF XMouse% > 343 AND XMouse% < 385 THEN
  137.                     Level%% = 2
  138.                     ValidMouse` = True
  139.                 ELSEIF XMouse% > 223 AND XMouse% < 265 THEN
  140.                     Level%% = 1
  141.                     ValidMouse` = True
  142.                 ELSEIF XMouse% > 103 AND XMouse% < 145 THEN
  143.                     Level%% = 0
  144.                     ValidMouse` = True
  145.                 END IF
  146.             END IF
  147.             IF _MOUSEBUTTON(ButtonNo%%) AND ValidMouse` THEN Skilled` = True
  148.         WEND
  149.         IF ValidMouse` THEN
  150.             SELECT CASE Level%%
  151.                 CASE 2
  152.                     _PUTIMAGE (333, 330), Highlight&
  153.                 CASE 1
  154.                     _PUTIMAGE (213, 330), Highlight&
  155.                 CASE ELSE
  156.                     _PUTIMAGE (93, 330), Highlight&
  157.             END SELECT
  158.         END IF
  159.         _DISPLAY
  160.         K$ = INKEY$
  161.         IF K$ <> "" THEN
  162.             IF VAL(K$) = 1 THEN
  163.                 Skilled` = True
  164.                 Level%% = 0
  165.             ELSEIF VAL(K$) = 2 THEN
  166.                 Skilled` = True
  167.                 Level%% = 1
  168.             ELSEIF VAL(K$) = 3 THEN
  169.                 Skilled` = True
  170.                 Level%% = 2
  171.             ELSEIF ASC(K$) = 27 THEN 'Esc - Quit Program
  172.                 Skilled` = True
  173.                 Pelmanism` = False
  174.                 DoGrid` = False
  175.                 DoMore` = False
  176.             END IF
  177.         END IF
  178.         K$ = ""
  179.     WEND
  180.     _FREEIMAGE Highlight&
  181.     _FREEIMAGE Img123&
  182.     _FREEIMAGE ImgSkills&
  183.     CALL UseUpMouse
  184.     'Do Puzzle
  185.     IF DoGrid` THEN
  186.         XLimit% = 57 + (GameLevel%%(Level%%, 0) - 1) * 107 + 45
  187.         YLimit% = 57 + (GameLevel%%(Level%%, 1) - 1) * 107 + 45
  188.         IsComplete` = False
  189.         Score% = 0
  190.         NoRemaining%% = GameLevel%%(Level%%, 0) * GameLevel%%(Level%%, 1)
  191.         NoPairs%% = 0
  192.         FirstV%% = 50
  193.         ValidMouse` = False
  194.         Flipping` = False
  195.         TurningBack` = False
  196.         FlipCount%% = 0
  197.         Paused` = False
  198.         PCount%% = 0
  199.         FirstGo` = True
  200.         REDIM Motion`(10, 6, 2), Selected%%(30), Choisi`(10, 6), Grid%%(10, 6)
  201.         RANDOMIZE (TIMER)
  202.         WHILE NoRemaining%% > 0
  203.             Vacant` = False
  204.             WHILE NOT Vacant`
  205.                 HorizPos%% = 1 + INT(GameLevel%%(Level%%, 0) * RND)
  206.                 VertPos%% = 1 + INT(GameLevel%%(Level%%, 1) * RND)
  207.                 IF Grid%%(HorizPos%%, VertPos%%) = 0 THEN Vacant` = True
  208.             WEND
  209.             NewPair` = False
  210.             WHILE NOT NewPair`
  211.                 PairNo%% = 1 + INT(NoObjectsLess1%% * RND)
  212.                 PairsExists` = False
  213.                 N%% = 1
  214.                 WHILE NOT PairsExists` AND N%% <= NoPairs%%
  215.                     IF PairNo%% = Selected%%(N%%) THEN PairsExists` = True
  216.                     N%% = N%% + 1
  217.                 WEND
  218.                 IF NOT PairsExists` THEN NewPair` = True
  219.             WEND
  220.             NoPairs%% = NoPairs%% + 1
  221.             Selected%%(NoPairs%%) = PairNo%%
  222.             Grid%%(HorizPos%%, VertPos%%) = PairNo%%
  223.             Vacant` = False
  224.             WHILE NOT Vacant`
  225.                 HorizPos%% = 1 + INT(GameLevel%%(Level%%, 0) * RND): VertPos%% = 1 + INT(GameLevel%%(Level%%, 1) * RND)
  226.                 IF Grid%%(HorizPos%%, VertPos%%) = 0 THEN Vacant` = True
  227.             WEND
  228.             Selected%%(NoPairs%%) = PairNo%%
  229.             Grid%%(HorizPos%%, VertPos%%) = PairNo%%
  230.             NoRemaining%% = NoRemaining%% - 2
  231.         WEND
  232.         NoRemaining%% = GameLevel%%(Level%%, 0) * GameLevel%%(Level%%, 1)
  233.         TempImg& = _NEWIMAGE(205 + XLimit%, YLimit% + 12, 32)
  234.         _DEST TempImg&
  235.         COLOR _RGB32(255, 255, 255), _RGBA32(100, 100, 100, 0)
  236.         CLS
  237.         FOR N%% = 0 TO GameLevel%%(Level%%, 0) - 1
  238.             FOR M%% = 0 TO GameLevel%%(Level%%, 1) - 1
  239.                 LINE (3 + N%% * 107, 3 + M%% * 107)-(3 + (N%% + 1) * 107, 3 + (M%% + 1) * 107), , B
  240.             NEXT M%%
  241.         NEXT N%%
  242.         UsedFont& = _LOADFONT("calibriz.ttf", 60)
  243.         _FONT UsedFont&
  244.         COLOR _RGB32(0, 0, 255)
  245.         _PRINTSTRING (XLimit% + 35, 355), "QUIT"
  246.         _FONT 16
  247.         _FREEFONT UsedFont&
  248.         UsedFont& = _LOADFONT("calibriz.ttf", 40)
  249.         _FONT UsedFont&
  250.         COLOR _RGB32(0, 255, 0)
  251.         _PRINTSTRING (XLimit% + 35, 190), "Score:"
  252.         _FONT 16
  253.         _FREEFONT UsedFont&
  254.         Background& = MakeHardware&(TempImg&)
  255.         TempImg& = _NEWIMAGE(104, 104, 32)
  256.         _DEST TempImg&
  257.         COLOR _RGB32(0, 176, 0), _RGBA32(100, 100, 100, 0)
  258.         CLS
  259.         LINE (0, 0)-(103, 103), , B
  260.         LINE (1, 1)-(102, 102), , B
  261.         Highlight& = MakeHardware&(TempImg&)
  262.         TempImg& = _NEWIMAGE(144, 52, 32)
  263.         _DEST TempImg&
  264.         COLOR _RGB32(0, 176, 0), _RGBA32(100, 100, 100, 0)
  265.         CLS
  266.         LINE (0, 0)-(143, 51), , B
  267.         Quitlight& = MakeHardware&(TempImg&)
  268.         SCREEN _NEWIMAGE(205 + XLimit%, YLimit% + 12, 32)
  269.         _SCREENMOVE 20, 20
  270.         _DEST 0
  271.         WHILE DoGrid`
  272.             IF TurningBack` THEN
  273.                 _LIMIT 65
  274.             ELSE
  275.                 _LIMIT 40
  276.             END IF
  277.             _PUTIMAGE (0, 0), Background&
  278.             IF BestScore%(Level%%) <> 0 THEN
  279.                 _PUTIMAGE (XLimit% + 30, 20), BestImg&
  280.                 IF BestScore%(Level%%) <= 9 THEN
  281.                     _PUTIMAGE (XLimit% + 140, 60), NosImg&(BestScore%(Level%%), 1)
  282.                 ELSE
  283.                     _PUTIMAGE (XLimit% + 140, 60), NosImg&(BestScore%(Level%%) \ 10, 1)
  284.                     _PUTIMAGE (XLimit% + 160, 60), NosImg&(BestScore%(Level%%) MOD 10, 1)
  285.                 END IF
  286.             END IF
  287.             IF Score% <= 9 THEN
  288.                 _PUTIMAGE (XLimit% + 140, 185), NosImg&(Score%, 0)
  289.             ELSE
  290.                 _PUTIMAGE (XLimit% + 140, 185), NosImg&(Score% \ 10, 0)
  291.                 _PUTIMAGE (XLimit% + 160, 185), NosImg&(Score% MOD 10, 0)
  292.             END IF
  293.             MouseClick` = False
  294.             WHILE _MOUSEINPUT
  295.                 ValidMouse` = False
  296.                 QuitMouse` = False
  297.                 XMouse% = _MOUSEX: YMouse% = _MOUSEY
  298.                 IF XMouse% > 7 AND XMouse% < (GameLevel%%(Level%%, 0)) * 107 AND YMouse% > 7 AND YMouse% < (GameLevel%%(Level%%, 1)) * 107 THEN
  299.                     ValidMouse` = True
  300.                     XX%% = (XMouse% - 7) \ 107
  301.                     YY%% = (YMouse% - 7) \ 107
  302.                     XHighLight% = 5 + 107 * XX%%
  303.                     YHighLight% = 5 + 107 * YY%%
  304.                 ELSEIF XMouse% > XLimit% + 35 AND XMouse% < XLimit% + 169 AND YMouse% > 355 AND YMouse% < 397 THEN
  305.                     QuitMouse` = True
  306.                     XHighLight% = XLimit% + 30
  307.                     YHighLight% = 350
  308.                 END IF
  309.                 IF _MOUSEBUTTON(ButtonNo%%) THEN
  310.                     IF XMouse% > XLimit% + 35 AND XMouse% < XLimit% + 169 AND YMouse% > 355 AND YMouse% < 397 THEN DoGrid` = False
  311.                     IF ValidMouse` THEN MouseClick` = True
  312.                 END IF
  313.             WEND
  314.             IF DoGrid` THEN
  315.                 IF ValidMouse` THEN
  316.                     _PUTIMAGE (XHighLight%, YHighLight%), Highlight&
  317.                 ELSEIF QuitMouse` THEN
  318.                     _PUTIMAGE (XHighLight%, YHighLight%), Quitlight&
  319.                 END IF
  320.                 FOR HorizPos%% = 1 TO GameLevel%%(Level%%, 0)
  321.                     FOR VertPos%% = 1 TO GameLevel%%(Level%%, 1)
  322.                         IF Motion`(HorizPos%%, VertPos%%, 2) THEN
  323.                             'Turn back
  324.                             IF Paused` THEN
  325.                                 _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), Images&(Grid%%(HorizPos%%, VertPos%%)) 'Fronts
  326.                                 PCount%% = PCount%% + 1
  327.                                 IF PCount%% = 40 THEN
  328.                                     Paused` = False
  329.                                     PCount%% = 0
  330.                                 END IF
  331.                             ELSE
  332.                                 IF FlipCount%% = 0 THEN
  333.                                     XPos% = 107 * (HorizPos%% - 1) + 7
  334.                                     YPos% = 107 * (VertPos%% - 1) + 7
  335.                                 END IF
  336.                                 IF FlipCount%% < 50 THEN
  337.                                     _PUTIMAGE (FlipCount%% + XPos%, YPos%)-(XPos% + 100 - FlipCount%%, YPos% + 100), Images&(Grid%%(HorizPos%%, VertPos%%))
  338.                                 ELSE
  339.                                     _PUTIMAGE (XPos% + FlipCount%%, YPos%)-(XPos% + 100 - FlipCount%%, YPos% + 100), ObverseImg&
  340.                                 END IF
  341.                                 FlipCount%% = FlipCount%% + 1
  342.                                 IF FlipCount%% = 100 THEN
  343.                                     FlipCount%% = 0
  344.                                     IF HorizPos%% = FirstH%% AND VertPos%% = FirstV%% THEN
  345.                                         Motion`(HorizPos%%, VertPos%%, 2) = False
  346.                                         Motion`(HorizPos%%, VertPos%%, 0) = False
  347.                                         Flipping` = False
  348.                                         TurningBack` = False
  349.                                         FirstV%% = 50
  350.                                         CALL UseUpMouse
  351.                                     ELSE
  352.                                         Motion`(HorizPos%%, VertPos%%, 2) = False
  353.                                         Motion`(HorizPos%%, VertPos%%, 0) = False
  354.                                         Motion`(FirstH%%, FirstV%%, 2) = True
  355.                                     END IF
  356.                                 END IF
  357.                             END IF
  358.                         ELSEIF Motion`(HorizPos%%, VertPos%%, 1) THEN
  359.                             'Turn forward
  360.                             IF FlipCount%% = 0 THEN
  361.                                 XPos% = 107 * (HorizPos%% - 1) + 7
  362.                                 YPos% = 107 * (VertPos%% - 1) + 7
  363.                             END IF
  364.                             IF FlipCount%% < 50 THEN
  365.                                 _PUTIMAGE (XPos% + 100 - FlipCount%%, YPos%)-(XPos% + FlipCount%%, YPos% + 100), ObverseImg&
  366.                             ELSE
  367.                                 _PUTIMAGE (100 - FlipCount%% + XPos%, YPos%)-(XPos% + FlipCount%%, YPos% + 100), Images&(Grid%%(HorizPos%%, VertPos%%))
  368.                             END IF
  369.                             FlipCount%% = FlipCount%% + 1
  370.                             IF FlipCount%% = 100 THEN
  371.                                 FlipCount%% = 0
  372.                                 Flipping` = False
  373.                                 Motion`(HorizPos%%, VertPos%%, 1) = False
  374.                                 Motion`(HorizPos%%, VertPos%%, 0) = True
  375.                                 IF FirstGo` THEN
  376.                                     FirstGo` = False
  377.                                 ELSE
  378.                                     FirstGo` = True
  379.                                     IF Grid%%(HorizPos%%, VertPos%%) = Grid%%(FirstH%%, FirstV%%) THEN 'Matched pair
  380.                                         Choisi`(HorizPos%%, VertPos%%) = True 'Registers that that grid position cannot be clicked any more
  381.                                         Choisi`(FirstH%%, FirstV%%) = True
  382.                                         NoRemaining%% = NoRemaining%% - 2
  383.                                         IF NoRemaining%% = 0 THEN
  384.                                             'Tah-dah sound (completed)
  385.                                             _SNDPLAYFILE ("fanfare.mp3")
  386.                                         ELSE
  387.                                             'Ching sound (match)
  388.                                             _SNDPLAYFILE ("match3.mp3")
  389.                                         END IF
  390.                                     ELSE
  391.                                         'Initiate sequential turn back
  392.                                         Motion`(HorizPos%%, VertPos%%, 2) = True
  393.                                         Flipping` = True
  394.                                         TurningBack` = True
  395.                                         Paused` = True
  396.                                         PCount%% = 0
  397.                                         _SNDPLAYFILE ("nomatch1.mp3"), , 0.2
  398.                                     END IF
  399.                                     IF Score% < 99 THEN Score% = Score% + 1
  400.                                     IF NoRemaining%% = 0 THEN
  401.                                         'Pairings Completed
  402.                                         IF Score% < BestScore%(Level%%) OR BestScore%(Level%%) = 0 THEN BestScore%(Level%%) = Score%
  403.                                     END IF
  404.                                 END IF
  405.                                 CALL UseUpMouse
  406.                             END IF
  407.                         ELSEIF Motion`(HorizPos%%, VertPos%%, 0) THEN
  408.                             _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), Images&(Grid%%(HorizPos%%, VertPos%%)) 'Fronts
  409.                         ELSE
  410.                             _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), ObverseImg& 'Backs
  411.                         END IF
  412.                     NEXT VertPos%%
  413.                 NEXT HorizPos%%
  414.                 _DISPLAY
  415.                 K$ = INKEY$
  416.                 IF K$ <> "" THEN
  417.                     IF ASC(K$) = 27 THEN 'Esc - Quit Program
  418.                         Pelmanism` = False
  419.                         DoGrid` = False
  420.                         DoMore` = False
  421.                     ELSEIF UCASE$(K$) = "Q" THEN
  422.                         DoGrid` = False
  423.                     END IF
  424.                 END IF
  425.                 K$ = ""
  426.                 IF MouseClick` AND DoGrid` AND NOT Flipping` THEN
  427.                     HorizPos%% = XX%% + 1
  428.                     VertPos%% = YY%% + 1
  429.                     IF Choisi`(HorizPos%%, VertPos%%) OR (FirstH%% = HorizPos%% AND FirstV%% = VertPos%%) THEN
  430.                         'Do nothing
  431.                     ELSE
  432.                         Motion`(HorizPos%%, VertPos%%, 1) = True 'Set this cell turning
  433.                         Flipping` = True
  434.                         IF FirstGo` THEN
  435.                             FirstH%% = HorizPos%%
  436.                             FirstV%% = VertPos%%
  437.                         END IF
  438.                     END IF
  439.                 END IF
  440.             END IF
  441.         WEND
  442.         _FREEIMAGE Background&
  443.         _FREEIMAGE Highlight&
  444.         _FREEIMAGE Quitlight&
  445.         CALL UseUpMouse
  446.     END IF
  447.     'Try Again?
  448.     IF DoMore` THEN
  449.         ImgYes& = _LOADIMAGE("PelmanYes.png", 33)
  450.         ImgNo& = _LOADIMAGE("PelmanNo.png", 33)
  451.         ImgAgain& = _LOADIMAGE("PlayAgain.png", 33)
  452.         TempImg& = _NEWIMAGE(110, 70, 32)
  453.         ValidMouse` = False
  454.         _DEST TempImg&
  455.         COLOR _RGB32(100, 255, 100), _RGBA32(100, 100, 100, 0)
  456.         CLS
  457.         LINE (0, 0)-(109, 69), , B
  458.         Highlight& = MakeHardware&(TempImg&)
  459.         SCREEN _NEWIMAGE(500, 500, 32)
  460.         _SCREENMOVE 100, 100
  461.         _DEST 0
  462.         CLS
  463.         WHILE DoMore`
  464.             _LIMIT 30
  465.             _PUTIMAGE (150, 50), ImgAgain&
  466.             _PUTIMAGE (200, 250), ImgYes&
  467.             _PUTIMAGE (195, 350), ImgNo&
  468.             WHILE _MOUSEINPUT
  469.                 XMouse% = _MOUSEX: YMouse% = _MOUSEY
  470.                 ValidMouse` = False
  471.                 IF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 275 AND YMouse% < 335 THEN
  472.                     ValidMouse` = True
  473.                     XHighLight% = 190
  474.                     YHighLight% = 270
  475.                 ELSEIF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 370 AND YMouse% < 430 THEN
  476.                     ValidMouse` = True
  477.                     XHighLight% = 190
  478.                     YHighLight% = 365
  479.                 END IF
  480.                 IF _MOUSEBUTTON(ButtonNo%%) THEN
  481.                     IF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 275 AND YMouse% < 335 THEN 'Another Game
  482.                         DoMore` = False
  483.                     ELSEIF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 370 AND YMouse% < 430 THEN 'Quit
  484.                         DoMore` = False
  485.                         Pelmanism` = False
  486.                     END IF
  487.                 END IF
  488.             WEND
  489.             IF ValidMouse` THEN _PUTIMAGE (XHighLight%, YHighLight%), Highlight&
  490.             K$ = INKEY$
  491.             IF K$ <> "" THEN
  492.                 IF ASC(K$) = 27 OR UCASE$(K$) = "N" THEN
  493.                     DoMore` = False
  494.                     Pelmanism` = False
  495.                 ELSEIF UCASE$(K$) = "Y" THEN
  496.                     DoMore` = False
  497.                 END IF
  498.             END IF
  499.             K$ = ""
  500.             _DISPLAY
  501.         WEND
  502.         _FREEIMAGE ImgYes&
  503.         _FREEIMAGE ImgNo&
  504.         _FREEIMAGE ImgAgain&
  505.         _FREEIMAGE Highlight&
  506.     END IF
  507.  
  508. 'Freeimages
  509. _FREEIMAGE ObverseImg&
  510. FOR N%% = 0 TO 9
  511.     _FREEIMAGE NosImg&(N%%, 1)
  512.     _FREEIMAGE NosImg&(N%%, 0)
  513. NEXT N%%
  514. _FREEIMAGE BestImg&
  515. FOR N%% = 0 TO NoObjectsLess1%%
  516.     _FREEIMAGE Images&(N%%)
  517. NEXT N%%
  518.  
  519. OPEN "pelman.dat" FOR OUTPUT AS #1
  520. PRINT #1, ButtonNo%%
  521. FOR N%% = 0 TO 2
  522.     PRINT #1, BestScore%(N%%)
  523. NEXT N%%
  524.  
  525.  
  526. FUNCTION MakeHardware& (Img&)
  527.     MakeHardware& = _COPYIMAGE(Img&, 33)
  528.     _FREEIMAGE Img&
  529.  
  530. SUB UseUpMouse
  531.     _KEYCLEAR
  532.     DO 'make sure that mouse button is released
  533.         Dum` = _MOUSEINPUT
  534.     LOOP UNTIL NOT _MOUSEBUTTON(ButtonNo%%)
  535.         IF _MOUSEBUTTON(ButtonNo%%) = mouse_down THEN 'Is the button still in the same position?
  536.             DO WHILE _MOUSEINPUT
  537.                 IF _MOUSEBUTTON(ButtonNo%%) <> mouse_down THEN EXIT DO 'Process through the queue until the button changes state
  538.             LOOP
  539.         END IF
  540.         mouse_down = _MOUSEBUTTON(ButtonNo%%)
  541.     WEND
  542.  
  543.  

This code is used with my Pelmanism Game Program (qv).

What I found is that spurious triggering of the main program (turning a picture over) can happen if Line 114 or Line 191 is omitted.  I think that my mouse button bounces a little and may cause more than 1 mouse down events when clicked.  So when you're selecting a game level, excess mouse clicks are carried over into the picture select part of the program, and a picture turns over without actually selecting it - you will probably need to use the actual program to undersatnd what I'm saying.  Thanks, Steve, in advance.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #24 on: January 05, 2019, 01:20:22 pm »
See if this doesn't clear up the issue a bit better for you:

Code: QB64: [Select]
  1. ' Pelmanism (Pairs) Game version 2 by QWERKEY 2019-01-05
  2. ' Images from openclipart.org,clipartpng.com & pngimg.com
  3. ' Sounds from findsounds.com
  4.  
  5. CONST True = -1`, False = 0`
  6. CONST NoObjectsLess1%% = 67
  7. DIM SHARED ButtonNo%%
  8. DIM BestScore%(2), GameLevel%%(2, 1), NosImg&(9, 1), Images&(NoObjectsLess1%%)
  9. $EXEICON:'.\Balloons.ico'
  10. _TITLE "Pelmanism Game"
  11.  
  12. DATA 4,4
  13. DATA 6,6
  14. DATA 10,6
  15. FOR N%% = 0 TO 2
  16.     FOR M%% = 0 TO 1
  17.         READ GameLevel%%(N%%, M%%)
  18.     NEXT M%%
  19. NEXT N%%
  20. 'Create Images
  21. DATA Bananas,Cherry,Carrots,Pepper,Tomato,Cat,Egg,Beer,Acorn,Feather,Squirrel,IcedBun,LightBulb,GoldCup
  22. DATA Parrot,LadyMouse,Mushrooms,Pineapple,Balloons,Rose,CloverLeaf,Goose,Raccoon,Raspberry,Violin,TeddyBear
  23. DATA Clock,Shoes,Wrench,Hammer,Computer,Matches,Diamond,WineGlass,Frog,Chimp,Apricot,RollsRoyce,Knight,Bee
  24. DATA Fish,IceCream,SnowFlake,XmasTree,Butterfly,Rainbow,Penguin,Fox,Hummingbird,Cashews,Tulips,Matryoshka
  25. DATA Lion,Apple,Hat,Heart,Key1,Ladybird,Strawberry,TV,Dog,Dolphin,Koala,Earth,Olives,Einstein,Plane,Flag
  26. FOR N%% = 0 TO NoObjectsLess1%%
  27.     READ Dum$
  28.     Images&(N%%) = _LOADIMAGE(Dum$ + ".png", 33)
  29. NEXT N%%
  30. IF RND > 0.5 THEN
  31.     ObverseImg& = _LOADIMAGE("Back1.png", 33)
  32.     ObverseImg& = _LOADIMAGE("Back2.png", 33)
  33. FOR N%% = 0 TO 9
  34.     TempImg& = _NEWIMAGE(40, 40, 32)
  35.     _DEST TempImg&
  36.     UsedFont& = _LOADFONT("calibriz.ttf", 40)
  37.     _FONT UsedFont&
  38.     COLOR _RGB32(255, 0, 0), _RGB32(0, 0, 0)
  39.     _PRINTSTRING (5, 5), LTRIM$(STR$(N%%))
  40.     _FONT 16
  41.     _FREEFONT UsedFont&
  42.     NosImg&(N%%, 1) = MakeHardware&(TempImg&)
  43. NEXT N%%
  44. FOR N%% = 0 TO 9
  45.     TempImg& = _NEWIMAGE(40, 40, 32)
  46.     _DEST TempImg&
  47.     UsedFont& = _LOADFONT("calibriz.ttf", 40)
  48.     _FONT UsedFont&
  49.     COLOR _RGB32(0, 255, 0), _RGB32(0, 0, 0)
  50.     _PRINTSTRING (5, 5), LTRIM$(STR$(N%%))
  51.     _FONT 16
  52.     _FREEFONT UsedFont&
  53.     NosImg&(N%%, 0) = MakeHardware&(TempImg&)
  54. NEXT N%%
  55. TempImg& = _NEWIMAGE(110, 74, 32)
  56. _DEST TempImg&
  57. UsedFont& = _LOADFONT("calibriz.ttf", 40)
  58. _FONT UsedFont&
  59. COLOR _RGB32(255, 0, 0), _RGB32(0, 0, 0)
  60. _PRINTSTRING (5, 5), "Best"
  61. _PRINTSTRING (5, 45), "Score:"
  62. _FREEFONT UsedFont&
  63. BestImg& = MakeHardware&(TempImg&)
  64. 'Load/Set Initial Data
  65. IF _FILEEXISTS("pelman.dat") THEN
  66.     OPEN "pelman.dat" FOR INPUT AS #1
  67.     INPUT #1, ButtonNo%%
  68.     FOR N%% = 0 TO 2
  69.         INPUT #1, BestScore%(N%%)
  70.     NEXT N%%
  71.     CLOSE #1
  72.     SelectButton
  73. 'CALL UseUpMouse
  74. 'Perform Game
  75. Pelmanism` = True
  76. WHILE Pelmanism`
  77.     GetSkillLevel
  78.     OldButton = _MOUSEBUTTON(ButtonNo%%) 'Get the current mouse state to make certain the user lifted it up after selecting the skill level
  79.     'Do Puzzle
  80.     IF DoGrid` THEN
  81.         XLimit% = 57 + (GameLevel%%(Level%%, 0) - 1) * 107 + 45
  82.         YLimit% = 57 + (GameLevel%%(Level%%, 1) - 1) * 107 + 45
  83.         IsComplete` = False
  84.         Score% = 0
  85.         NoRemaining%% = GameLevel%%(Level%%, 0) * GameLevel%%(Level%%, 1)
  86.         NoPairs%% = 0
  87.         FirstV%% = 50
  88.         ValidMouse` = False
  89.         Flipping` = False
  90.         TurningBack` = False
  91.         FlipCount%% = 0
  92.         Paused` = False
  93.         PCount%% = 0
  94.         FirstGo` = True
  95.         REDIM Motion`(10, 6, 2), Selected%%(30), Choisi`(10, 6), Grid%%(10, 6)
  96.         RANDOMIZE (TIMER)
  97.         WHILE NoRemaining%% > 0
  98.             Vacant` = False
  99.             WHILE NOT Vacant`
  100.                 HorizPos%% = 1 + INT(GameLevel%%(Level%%, 0) * RND)
  101.                 VertPos%% = 1 + INT(GameLevel%%(Level%%, 1) * RND)
  102.                 IF Grid%%(HorizPos%%, VertPos%%) = 0 THEN Vacant` = True
  103.             WEND
  104.             NewPair` = False
  105.             WHILE NOT NewPair`
  106.                 PairNo%% = 1 + INT(NoObjectsLess1%% * RND)
  107.                 PairsExists` = False
  108.                 N%% = 1
  109.                 WHILE NOT PairsExists` AND N%% <= NoPairs%%
  110.                     IF PairNo%% = Selected%%(N%%) THEN PairsExists` = True
  111.                     N%% = N%% + 1
  112.                 WEND
  113.                 IF NOT PairsExists` THEN NewPair` = True
  114.             WEND
  115.             NoPairs%% = NoPairs%% + 1
  116.             Selected%%(NoPairs%%) = PairNo%%
  117.             Grid%%(HorizPos%%, VertPos%%) = PairNo%%
  118.             Vacant` = False
  119.             WHILE NOT Vacant`
  120.                 HorizPos%% = 1 + INT(GameLevel%%(Level%%, 0) * RND): VertPos%% = 1 + INT(GameLevel%%(Level%%, 1) * RND)
  121.                 IF Grid%%(HorizPos%%, VertPos%%) = 0 THEN Vacant` = True
  122.             WEND
  123.             Selected%%(NoPairs%%) = PairNo%%
  124.             Grid%%(HorizPos%%, VertPos%%) = PairNo%%
  125.             NoRemaining%% = NoRemaining%% - 2
  126.         WEND
  127.         NoRemaining%% = GameLevel%%(Level%%, 0) * GameLevel%%(Level%%, 1)
  128.         TempImg& = _NEWIMAGE(205 + XLimit%, YLimit% + 12, 32)
  129.         _DEST TempImg&
  130.         COLOR _RGB32(255, 255, 255), _RGBA32(100, 100, 100, 0)
  131.         CLS
  132.         FOR N%% = 0 TO GameLevel%%(Level%%, 0) - 1
  133.             FOR M%% = 0 TO GameLevel%%(Level%%, 1) - 1
  134.                 LINE (3 + N%% * 107, 3 + M%% * 107)-(3 + (N%% + 1) * 107, 3 + (M%% + 1) * 107), , B
  135.             NEXT M%%
  136.         NEXT N%%
  137.         UsedFont& = _LOADFONT("calibriz.ttf", 60)
  138.         _FONT UsedFont&
  139.         COLOR _RGB32(0, 0, 255)
  140.         _PRINTSTRING (XLimit% + 35, 355), "QUIT"
  141.         _FONT 16
  142.         _FREEFONT UsedFont&
  143.         UsedFont& = _LOADFONT("calibriz.ttf", 40)
  144.         _FONT UsedFont&
  145.         COLOR _RGB32(0, 255, 0)
  146.         _PRINTSTRING (XLimit% + 35, 190), "Score:"
  147.         _FONT 16
  148.         _FREEFONT UsedFont&
  149.         Background& = MakeHardware&(TempImg&)
  150.         TempImg& = _NEWIMAGE(104, 104, 32)
  151.         _DEST TempImg&
  152.         COLOR _RGB32(0, 176, 0), _RGBA32(100, 100, 100, 0)
  153.         CLS
  154.         LINE (0, 0)-(103, 103), , B
  155.         LINE (1, 1)-(102, 102), , B
  156.         Highlight& = MakeHardware&(TempImg&)
  157.         TempImg& = _NEWIMAGE(144, 52, 32)
  158.         _DEST TempImg&
  159.         COLOR _RGB32(0, 176, 0), _RGBA32(100, 100, 100, 0)
  160.         CLS
  161.         LINE (0, 0)-(143, 51), , B
  162.         Quitlight& = MakeHardware&(TempImg&)
  163.         SCREEN _NEWIMAGE(205 + XLimit%, YLimit% + 12, 32)
  164.         _SCREENMOVE 20, 20
  165.         _DEST 0
  166.         WHILE DoGrid`
  167.             IF TurningBack` THEN
  168.                 _LIMIT 65
  169.             ELSE
  170.                 _LIMIT 40
  171.             END IF
  172.             _PUTIMAGE (0, 0), Background&
  173.             IF BestScore%(Level%%) <> 0 THEN
  174.                 _PUTIMAGE (XLimit% + 30, 20), BestImg&
  175.                 IF BestScore%(Level%%) <= 9 THEN
  176.                     _PUTIMAGE (XLimit% + 140, 60), NosImg&(BestScore%(Level%%), 1)
  177.                 ELSE
  178.                     _PUTIMAGE (XLimit% + 140, 60), NosImg&(BestScore%(Level%%) \ 10, 1)
  179.                     _PUTIMAGE (XLimit% + 160, 60), NosImg&(BestScore%(Level%%) MOD 10, 1)
  180.                 END IF
  181.             END IF
  182.             IF Score% <= 9 THEN
  183.                 _PUTIMAGE (XLimit% + 140, 185), NosImg&(Score%, 0)
  184.             ELSE
  185.                 _PUTIMAGE (XLimit% + 140, 185), NosImg&(Score% \ 10, 0)
  186.                 _PUTIMAGE (XLimit% + 160, 185), NosImg&(Score% MOD 10, 0)
  187.             END IF
  188.             MouseClick` = False
  189.             WHILE _MOUSEINPUT: WEND
  190.             ValidMouse` = False
  191.             QuitMouse` = False
  192.             XMouse% = _MOUSEX: YMouse% = _MOUSEY
  193.             IF XMouse% > 7 AND XMouse% < (GameLevel%%(Level%%, 0)) * 107 AND YMouse% > 7 AND YMouse% < (GameLevel%%(Level%%, 1)) * 107 THEN
  194.                 ValidMouse` = True
  195.                 XX%% = (XMouse% - 7) \ 107
  196.                 YY%% = (YMouse% - 7) \ 107
  197.                 XHighLight% = 5 + 107 * XX%%
  198.                 YHighLight% = 5 + 107 * YY%%
  199.             ELSEIF XMouse% > XLimit% + 35 AND XMouse% < XLimit% + 169 AND YMouse% > 355 AND YMouse% < 397 THEN
  200.                 QuitMouse` = True
  201.                 XHighLight% = XLimit% + 30
  202.                 YHighLight% = 350
  203.             END IF
  204.             IF _MOUSEBUTTON(ButtonNo%%) AND NOT OldButton THEN 'check to make certain the mouse is UP, before we count a down event
  205.                 IF XMouse% > XLimit% + 35 AND XMouse% < XLimit% + 169 AND YMouse% > 355 AND YMouse% < 397 THEN DoGrid` = False
  206.                 IF ValidMouse` THEN MouseClick` = True
  207.             END IF
  208.             OldButton = _MOUSEBUTTON(ButtonNo%%) 'store whether mouse was up or down last
  209.  
  210.             IF DoGrid` THEN
  211.                 IF ValidMouse` THEN
  212.                     _PUTIMAGE (XHighLight%, YHighLight%), Highlight&
  213.                 ELSEIF QuitMouse` THEN
  214.                     _PUTIMAGE (XHighLight%, YHighLight%), Quitlight&
  215.                 END IF
  216.                 FOR HorizPos%% = 1 TO GameLevel%%(Level%%, 0)
  217.                     FOR VertPos%% = 1 TO GameLevel%%(Level%%, 1)
  218.                         IF Motion`(HorizPos%%, VertPos%%, 2) THEN
  219.                             'Turn back
  220.                             IF Paused` THEN
  221.                                 _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), Images&(Grid%%(HorizPos%%, VertPos%%)) 'Fronts
  222.                                 PCount%% = PCount%% + 1
  223.                                 IF PCount%% = 40 THEN
  224.                                     Paused` = False
  225.                                     PCount%% = 0
  226.                                 END IF
  227.                             ELSE
  228.                                 IF FlipCount%% = 0 THEN
  229.                                     XPos% = 107 * (HorizPos%% - 1) + 7
  230.                                     YPos% = 107 * (VertPos%% - 1) + 7
  231.                                 END IF
  232.                                 IF FlipCount%% < 50 THEN
  233.                                     _PUTIMAGE (FlipCount%% + XPos%, YPos%)-(XPos% + 100 - FlipCount%%, YPos% + 100), Images&(Grid%%(HorizPos%%, VertPos%%))
  234.                                 ELSE
  235.                                     _PUTIMAGE (XPos% + FlipCount%%, YPos%)-(XPos% + 100 - FlipCount%%, YPos% + 100), ObverseImg&
  236.                                 END IF
  237.                                 FlipCount%% = FlipCount%% + 1
  238.                                 IF FlipCount%% = 100 THEN
  239.                                     FlipCount%% = 0
  240.                                     IF HorizPos%% = FirstH%% AND VertPos%% = FirstV%% THEN
  241.                                         Motion`(HorizPos%%, VertPos%%, 2) = False
  242.                                         Motion`(HorizPos%%, VertPos%%, 0) = False
  243.                                         Flipping` = False
  244.                                         TurningBack` = False
  245.                                         FirstV%% = 50
  246.                                         'CALL UseUpMouse
  247.                                     ELSE
  248.                                         Motion`(HorizPos%%, VertPos%%, 2) = False
  249.                                         Motion`(HorizPos%%, VertPos%%, 0) = False
  250.                                         Motion`(FirstH%%, FirstV%%, 2) = True
  251.                                     END IF
  252.                                 END IF
  253.                             END IF
  254.                         ELSEIF Motion`(HorizPos%%, VertPos%%, 1) THEN
  255.                             'Turn forward
  256.                             IF FlipCount%% = 0 THEN
  257.                                 XPos% = 107 * (HorizPos%% - 1) + 7
  258.                                 YPos% = 107 * (VertPos%% - 1) + 7
  259.                             END IF
  260.                             IF FlipCount%% < 50 THEN
  261.                                 _PUTIMAGE (XPos% + 100 - FlipCount%%, YPos%)-(XPos% + FlipCount%%, YPos% + 100), ObverseImg&
  262.                             ELSE
  263.                                 _PUTIMAGE (100 - FlipCount%% + XPos%, YPos%)-(XPos% + FlipCount%%, YPos% + 100), Images&(Grid%%(HorizPos%%, VertPos%%))
  264.                             END IF
  265.                             FlipCount%% = FlipCount%% + 1
  266.                             IF FlipCount%% = 100 THEN
  267.                                 FlipCount%% = 0
  268.                                 Flipping` = False
  269.                                 Motion`(HorizPos%%, VertPos%%, 1) = False
  270.                                 Motion`(HorizPos%%, VertPos%%, 0) = True
  271.                                 IF FirstGo` THEN
  272.                                     FirstGo` = False
  273.                                 ELSE
  274.                                     FirstGo` = True
  275.                                     IF Grid%%(HorizPos%%, VertPos%%) = Grid%%(FirstH%%, FirstV%%) THEN 'Matched pair
  276.                                         Choisi`(HorizPos%%, VertPos%%) = True 'Registers that that grid position cannot be clicked any more
  277.                                         Choisi`(FirstH%%, FirstV%%) = True
  278.                                         NoRemaining%% = NoRemaining%% - 2
  279.                                         IF NoRemaining%% = 0 THEN
  280.                                             'Tah-dah sound (completed)
  281.                                             _SNDPLAYFILE ("fanfare.mp3")
  282.                                         ELSE
  283.                                             'Ching sound (match)
  284.                                             _SNDPLAYFILE ("match3.mp3")
  285.                                         END IF
  286.                                     ELSE
  287.                                         'Initiate sequential turn back
  288.                                         Motion`(HorizPos%%, VertPos%%, 2) = True
  289.                                         Flipping` = True
  290.                                         TurningBack` = True
  291.                                         Paused` = True
  292.                                         PCount%% = 0
  293.                                         _SNDPLAYFILE ("nomatch1.mp3"), , 0.2
  294.                                     END IF
  295.                                     IF Score% < 99 THEN Score% = Score% + 1
  296.                                     IF NoRemaining%% = 0 THEN
  297.                                         'Pairings Completed
  298.                                         IF Score% < BestScore%(Level%%) OR BestScore%(Level%%) = 0 THEN BestScore%(Level%%) = Score%
  299.                                     END IF
  300.                                 END IF
  301.                                 'CALL UseUpMouse
  302.                             END IF
  303.                         ELSEIF Motion`(HorizPos%%, VertPos%%, 0) THEN
  304.                             _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), Images&(Grid%%(HorizPos%%, VertPos%%)) 'Fronts
  305.                         ELSE
  306.                             _PUTIMAGE (107 * (HorizPos%% - 1) + 7, 107 * (VertPos%% - 1) + 7), ObverseImg& 'Backs
  307.                         END IF
  308.                     NEXT VertPos%%
  309.                 NEXT HorizPos%%
  310.                 _DISPLAY
  311.                 K$ = INKEY$
  312.                 IF K$ <> "" THEN
  313.                     IF ASC(K$) = 27 THEN 'Esc - Quit Program
  314.                         Pelmanism` = False
  315.                         DoGrid` = False
  316.                         DoMore` = False
  317.                     ELSEIF UCASE$(K$) = "Q" THEN
  318.                         DoGrid` = False
  319.                     END IF
  320.                 END IF
  321.                 K$ = ""
  322.                 IF MouseClick` AND DoGrid` AND NOT Flipping` THEN
  323.                     HorizPos%% = XX%% + 1
  324.                     VertPos%% = YY%% + 1
  325.                     IF Choisi`(HorizPos%%, VertPos%%) OR (FirstH%% = HorizPos%% AND FirstV%% = VertPos%%) THEN
  326.                         'Do nothing
  327.                     ELSE
  328.                         Motion`(HorizPos%%, VertPos%%, 1) = True 'Set this cell turning
  329.                         Flipping` = True
  330.                         IF FirstGo` THEN
  331.                             FirstH%% = HorizPos%%
  332.                             FirstV%% = VertPos%%
  333.                         END IF
  334.                     END IF
  335.                 END IF
  336.             END IF
  337.         WEND
  338.         _FREEIMAGE Background&
  339.         _FREEIMAGE Highlight&
  340.         _FREEIMAGE Quitlight&
  341.         'CALL UseUpMouse
  342.     END IF
  343.     'Try Again?
  344.     IF DoMore` THEN
  345.         ImgYes& = _LOADIMAGE("PelmanYes.png", 33)
  346.         ImgNo& = _LOADIMAGE("PelmanNo.png", 33)
  347.         ImgAgain& = _LOADIMAGE("PlayAgain.png", 33)
  348.         TempImg& = _NEWIMAGE(110, 70, 32)
  349.         ValidMouse` = False
  350.         _DEST TempImg&
  351.         COLOR _RGB32(100, 255, 100), _RGBA32(100, 100, 100, 0)
  352.         CLS
  353.         LINE (0, 0)-(109, 69), , B
  354.         Highlight& = MakeHardware&(TempImg&)
  355.         SCREEN _NEWIMAGE(500, 500, 32)
  356.         _SCREENMOVE 100, 100
  357.         _DEST 0
  358.         CLS
  359.         WHILE DoMore`
  360.             _LIMIT 30
  361.             _PUTIMAGE (150, 50), ImgAgain&
  362.             _PUTIMAGE (200, 250), ImgYes&
  363.             _PUTIMAGE (195, 350), ImgNo&
  364.             WHILE _MOUSEINPUT: WEND
  365.             XMouse% = _MOUSEX: YMouse% = _MOUSEY
  366.             ValidMouse` = False
  367.             IF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 275 AND YMouse% < 335 THEN
  368.                 ValidMouse` = True
  369.                 XHighLight% = 190
  370.                 YHighLight% = 270
  371.             ELSEIF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 370 AND YMouse% < 430 THEN
  372.                 ValidMouse` = True
  373.                 XHighLight% = 190
  374.                 YHighLight% = 365
  375.             END IF
  376.             IF _MOUSEBUTTON(ButtonNo%%) AND NOT OldButton THEN
  377.                 IF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 275 AND YMouse% < 335 THEN 'Another Game
  378.                     DoMore` = False
  379.                 ELSEIF XMouse% > 195 AND XMouse% < 295 AND YMouse% > 370 AND YMouse% < 430 THEN 'Quit
  380.                     DoMore` = False
  381.                     Pelmanism` = False
  382.                 END IF
  383.             END IF
  384.             OldButton = _MOUSEBUTTON(ButtonNo%%)
  385.  
  386.             IF ValidMouse` THEN _PUTIMAGE (XHighLight%, YHighLight%), Highlight&
  387.             K$ = INKEY$
  388.             IF K$ <> "" THEN
  389.                 IF ASC(K$) = 27 OR UCASE$(K$) = "N" THEN
  390.                     DoMore` = False
  391.                     Pelmanism` = False
  392.                 ELSEIF UCASE$(K$) = "Y" THEN
  393.                     DoMore` = False
  394.                 END IF
  395.             END IF
  396.             K$ = ""
  397.             _DISPLAY
  398.         WEND
  399.         _FREEIMAGE ImgYes&
  400.         _FREEIMAGE ImgNo&
  401.         _FREEIMAGE ImgAgain&
  402.         _FREEIMAGE Highlight&
  403.     END IF
  404.  
  405. 'Freeimages
  406. _FREEIMAGE ObverseImg&
  407. FOR N%% = 0 TO 9
  408.     _FREEIMAGE NosImg&(N%%, 1)
  409.     _FREEIMAGE NosImg&(N%%, 0)
  410. NEXT N%%
  411. _FREEIMAGE BestImg&
  412. FOR N%% = 0 TO NoObjectsLess1%%
  413.     _FREEIMAGE Images&(N%%)
  414. NEXT N%%
  415.  
  416. OPEN "pelman.dat" FOR OUTPUT AS #1
  417. PRINT #1, ButtonNo%%
  418. FOR N%% = 0 TO 2
  419.     PRINT #1, BestScore%(N%%)
  420. NEXT N%%
  421.  
  422.  
  423. FUNCTION MakeHardware& (Img&)
  424.     MakeHardware& = _COPYIMAGE(Img&, 33)
  425.     _FREEIMAGE Img&
  426.  
  427. SUB SelectButton
  428.     SHARED ButtonNo%%
  429.     SCREEN _NEWIMAGE(500, 500, 32)
  430.     _SCREENMOVE 100, 100
  431.     _DEST 0
  432.     CLS
  433.     Mousey& = _LOADIMAGE("Mouse.png", 33)
  434.     LOCATE 2, 7
  435.     PRINT "Click on the mouse below with your normal button";
  436.     LOCATE 3, 5
  437.     PRINT "Click (not double-click) to make this screen disappear";
  438.     CorrectButton` = False: ButtonNo%% = 1
  439.     WHILE NOT CorrectButton`
  440.         _LIMIT 60
  441.         _PUTIMAGE (50, 100), Mousey&
  442.         'Assumes hardware has mouse buttons, value <=5
  443.         WHILE _MOUSEINPUT: WEND
  444.         IF _MOUSEBUTTON(1) THEN
  445.             CorrectButton` = True
  446.             ButtonNo%% = 1
  447.         ELSEIF _MOUSEBUTTON(2) THEN
  448.             CorrectButton` = True
  449.             ButtonNo%% = 2
  450.         ELSEIF _MOUSEBUTTON(3) THEN
  451.             CorrectButton` = True
  452.             ButtonNo%% = 3
  453.         ELSEIF _MOUSEBUTTON(4) THEN
  454.             CorrectButton` = True
  455.             ButtonNo%% = 4
  456.         ELSEIF _MOUSEBUTTON(5) THEN
  457.             CorrectButton` = True
  458.             ButtonNo%% = 5
  459.         END IF
  460.         _DISPLAY
  461.     WEND
  462.     _FREEIMAGE Mousey&
  463.  
  464.  
  465. SUB GetSkillLevel
  466.     SHARED ButtonNo%%, Skilled`, Pelmanism`, DoGrid`, DoMore`, Level%%
  467.  
  468.     'Set Game Level
  469.     TempImg& = _NEWIMAGE(70, 90, 32)
  470.     _DEST TempImg&
  471.     COLOR _RGB32(100, 255, 100), _RGBA32(100, 100, 100, 0)
  472.     CLS
  473.     LINE (0, 0)-(69, 89), , B
  474.     Highlight& = MakeHardware&(TempImg&)
  475.     Img123& = _LOADIMAGE("Pelman123.png", 33)
  476.     ImgSkills& = _LOADIMAGE("SkillLevel.png", 33)
  477.     SCREEN _NEWIMAGE(500, 500, 32)
  478.     _SCREENMOVE 100, 100
  479.     _DEST 0
  480.     CLS
  481.     Skilled` = False
  482.     ValidMouse` = False
  483.     DoGrid` = True
  484.     DoMore` = True
  485.     WHILE NOT Skilled`
  486.         _LIMIT 30
  487.         _PUTIMAGE (70, 50), ImgSkills&
  488.         _PUTIMAGE (30, 300), Img123&
  489.         WHILE _MOUSEINPUT: WEND
  490.         XMouse% = _MOUSEX: YMouse% = _MOUSEY
  491.         ValidMouse` = False
  492.         IF YMouse% > 345 AND YMouse% < 405 THEN
  493.             IF XMouse% > 343 AND XMouse% < 385 THEN
  494.                 Level%% = 2
  495.                 ValidMouse` = True
  496.             ELSEIF XMouse% > 223 AND XMouse% < 265 THEN
  497.                 Level%% = 1
  498.                 ValidMouse` = True
  499.             ELSEIF XMouse% > 103 AND XMouse% < 145 THEN
  500.                 Level%% = 0
  501.                 ValidMouse` = True
  502.             END IF
  503.         END IF
  504.         IF _MOUSEBUTTON(ButtonNo%%) AND ValidMouse` THEN Skilled` = True
  505.  
  506.         IF ValidMouse` THEN
  507.             SELECT CASE Level%%
  508.                 CASE 2
  509.                     _PUTIMAGE (333, 330), Highlight&
  510.                 CASE 1
  511.                     _PUTIMAGE (213, 330), Highlight&
  512.                 CASE ELSE
  513.                     _PUTIMAGE (93, 330), Highlight&
  514.             END SELECT
  515.         END IF
  516.         _DISPLAY
  517.         K$ = INKEY$
  518.         IF K$ <> "" THEN
  519.             IF VAL(K$) = 1 THEN
  520.                 Skilled` = True
  521.                 Level%% = 0
  522.             ELSEIF VAL(K$) = 2 THEN
  523.                 Skilled` = True
  524.                 Level%% = 1
  525.             ELSEIF VAL(K$) = 3 THEN
  526.                 Skilled` = True
  527.                 Level%% = 2
  528.             ELSEIF ASC(K$) = 27 THEN 'Esc - Quit Program
  529.                 Skilled` = True
  530.                 Pelmanism` = False
  531.                 DoGrid` = False
  532.                 DoMore` = False
  533.             END IF
  534.         END IF
  535.         K$ = ""
  536.     WEND
  537.     _FREEIMAGE Highlight&
  538.     _FREEIMAGE Img123&
  539.     _FREEIMAGE ImgSkills&
  540.     'CALL UseUpMouse
  541.  
  542.  

Since you had 3 different areas which did the general mouse handling for you, I separated them into their own little independent modules so I could sort them out a bit easier with the program.  Feel free to move them back together, if that suits your needs better -- this was just to help me sort out how many mouse routines I was actually dealing with.  ;)

If you notice, in each section, I only use WHILE _MOUSEINPUT: WEND to update the mouse information for the program.  There's *no* calls to an UseUpMouse routine, as it's no longer needed at all.  (In fact, that little routine has been removed completely from this, for us.)

All you basically needed was a little flag which tracked whether or not the mouse was UP or DOWN prior in the program.  You don't want to count any old DOWN event as a click; you want the mouse to be UP first and then pressed DOWN to be a click.

Code: QB64: [Select]
  1.             IF _MOUSEBUTTON(ButtonNo%%) AND NOT OldButton THEN 'check to make certain the mouse is UP, before we count a down event
  2.                 IF XMouse% > XLimit% + 35 AND XMouse% < XLimit% + 169 AND YMouse% > 355 AND YMouse% < 397 THEN DoGrid` = False
  3.                 IF ValidMouse` THEN MouseClick` = True
  4.             END IF
  5.             OldButton = _MOUSEBUTTON(ButtonNo%%) 'store whether mouse was up or down last
  6.  


No need for a clean up routine as you were using it, and no worries about your program lagging trying to process code inside the WHILE-WEND mouse update. 

Try it out, and if you have any questions, feel free to ask.  It's how we learn, after all.  ;D
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #25 on: January 06, 2019, 05:08:12 am »
Steve, thanks very much.  That seems to work fine.  From my reading of the Wiki, I completely misunderstood the WHILE _MOUSEINPUT: WEND requirements.  I thought that all subsequent Mouse data (eg _MOUSEX & _MOUSEBUTTON()) had to be inside that loop, but following it later works as well.  So, yes, I've have learnt a little.  I'll study your code further to fully understand how to do Mouse event processing properly.

Elsewhere from Steve:
Quote
And people wonder why I quit farming!  /sigh

All those hours you used to spend farming, now taken up spoon-feeding other dumb animals!!
« Last Edit: January 06, 2019, 06:36:10 am by Qwerkey »