b+ Beginners Corner
#21
Oh hey! Here is the unenRitchied AI Missile Guided version called AIM - AI Missile.bas
Code: (Select All)
W = 800: H = 600
Screen _NewImage(800, 600, 32)
Randomize Timer
Color &HFFFFFFFF, &HFF6666DD
Cls
a:
a = Rnd * W: b = 0: c = Rnd * 6 - 3: d = Rnd * 3 + 3: x = 400: y = H: lastx = x: lasty = y: lasta = a: lastb = b: l = 5
l = l * 10
Do
    _Title "AIM-AI Missile Defense - Hits:" + Str$(t) + ", Misses:" + Str$(m)
    a = a + c: b = b + d: ang = _Atan2(b - y, a - x)
    x = x + 7 * Cos(ang): y = y + 7 * Sin(ang)
    If x < 0 Or y < 0 Or a < 0 Or b < 0 Or x > W Or a > W Or b > H Then
        If b > H Or x < 0 Or y < 0 Or x > W Then m = m + 1
        GoTo a:
    End If
    If ((x - a) ^ 2 + (y - b) ^ 2) ^ .5 < 10 Then
        For r = 1 To 20 Step 4
            Circle ((x + a) / 2, (y + b) / 2), r, &HFFFF0000
            _Limit 10
        Next
        t = t + 1: GoTo a:
    Else
        Line (x, y)-(lastx, lasty), &HFF006600: Line (a, b)-(lasta, lastb), &HFFDDDDFF
        lastx = x: lasty = y: lasta = a: lastb = b
    End If
    _Limit l
Loop Until t = 50
Sleep

That draws a sort of Hippie message overall when you run it.
b = b + ...
Reply
#22
(06-23-2023, 09:56 PM)bplus Wrote: BTW never, never, never use single letter constants if you ever hope to modify your code later and change names to make it more readable.
Yeah, single letter constants and globally shared single letter variables become your worst enemy very quickly. It's tempting to use them at first to quickly type in an idea but they quickly become a headache later on when cleaning up the code.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#23
I've written code in QBasic for a Drop Down Menu. I used that old standard code routine of printing one, erase that one, print two, erase two, print three .. printing and erasing was the basic way of creating the drop down effect. There has been so many improvements to the language since then. Has the basic print/erase method changed at all in terms of creating a drop down menu?
Reply
#24
(06-24-2023, 02:35 PM)Dimster Wrote: I've written code in QBasic for a Drop Down Menu. I used that old standard code routine of printing one, erase that one, print two, erase two, print three .. printing and erasing was the basic way of creating the drop down effect. There has been so many improvements to the language since then. Has the basic print/erase method changed at all in terms of creating a drop down menu?

Hi Dimster!

I think you might of missed where you wanted to post your question, maybe here
https://staging.qb64phoenix.com/showthread.php?tid=1768
instead?

There are a thousand ways to do this, I was tempted to post some other ways in that post but... I didn't want to hijack.

But since you ask in this little corner of forum, I will say basic methods don't change much when QB64pe tries to stay compatible with the past but sure as shoot'n there are new ways always being added to our tool box!

So I will show some alternates I considered to do a Multiple Input:

Here is short and sweet:
Code: (Select All)
again:
Input "Please enter 3 inputs separated by commas "; i1$, i2$, i3$
Print "n for no!, Process?: "; i1$; ", "; i2$; ", "; i3$
Input confirm$
If confirm$ = "n" Then GoTo again
Print "processing..."
The above code is unforgiving if you type soemthing wrong.

To fix that here is a menu of choices to edit until you get everything as you want:
Code: (Select All)
_Title "Multiple Input Menu demo" 'b+ 2021-06-11

Type InputItem
    As String promptName, SValue
End Type

ReDim Shared nItems
nItems = 12 ' number of inputs plus 2 for quit and goto for processing inputs

