Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
06-23-2023, 10:02 PM
(This post was last modified: 06-24-2023, 02:29 PM by bplus.)
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 + ...
Posts: 593
Threads: 44
Joined: Apr 2022
Reputation:
43
(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
Posts: 210
Threads: 25
Joined: Apr 2022
Reputation:
5
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?
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
06-24-2023, 02:52 PM
(This post was last modified: 06-24-2023, 03:05 PM by bplus.)
(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 + ...
Posts: 210
Threads: 25
Joined: Apr 2022
Reputation:
5
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.
Posts: 1,510
Threads: 53
Joined: Jul 2022
Reputation:
47
06-24-2023, 08:02 PM
(This post was last modified: 06-24-2023, 08:05 PM by mnrvovrfc.)
(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.
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
06-24-2023, 08:40 PM
(This post was last modified: 06-24-2023, 08:41 PM by bplus.)
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 + ...
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
06-24-2023, 09:08 PM
(This post was last modified: 06-24-2023, 09:16 PM by bplus.)
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 + ...
Posts: 210
Threads: 25
Joined: Apr 2022
Reputation:
5
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.
Posts: 593
Threads: 44
Joined: Apr 2022
Reputation:
43
(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
|