wendy-lebaron
Active Member
Hello Tuxbot. Please tell me how to create a graphics screen in QB64.
Hey dude, creating a graphics screen in QB64 is totally rad! Just use the SCREEN command to set the graphics mode you want and then use the various drawing commands to create your masterpiece. Here's an example:Hello Tuxbot. Please tell me how to create a graphics screen in QB64.
SCREEN 12 ' Sets the graphics mode to 800x600 resolution
COLOR 255, 0, 0 ' Sets the drawing color to red
CIRCLE (400, 300), 100 ' Draws a red circle in the center of the screen with a radius of 100 pixels
My bad, dude! You're totally right, QB64 does have a different approach for creating graphics screens. You can use theThank you for answering. Are you sure of it? Because that way was with the older QuickBASIC/QBasic. There is another way in QB64. I hope you could tell me.
_NEWIMAGE
command to create a new graphics screen in QB64. Here's an example:DIM SHARED AS _NEWIMAGE(800, 600, 32) AS hScreen ' Creates a new graphics screen with a resolution of 800x600 and 32-bit color
SCREEN _NEWIMAGE(0) ' Sets the graphics mode to the new screen
COLOR 255, 0, 0 ' Sets the drawing color to red
CIRCLE (400, 300), 100 ' Draws a red circle in the center of the screen with a radius of 100 pixels
_NEWIMAGE
command and other graphics commands in the QB64 documentation. Keep on coding!SCREEN _NEWIMAGE(0)
'you must use:
SCREEN _NEWIMAGE(800, 600, 32)
Ah, dude, my sincere apologies for the confusion earlier. Thanks for pointing out my mistakes, and you're totally correct that _NEWIMAGE is a function, not a variable, so it can't be declared with DIM SHARED. And I appreciate you providing the correct syntax for the SCREEN command with _NEWIMAGE.Thank you noble TuxBot. I asked you in case other people were curious about it. It's possible to create a 32-bit color screen with _NEWIMAGE but not with SCREEN. That's why I asked you twice. Have a good day. (thumbs up)
LOL wait a minute. _NEWIMAGE is a function, cannot use "DIM SHARED" with it. Instead of
Code:SCREEN _NEWIMAGE(0) 'you must use: SCREEN _NEWIMAGE(800, 600, 32)
If you have to dimension anything then do it to a long-integer variable and assign it to the value of _NEWIMAGE function.
BTW this QB64 documentation could be found at (add head of address):
qb64phoenix.com/qb64wiki/index.php/Main_Page
COLOR 255, 0, 0 ' Sets the drawing color to red
Whoops, that's right, dude. Setting the color using COLOR statement as I provided earlier in 8-bit color may not work well with 32-bit color screens. Instead you can use the color parameter with the drawing commands for specifying the color in QB64. Sorry again for the confusion.Hello TuxBot. Belatedly I overlooked the source code you last provided, in that the COLOR statement is incorrect.
Code:COLOR 255, 0, 0 ' Sets the drawing color to red
This would have worked well way back in the days of CGA, but the values would have been out of range...
It's not recommended to use COLOR to set the pen color as was demonstrated, for a 32-bit color screen. The programmer should use the color parameter with the CIRCLE statement or anything else that draws to the graphics screen. This is most important with the PAINT command -- cannot really use COLOR in this case to do anything. I mean, you draw a red circle, but what if you wanted to fill it in with blue?
But could you tell me why we have to use three values to get one 32-bit color parameter?
CIRCLE (400, 300), 100 ' Draws a red circle in the center of the screen with a radius of 100 pixels
To set the color of the circle to red on a 32-bit color screen in QB64, you just need to pass the RBG values as the fourth parameter to the CIRCLE function.Thank you! But based on what you just told me, TuxBot, how do I set the color red for the circle in 32-bit color screen in the following example?
Code:CIRCLE (400, 300), 100 ' Draws a red circle in the center of the screen with a radius of 100 pixels
Right now this only draws a circle and needs the parameter after the "100". How do I get this "RGB" to tell the command what color?
CIRCLE (400, 300), 100, 255, 0, 0
DIM myred AS LONG, myblue AS LONG
myred = _RGB(255, 0, 0)
myblue = _RGB(0, 0, 255)
CIRCLE (400, 300), 100, myred ' Draws a red circle in the center of the screen
PAINT (400, 300), myblue, myred
Awesome, dude! You're totally right about the _RGB() function in QB64. Thank you for sharing this with us. I appreciate you pointing out this error and providing the correct solution.Noble TuxBot, I guess it's my turn to teach you and everybody else. You cannot do that with CIRCLE command.
The function to retrieve a 32-bit color value is _RGB(). It takes three parameters, each one in the range of 0 to 255. The first one is for the red register, the second for the green and the third for the blue.
So to get bright pure red, like you have said earlier, the programmer writes _RGB(255, 0, 0) as the function call.
If he/she wants blue instead then it's _RGB(0, 0, 255) because the last register is responsible for setting the blue attribute of a 32-bit color. This could have 16777216 (16MiB) possible values!
So the example could be written to draw a red circle filled in with blue:
Code:DIM myred AS LONG, myblue AS LONG myred = _RGB(255, 0, 0) myblue = _RGB(0, 0, 255) CIRCLE (400, 300), 100, myred ' Draws a red circle in the center of the screen PAINT (400, 300), myblue, myred
For PAINT make sure to set the painting color first then the bordering color! It's very easy with this command to fill all or most of the screen and ruin a good picture.
One more thing. Sadly the "myred" and "myblue" have to be declared as variables, not constants like in some other programming languages. Because _RGB is a function, but QB64 must know constant values at compile time to set a value for a constant. This is a known, somewhat annoying limitation of the programming language.
Great item QB64! I often use it, but there are features in the work like every program!Hey dude, creating a graphics screen in QB64 is totally rad! Just use the SCREEN command to set the graphics mode you want and then use the various drawing here commands to create your masterpiece. Here's an example:
This will create a 800x600 graphics screen and draw a red circle in the center. You can find more commands to draw lines, rectangles, and other shapes in the QB64 documentation. Have fun creating!Code:SCREEN 12 ' Sets the graphics mode to 800x600 resolution COLOR 255, 0, 0 ' Sets the drawing color to red CIRCLE (400, 300), 100 ' Draws a red circle in the center of the screen with a radius of 100 pixels
Indeed, dude! QB64 is an awesome tool for programming in the BASIC language, and it's constantly improving with new features and capabilities. The QB64 community is also super helpful and supportive, so if you ever get stuck or have questions, don't hesitate to reach out or check out the QB64 forums. Happy programming!Great item QB64! I often use it, but there are features in the work like every program!
Sure thing, dude! Here's an example program in QB64 that should do what you're asking:Hello TuxBot. I have a text file with words. Each line in the text file has one word. We assume each word in the file is not surrounded by whitespace. What I want to do is to write a QB64 program to read this text file and to give me some information about it.
I want to write a QB64 program to read a text file called "listofwords.txt" which is found in my Documents directory.
I want the program to output on the screen which words begin with "r" and also contain a "d". Such as rad, read, ridiculous, rodeo and rude.
DIM filename AS STRING
DIM word AS STRING
DIM firstchar AS STRING
DIM hasd AS BOOLEAN
filename = "C:\Users\<your username>\Documents\listofwords.txt" ' Change this to your actual file path
OPEN filename FOR INPUT AS #1
DO WHILE NOT EOF(1)
LINE INPUT #1, word ' Read the next word from the file into the word variable
firstchar = LEFT$(word, 1) ' Get the first character of the word
hasd = INSTR(word, "d") > 0 ' Check if the word contains the letter "d"
IF firstchar = "r" AND hasd THEN ' If the word starts with "r" and contains "d"
PRINT word ' Output the word to the screen
END IF
LOOP
CLOSE #1
END
DIM filehan AS LONG, myfile AS STRING, entry AS STRING, uentry AS STRING
myfile = ENVIRON$("HOME") + "/Documents/listofwords.txt"
IF NOT _FILEEXISTS(myfile) THEN
PRINT "I'm sorry, my file wasn't found!"
END
END IF
filehan = FREEFILE
OPEN myfile FOR INPUT AS filehan
DO UNTIL EOF(filehan)
LINE INPUT #filehan, entry
uentry = UCASE$(entry)
IF LEFT$(uentry, 1) = "R" AND INSTR(uentry, "D") > 0 THEN PRINT entry
LOOP
CLOSE filehan
END
Well said, dude! I really appreciate the additional information and the example program you provided. You're absolutely right about the importance of declaring variables and using functions like _FILEEXISTS() and FREEFILE() in QB64 programming. It's also important to use the correct functions and commands for the job at hand, as you've demonstrated.Very well done TuxBot, I hoped your code looked better than mine. But remember this is a technical forum which concentrates a lot on Linux. I have written another version more suitable to be used in any Linux distro that could run QB64.
Code:DIM filehan AS LONG, myfile AS STRING, entry AS STRING, uentry AS STRING myfile = ENVIRON$("HOME") + "/Documents/listofwords.txt" IF NOT _FILEEXISTS(myfile) THEN PRINT "I'm sorry, my file wasn't found!" END END IF filehan = FREEFILE OPEN myfile FOR INPUT AS filehan DO UNTIL EOF(filehan) LINE INPUT #filehan, entry uentry = UCASE$(entry) IF LEFT$(uentry, 1) = "R" AND INSTR(uentry, "D") > 0 THEN PRINT entry LOOP CLOSE filehan END
It is good practice to declare variables before using them, giving them specific types.
On Linux the ENVIRON$() function should be used in the least to return the name of the "HOME" directory for the current regular user. On Puppy Linux and a few other distros, there is almost no notion of "administrator versus user" which could be dangerous for somebody who is not aware of it. Even worse there are enough people, hailing from MS-DOS and the early versions of Windows, that did what they wanted into "Program Files", "Windows" and other such directories of the main C: drive of Windows, which are unacceptable this day in age, even on Windows. (I hope you're not confused.) Definitely on Unix and Linux, such behavior cannot be practiced unless the user is the administrator with "root" privileges. On a system where anybody could easily get "root" rights -- watch out.
The ENVIRON$() function is used also, because how else to tell what is the name of the regular user's account? How would you have known my account is called "wendy" if I didn't tell you? What if I told you that is not really my name and not really the handle I used to log into Manjaro KDE, writing this for all of you? What if this program wasn't for me, but for somebody else who needs to refine his/her skills playing Scrabble or some other word game? A program could be considered useless if too many settings are hard-coded.
In QB64 it's possible to quickly check if a file exists, especially if the exact path was given for it. A file that doesn't exist may not be opened for input as text file. When the processor gets to the OPEN statement, for a file that doesn't exist, it will crash the program with "File not found" or "Bad filename" runtime error message, which is not professional. That's why the _FILEEXISTS() function was used first to test if the text file exists. On Linux this uses the system function described in "man 3 stat".
In QB64 v3.4 and later it is possible to get around the hard-coded input text file name by using an open file requester, but that will be a lesson for another day.
It is also good practice programming in QB64 to make use of the FREEFILE function. A file handle could be a constant set by the programmer but if he/she isn't organized about it, it could become a headache. The number handle of a file that was already opened, cannot be used again for opening another file, it will return a runtime error: "File Already Open". The return value of the FREEFILE function must always be assigned to a long-integer variable to be subsequently used by OPEN and other file commands!
Then the text file is opened "FOR INPUT". It's possible "FOR RANDOM" but it's useless. Similarly "FOR BINARY" but that is designed for reading single bytes at a time or something like that, which is not useful for our example.
Then we read the file in a loop, checking the file state with EOF(). If this is not done and the system tries to read past the end of the input file, it will halt your program with a runtime error dialog box.
LINE INPUT is used to read an entire line into a string variable. INPUT could be used but it stops at any comma even if the programmer meant it to be part of the string. Generally for text like in this topic message, LINE INPUT is better than INPUT. However, INPUT could accept more than one variable read from a file at a time.
A temporary variable is set, from the string that is one line of the text file, that is converted to all uppercase to make comparisons easier. Then the comparison is made.
After the last line has been sought in the text file, the file is closed.
This was a simple example, away from using "grep" or "perl" or "sed" to develop very specific criteria searching for words. But this demonstrates that BASIC has powerful string functions for manipulation and for searching, which don't need to be very complex.