' initial item names (like variables)
ReDim inps(1 To nItems) As InputItem
For i = 1 To nItems - 2
    inps(i).promptName = "Demo Input Item #" + _Trim$(Str$(i))
Next
inps(nItems - 1).promptName = "Process Inputs"
inps(nItems).promptName = "Quit"
Do
    Cls
    For i = 1 To nItems
        Print "#" + _Trim$(Str$(i)), inps(i).promptName;
        If inps(i).SValue <> "" Then Print " = "; inps(i).SValue Else Print
    Next
    Print: Input "Enter choice # "; choice
    If choice < nItems - 1 Then
        Print "Please enter, " + inps(choice).promptName + " ";
        Input inps(choice).SValue
    End If
Loop Until choice >= nItems - 1 And choice <= nItems
Select Case choice
    Case nItems: Print "You quit, goodbye!": End
    Case nItems - 1
        ' <<< could check inputs here and handle errors
        GoTo processInputs
End Select

processInputs:
' doit   remember SValues are strings!
Print "Processing Inputs now..."

This allows you to use arrow keys up and down until you press enter on last field:
Code: (Select All)
Option _Explicit ' to remind what I haven't dim'd  B+ mod Cobalt and NOVARSEG and Dav 2021-06-15
Dim As Long cursor, nInputs, i
Dim k$
'setups
nInputs = 6 'for this example we will allow up to nInputs inputs
Dim Inputs$(1 To nInputs)
Dim prompts$(1 To nInputs)
prompts$(1) = "First Name: "
prompts$(2) = " Last Name: "
prompts$(3) = "Home Phone: "
prompts$(4) = "Cell Phone: "
prompts$(5) = "Birth date: "
prompts$(6) = "     State: "
cursor = 1 'start on the first input line
'start our loop up
Do
    k$ = InKey$ 'keyboard input
    For i = 1 To nInputs 'loop through all our input options
        Locate i, 1: Print prompts$(i); Inputs$(i);
        'print a "cursor" to show which input user is on, use space$ to clear other lines
        If i = cursor Then Print "_" + " " Else Print Space$(2)
    Next
    If Len(k$) Then 'let us process which line the user is inputing
        Select Case Asc(Right$(k$, 1))
            Case 13: If cursor = nInputs Then Exit Do Else cursor = cursor + 1 ' no exit unless on last line
            Case 8: Inputs$(cursor) = Left$(Inputs$(cursor), Len(Inputs$(cursor)) - 1) 'backspace to clear this input
            Case 27: Exit Do
            Case 72, 75: If cursor > 1 Then cursor = cursor - 1 ' up
            Case 73: cursor = 1 'pgUp
            Case 80, 77: If cursor < nInputs Then cursor = cursor + 1 'down
            Case 81: cursor = nInputs ' pgDn
            Case 32 To 122: Inputs$(cursor) = Inputs$(cursor) + k$
        End Select
    End If
    _Limit 30 'up date 30times a sec to save CPU use
Loop
'show results of inputs
For i = 1 To nInputs
    Print i, prompts$(i); "= "; Inputs$(i)
Next

I had that titled "best" but Steve has a really nice version that bests mine with popup like menu functioning:
(Come to think, there was a slew awhile back. Dav had a nice one too and someone else I think, Pete? ...)
Code: (Select All)
Screen _NewImage(1280, 720, 32)
Dim As String prompt(3), results(3)
prompt(0) = "Name": prompt(1) = "Age": prompt(2) = "Sex": prompt(3) = "Phone Number"
For i = 1 To 100 'Draw some stuff on the screen for a background
    Line (Rnd * 1280, Rnd * 720)-(Rnd * 1280, Rnd * 720), _RGB32(Rnd * 255, Rnd * 255, Rnd * 255), BF
