Author Topic: How do you solve this issue? I'm not able to catch the bug  (Read 7233 times)

0 Members and 1 Guest are viewing this topic.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi guys
while I'm playing to code I have fallen in this issue....
run the following code and press more time SpaceBar while blu circles touche the top of screen...

Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER
  4.  
  5. A = _NEWIMAGE(Wscreen, Hscreen, 32)
  6. IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"
  7.  
  8.     CLS
  9.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  10.     PRINT " to test the issue press space while balls arrive to the top of screen"
  11.     FOR W = 1 TO MaxBall STEP 1
  12.         IF Yball(W) > 0 THEN
  13.             CIRCLE (200, Yball(W)), Rball, Blu
  14.             PAINT STEP(0, 0), Blu, Blu
  15.             Yball(W) = Yball(W) - YVel
  16.             IF Yball(W) <= 0 THEN IF CountBall > 0 THEN CountBall = CountBall - 1
  17.         END IF
  18.     NEXT W
  19.     IF _KEYDOWN(32) = -1 THEN
  20.         IF CountBall < MaxBall THEN
  21.             CountBall = CountBall + 1
  22.             Yball(CountBall) = (Hscreen - (2 * Rball))
  23.         END IF
  24.     END IF
  25.     _LIMIT 10
and here its cousin that uses INKEY at the place of _KEYDOWN... but the issue lasts...

Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER
  4. A = _NEWIMAGE(Wscreen, Hscreen, 32)
  5. IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"
  6.  
  7.     K = INKEY$
  8.     CLS
  9.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  10.     PRINT " to test the issue press space while balls arrive to the top of screen"
  11.     FOR W = 1 TO MaxBall STEP 1
  12.         IF Yball(W) > 0 THEN
  13.             CIRCLE (200, Yball(W)), Rball, Blu
  14.             PAINT STEP(0, 0), Blu, Blu
  15.             Yball(W) = Yball(W) - YVel
  16.             IF Yball(W) <= 0 THEN IF CountBall > 0 THEN CountBall = CountBall - 1
  17.         END IF
  18.     NEXT W
  19.     IF K = " " THEN
  20.         IF CountBall < MaxBall THEN
  21.             CountBall = CountBall + 1
  22.             Yball(CountBall) = (Hscreen - (2 * Rball))
  23.         END IF
  24.     END IF
  25.     _LIMIT 10
  26. LOOP UNTIL K = CHR$(27)

in pseudocode
Quote
DO
    take input keyboard
    Clearscreen
    print help output at 1,1
    FOR all balls
           IF ball has Y >0
                     it draws ball
                     it calculates new position
                     IF newPosition is out of screen
                                              it decrease counter of active balls
    IF userPress SpaceBar
          IF counter of active balls is not max
                 It increases counter of active balls
                 it setups new ball position
UNTIL userPress EscapeKey

well, how can instructions external to FOR loop  affect the variable counter of active balls and let loose the correlation between images and counter?
How do you manage a similar issue?

Thanks for read and feedback
Programming isn't difficult, only it's  consuming time and coffee

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #1 on: May 07, 2019, 06:13:24 pm »
reply for first source code

Hi. With a quick glance, I see contradictory conditions on row 17 that can never be fulfilled due to the condition on row 13.

On line 23, you write the NEXT balls down to 380. Therefore, after pressing the space bar, another ball from the bottom starts. If you think that a circle without a blue fill is drawn is a bug, it do PAINT, because in the moment if in start area is second circle, is this used as color border. I would solve it by drawing a blue circle as a texture into NEWIMAGE and then inserting the image so obtained using PUTIMAGE (or GET) to the target position.
« Last Edit: May 07, 2019, 06:31:22 pm by Petr »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #2 on: May 07, 2019, 07:01:50 pm »
Hi Petr
thanks for you time

sorry for my bad communication...
I'll try to be clearer using 2 screenshot

  [ You are not allowed to view this attachment ]    [ You are not allowed to view this attachment ]  

so as you can see if you press spacebar while blue circles are going up over the top of the screen theorically other circles have been made but on the screen there are few images in respect of number of counted circles...