Next
Print "SLEEPING SO YOU CAN SEE OUR BACKGROUND"
Sleep
MultiInput 100, 100, prompt(), results(), 20
Print: Print "As you can see, when finished, our pop up restored our background..."
Print "And your answers were the following:"
For i = 0 To UBound(results): Print results(i): Next

'ref: SMcNeill    https://staging.qb64phoenix.com/showthread.php?tid=141
Sub MultiInput (xPos, yPos, prompt() As String, results() As String, maxLength As Integer)
    backupImage = _CopyImage(0) 'copy our screen
    B = _Blend: _DontBlend: A = _AutoDisplay: u = UBound(prompt)
    For i = 0 To u 'get box size
        p = _PrintWidth(prompt(i)): If p > maxWidth Then maxWidth = p
    Next
    boxWidth = maxWidth + maxLength * _FontWidth + 10: boxheight = (u + 1) * (_FontHeight + 3)
    Do
        If Timer > t# + .5 Then blink = Not blink: t# = Timer
        k = _KeyHit 'get input
        Select Case k
            Case 18432: selection = selection - 1: If selection < 0 Then selection = u 'up
            Case 20480, 13: selection = selection + 1: If selection > u Then selection = 0 'down
            Case 27: Exit Do 'esc is the exit/finish code
            Case 8: results(selection) = Left$(results(selection), Len(results(selection)) - 1) 'backspace
            Case 32 To 255: results(selection) = results(selection) + Chr$(k) 'all else
        End Select

        _PutImage , backupImage 'restore background
        Line (xPos, yPos)-Step(boxWidth, boxheight), 0, BF: Line (x + xPos + maxWidth + 1, y + yPos)-Step(0, boxheight), -1 'draw box
        For i = 0 To u
            Line (x + xPos, y + i * (_FontHeight + 3) + yPos)-Step(boxWidth, _FontHeight + 3), -1, B
            _PrintString (x + xPos + 2, y + i * (_FontHeight + 3) + yPos + 2), prompt(i)
            If i = selection And blink Then out$ = results(i) + Chr$(219) Else out$ = results(i)
            _PrintString (x + xPos + maxWidth + 3, y + i * (_FontHeight + 3) + yPos + 2), out$
        Next
        _Limit 30: _Display
    Loop
    _PutImage , backupImage
    If B Then _Blend
    If A Then _AutoDisplay
    _FreeImage backupImage
End Sub
b = b + ...
Reply
#25
Those are definitely menus, but I was thinking more along the lines of a drop drown. Here is an example of what I had in mind. This example comes from the old Qbasic coding days and I see where I did change the animation of the drop down from the print/erase to a loop with a delay to slow down the drop. Also, only the "1 - Opening Info" menu item is working here but it gives you a good idea of the drop down effect. 
Code: (Select All)
Cls
Screen 12
Width 80, 60
_FullScreen
'Large background box
Line (0, 0)-(640, 50), 7, BF

'The 5 smaller background boxes
Line (7, 7)-(126, 46), 4, BF
Line (127, 7)-(247, 46), 2, BF
Line (248, 7)-(368, 46), 6, BF
Line (369, 7)-(489, 46), 14, BF
Line (490, 7)-(610, 46), 1, BF

'The menu within the smaller boxes
Locate 4, 2
Color 5
Print "1";
Color 15
Print "-Opening Info"
Locate 4, 19
Color 5
Print "2";
Color 15
Print "-Update"
Locate 4, 34
Color 5
Print "3";
Color 15
Print "-Analyze"
Locate 4, 49
Color 5
Print "4";
Color 15
Print "-Results"
Locate 4, 66
Color 5
Print "5";
Color 15
Print "-Quit"

'The choice question
Locate 8, 5
Input choice

If choice = 1 Then Opening
'If choice = 2 Then Update
'If choice = 3 Then Analyze
'If choice = 4 Then Results
'If choice = 5 Then Quit