PS yes the graphic blu circle code must be perfected but also so it shows the issue.
Programming isn't difficult, only it's  consuming time and coffee

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #3 on: May 08, 2019, 01:59:32 am »
I did it a bit. Instead of the complicated IF conditions, I simply restart the counter to zero in each pass and let it count again. She goes through the loop the same way. Another problem was that the plus counter reacted too quickly. So I solved it by removing the K& pointer that references _KEYDOWN as soon as it responds. It's probably not the cleanest solution, but it works.

Code: [Select]
CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
CONST Blu = _RGB32(0, 0, 255)
DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER

A = _NEWIMAGE(Wscreen, Hscreen, 32)
IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"

DO
    CLS
    LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
    PRINT " to test the issue press space while balls arrive to the top of screen"

    CountBall = 0
    FOR W = 1 TO MaxBall
        IF Yball(W) > 1 THEN
            CIRCLE (200, Yball(W)), Rball, Blu
            PAINT STEP(0, 0), Blu, Blu
            Yball(W) = Yball(W) - YVel
        END IF
        IF Yball(W) > 0 THEN CountBall = CountBall + 1
    NEXT

    k& = _KEYDOWN(32)
    WHILE k&
        IF CountBall < MaxBall THEN
            CountBall = CountBall + 1
            Yball(CountBall) = (Hscreen - (2 * Rball))
        END IF
        k& = 0
    WEND
    _LIMIT 50

LOOP UNTIL _KEYDOWN(27)
END
« Last Edit: May 08, 2019, 02:21:38 am by Petr »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #4 on: May 08, 2019, 04:14:07 am »
Thanks Petr

you give me different point of view that I have no taken before.

Your solution works but let out the unexpressed goal to let user to spam until 10 balls holding the fireKey pressed.
Also I have thought that this can be related to the speed of _KEYDOWN but also INKEY$ does the same, and also in QBasic in DOSBox the code returns the same results.... so it is clear that the issue is in the algorythm...

I'll dig in this direction observing the flow....Thanks again
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #5 on: May 08, 2019, 09:45:14 am »
Hi TempodiBasic,

Is the problem getting too many balls made off one keypress?

If so, try  k = ""  in loop with INKEY$ or _KEYCLEAR (check Help for arguments 1, 2, 3 or none) in loop with _KEYDOWN.

AND/OR catch the time you draw/count one ball and make sure some time has passed before drawing/counting another.
« Last Edit: May 08, 2019, 09:52:45 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #6 on: May 08, 2019, 10:17:27 am »
Oh! you probably want to do this: (allow up to 10 balls going up AND keep the count correct)
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER
  4. A = _NEWIMAGE(Wscreen, Hscreen, 32)
  5. IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"
  6.  
  7.  
  8.     K = INKEY$
  9.     CLS
  10.     GOSUB countBalls
  11.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  12.     PRINT " to test the issue press space while balls arrive to the top of screen"
  13.     FOR W = 1 TO MaxBall STEP 1
  14.         IF Yball(W) > 0 THEN
  15.             CIRCLE (200, Yball(W)), Rball, Blu
  16.             PAINT STEP(0, 0), Blu, Blu
  17.             Yball(W) = Yball(W) - YVel
  18.             'IF Yball(W) <= 0 THEN
  19.             '    IF CountBall > 0 THEN CountBall = CountBall - 1
  20.  
  21.             'END IF
  22.         END IF
  23.     NEXT W
  24.     IF K = " " THEN
  25.         FOR ball = 1 TO MaxBall
  26.             IF Yball(ball) <= 0 THEN
  27.                 Yball(ball) = Hscreen - (2 * Rball)
  28.                 EXIT FOR
  29.             END IF
  30.         NEXT
  31.         'IF CountBall < MaxBall THEN
  32.         '    CountBall = CountBall + 1
  33.         '    Yball(CountBall) = (Hscreen - (2 * Rball))
  34.         'END IF
  35.     END IF
  36.     _LIMIT 10
  37. LOOP UNTIL K = CHR$(27)
  38.  
  39. countBalls:
  40. CountBall = 0
  41. FOR c = 1 TO MaxBall
  42.     IF Yball(c) > 0 THEN CountBall = CountBall + 1
  43.  
  44.  
  45.  
« Last Edit: May 08, 2019, 11:12:24 am by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #7 on: May 09, 2019, 06:18:37 am »
Hi Bplus
thanks for your solution!
It works fine.

Sorry for _KEYCLEAR from the wiki it seems to give for no help for _KEYDOWN input as you can see here http://qb64.org/wiki/KEYCLEAR
CPR (Copy-Paste-Run)
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER
  4.  
  5. A = _NEWIMAGE(Wscreen, Hscreen, 32)
  6. IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"
  7.  
  8.     '_KEYCLEAR
  9.     CLS
  10.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  11.     PRINT " to test the issue press space while balls arrive to the top of screen"
  12.     FOR W = 1 TO MaxBall STEP 1
  13.         IF Yball(W) > 0 THEN
  14.             CIRCLE (200, Yball(W)), Rball, Blu
  15.             PAINT STEP(0, 0), Blu, Blu
  16.             Yball(W) = Yball(W) - YVel
  17.             IF Yball(W) <= 0 THEN IF CountBall > 0 THEN CountBall = CountBall - 1
  18.         END IF
  19.     NEXT W
  20.     IF _KEYDOWN(32) = -1 THEN
  21.         _KEYCLEAR
  22.         IF CountBall < MaxBall THEN
  23.             CountBall = CountBall + 1
  24.             Yball(CountBall) = (Hscreen - (2 * Rball))
  25.         END IF
  26.     END IF
  27.     _LIMIT 10
  28.  

Programming isn't difficult, only it's  consuming time and coffee

FellippeHeitor

  • Guest
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #8 on: May 09, 2019, 06:42:12 am »
If the key is down, there is no no command that will force it up. It's down because the user is pressing it down.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #9 on: May 09, 2019, 09:10:54 am »
If the key is down, there is no no command that will force it up. It's down because the user is pressing it down.

Right, sorry if I added to confusion by bringing up _KEYCLEAR.

I think _KEYDOWN best used for detecting keypress combinations.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #10 on: May 09, 2019, 09:19:12 am »
Thanks Fellippe

I think that the second issue must be managed by a flag like here
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER
  4. DIM Sflag AS LONG
  5.  
  6. A = _NEWIMAGE(Wscreen, Hscreen, 32)
  7. IF A < -2 THEN SCREEN A ELSE PRINT "Error in Screen setup"
  8. Sflag = 0
  9.  
  10.     CLS
  11.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  12.     PRINT " to test the issue press space while balls arrive to the top of screen"
  13.     FOR W = 1 TO MaxBall STEP 1
  14.         IF Yball(W) > 0 THEN
  15.             CIRCLE (200, Yball(W)), Rball, Blu
  16.             PAINT STEP(0, 0), Blu, Blu
  17.             Yball(W) = Yball(W) - YVel
  18.             IF Yball(W) <= 0 THEN IF CountBall > 0 THEN CountBall = CountBall - 1
  19.         END IF
  20.     NEXT W
  21.     IF _KEYDOWN(32) = -1 THEN
  22.         IF Sflag = 0 THEN Sflag = TIMER ' ELSE Sflag = 0
  23.         LOCATE 4, 1: PRINT Sflag; " "; TIMER
  24.         IF CountBall < MaxBall AND (TIMER > Sflag + .25) THEN
  25.             CountBall = CountBall + 1
  26.             Yball(CountBall) = (Hscreen - (2 * Rball))
  27.             Sflag = 0
  28.         END IF
  29.     END IF
  30.     _LIMIT 10
  31.  
  32.  
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #11 on: May 09, 2019, 10:49:52 am »
Hi TempodiBasic,

Your counts are still off. What is sFlag supposed to do, space out the shots?

Here is much more direct way to do the thing:
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, W AS INTEGER, CountBall AS INTEGER, K AS STRING, fsec AS SINGLE, lastTime AS SINGLE
  4. SCREEN _NEWIMAGE(Wscreen, Hscreen, 32)
  5.     K = INKEY$
  6.     CLS
  7.     CountBall = 0
  8.     FOR W = 1 TO MaxBall
  9.         IF Yball(W) > 0 THEN
  10.             CIRCLE (200, Yball(W)), Rball, Blu
  11.             PAINT STEP(0, 0), Blu, Blu
  12.             CountBall = CountBall + 1: Yball(W) = Yball(W) - YVel
  13.         ELSE
  14.             fsec = TIMER(.001)
  15.             IF K = " " AND fsec - lastTime > .5 THEN Yball(W) = (Hscreen - (2 * Rball)): K = "": lastTime = fsec
  16.         END IF
  17.     NEXT W
  18.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  19.     _DISPLAY 'stop blinking
  20.     _LIMIT 10