Sub Opening

    For Z = 51 To 450
        For dlay = 1 To 500000: Next
        Line (7, 51)-(126, Z), 4, BF
    Next Z
    Z = 0
    Locate 10, 3
    Color 15
    Print "Last Entry"
    Locate 10, 20
    Color 2
    Close 1

    Print "Aug 15, 2021"
    Locate 15, 3
    Color 15
    Print "Status"
    Locate 15, 20
    Color 2
    Print "Events Data Entered Ok"
   
    Locate 20, 3
    Color 15
    Print "Prediction"

    Locate 20, 20
    Color 2
    Print "Results Imply Events 2 & 3 will dominate for 11 days"

    Locate 25, 3
    Color 15
    Print "Present Cycle"
    Locate 26, 3
    Print "Events "
    Locate 27, 3
    Color 1 'Blue
    Print "None Event"
    Locate 28, 3
    Color 14 'Yellow
    Print "Below Average"
    Locate 29, 3
    Color 2 'Green
    Print "Average"
    Locate 30, 3
    Color 12 'Light Red / Pink
    Print "Above Average"
    Locate 31, 3
    Color 4 'Red
    Print "EXTREME"
    Locate 26, 20
    Color 2






    Locate 55, 3
    Color 15
    Print "Next Task"
    Locate 55, 20
    Color 2
    Print "Input The Number for The Next Task ";
    Input NextTask

End Sub
  
When you factor in the additional menu item choices of 2,3,4 & 5 , the code can become quite lengthy. Using the modern day QB64PE, I would think the _DELAY command would be drop rate control and "reveal" of the submenu items, as the drop progresses, would be better than the sudden appearance.
Reply
#26
(06-24-2023, 07:48 PM)Dimster Wrote: When you factor in the additional menu item choices of 2,3,4 & 5 , the code can become quite lengthy. Using the modern day QB64PE, I would think the _DELAY command would be drop rate control and "reveal" of the submenu items, as the drop progresses, would be better than the sudden appearance.

bplus is trying to help you with a solution, because adding menu items your way is an impossible way to program. It doesn't matter if you're doing a "dropdown" or any kind of menu. The thing is you need to use a string array to keep track of the elements of the menu, so you could use your menu-creating code again in the future. With the example you provided, you will be able to create that one application, and then hesitate to do another one the same way again.

What if you decided you wanted one menu option to open another menu. Ahh, the sub-menus found in many applications like Libreoffice Writer. It becomes tricky then. Have a double-dimensional string array which is each menu with its distinct set of options. This includes any menu-within-a-menu. Then it requires trickery to show the "main" menus and when to show the sub-menus.

I have code that somebody else wrote long ago for QuickBASIC for a simple menu in SCREEN 0, with colors and stuff. However it doesn't restore the screen area under the menu. Basically it clears the screen, puts on the menu, accepts the input and then clears the screen again for the rest of the program execution. I have to go dig into my backups...

EDIT: Read the previous post again. So what you want is animations? The dumbass animations I'm still trying to kill on Linux LOL which slow down my computer.

Well, then it becomes even more important how you organize your menu. You begin drawing the menu with the first item only, and the box around it. Then a very short pause. Then you redraw the menu, overwriting the bottom of the menu with the second option and restoring the whole box. Then another very short pause. And so on until you have all the menu entries. This is just visual trickery which could affect how the user could interact with the program. I don't know about you but I want snappy response in my programs without discussion. I cannot get it, for example from the QB64 IDE on Linux which is the main reason why I don't use it very much except for formatting source code to post on this forum.
Reply
#27
Sorry @Dimster I was a little off about drop downing, instead my focus was on doing multiple input which is handy for filling out a database form. Never did much with drop down menus but mnrvovrfc is right about using a string array and setting up your code so what you do come up with for drop downs can be reused again in other apps. 

@TerryRitchie this might be a topic for Game Programming (I just did a quick scan for it and came up empty).
I swear I remember seeing menu code of yours sometime ago, maybe mistaken. 