EDIT: To space out shots with TIMER
« Last Edit: May 09, 2019, 11:19:59 am by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #12 on: May 09, 2019, 12:21:26 pm »
Hi Bplus
Thanks again...
for the working code that solve the issue
for the polite code, shrinked and direct
for the TIMER spacing out...

and it work well also using _KEYDOWN(32) see here
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, A AS LONG, W AS INTEGER, CountBall AS INTEGER, fsec AS SINGLE, lastTime AS SINGLE
  4. SCREEN _NEWIMAGE(Wscreen, Hscreen, 32)
  5.     CLS
  6.     CountBall = 0
  7.     FOR W = 1 TO MaxBall
  8.         IF Yball(W) > 0 THEN
  9.             CIRCLE (200, Yball(W)), Rball, Blu
  10.             PAINT STEP(0, 0), Blu, Blu
  11.             CountBall = CountBall + 1: Yball(W) = Yball(W) - YVel
  12.         ELSE
  13.             fsec = TIMER(.001)
  14.             IF _KEYDOWN(32) AND fsec - lastTime > .5 THEN Yball(W) = (Hscreen - (2 * Rball)): lastTime = fsec
  15.         END IF
  16.     NEXT W
  17.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  18.     _DISPLAY 'stop blinking
  19.     _LIMIT 10
  20.  

PS have you another way to space shots in the time so that the images don't fuse among them?

PSS In the while I have seen that original code build two different structures a FIFO stack of images on the screen and a LIFO stack of Yposition in the array Yball. These last two structures are incompatible, so it need to shift the Y values in the array as soon as the images go over the 0 Y position. And then to recalculate the CountBall after resetting it to 0.
Your way is surely direct and simpler.
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #13 on: May 09, 2019, 12:37:46 pm »
Hi TempodiBasic,

Another way to space the balls is to watch the Y values in Yball array, use say a min of a 2 * ball radius distance between the balls. That would be a little more work but then your _LIMIT setting of 10 and your TIMER setting of .5 won't have to be recalibrated for another _LIMIT setting.

Actually, this might be even better! because _LIMIT and TIMER space don't have to be calibrated.
Code: QB64: [Select]
  1. CONST YVel = 5, Hscreen = 400, Wscreen = 600, Rball = 10, MaxBall = 10
  2. CONST Blu = _RGB32(0, 0, 255)
  3. DIM Yball(1 TO MaxBall) AS INTEGER, W AS INTEGER, CountBall AS INTEGER, K AS STRING, lastBallIndex AS INTEGER
  4. SCREEN _NEWIMAGE(Wscreen, Hscreen, 32)
  5. lastBallIndex = 1
  6.     K = INKEY$
  7.     CLS
  8.     CountBall = 0
  9.     FOR W = 1 TO MaxBall
  10.         IF Yball(W) > 0 THEN
  11.             CIRCLE (200, Yball(W)), Rball, Blu
  12.             PAINT STEP(0, 0), Blu, Blu
  13.             CountBall = CountBall + 1: Yball(W) = Yball(W) - YVel
  14.         ELSE
  15.             IF K = " " AND Hscreen - Yball(lastBallIndex) > 4 * Rball THEN
  16.                 Yball(W) = Hscreen - (2 * Rball): K = "": lastBallIndex = W
  17.             END IF
  18.         END IF
  19.     NEXT W
  20.     LOCATE 1, 1: PRINT " press Space to shoot, Esc to quit      Countball="; CountBall
  21.     _DISPLAY 'stop blinking
  22.     _LIMIT 50 'works for any reasonable LIMIT set
  23.  
  24.  
« Last Edit: May 09, 2019, 01:00:34 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: How do you solve this issue? I'm not able to catch the bug
« Reply #14 on: May 11, 2019, 07:49:45 pm »
You're right Bplus
Thanks

I have forgotten the structure of the world, time and space!
Programming isn't difficult, only it's  consuming time and coffee