I will dig around my files.
b = b + ...
Reply
#28
Oh maybe we can play around with this starter code:
Code: (Select All)
_Title "Button Menu demo" '  b+ 2023-06-24

Dim menu$(1 To 10)

Screen _NewImage(800, 720, 32)
_ScreenMove 250, 0

For i = 1 To 9
    menu$(i) = "This menu item #" + _Trim$(Str$(i))
Next
menu$(10) = "Quit"
Do
    selectedN = getButtonNumberChoice%(menu$())
    Print "You selected "; menu$(selectedN)
Loop Until selectedN = 10

Sub drwBtn (x, y, s$) '200 x 50
    Dim fc~&, bc~&
    Line (x, y)-Step(200, 50), _RGB32(0, 0, 0), BF
    Line (x, y)-Step(197, 47), _RGB32(255, 255, 255), BF
    Line (x + 1, y + 1)-Step(197, 47), &HFFBABABA, BF
    fc~& = _DefaultColor: bc~& = _BackgroundColor ' save color before we chnge
    Color _RGB32(0, 0, 0), &HFFBABABA
    _PrintString (x + 100 - 4 * Len(s$), y + 17), s$
    Color fc~&, bc~& ' restore color
End Sub

'this works pretty good for a menu of buttons to get menu number
Function getButtonNumberChoice% (choice$())
    'this sub uses drwBtn
    ub = UBound(choice$)
    lb = LBound(choice$)
    For b = lb To ub '  drawing a column of buttons at _width - 210 starting at y = 10
        drwBtn _Width - 210, b * 60 + 10, choice$(b)
    Next
    Do
        While _MouseInput: Wend
        mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
        If mb Then
            If mx > _Width - 210 And mx <= _Width - 10 Then
                For b = lb To ub
                    If my >= b * 60 + 10 And my <= b * 60 + 60 Then
                        Line (_Width - 210, 0)-(_Width, _Height), bColor, BF
                        ' delay before exit to give user time to release mouse button
                        getButtonNumberChoice% = b: _Delay .25: Exit Function
                    End If
                Next
                Beep
            Else
                Beep
            End If
        End If
        _Limit 60
    Loop
End Function

Modify so:
1. the buttons are stacked one above the other to fit more
2. add a parameter xAcross to designate the column to run the buttons down from
3. save the screen section before menu is displayed, display menu then replace the screen section with saved image
b = b + ...
Reply
#29
Hi Minerva - my apologies to bplus if I gave the impression that I did not read his example or run them. I do eagerly read and run the code and always find something new that I hadn't thought of before. Thanks b+.

I have worked with a lot of menu styles, even tried to adopt some of those really interesting child window by Tempodi but I seem to always drift back to the efficiency of the Drop Drop. It reduces a lot of screen clutter of multiple displays of menus plus it provides a lot more of the screen to display results of the choices.  I'd like to think of myself as knowing how to program but I was sold on Qbasic and just looking over what's available in the language with QB64PE, I'm finding it a little confusing on the best way to use the new syntax/code with the underscore (ie _Delay) and if the various  underscored Screen stuff ( ie _Screenhide, _Screenshow) along with defining a window may be a new way to create and place a drop down menu.

Love the comment on killing animation.
Reply
#30
(06-24-2023, 08:40 PM)bplus Wrote: Sorry @Dimster I was a little off about drop downing, instead my focus was on doing multiple input which is handy for filling out a database form. Never did much with drop down menus but mnrvovrfc is right about using a string array and setting up your code so what you do come up with for drop downs can be reused again in other apps. 

@TerryRitchie this might be a topic for Game Programming (I just did a quick scan for it and came up empty).
I swear I remember seeing menu code of yours sometime ago, maybe mistaken. 

I will dig around my files.
Yes, I have a menu library. If it's not in my library section I'll get it up shortly.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply




Users browsing this thread: 17 Guest(s)