QB64.org Forum

Active Forums => Programs => Topic started by: SierraKen on August 09, 2019, 03:10:54 pm

Title: Help with Starfield
Post by: SierraKen on August 09, 2019, 03:10:54 pm
I've put hours and hours of time in my life to trying to make a starfield over the years. Like the kind that you see in Star Trek or Star Wars with the stars flying toward you.
Once in awhile I dive into it to see if I can think of any new thoughts about it. And what I have here might not ever work. But I'm just wondering about one error message it says. Why does it say "Subscript Out of Range" when have DIMed the variables plenty enough? If any of you know about another Starfield I can learn by, that would be great! I've looked on Google and can't seem to find one although it does say people have made them. Anyway, I'm stuck with this error message for now.
Code: QB64: [Select]
  1. DIM x(2000), y(2000), dx(2000), dy(2000)
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. st = 1
  4. x(st) = INT(RND * 200) + 300
  5. IF x(st) < 400 THEN dx(st) = -1
  6. IF x(st) > 399 THEN dx(st) = 1
  7. y(st) = INT(RND * 200) + 200
  8. IF y(st) < 300 THEN dy(st) = -1
  9. IF y(st) > 299 THEN dy(st) = 1
  10. go:
  11. a$ = INKEY$
  12. IF a$ = CHR$(27) THEN END
  13. stars = INT(RND * 1000) + 1
  14. IF stars > 999 THEN
  15.     st = st + 1
  16.     IF st > 1000 THEN st = 2
  17.     x(st) = INT(RND * 200) + 300
  18.     IF x(st) < 400 THEN dx(st) = -1
  19.     IF x(st) > 399 THEN dx(st) = 1
  20.     y(st) = INT(RND * 200) + 200
  21.     IF y(st) < 300 THEN dy(st) = -1
  22.     IF y(st) > 299 THEN dy(st) = 1
  23. x(st) = x(st) + dx(st)
  24. y(st) = y(st) + dy(st)
  25. IF x(st) > 800 OR x(st) < 0 OR y(st) > 600 OR y(st) < 0 THEN GOTO go:
  26. LINE (x(st), y(st))-(x(st) + 3, y(st + 3)), rgb32(255, 255, 255), BF
  27. _DELAY .05
  28. LINE (x(st), y(st))-(x(st) + 3, y(st + 3)), rgb32(0, 0, 0), BF
  29. GOTO go:
  30.  
Title: Re: Help with Starfield
Post by: SierraKen on August 09, 2019, 03:26:30 pm
Actually I just dug one up that someone made from 1996. It has a lot of geometry in it that I won't understand. I'm just looking to make a basic one.
But if you are interested, here it is... I put a _LIMIT command on the loop.

Code: QB64: [Select]
  1. '---------------------------------------------------------------------------
  2.  
  3. '|                            Star Field 1.1                               |
  4.  
  5. '|                A first-person view of flying in space.                  |
  6.  
  7. '|                                                                         |
  8.  
  9. '|                            October 1996                                 |
  10.  
  11. '|                                  by                                     |
  12.  
  13. '|             William Travis Jones  /  wtjones@cswnet.com                 |
  14.  
  15. '|                                                                         |
  16.  
  17. '|                                                                         |
  18.  
  19. '|          Keyboard layout: None, just press a key to quit.               |
  20.  
  21. '|                   Several things are customizable.                      |
  22.  
  23. '|                            Tab Stops: 3                                 |
  24.  
  25. '---------------------------------------------------------------------------
  26.  
  27.  
  28.  
  29. '     As I got more and more hooked on QBASIC, I always wondered how to make
  30.  
  31. 'one of those zooming star animations like the Windows screen savers:
  32.  
  33. '"Flying Windows" and "Flying Through Space". I could study it all
  34.  
  35. 'I wanted, but the fact was I didn't understand how they got the
  36.  
  37. 'values for each of the stars as they moved. I knew that each time through
  38.  
  39. 'the loop, I could: alter the x value, the y value, or both. The screen saver
  40.  
  41. 'went against my current (at the time) knowledge of not just BASIC, but
  42.  
  43. 'programming in general.
  44.  
  45. '     From looking at the screen savers closely, you can easily tell that
  46.  
  47. 'each star(or logo) has a focal point and then moves in a straight line
  48.  
  49. 'outward in each loop.
  50.  
  51. 'The QBASIC LINE statement does the same thing, but wont let you get the
  52.  
  53. 'value of each pixel, which is what I needed.
  54.  
  55. '     I figured the way Microsoft did the screen savers was probably from a
  56.  
  57. 'simple calculation, and that most if not all programs that did similar point
  58.  
  59. 'movement used the same formula. I just needed to find it.
  60.  
  61. '     I posted on comp.sys.lang.basic a request of how to make a point
  62.  
  63. 'rotate around another. Soon after, someone emailed me a small program that
  64.  
  65. 'made a small circle rotate around in another in the center. Thanks Brennen
  66.  
  67. 'Bearnes!
  68.  
  69. '  The source was very easy to understand, except for the
  70.  
  71. 'fact that it uses sine and cosine. I really didn't understand
  72.  
  73. 'what that mean't, and I still don't know to tell you the truth. So
  74.  
  75. 'far I can tell that the program uses sine and cosine to
  76.  
  77. 'emulate the radius of a circle. All I do can pass it: the angle ,x and y
  78.  
  79. 'of the center point(not nesessarily the center of the screen), and the
  80.  
  81. 'radius to get the x and y coordinites of whatever point I need. The
  82.  
  83. 'points in this program are of course the stars. I should stop babbling and
  84.  
  85. 'start with the code...
  86.  
  87. '---------------------------------------------------------------------------
  88.  
  89. '  Update... 1.1 is MUCH faster! It loads the sine and cosine tables into
  90.  
  91. 'memory for a huge speed boost of about 80% or maybe more. I can now make
  92.  
  93. 'all variable integers except I use single precision floating-point
  94.  
  95. 'variables for the tables. I will give Brent P. Newhall credit for the
  96.  
  97. 'table creation code. This version runs uncompiled almost as fast as M/K's
  98.  
  99. 'StarWarp 1.2 in compiled form! (Not trying to be competitive, being theirs
  100.  
  101. 'is in 640*480 and has the stars seem to come from a more distant
  102.  
  103. 'starting point for realism.)
  104.  
  105. '  Each star is reset at or near the middle after reaching a certian radius.
  106.  
  107. 'the downside is that sometimes stars are getting caculated and drawn even
  108.  
  109. 'if they are offscreen. I am working on a version that checks if the stars
  110.  
  111. 'are out of the 320*200 area and then resets them. There are a few problems
  112.  
  113. 'with it, but I will figure it out.
  114.  
  115.  
  116.  
  117. DEFINT A-Z 'now n is not the only integer variable
  118.  
  119. DIM SHARED cosine(0 TO 359) AS SINGLE, sine(0 TO 359) AS SINGLE
  120.  
  121.  
  122.  
  123. PRINT "Creating tables..."
  124.  
  125. FOR n = 0 TO 359
  126.  
  127.     cosine(n) = COS(n * 3.14159 / 180)
  128.  
  129.     sine(n) = SIN(n * 3.14159 / 180)
  130.  
  131.  
  132.  
  133.  
  134. TYPE star 'data type for a star
  135.  
  136.     x AS INTEGER
  137.  
  138.     y AS INTEGER
  139.  
  140.     angle AS INTEGER '360 possible values
  141.  
  142.     radius AS INTEGER 'distance from the center
  143.  
  144.     speed AS INTEGER 'amount of pixels to jump
  145.  
  146.  
  147. CONST tou = 250 'total number of stars on the outer part
  148.  
  149. CONST tin = 50 'total number of stars in the inner part
  150.  
  151. CONST centx = 160, centy = 100
  152.  
  153. CONST true = -1, false = NOT true
  154.  
  155. CONST clrdgry = 8, clrlgry = 7, clrwht = 15 'color constants
  156.  
  157. CONST activepage = 1, visualpage = 0, blankpage = 2
  158.  
  159. DIM outer(1 TO tou) AS star
  160.  
  161. DIM inner(1 TO tin) AS star
  162.  
  163.  
  164. 'these two loops give all the stars starting positions
  165.  
  166. FOR n = 1 TO tou
  167.  
  168.     outer(n).radius = INT(RND * 180) + 30 'at least 30 pixels from center
  169.  
  170.     outer(n).angle = INT(RND * 360)
  171.  
  172.     outer(n).speed = 1
  173.  
  174.  
  175. FOR n = 1 TO tin
  176.  
  177.     inner(n).radius = INT(RND * 200) 'these can start anywhere
  178.  
  179.     inner(n).angle = INT(RND * 360)
  180.  
  181.     inner(n).speed = 1
  182.  
  183.  
  184. '320*200 @ 16 colors - I only use: black, white, and 2 shades of gray
  185.  
  186. SCREEN 7, , workpage, visiblepage 'show one page, but draw on another
  187.  
  188. '******************** {MAIN LOOP} ********************
  189.  
  190.     _LIMIT 50
  191.  
  192.     'calculate the stars with a pi generator
  193.  
  194.     GOSUB doouter
  195.  
  196.     GOSUB doinner
  197.  
  198.     PCOPY blankpage, activepage 'blank out the active page
  199.  
  200.     'draw the stars
  201.  
  202.     GOSUB updateouter
  203.  
  204.     GOSUB updateinner
  205.  
  206.     'LOCATE 12, 16: PRINT "Star Field": LOCATE 22, 17: PRINT "1996 WTJ"
  207.  
  208.     PCOPY activepage, visualpage 'copy the active page to the visual page
  209.  
  210.     SCREEN 7, , activepage, visualpage 'flip it
  211.  
  212.  
  213. '******************** {END MAIN LOOP} ********************
  214.  
  215.  
  216. '******************** {END PROGRAM} **********************
  217.  
  218.  
  219.  
  220. updateouter:
  221.  
  222. FOR n = 1 TO tou
  223.  
  224.     IF outer(n).radius > 75 THEN 'the closer the brighter
  225.  
  226.         PSET (outer(n).x, outer(n).y), clrlgry
  227.  
  228.     ELSE
  229.  
  230.         PSET (outer(n).x, outer(n).y), clrdgry
  231.  
  232.     END IF
  233.  
  234.  
  235.  
  236.  
  237.  
  238. updateinner:
  239.  
  240. FOR n = 1 TO tin
  241.  
  242.     IF inner(n).radius > 80 THEN 'the closer the bigger
  243.  
  244.         LINE (inner(n).x, inner(n).y)-(inner(n).x + 1, inner(n).y + 1), clrwht, B
  245.  
  246.     ELSE
  247.  
  248.         PSET (inner(n).x, inner(n).y), clrwht
  249.  
  250.     END IF
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. doouter:
  259.  
  260. FOR n = 1 TO tou
  261.  
  262.     IF outer(n).radius > 150 THEN 'put back in center
  263.  
  264.         outer(n).radius = INT(RND * 150) + 30
  265.  
  266.         outer(n).angle = INT(RND * 360)
  267.  
  268.         outer(n).speed = 1
  269.  
  270.     END IF
  271.  
  272.     IF outer(n).radius > 35 THEN outer(n).speed = 2
  273.  
  274.     IF outer(n).radius > 45 THEN outer(n).speed = 4
  275.  
  276.     IF outer(n).radius > 75 THEN outer(n).speed = 6
  277.  
  278.  
  279. FOR n = 1 TO tou
  280.  
  281.     outer(n).radius = outer(n).radius + outer(n).speed
  282.  
  283.     outer(n).x = centx + outer(n).radius * (cosine(outer(n).angle))
  284.  
  285.     outer(n).y = centy - outer(n).radius * (sine(outer(n).angle))
  286.  
  287.  
  288.  
  289.  
  290.  
  291. doinner:
  292.  
  293. FOR n = 1 TO tin
  294.  
  295.     IF inner(n).radius > 150 THEN 'put back in center
  296.  
  297.         inner(n).radius = INT(RND * 40)
  298.  
  299.         inner(n).angle = INT(RND * 360)
  300.  
  301.         inner(n).speed = 3
  302.  
  303.     END IF
  304.  
  305.     IF inner(n).radius > 15 THEN inner(n).speed = 4
  306.  
  307.     IF inner(n).radius > 45 THEN inner(n).speed = 8
  308.  
  309.     IF inner(n).radius > 75 THEN inner(n).speed = 10
  310.  
  311.  
  312. FOR n = 1 TO tin
  313.  
  314.     inner(n).radius = inner(n).radius + inner(n).speed
  315.  
  316.     inner(n).x = centx + inner(n).radius * (cosine(inner(n).angle))
  317.  
  318.     inner(n).y = centy - inner(n).radius * (sine(inner(n).angle))
  319.  
  320.  
  321.  
  322.  
Title: Re: Help with Starfield
Post by: SMcNeill on August 09, 2019, 03:29:21 pm
https://www.qb64.org/forum/index.php?topic=1300.msg105528#msg105528 — here’s an example from the forums.
Title: Re: Help with Starfield
Post by: Petr on August 09, 2019, 03:31:22 pm
Hi. Rewrite rgb32 to _RGB32 (row 31, 33)
Title: Re: Help with Starfield
Post by: SierraKen on August 09, 2019, 03:41:19 pm
LOL Thanks guys! I had a feeling it was a simple mistake on a command. Of course the program still doesn't work but I'll look more into it later and also check out SmMcNeill's link later today. Thanks again.
Title: Re: Help with Starfield
Post by: OldMoses on August 09, 2019, 06:35:57 pm
I'm not saying it can't be done without trig (ala sine & cosine), but I would say that it would be much harder without it. Even doing the trig math in the loop, I would expect QB64 to be fast enough that you would have to slow it down with _LIMIT for a pleasing effect. Depending, of course, on how many stars you are plotting.

The geometry of trig is not terribly complex, it just takes some getting used to in order to be comfortable with what it will do for you. The recent tutorial that Steve uploaded is a really good explanation of how it works.

https://www.qb64.org/forum/index.php?topic=1583.msg108049#msg108049

The space vector simulator that I've been working on is not a star field generator but it makes extensive use of sine and cosine functions. I have two library routines that I use:

Code: QB64: [Select]
  1. FUNCTION SinCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  2.  
  3.     'Polar coordinate X finder
  4.     'used to find X coordinate of a speed/distance (var1) and heading/azimuth (var2) in degrees
  5.     SinCalc = var1 * SIN(_D2R(var2))
  6.  
  7. END FUNCTION 'SinCalc
  8.  
  9. FUNCTION CosCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  10.  
  11.     'Polar coordinate Y finder
  12.     'used to find Y coordinate of a speed/distance (var1) and heading/azimuth (var2) in degrees
  13.     CosCalc = var1 * COS(_D2R(var2))
  14.  
  15. END FUNCTION 'CosCalc
  16.  

BTW, var1 in the above examples does not necessarily have to be _INTEGER64, that's just what I need in my particular application as it is working with insanely large kilometer distances.

I set up a WINDOW with x,y that ranges from negative to positive coordinates, like:

    VIEW (1, 1)-(618, 618), background color, border color if any '                  set graphics port square window
    WINDOW (-1000, 1000)-(1000, -1000) '                        set relative cartesian coords 2000x2000 here, but any can be used

at which point the origin 0,0 is at the center of the screen, or you could just use a relative offset value in the calculations if you prefer. Then as you update star positions you just plug in the angle direction and the speed or distance into the functions. Sine gives you your new X position and Cosine gives you your new Y position as the program iterates through your loop.

It's well worth the study, as it can be the basis for drawing all sorts of radial features, compass faces, clock faces, etc.
Title: Re: Help with Starfield
Post by: bplus on August 09, 2019, 09:07:59 pm
The extended conversation of Starfields was here:
https://www.qb64.org/forum/index.php?topic=1146.msg103395;topicseen#msg103395

And tonight I discover moving through a star field is an awful lot like an explosion, only there is a hole in the middle and all the particles are scattered about the center when they come to view:

Starfield in 50!
Code: QB64: [Select]
  1. _TITLE "Starfield press Up / Down Arrows" '2019-08-09 B+"
  2. 'created from Simple explosion but put "hole" in middle and scatter start locations
  3. SCREEN _NEWIMAGE(720, 720, 32) 'need a graphics screen for graphics
  4. _SCREENMOVE 100, 10 'so bplus can view screen past his tool bar on left
  5. DIM n, p, speed, kh AS LONG
  6. n = 60 'number of stars
  7. DIM SHARED x(n), y(n) 'star location x, y
  8. DIM SHARED dx(n), dy(n) 'traveling in x, y vectors dx, dy (the change in x direction and the change in y direction)
  9.  
  10. FOR p = 0 TO n
  11.     newStar p
  12. speed = 100
  13. WHILE kh <> 27 'while no escape key pressed
  14.     kh = _KEYHIT
  15.     IF kh = 18432 AND speed < 200 THEN speed = speed + 20
  16.     IF kh = 20480 AND speed > 40 THEN speed = speed - 20
  17.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 30), BF 'only semi black out screen, this effect is so cool!!!!
  18.     FOR p = 0 TO n 'show star by looping through the bunch
  19.         CIRCLE (x(p), y(p)), dx(p)
  20.         IF ABS(dx(p)) >= 1 THEN PAINT (x(p), y(p)), &HFFFFFFFF, &HFFFFFFFF
  21.         'update each star location
  22.         dx(p) = 1.04 * dx(p) 'accel as get closer
  23.         x(p) = x(p) + dx(p) 'change x position
  24.         dy(p) = 1.04 * dy(p) ' increase accel as get closer
  25.         y(p) = y(p) + dy(p) 'change y position
  26.         IF y(p) < -2 OR y(p) > _HEIGHT + 2 THEN newStar p 'replace stars going off screen with new ones
  27.         IF x(p) < -2 OR x(p) > _WIDTH + 2 THEN newStar p
  28.     NEXT
  29.     LOCATE 1, 1: PRINT SPACE$(20)
  30.     LOCATE 1, 1: PRINT "Warp "; speed \ 20
  31.     _DISPLAY 'this so screen wont flicker
  32.     _LIMIT speed 'this needs to go faster than explosion
  33.  
  34. SUB newStar (p)
  35.     DIM d, dist
  36.     'select a random angle = direction to go
  37.     d = 360 * RND 'direction in degrees is a random number from 0 to 360
  38.     dist = 360 * RND + 15 'some distance from around center
  39.     'star location to start
  40.     x(p) = _WIDTH / 2 + dist * COS(_D2R(d))
  41.     y(p) = _HEIGHT / 2 + dist * SIN(_D2R(d))
  42.     'as stars get closer they will speed up so start them all a 1
  43.     'the following calculates the x component of the star vector , the change the star will make along the x axis
  44.     dx(p) = 1 * COS(_D2R(d)) ' _D2R converts our random direction in degrees to radians for COS to process
  45.     'the following calculates the y component of the star vector , the change the star will make along the y axis
  46.     dy(p) = 1 * SIN(_D2R(d)) ' _D2R converts our random direction in degrees to radians for SIN to process
  47.  
Title: Re: Help with Starfield
Post by: STxAxTIC on August 09, 2019, 09:13:28 pm
Trigless starfield:

Code: QB64: [Select]
  1.  
  2. TYPE particle
  3.     x AS DOUBLE
  4.     y AS DOUBLE
  5.     vx AS DOUBLE
  6.     vy AS DOUBLE
  7.  
  8. num = 1000
  9. DIM star(num) AS particle
  10.  
  11. FOR k = 1 TO num
  12.     GOSUB makestar
  13.  
  14. dt = .01
  15.     CLS
  16.     FOR k = 1 TO num
  17.         star(k).x = star(k).x + star(k).vx * dt
  18.         star(k).y = star(k).y + star(k).vy * dt
  19.         r2 = star(k).x * star(k).x + star(k).y * star(k).y
  20.         IF (r2 > 400 ^ 2) THEN GOSUB makestar
  21.         PSET (star(k).x + _WIDTH / 2, -star(k).y + _HEIGHT / 2), 15
  22.     NEXT
  23.     _LIMIT 60
  24.     _DISPLAY
  25.  
  26. makestar: 'requires k
  27. star(k).x = (RND - .5) * _WIDTH
  28. star(k).y = (RND - .5) * _HEIGHT
  29. v = 5 + RND * 5
  30. star(k).vx = star(k).x * v
  31. star(k).vy = star(k).y * v
Title: Re: Help with Starfield
Post by: OldMoses on August 09, 2019, 10:34:10 pm
Trigless starfield:

I think I stand corrected. That's a really cool effect.
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 12:02:42 am
Well, nobody's perfect. I've looked at the codes, tried to understand, but haven't learned a lot about many commands like TYPE as well as the math that's above my head. Oh well, at least we got some great starfields from this thread. I will just have to gain more knowledge later on by practicing more. The best I can do is make 1 star move at you at a time. Here is where I got to. And I know why it's not working because my programs are VERY 2 dimensional with my thinking. It's almost like I need a variable inside a variable inside a variable LOL.

Code: QB64: [Select]
  1. _LIMIT 100
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. GOSUB go3:
  4. go2:
  5. x = x + dx
  6. y = y + dy
  7. IF x > 799 OR x < 0 OR y > 599 OR y < 0 THEN GOSUB go3:
  8. FOR s = .25 TO 3 STEP .25
  9.     CIRCLE (x, y), s, _RGB32(255, 255, 255)
  10. _DELAY .01
  11. FOR s = .25 TO 3 STEP .25
  12.     CIRCLE (x, y), s, _RGB32(0, 0, 0)
  13. t = t + 1
  14. IF t > 500 THEN GOSUB go3:
  15. GOTO go2:
  16.  
  17. go3:
  18. t = 0
  19. x = INT(RND * 300) + 200
  20. y = INT(RND * 200) + 200
  21. IF x > 400 THEN dx = 1
  22. IF x < 401 THEN dx = -1
  23. IF y > 300 THEN dy = 1
  24. IF y < 299 THEN dy = -1
  25.  
  26.  

Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 12:39:14 am
Well here is STxAxTIC's code without TYPE and on a proper screen to do the cool effect:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(500, 500, 32)
  2.  
  3. num = 1000
  4.  
  5. DIM x(num), y(num), dx(num), dy(num)
  6. FOR k = 1 TO num
  7.     GOSUB makestar
  8.  
  9. dt = .01
  10.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  11.     FOR k = 1 TO num
  12.         x(k) = x(k) + dx(k) * dt
  13.         y(k) = y(k) + dy(k) * dt
  14.         r2 = x(k) * x(k) + y(k) * y(k)
  15.         IF (r2 > 400 ^ 2) THEN GOSUB makestar
  16.         PSET (x(k) + _WIDTH / 2, -y(k) + _HEIGHT / 2), _RGB32(255, 255, 255)
  17.     NEXT
  18.     _LIMIT 60
  19.     _DISPLAY
  20.  
  21. makestar: 'requires k
  22. x(k) = (RND - .5) * _WIDTH
  23. y(k) = (RND - .5) * _HEIGHT
  24. v = 5 + RND * 5
  25. dx(k) = x(k) * v
  26. dy(k) = y(k) * v
  27.  
  28.  

So no Trig and no TYPE but he likes to graph things / locate things as offset from screen center and the r2 thing is about seeing if stars are 400 pixels away from center or out of bounds and time for a new Star.
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 01:33:39 am
Well, nobody's perfect. I've looked at the codes, tried to understand, but haven't learned a lot about many commands like TYPE as well as the math that's above my head. Oh well, at least we got some great starfields from this thread. I will just have to gain more knowledge later on by practicing more. The best I can do is make 1 star move at you at a time. Here is where I got to. And I know why it's not working because my programs are VERY 2 dimensional with my thinking. It's almost like I need a variable inside a variable inside a variable LOL.

Code: QB64: [Select]
  1. _LIMIT 100
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. GOSUB go3:
  4. go2:
  5. x = x + dx
  6. y = y + dy
  7. IF x > 799 OR x < 0 OR y > 599 OR y < 0 THEN GOSUB go3:
  8. FOR s = .25 TO 3 STEP .25
  9.     CIRCLE (x, y), s, _RGB32(255, 255, 255)
  10. _DELAY .01
  11. FOR s = .25 TO 3 STEP .25
  12.     CIRCLE (x, y), s, _RGB32(0, 0, 0)
  13. t = t + 1
  14. IF t > 500 THEN GOSUB go3:
  15. GOTO go2:
  16.  
  17. go3:
  18. t = 0
  19. x = INT(RND * 300) + 200
  20. y = INT(RND * 200) + 200
  21. IF x > 400 THEN dx = 1
  22. IF x < 401 THEN dx = -1
  23. IF y > 300 THEN dy = 1
  24. IF y < 299 THEN dy = -1
  25.  
  26.  

Before working with whole screen of moving circles, study this for basic structure of animating, get one moving circle going, the rest will be way easier:

Code: QB64: [Select]
  1. _TITLE "BASIC Animation 101: Drawing a moving circle"
  2. SCREEN _NEWIMAGE(500, 500, 32)
  3.  
  4. 'initialize variables
  5. GOSUB newCircle
  6.  
  7. 'setup main loop
  8.  
  9.     CLS 'each loop around start by erasing everything
  10.  
  11.  
  12.     'now draw all your objects at their x, y location
  13.  
  14.     'here is a call to the sub circle fill
  15.     circleFill x, y, 10, _RGB32(0, 0, 255)
  16.  
  17.     'calculate the new location for everything
  18.     x = x + dx
  19.     y = y + dy
  20.  
  21.     'are we still inside the screen for everything?
  22.     IF x < 0 OR x > _WIDTH THEN GOSUB newCircle
  23.     IF y < 0 OR y > _HEIGHT THEN GOSUB newCircle
  24.  
  25.  
  26.     _DISPLAY ' stop flicker from  cls
  27.  
  28.     _LIMIT 60 'slow this sucker down so humans can see the action
  29.  
  30. LOOP UNTIL _KEYHIT = 27 'setup an exit
  31.  
  32. END 'dont let program execution go beyond this point
  33.  
  34. newCircle:
  35. x = RND * _WIDTH * 5 + _WIDTH * .25
  36. y = RND * _HEIGHT * 5 + _WIDTH * .25
  37. dx = RND * 10 - 5
  38. dy = RND * 10 - 5
  39.  
  40. ' this is very handy if circles don't overlap
  41. SUB circleFill (x, y, r, colr AS _UNSIGNED LONG)
  42.     CIRCLE (x, y), r, colr
  43.     IF r >= 1 THEN PAINT (x, y), colr, colr
  44.  
  45.  

EDIT: added radius check before painting for circleFill
Title: Re: Help with Starfield
Post by: OldMoses on August 10, 2019, 07:36:21 am
Here's one that doesn't use "much" trig, other than a reference to the Pythagorean theorem. Frankly, I'm a little surprised it worked.

It uses a 3D "space" to acheive an apparent movement effect, with more distant stars moving more slowly past the user's POV. Then scales it to a viewport ahead of the viewer's perspective.

It has a more sedate pace. You can change the speed variable if you want Scotty to give you warp 8. BTW, he hates doing that... ;)

Code: QB64: [Select]
  1. a& = _NEWIMAGE(600, 600, 32)
  2. TYPE star '                                                     define the star data type
  3.     x AS INTEGER
  4.     y AS INTEGER
  5.     z AS INTEGER
  6.     xa AS INTEGER
  7.     ya AS INTEGER
  8.  
  9. DIM SHARED max AS INTEGER: max = 500
  10. DIM SHARED vprt AS INTEGER: vprt = 600 '                        set the viewport setback from viewer's eye
  11. DIM SHARED p(max) AS star '                                     dimension the star data array
  12. DIM SHARED speed AS INTEGER: speed = 1 '                        warp factor
  13.  
  14. PopVoid '                                                       OldMoses said "Let there be light" and the universe was, is and ever shall be
  15. WINDOW (-300, 300)-(300, -300) '                                create viewport window, Cap'n Kirk spends his days staring at this
  16.  
  17. DO '                                                            draw the stars
  18.     CLS
  19.     FOR x = 1 TO max '                                          iterate through all stars
  20.         p(x).xa = p(x).x / Pythagorus(p(x)) * vprt '            get relative screen position from absolute position for x & y
  21.         p(x).ya = p(x).y / Pythagorus(p(x)) * vprt
  22.         IF ABS(p(x).xa) < 301 AND ABS(p(x).ya) < 301 THEN '     place the star if within the viewport
  23.             PSET (p(x).xa, p(x).ya)
  24.         END IF
  25.         p(x).z = p(x).z - speed '                               move the star closer to the viewer
  26.         IF p(x).z < 0 THEN ReplaceStar x '                      add new stars as existing ones go behind the viewer
  27.     NEXT x
  28.     _DISPLAY '                                                  eliminate screen flicker
  29.     _LIMIT 500 '                                                smooth out the action
  30.  
  31.  
  32. SUB PopVoid '                                                   Do an initial population of stars
  33.  
  34.     FOR x = 1 TO max '                                          place a 'max' # of stars randomly in a 3D space
  35.         RANDOMIZE TIMER
  36.         p(x).x = INT(RND * 5000) - 2500
  37.         p(x).y = INT(RND * 5000) - 2500
  38.         p(x).z = INT(RND * 5000) + 1
  39.     NEXT x
  40.  
  41. END SUB 'PopVoid
  42.  
  43.  
  44. FUNCTION Pythagorus (var1 AS star)
  45.  
  46.     'Use to find distance between two 3D points
  47.     'Also calculate speed of updated vectors
  48.  
  49.     DIM diff AS star
  50.     diff.x = ABS(var1.x)
  51.     diff.y = ABS(var1.y)
  52.     diff.z = ABS(var1.z)
  53.     horizontal = _HYPOT(diff.x, diff.y)
  54.     Pythagorus = _HYPOT(horizontal, diff.z)
  55.  
  56. END FUNCTION 'Pythagorus
  57.  
  58.  
  59. SUB ReplaceStar (var AS INTEGER) '                              This replaces any star that goes behind the viewer
  60.  
  61.     p(var).x = INT(RND * 5000) - 2500
  62.     p(var).y = INT(RND * 5000) - 2500
  63.     p(var).z = 5000
  64.  
  65. END SUB 'ReplaceStar
  66.  
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 10:27:20 am
Choice bite the bullet and learn some trig = how to use SIN and COS functions or go on being ignorant of some extremely useful tools for graphing.

If I want Ken to bite the bullet and learn SIN and COS use, I offer a quick tutorial on SIN and COS and apply it to Star Field creation and animation:

Here is my tutorial on SIN and COS use and applied to Star Field app.
Quote
about SIN and COS.txt 2019-08-10 B+

The first thing to know about SIN and COS functions used in BASIC is that they take Radian angles as arguments.

What is a Radian angle?
It is another unit of measure for angles expressed in terms of Pi. A circle is 2 * Pi radians, remember this one fact!
The more common unit of measure for angles is Degrees a circle is 360 Degrees.

Let us compare Degree angle measures with Radian measures:
A half circle is 360 Degrees / 2 = 180 Degrees,    a half circle in Radians is 2 * Pi / 2 = Pi
A forth circle is 360 Degrees / 4 = 90 Degrees,    a forth circle in Radians is 2 * Pi / 4 = Pi / 2 or 1/2 * Pi
A third circle is 360 Degrees / 3 = 120 Degrees,   a third circle in Radians is 2 * Pi / 3 = 2/3 * Pi
An nth of a circle is 360 / n Degrees,             an nth of a circle in Radians is 2 * Pi / n.

QB64 has a function _D2R(degreeAngle) that converts an angle measure from Degrees to Radians.
QB64 has a function that reverses that conversion _R2D that converts Radian angles to Degree angles.
QB64 also has a function for multiples of Pi = _PI(multiple), you can just use _PI if the multiple is 1.

In BASIC graphics:
0 Degrees or Radians are due East of the point in question often the center of the screen.
South is 90 Degrees or Pi / 2 Radians.
West is 180 Degrees or Pi Radians.
North is 270 Degrees or 3 / 2 * Pi.

Notice as Degrees or Radians increase you go Clockwise around a central point.



So what does SIN and COS have to do with programming, specially graphics?

Given some point (x, y) say the middle of the screen (_WIDTH / 2, _HEIGHT / 2),
say you want to know where a point(x, y) is that is 45 degrees SE of it and 100 pixels away.

These formula's will get you that point:
Lets call the coordinates for the center of the screen (xCenter, yCenter) often denoted (xc, yc) for short.
45 Degrees is 1/8 of circle or 2 * Pi / 8 ( a circle 2 * Pi divided 8 times)

x = xCenter + 100 * COS(2 * Pi / 8) 'plug in Radian values directly
y = yCenter + 100 * SIN(2 * Pi / 8)
or
x = xc + 100 * COS(_D2R(45)) ' let QB64 function do the conversion of 45 degrees to Radians
y = yc + 100 * SIN(_D2R(45))




Suppose we want to draw a Equilateral triangle about the center of the screen:
If you imagine 3 spokes coming out from center of screen to meet the 3 points of the triangle,
you can see that the points divide the circle evenly to 3 parts, angles are 2 * Pi / 3 in Radians.

The 3 points are 0, 1, and 2 multiples of the angle 2 * Pi / 3 = 0, 2/3 * Pi, 4/3 * Pi
(This is for an Equilateral Triangle that points dues East because the first point is at 0 Degrees = 0 Radians).
So the 6 calculations for the 3 points are (for Radius = R from center to Triangle point):
FOR i = 0 to 2
   x = xc + R * COS(i * _PI(2 / 3))
   y = yc + R * SIN(i * _PI(2 / 3))   
NEXT

Here is a quick little program to draw a triangle about the center of a screen:

Code: QB64: [Select]
  1.         SCREEN _NEWIMAGE(500, 500, 32)
  2.         DIM SHARED xc, yc    
  3.         xc = _WIDTH / 2 'middle of screen
  4.         yc = _HEIGHT / 2 ' middle of screen
  5.         R = 100
  6.         radianEquilateralAngle = _PI(2 / 3)
  7.         FOR i = 0 TO 3 ' we have to visit 4 points to return to place of start
  8.                 x = xc + R * COS(i * radianEquilateralAngle)
  9.                 y = yc + R * SIN(i * radianEquilateralAngle)
  10.                 IF i = 0 THEN PSET (x, y) ELSE LINE -(x, y)
  11.         NEXT
  12.         INPUT " Press enter to turn this triangle up! "; w$
  13.  
  14.         CLS
  15.         ' We can turn this triangle so that it points up
  16.         ' by adding 30 degrees = 2 * Pi / 12 Radians to the Angles in the SIN, COS functions.
  17.         FOR[co i = 0 TO 3 ' we have to visit 4 points to return to place of start
  18.                 'x = xc + R * COS(i * radianEquilateralAngle + _D2R(30))
  19.                 'y = yc + R * SIN(i * radianEquilateralAngle + _D2R(30))
  20.                 x = xc + R * COS(i * radianEquilateralAngle + _PI(2 / 12))
  21.                 y = yc + R * SIN(i * radianEquilateralAngle + _PI(2 / 12))
  22.                 IF i = 0 THEN PSET (x, y) ELSE LINE -(x, y)
  23.         NEXT

   
Now suppose we wish to create a Star Field about the center of the screen.
The center of the screen is important to build the stars around because to create the effect
of moving through the field we have to show the stars moving away from the center of the screen.

So we keep our xc, yc variables for the screen center and pick random angles and random distances to draw the stars.

   
'addition code added on for Star Field setup demo:
Code: QB64: [Select]
  1.         INPUT " Press enter to see demo of moving through Star Field "; w$
  2.         'Let the number of stars be:
  3.         nStars = 200
  4.  
  5.         ' Setup containers to save star data in, SHARE these containers for SUB access to them:
  6.         DIM SHARED starX(nStars), starY(nStars), starDX(nStars), starDY(nStars)
  7.  
  8.         'initialize the Stars with locations (x, y)
  9.         'and vectors dx, dy to represent the horizontal and vertical changes of the x and y axis
  10.         'they will be moving.
  11.  
  12.         ' Do this by writing a sub to do one star by it's index in the 4 star arrays.
  13.         ' See SUB newStar
  14.  
  15.         ' and then run newStars through a loop loading the star data containers with star info.
  16.         FOR i = 0 TO nStars
  17.                 newStar i
  18.         NEXT
  19.  
  20.         'setup main animation loop
  21.         DO
  22.                 CLS 'erase everything!
  23.                 'draw stars and update their location for next loop around unless they have moved beyond the screen
  24.                 FOR i = 0 TO nStars
  25.                         circleFill starX(i), starY(i), 1, _RGB32(255, 255, 255) 'draw it
  26.  
  27.                         'calc next frame loaction
  28.                         starX(i) = starX(i) + starDX(i)
  29.                         starY(i) = starY(i) + starDY(i)
  30.  
  31.                         ' are we still inside the screen? if not the make a new Star for the index i
  32.                         IF starX(i) < -2 OR starX(i) > _WIDTH + 2 THEN newStar i
  33.                         IF starY(i) < -2 OR starY(i) > _HEIGHT + 2 THEN newStar i
  34.                 NEXT
  35.                 _DISPLAY 'stop flicker from using CLS
  36.                 _LIMIT 100 ' nice even flow of frames and saves fan
  37.         LOOP UNTIL _KEYHIT = 27 'exit loop at esacoe key press
  38.  
  39.         SUB newStar (index)
  40.                 DIM rDegree, rDistance
  41.                 'setup stars by picking a random direction from the center of the screen and at a random distance
  42.                 'random direction = d in Degrees
  43.                 rDegree = RND * 360
  44.                 rDistance = RND * _WIDTH / 2 * SQR(2)
  45.  
  46.                 'using SIN and COS formulas for (x, y) about a center point
  47.                 'xc and yc are SHARED with main code
  48.                 starX(index) = xc + rDistance * COS(_D2R(rDegree))
  49.                 starY(index) = yc + rDistance * SIN(_D2R(rDegree))
  50.  
  51.                 'and the changes on x, y axis as stars move each  frame is
  52.                 starDX(index) = COS(_D2R(rDegree)) ' the change to the X coordinate
  53.                 starDY(index) = SIN(_D2R(rDegree)) ' the change to the Y coordinate
  54.         END SUB
  55.  
  56.         ' this is very handy if circles don't overlap
  57.         SUB circleFill (x, y, r, colr AS _UNSIGNED LONG)
  58.                 CIRCLE (x, y), r, colr
  59.                 IF r >= 1 THEN PAINT (x, y), colr, colr
  60.         END SUB
  61.  
  62.  
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 10:36:09 am
Here's my go at moving through a starfield; ala StarTrek warp drive:

Code: QB64: [Select]
  1. TYPE Dot_type
  2.     x AS _FLOAT
  3.     y AS _FLOAT
  4.     movex AS _FLOAT
  5.     movey AS _FLOAT
  6.     size AS _FLOAT
  7. DIM dots(10000) AS Dot_type
  8.  
  9.  
  10. SCREEN _NEWIMAGE(1024, 720, 32)
  11. WINDOW (-1000, -1000)-(1000, 1000)
  12.  
  13.  
  14. FOR x = -10 TO 10 'initialize dots
  15.     FOR y = -10 TO 10
  16.         dotsinplay = dotsinplay + 1
  17.         dots(dotsinplay).x = RND * 100 - 50
  18.         dots(dotsinplay).y = RND * 100 - 50
  19.         dots(dotsinplay).movex = RND * 10 - 5
  20.         dots(dotsinplay).movey = RND * 10 - 5
  21.         dots(dotsinplay).color = &HFF000000 + INT(RND * &HFFFFFF) + 1
  22.         dots(dotsinplay).size = RND * 5
  23.     NEXT
  24.  
  25.  
  26.  
  27.  
  28.     i = 1
  29.     DO 'move and replace dots which would go off screen
  30.         dots(i).x = dots(i).x + dots(i).movex
  31.         dots(i).y = dots(i).y + dots(i).movey
  32.         IF dots(i).x < -1000 OR dots(i).x > 1000 or _
  33.            dots(i).y < -1000 OR dots(i).y > 1000 THEN
  34.             dots(i).x = RND * 100 - 50
  35.             dots(i).y = RND * 100 - 50
  36.             dots(i).movex = RND * 10 - 5
  37.             dots(i).movey = RND * 10 - 5
  38.             dots(i).color = &HFF000000 + INT(RND * &HFFFFFF) + 1
  39.             dots(i).size = RND * 5
  40.         END IF
  41.         i = i + 1
  42.     LOOP UNTIL i >= dotsinplay
  43.     CLS
  44.     i = 1
  45.     DO 'display dots
  46.         CircleFill dots(i).x, dots(i).y, dots(i).size, dots(i).color
  47.         i = i + 1
  48.     LOOP UNTIL i >= dotsinplay
  49.     _DISPLAY
  50.  
  51. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  52.     ' CX = center x coordinate
  53.     ' CY = center y coordinate
  54.     '  R = radius
  55.     '  C = fill color
  56.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  57.     DIM X AS INTEGER, Y AS INTEGER
  58.     Radius = ABS(R)
  59.     RadiusError = -Radius
  60.     X = Radius
  61.     Y = 0
  62.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  63.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  64.     WHILE X > Y
  65.         RadiusError = RadiusError + Y * 2 + 1
  66.         IF RadiusError >= 0 THEN
  67.             IF X <> Y + 1 THEN
  68.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  69.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  70.             END IF
  71.             X = X - 1
  72.             RadiusError = RadiusError - X * 2
  73.         END IF
  74.         Y = Y + 1
  75.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  76.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  77.     WEND
  78.  
  79.  

No trig involved at all.  (Unless you count the CircleFill routine, and it can be replaced with a PSET easily enough, which is what I used originally, and why our variable name is "dots".)

Concept is simple:  Choose a point on the screen.  Choose it a direction to move in.  Simply move it, and draw it, until it moves off screen, then repeat the process.
Title: Re: Help with Starfield
Post by: johnno56 on August 10, 2019, 11:01:10 am
Ya gotta love star fields - 'trig-less' or not - Very cool.
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 11:04:06 am
And now with 10 warp speeds installed on our TrekDrive!

Code: QB64: [Select]
  1. TYPE Dot_type
  2.     x AS _FLOAT
  3.     y AS _FLOAT
  4.     movex AS _FLOAT
  5.     movey AS _FLOAT
  6.     size AS _FLOAT
  7. DIM dots(10000) AS Dot_type
  8.  
  9.  
  10. SCREEN _NEWIMAGE(1024, 720, 32)
  11. WINDOW (-1000, -1000)-(1000, 1000)
  12.  
  13. dotsinplay = 1000
  14. FOR i = 1 TO dotsinplay
  15.     dots(i).x = RND * 100 - 50
  16.     dots(i).y = RND * 100 - 50
  17.     dots(i).movex = RND * 10 - 5
  18.     dots(i).movey = RND * 10 - 5
  19.     dots(i).color = &HFF000000 + INT(RND * &HFFFFFF) + 1
  20.     dots(i).size = RND * 5
  21.  
  22.  
  23.  
  24.  
  25. warpspeed = 1
  26.     CLS
  27.     i = 1
  28.     DO 'move and replace dots which would go off screen
  29.         dots(i).x = dots(i).x + dots(i).movex * warpspeed
  30.         dots(i).y = dots(i).y + dots(i).movey * warpspeed
  31.         IF dots(i).x < -1000 OR dots(i).x > 1000 or _
  32.            dots(i).y < -1000 OR dots(i).y > 1000 THEN
  33.             dots(i).x = RND * 100 - 50
  34.             dots(i).y = RND * 100 - 50
  35.             dots(i).movex = (RND * 10 - 5)
  36.             dots(i).movey = (RND * 10 - 5)
  37.             dots(i).color = &HFF000000 + INT(RND * &HFFFFFF) + 1
  38.             dots(i).size = RND * 5
  39.         END IF
  40.         CircleFill dots(i).x, dots(i).y, dots(i).size, dots(i).color
  41.         i = i + 1
  42.     LOOP UNTIL i >= dotsinplay
  43.     LOCATE 1, 1: PRINT "Warp Speed:"; warpspeed
  44.  
  45.     a$ = INKEY$
  46.     SELECT CASE a$
  47.         CASE "1" TO "9": warpspeed = VAL(a$)
  48.         CASE "0"
  49.             _AUTODISPLAY
  50.             CLS
  51.             PRINT "THE ENGINES CAN'T TAKE ANY MORE CAPT'N!"
  52.             FOR i = 1 TO 5
  53.                 _DELAY 1
  54.                 FOR j = 1 TO i - 1:
  55.                     PRINT ".";
  56.                 NEXT
  57.                 PRINT "."
  58.             NEXT
  59.             _DELAY 1
  60.             PRINT "BOOOOOOOOOOOOOOMMMMMMM!!!!"
  61.             BEEP
  62.             BEEP
  63.             SYSTEM
  64.     END SELECT
  65.     _DISPLAY
  66.  
  67. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  68.     ' CX = center x coordinate
  69.     ' CY = center y coordinate
  70.     '  R = radius
  71.     '  C = fill color
  72.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  73.     DIM X AS INTEGER, Y AS INTEGER
  74.     Radius = ABS(R)
  75.     RadiusError = -Radius
  76.     X = Radius
  77.     Y = 0
  78.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  79.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  80.     WHILE X > Y
  81.         RadiusError = RadiusError + Y * 2 + 1
  82.         IF RadiusError >= 0 THEN
  83.             IF X <> Y + 1 THEN
  84.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  85.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  86.             END IF
  87.             X = X - 1
  88.             RadiusError = RadiusError - X * 2
  89.         END IF
  90.         Y = Y + 1
  91.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  92.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  93.     WEND
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 01:23:07 pm
Yeah Steve, I debated whether to use your "Gold Standard" CircleFill routine, the one tried and tested here and maybe  even at Walter's forum... and likely long before I came to [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there], but I figured Ken might be more inclined to buy a smaller more easy to understand SUB circleFill using PAINT??? Dang just get him to use a SUB properly to see the convenience!

In attempt to help Ken, I also dumped the use of TYPE which does keep all those arrays under one more manage-able name and index. I know others who avoid this structure form of data, it's easier to understand the tenancy to avoid that complexity.

I am afraid Ken is very into his way of doing things like drawing and the blacking out moving figures rather than simple CLS and redraw everything like he is back in 80's when that sort of thing took too much time (ha! or using JB). And why RANDOMIZE TIMER before every use of RND???

I am sorry to see all the folks encouraging the non use of trig, all these people who do know how to use trig. I don't get it, sure Star fields can be done easily without SIN and COS but it seems an ideal time for some SIN COS practice. Does doing Star Fields without trig help Ken?  Oh sure, it helps him avoid SIN and COS that much longer :D

Can anyone do regular polygons without SIN and COS? Probably, but who wants to try?
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 02:20:25 pm
Can anyone do regular polygons without SIN and COS? Probably, but who wants to try?

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 256)
  2.  
  3. FOR i = 3 TO 10
  4.     CLS
  5.     angle = 360 / i
  6.     a$ = _TRIM$(STR$(angle))
  7.     d$ = "U100"
  8.     PSET (500, 300)
  9.     n = 0
  10.     d$ = "U100"
  11.     FOR j = 1 TO i
  12.         n = n + angle
  13.         a$ = _TRIM$(STR$(n))
  14.         d$ = d$ + " TA" + a$ + " U100"
  15.     NEXT
  16.     DRAW d$
  17.     SLEEP

;D
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 02:24:43 pm
Oh yeah draw strings, OK! :)
Title: Re: Help with Starfield
Post by: OldMoses on August 10, 2019, 05:28:49 pm
Being an inveterate tweaker, I've been messing with this star field thing. While I didn't use SIN & COS in the original code, I reasoned that I could use it to add some navigational fun. SIN will slew the stars left and right with the use of the left and right arrow keys, and plus and minus keys will speed and slow the action.

Well then I thought, hell, use COS to pitch up and down as well. Except that approaching that in the same manner makes the display go batty. Uncomment line 35 to see the effect. I'm not sure why it dislikes one and not the other...

Code: QB64: [Select]
  1. a& = _NEWIMAGE(600, 600, 32)
  2. TYPE star '                                                     define the star data type
  3.     x AS INTEGER
  4.     y AS INTEGER
  5.     z AS INTEGER
  6.     xa AS INTEGER
  7.     ya AS INTEGER
  8.  
  9. DIM SHARED max AS INTEGER: max = 500
  10. DIM SHARED vprt AS INTEGER: vprt = 600 '                        set the viewport setback from viewer's eye
  11. DIM SHARED p(max) AS star '                                     dimension the star data array
  12. DIM SHARED speed AS INTEGER: speed = 2 '                        warp factor
  13.  
  14. PopVoid '                                                       OldMoses said "Let there be light" and the universe was, is and ever shall be
  15. WINDOW (-300, 300)-(300, -300) '                                create viewport window, Cap'n Kirk spends his days staring at this
  16.  
  17. DO '                                                            draw the stars
  18.     x$ = INKEY$
  19.     IF x$ = "" THEN
  20.         xch = 0: ych = 0
  21.     END IF
  22.     IF x$ = CHR$(43) THEN speed = speed + 1
  23.     IF x$ = CHR$(45) THEN speed = speed - 1
  24.     IF x$ = CHR$(0) + CHR$(75) THEN xch = 1 '      steering left/right
  25.     IF x$ = CHR$(0) + CHR$(77) THEN xch = -1
  26.     IF x$ = CHR$(0) + CHR$(72) THEN ych = 1 '      pitching up/down
  27.     IF x$ = CHR$(0) + CHR$(80) THEN ych = -1
  28.     CLS
  29.     FOR x = 1 TO max '                                          iterate through all stars
  30.         p(x).x = p(x).x + SinCalc(p(x).z, xch * 0.3)
  31.         'p(x).y = p(x).y + CosCalc(p(x).z, ych * 0.3)
  32.         p(x).xa = p(x).x / Pythagorus(p(x)) * vprt '            get relative screen position from absolute position for x & y
  33.         p(x).ya = p(x).y / Pythagorus(p(x)) * vprt
  34.         IF ABS(p(x).xa) < 301 AND ABS(p(x).ya) < 301 THEN '     place the star if within the viewport
  35.             PSET (p(x).xa, p(x).ya)
  36.         END IF
  37.         p(x).z = p(x).z - speed '                               move the star closer to the viewer
  38.         IF p(x).z < 0 THEN ReplaceStar x '                      add new stars as existing ones go behind the viewer
  39.     NEXT x
  40.     _DISPLAY '                                                  eliminate screen flicker
  41.     _LIMIT 500 '                                                smooth out the action
  42.  
  43.  
  44. SUB PopVoid '                                                   Do an initial population of stars
  45.  
  46.     FOR x = 1 TO max '                                          place a 'max' # of stars randomly in a 3D space
  47.         RANDOMIZE TIMER
  48.         p(x).x = INT(RND * 15000) - 7500
  49.         p(x).y = INT(RND * 15000) - 7500
  50.         p(x).z = INT(RND * 15000) + 1
  51.     NEXT x
  52.  
  53. END SUB 'PopVoid
  54.  
  55.  
  56. FUNCTION Pythagorus (var1 AS star)
  57.  
  58.     'Use to find distance between two 3D points
  59.  
  60.     horizontal = _HYPOT(ABS(var1.x), ABS(var1.y))
  61.     Pythagorus = _HYPOT(horizontal, ABS(var1.z))
  62.  
  63. END FUNCTION 'Pythagorus
  64.  
  65.  
  66. SUB ReplaceStar (var AS INTEGER) '                              This replaces any star that goes behind the viewer
  67.  
  68.     p(var).x = INT(RND * 15000) - 7500
  69.     p(var).y = INT(RND * 15000) - 7500
  70.     p(var).z = 15000
  71.  
  72. END SUB 'ReplaceStar
  73.  
  74. FUNCTION SinCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  75.  
  76.     'Polar coordinate X finder
  77.     'used to find X coordinate of a speed/distance (var1) and heading/azimuth (var2)
  78.     SinCalc = var1 * SIN(_D2R(var2))
  79.  
  80. END FUNCTION 'SinCalc
  81.  
  82.  
  83. FUNCTION CosCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  84.  
  85.     'Polar coordinate Y finder
  86.     'used to find Y coordinate of a speed/distance (var1) and heading/azimuth (var2)
  87.     CosCalc = var1 * COS(_D2R(var2))
  88.  
  89. END FUNCTION 'CosCalc
  90.  
  91.  
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 09:36:50 pm
Well, I finally made it! Well, actually I tried to make it with my own code but ended up using just about all of B+'s example. It sure is teaching me a lot though and I thank you to all of you guys for your example codes. I won't be able to remember the math involved (I know it's simple math), unless someday I use this many times to make things with (because of my memory problems). But I did add to it some things that B+ didn't have, like 3 different colored stars, white, red, and blue (for white, Red Giants, and Blue Giants), and different sizes of stars using CIRCLE and PAINT. I also used an example I found on this thread to use keys to speed up and slow down, which are the up and down arrow keys. Instead of Impulse Speed I use "Cruise Speed" and then Warp 1-10. If you guys, especially B+, don't want this on my website I won't put it on. But I did add credits to the top of the code that you can read below. Thank you again for the help. I might use this in other games or programs (unless you don't want me to). Oh also, I finally know why I couldn't make my own originally, I was very close though, but didn't make just 1 star at a time like this does (except for the first stars).  I know this line must delete all the stars to add motion to them all at once, but does it also make the star tails? I need to experiment with this type of stuff later. :)
 LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF

Here it is, I added lots of remarks to remember the reasons later and for others.

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2.  
  3. _TITLE "Warp Speed  - Use Up and Down Arrow Keys"
  4. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  5.  
  6. SCREEN _NEWIMAGE(800, 800, 32)
  7.  
  8. 'Set the default speed, amount of stars, and then make the first stars.
  9. speed = .001
  10. amount = 750
  11. FOR stars = 1 TO amount
  12.     GOSUB make:
  13. NEXT stars
  14.  
  15.     _LIMIT 500
  16.     FOR stars = 1 TO amount
  17.         a$ = INKEY$
  18.         IF a$ = CHR$(27) THEN END
  19.  
  20.         'Detect the arrow keys to make it go faster or slower.
  21.         IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  22.         IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  23.         IF warp < .0003 THEN warp = 0
  24.         IF warp > 10 THEN warp = 10
  25.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  26.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  27.         IF speed < .001 THEN speed = .001
  28.         IF speed > .01 THEN speed = .01
  29.  
  30.         'Move the stars.
  31.         x(stars) = x(stars) + dx(stars) * speed
  32.         y(stars) = y(stars) + dy(stars) * speed
  33.  
  34.         'See how many stars are on screen, if there's a certain amount, GOSUB to make: to make a new star.
  35.         r = x(stars) * x(stars) + y(stars) * y(stars)
  36.         IF (r > 600 ^ 2) THEN GOSUB make:
  37.  
  38.         'Draw the stars, c(stars) is the choice of color.
  39.         IF c(stars) < 75 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  40.         IF c(stars) > 74 AND c(stars) < 85 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  41.         IF c(stars) > 84 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  42.  
  43.         'If the size of the star is less than 1, skip paint.
  44.         IF sz(stars) < 1 THEN GOTO nopaint:
  45.  
  46.         'Paint the stars.
  47.         IF c(stars) < 75 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  48.         IF c(stars) > 74 AND c(stars) < 85 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  49.         IF c(stars) > 84 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  50.         nopaint:
  51.     NEXT stars
  52.  
  53.     _DISPLAY
  54.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  55.  
  56.  
  57. make:
  58.  
  59. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  60.  
  61. x(stars) = (RND - .5) * _WIDTH
  62.  
  63. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  64.  
  65. y(stars) = (RND - .5) * _HEIGHT
  66.  
  67. 'Get a random star size between .25 and 2.
  68.  
  69. sz(stars) = (RND * 2) + .25
  70.  
  71. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  72.  
  73. c(stars) = INT(RND * 100) + 1
  74.  
  75. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  76.  
  77. v = 5 + RND * 5
  78. dx(stars) = x(stars) * v
  79. dy(stars) = y(stars) * v
  80.  
  81.  
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 10:06:07 pm
Yeah, this line:
 LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
layers the star field with coats of transparent black, the oldest on screen eventually get covered over, this creates the tail effect, thanks Fellippe, from whom I learned that trick.

Looks pretty good Ken :)

I have this strange urge to stand up and salute your stars!

Update: this is looking like my translation of STxAxTIC's code the locating of stars is signature STxAxTIC.

These lines:
Code: QB64: [Select]
  1.   'See how many stars are on screen, if there's a certain amount, GOSUB to make: to make a new star.
  2.         r = x(stars) * x(stars) + y(stars) * y(stars)
  3.         IF (r > 600 ^ 2) THEN GOSUB make:
  4.  
are measuring the distance of x, y from the center of the screen. A new star is made when the distance is beyond borders of screen.

Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 10:16:05 pm
Thanks B+!  LOL I thought the same thing, red, white, and blue.
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 10:24:53 pm
This is just directly from your example. Wow it is measurement from the center I think. It's not adding stars, I'll change the remark, thank you.

Edit: B+ the more I think about this line, the more confusing it is to me. And I have no idea why it works. I tried using my program without these 2 lines and it only did the first stars and wouldn't make any more, so I put it back. It's confusing because 600 to the second power equals 360,000 which has nothing to do with X * X plus Y * Y.  For example, if a star made it to X=10, Y=10, then 10 * 10 = 100 and again 10 * 10 = 100 so 100 + 100 = 200, nowhere neat 600 to the second power. What am I missing?

Edit again: And I know its 360000 because I took out the equation and just put in 360000 and the program runs fine, but HOW can r get up that high of a number?? lol



Yeah, this line:
 LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
layers the star field with coats of transparent black, the oldest on screen eventually get covered over, this creates the tail effect, thanks Fellippe, from whom I learned that trick.

Looks pretty good Ken :)

I have this strange urge to stand up and salute your stars!

Update: this is looking like my translation of STxAxTIC's code the locating of stars is signature STxAxTIC.
Code: QB64: [Select]
  1.  
  2. These lines:
  3.   'See how many stars are on screen, if there's a certain amount, GOSUB to make: to make a new star.
  4.         r = x(stars) * x(stars) + y(stars) * y(stars)
  5.         IF (r > 600 ^ 2) THEN GOSUB make:
  6.  
are measuring the distance of x, y from the center of the screen. A new star is made when the distance is beyond borders of screen.
Title: Re: Help with Starfield
Post by: OldMoses on August 10, 2019, 10:28:26 pm
Nicely done Ken, I've been intrigued by the alpha overlay tip too, makes a nice comet trail effect. Kind of hoping I'll think of a project I can use it in myself.
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 10:35:02 pm
Thanks OldMoses, this is almost all B+'s example code, so I am grateful to learn from that.
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 10:44:47 pm
It’s a simple version of Pytagorean’s Theorem.  When it comes to a right triangle, the hypotenuse is twice the sum of the squares of the other 2 sides....

Simply put, in a circle, r ^ 2 = x ^ 2 + y ^ 2



Run the tutorial in reply #4 here, and see if it helps you understand it: https://www.qb64.org/forum/index.php?topic=1583.msg108049#msg108049
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 10:48:02 pm
A-HA! I found the reason B+! Those 2 lines just detect to see if any star goes past 600, either vertically or horizontally. It's just a trick to see how far the farthest stars have gone in that 1 direction. And since all of the directions move the same speed and length, only 1 direction is needed. If any of them passed up 600, it would make another new star in make: Knowing this, I changed the 600 to 800 because I had changed the screen size to 800 x 800 when I made the program. And now the stars even look better!!! Here is a better version:

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2.  
  3. _TITLE "Warp Speed  - Use Up and Down Arrow Keys"
  4. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  5.  
  6. SCREEN _NEWIMAGE(800, 800, 32)
  7.  
  8. 'Set the default speed, amount of stars, and then make the first stars.
  9. speed = .001
  10. amount = 750
  11. FOR stars = 1 TO amount
  12.     GOSUB make:
  13. NEXT stars
  14.  
  15.     _LIMIT 500
  16.     FOR stars = 1 TO amount
  17.         a$ = INKEY$
  18.         IF a$ = CHR$(27) THEN END
  19.  
  20.         'Detect the arrow keys to make it go faster or slower.
  21.         IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  22.         IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  23.         IF warp < .0003 THEN warp = 0
  24.         IF warp > 10 THEN warp = 10
  25.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  26.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  27.         IF speed < .001 THEN speed = .001
  28.         IF speed > .01 THEN speed = .01
  29.  
  30.         'Move the stars.
  31.         x(stars) = x(stars) + dx(stars) * speed
  32.         y(stars) = y(stars) + dy(stars) * speed
  33.  
  34.         'Detect to see if any star goes past the screen 800 x 800, if so, GOSUB make: to make a new star.
  35.         r = x(stars) * x(stars) + y(stars) * y(stars)
  36.         IF (r > 800 ^ 2) THEN GOSUB make:
  37.  
  38.         'Draw the stars, c(stars) is the choice of color.
  39.         IF c(stars) < 75 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  40.         IF c(stars) > 74 AND c(stars) < 85 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  41.         IF c(stars) > 84 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  42.  
  43.         'If the size of the star is less than 1, skip paint.
  44.         IF sz(stars) < 1 THEN GOTO nopaint:
  45.  
  46.         'Paint the stars.
  47.         IF c(stars) < 75 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  48.         IF c(stars) > 74 AND c(stars) < 85 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  49.         IF c(stars) > 84 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  50.         nopaint:
  51.     NEXT stars
  52.  
  53.     'This stops flickering.
  54.     _DISPLAY
  55.  
  56.     'Erase the stars for motion but keep a transparent black for the trails.
  57.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  58.  
  59.  
  60. make:
  61.  
  62. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  63.  
  64. x(stars) = (RND - .5) * _WIDTH
  65.  
  66. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  67.  
  68. y(stars) = (RND - .5) * _HEIGHT
  69.  
  70. 'Get a random star size between .25 and 2.
  71.  
  72. sz(stars) = (RND * 2) + .25
  73.  
  74. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  75.  
  76. c(stars) = INT(RND * 100) + 1
  77.  
  78. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  79.  
  80. v = 5 + RND * 5
  81. dx(stars) = x(stars) * v
  82. dy(stars) = y(stars) * v
  83.  
  84.  
  85.  
Title: Re: Help with Starfield
Post by: SierraKen on August 10, 2019, 10:53:37 pm
True SMcNeill, but it's still only moving right or moving down because if a star went to the left or up, that equation wouldn't work.
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 11:05:45 pm
A-HA! I found the reason B+! Those 2 lines just detect to see if any star goes past 600, either vertically or horizontally. It's just a trick to see how far the farthest stars have gone in that 1 direction. And since all of the directions move the same speed and length, only 1 direction is needed. If any of them passed up 600, it would make another new star in make: Knowing this, I changed the 600 to 800 because I had changed the screen size to 800 x 800 when I made the program. And now the stars even look better!!! Here is a better version:
...

True SMcNeill, but it's still only moving right or moving down because if a star went to the left or up, that equation wouldn't work.

Hi Ken,

Ah mathematics! When you square a number negative or positive the square is always positive and gigantic!

800 ^ 2 = 640,000 gigantic AND positive, you were right to increase the number.

The distance between two things is a positive what is a negative distance? there are negative directions though.
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 11:09:40 pm
A-HA! I found the reason B+! Those 2 lines just detect to see if any star goes past 600, either vertically or horizontally. It's just a trick to see how far the farthest stars have gone in that 1 direction. And since all of the directions move the same speed and length, only 1 direction is needed. If any of them passed up 600, it would make another new star in make: Knowing this, I changed the 600 to 800 because I had changed the screen size to 800 x 800 when I made the program. And now the stars even look better!!! Here is a better version:

You're not quite right in your thinking there.

Here's a quick thought process for you to try:  Take a square piece of page and lay it flat on any surface.  Take another piece of paper the same size and hold it vertical at the edge of the first one.  Now, will another sheet, the same size, fit from the far edges of both sides?

If you have your paper like so (pardon the rough ASCII art):

|
|
|______


Would the same size paper fit to make that triangle there?

Easy answer:  It wouldn't.

To fit, that sheet of paper would have to be SQR(left side ^ 2 + bottom side ^ 2)...

Or, simplified SQR(2) in this case, times as long as the other sides. 

SQR (1 page size ^ 2 + 1 page size ^ 2)=
SQR (1 page size + 1 page size)=    *After all, 1 ^ 2 is still 1...
SQR (2 page size)



And how does this apply to your math in particular?

The center of your screen is at 400,400, so it's 400 pixels from the top and 400 pixels from the left.  On the perfect diagonal, the distance from (400,400) to (0,0) makes one of those triangles once again, just as I was pointing out with the paper example above, so it's SQR(2) * 400 pixels in length...

566 pixels from the center, in any direction, will place you off the edge of the screen.



If it's only 566 pixels to the edge, why did Stx use 600 as his limit??

Same reason most programmers do such things; he knew it was off the screen with a little mental math, and didn't need to be bothered to figure out the exact distance for things to work properly for his code.  He just plugged in a simple value "close enough", and then moved on and didn't worry about the fine details...

       IF (r > 600 ^ 2) THEN GOSUB make: 

The above line would work just as well if the value was IF (r > 566 ^ 2) THEN GOSUB make: 

Making it 800 doesn't make the program any better.  ;)
Title: Re: Help with Starfield
Post by: SMcNeill on August 10, 2019, 11:17:05 pm
800 ^ 2 = 640,000 gigantic AND positive, you were right to increase the number.

Except your not dealing with 800 pixels in every direction -- that's the total _WIDTH and _HEIGHT of the screen.  The centerpoint is half that, at 400,400, so you only need the distance of the diagonal from (400,400) to (0,0), which is 566 pixels. 

The distance between two things is a positive what is a negative distance? there are negative directions though.

I agree with this, 100%.  Distance is a set value zero or greater.  Positive or Negative simply tells you which direction that distance is in relation to your origin.

A.....B
The distance between A and B above is 5 dots.  Since A is the origin, it's positive 5 dots.

B.....A
And now, the distance between A and B is still 5 dots.  But, since A is the origin, it's negative 5 dots.

Positive/Negative just tells you the direction to move in from the origin.  ;)
Title: Re: Help with Starfield
Post by: bplus on August 10, 2019, 11:55:59 pm
Except your not dealing with 800 pixels in every direction -- that's the total _WIDTH and _HEIGHT of the screen.  The centerpoint is half that, at 400,400, so you only need the distance of the diagonal from (400,400) to (0,0), which is 566 pixels. 

I agree with this, 100%.  Distance is a set value zero or greater.  Positive or Negative simply tells you which direction that distance is in relation to your origin.

A.....B
The distance between A and B above is 5 dots.  Since A is the origin, it's positive 5 dots.

B.....A
And now, the distance between A and B is still 5 dots.  But, since A is the origin, it's negative 5 dots.

Positive/Negative just tells you the direction to move in from the origin.  ;)

OK, I was maybe thrown by STxAxTIC's method of locating stars... 400^2 + 400^2 is probably right for 800x800 screen, I was thinking 800 x 800 was bigger than screen 12 in area.

For the record, here is my conditions for making a new star which avoids squaring (and SQRing for proper distance)
Code: QB64: [Select]
  1.         IF y(p) < -2 OR y(p) > _HEIGHT + 2 THEN newStar p 'replace stars going off screen with new ones
  2.         IF x(p) < -2 OR x(p) > _WIDTH + 2 THEN newStar p
  3.  
But I am not locating things like STxAxTIC
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 12:03:30 am
SmMcNeill, I still don't understand this. Why would 400 ^ 2 + 400 ^2 = 320,000 matter to anything I'm doing? I did take Geometry in High School back in the 80's, but this does not sound right to me. _WIDTH of the ENTIRE screen is only 800, so this circle could never fit anywhere near the size of my screen. Unless that's what the programmer wanted? A circle that's 800 times the width of the screen? 
Title: Re: Help with Starfield
Post by: SMcNeill on August 11, 2019, 12:04:34 am
Warp Drive in reverse:

Code: QB64: [Select]
  1. TYPE Dot_type
  2.     x AS _FLOAT
  3.     y AS _FLOAT
  4.     ox AS _FLOAT
  5.     oy AS _FLOAT
  6.     speed AS _FLOAT
  7. DIM dots(10000) AS Dot_type
  8.  
  9.  
  10. SCREEN _NEWIMAGE(501, 501, 32)
  11. WINDOW (-250, -250)-(250, 250)
  12.  
  13. dotsinplay = 0
  14.  
  15. FOR i = -250 TO 250
  16.     dotsinplay = dotsinplay + 1
  17.     dots(dotsinplay).x = i
  18.     dots(dotsinplay).y = 250
  19.     dots(dotsinplay).ox = dots(dotsinplay).x
  20.     dots(dotsinplay).oy = dots(dotsinplay).y
  21.     dots(dotsinplay).color = &HFF000001 + INT(RND * &HFFFFFF)
  22.     dots(dotsinplay).speed = RND * 200
  23.     dotsinplay = dotsinplay + 1
  24.     dots(dotsinplay).x = i
  25.     dots(dotsinplay).y = -250
  26.     dots(dotsinplay).ox = dots(dotsinplay).x
  27.     dots(dotsinplay).oy = dots(dotsinplay).y
  28.     dots(dotsinplay).color = &HFF000001 + INT(RND * &HFFFFFF)
  29.     dots(dotsinplay).speed = RND * 200
  30.     dotsinplay = dotsinplay + 1
  31.     dots(dotsinplay).x = 250
  32.     dots(dotsinplay).y = i
  33.     dots(dotsinplay).ox = dots(dotsinplay).x
  34.     dots(dotsinplay).oy = dots(dotsinplay).y
  35.     dots(dotsinplay).color = &HFF000001 + INT(RND * &HFFFFFF)
  36.     dots(dotsinplay).speed = RND * 200
  37.     dotsinplay = dotsinplay + 1
  38.     dots(dotsinplay).x = -250
  39.     dots(dotsinplay).y = i
  40.     dots(dotsinplay).ox = dots(dotsinplay).x
  41.     dots(dotsinplay).oy = dots(dotsinplay).y
  42.     dots(dotsinplay).color = &HFF000001 + INT(RND * &HFFFFFF)
  43.     dots(dotsinplay).speed = RND * 200
  44.  
  45.  
  46.     _LIMIT 100
  47.     LINE (-250, -250)-(250, 250), &H77000000, BF
  48.     'CLS
  49.     FOR i = 1 TO dotsinplay
  50.         PSET (dots(i).x, dots(i).y), dots(i).color
  51.         dots(i).x = dots(i).x - dots(i).ox / dots(i).speed
  52.         dots(i).y = dots(i).y - dots(i).oy / dots(i).speed
  53.         IF SGN(dots(i).ox) * dots(i).x < 0 OR SGN(dots(i).oy) * dots(i).y < 0 THEN
  54.             dots(i).x = dots(i).ox
  55.             dots(i).y = dots(i).oy
  56.         END IF
  57.     NEXT
  58.     _DISPLAY
  59.  

Or maybe, if I was to add a small rotation to the screen as it goes, I could call it a Swirl Into Blackhole.   

Maybe it's just me, but I actually like this effect quite a bit.  ;D
Title: Re: Help with Starfield
Post by: bplus on August 11, 2019, 12:23:20 am
SmMcNeill, I still don't understand this. Why would 400 ^ 2 + 400 ^2 = 320,000 matter to anything I'm doing? I did take Geometry in High School back in the 80's, but this does not sound right to me. _WIDTH of the ENTIRE screen is only 800, so this circle could never fit anywhere near the size of my screen. Unless that's what the programmer wanted? A circle that's 800 times the width of the screen? 

You address Steve, but I'd like to take a shot at answering because I am a bit confused myself.

The farthest points on the screen from the center are in the corners, what is the distance from center to corner?
x distance = 400, y distance = 400 so it is the SQR(400 ^ 2 + 400 ^ 2) ~ 566

but we are leaving the x and y squared, so we leave the distance squared to compare apples to apples and avoid using SQR function.



Title: Re: Help with Starfield
Post by: bplus on August 11, 2019, 12:25:11 am
LOL Steve, your warp drive in reverse looks like a vacuum cleaner, quick sand?
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 12:29:20 am
Hmm OK then yes, maybe the programmer did want a GIANT circle 800 times larger than the computer screen. I think because I don't understand this that much, I'm going to change it to use B+'s _WIDTH and _HEIGHT limitation example a couple posts before this instead. :) Thanks!
Title: Re: Help with Starfield
Post by: SMcNeill on August 11, 2019, 12:30:20 am
SmMcNeill, I still don't understand this. Why would 400 ^ 2 + 400 ^2 = 320,000 matter to anything I'm doing? I did take Geometry in High School back in the 80's, but this does not sound right to me. _WIDTH of the ENTIRE screen is only 800, so this circle could never fit anywhere near the size of my screen. Unless that's what the programmer wanted? A circle that's 800 times the width of the screen?

Give this demo a run and see if it explains the concept better than I ever could without much better pictures than ASCII art allows in a text forum:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 800, 32)
  2.  
  3.     count = count + 1
  4.     CLS
  5.     CIRCLE (400, 400), count, -1
  6.     PAINT (400, 400), -1
  7.     _DISPLAY
  8.     _TITLE STR$(count)
  9.     _LIMIT 40
  10.     IF count = 400 THEN
  11.         BEEP
  12.         PRINT "Notice that with a size of 400, we've now touched the midpoints of the edges if the screen?"
  13.         _DISPLAY
  14.         SLEEP
  15.         _KEYCLEAR
  16.  
  17.     END IF
  18.     IF count = 566 THEN
  19.         COLOR &HFF000000, 0
  20.         BEEP
  21.         PRINT "We're now at 566...  Notice how we've now covered the whole screen, completely?"
  22.         _DISPLAY
  23.         SLEEP
  24.         _KEYCLEAR
  25.         EXIT DO
  26.     END IF
  27.  
  28. PRINT "Now, at this point, let's do a little math."
  29. PRINT "Pythogoren's Theorum says:   A ^ 2 + B ^ 2 = C ^ 2"
  30. PRINT "In this case, it's 400 ^ 2 + 400 ^ 2 = C ^ 2"
  31. PRINT "Or 160000 + 160000 = C ^ 2"
  32. PRINT "Which turns into 320000 = C ^ 2"
  33. PRINT "And simplified, becomes SQR(320000) = C"
  34. PRINT "Which, oddly enough, gives us:"; SQR(320000)
  35. PRINT "So it rounds up to 566, since we can't process a fraction of a loop..."
  36. PRINT "And that's where the 400 ^ 2 + 400 ^2 being less than 600 ^2 comes from..."
  37. PRINT "That 600 ^ 2 is just lazy math and a fast guesstimate, which is definitely off the screen."
  38. PRINT "Because  if 566 covers the whole screen, 600 certainly isn't going to have any issues covering it as well."
  39.  
Title: Re: Help with Starfield
Post by: bplus on August 11, 2019, 12:43:23 am
Hmm OK then yes, maybe the programmer did want a GIANT circle 800 times larger than the computer screen. I think because I don't understand this that much, I'm going to change it to use B+'s _WIDTH and _HEIGHT limitation example a couple posts before this instead. :) Thanks!

Ken be careful, my limits don't work the same for this setup:
Code: QB64: [Select]
  1. x(stars) = (RND - .5) * _WIDTH
  2.  
  3. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  4.  
  5. y(stars) = (RND - .5) * _HEIGHT
  6.  
  7.  

These gives x and y a range of -400 to 400.

So check if  x < - 400 or x > 400 then make newStar or use _width/2 *-1 and _width/2
likewise for y  if y < -400 or y > 400 then make newStar
that should be something we all can understand.

BTW, I don't understand your comment about 2 decimal points.
RND -.5 takes a number from 0 to 1 and makes it a number from -.5 to .5
multiply that by width or height of 800 and you get a number between -400 and 400.

Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 12:51:28 am
Wow yes! The negative numbers! That's what SmMcNeil was referring to, making the 0,0 in the middle of the screen. Makes a lttle more sense now to me, although it's too late tonight to do the geometry again lol.  I totally overlooked that. So I changed it to the limits of -400 and 400 on both X and Y now and it works great! I wondered why it was only in 1 corner. LOL
Thanks again, wow what a learning day for me. :)

Here it is again:

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2.  
  3. _TITLE "Warp Speed  - Use Up and Down Arrow Keys"
  4. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  5.  
  6. SCREEN _NEWIMAGE(800, 800, 32)
  7.  
  8. 'Set the default speed, amount of stars, and then make the first stars.
  9. speed = .001
  10. amount = 750
  11. FOR stars = 1 TO amount
  12.     GOSUB make:
  13. NEXT stars
  14.  
  15.     _LIMIT 500
  16.     FOR stars = 1 TO amount
  17.         a$ = INKEY$
  18.         IF a$ = CHR$(27) THEN END
  19.  
  20.         'Detect the arrow keys to make it go faster or slower.
  21.         IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  22.         IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  23.         IF warp < .0003 THEN warp = 0
  24.         IF warp > 10 THEN warp = 10
  25.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  26.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  27.         IF speed < .001 THEN speed = .001
  28.         IF speed > .01 THEN speed = .01
  29.  
  30.         'Move the stars.
  31.         x(stars) = x(stars) + dx(stars) * speed
  32.         y(stars) = y(stars) + dy(stars) * speed
  33.  
  34.         'Get a new star if one goes off the screen.
  35.         IF x(stars) < -400 OR x(stars) > 400 OR y(stars) < -400 OR y(stars) > 400 THEN GOSUB make:
  36.  
  37.         'r = x(stars) * x(stars) + y(stars) * y(stars)
  38.         'IF (r > 600 ^ 2) THEN GOSUB make:
  39.  
  40.         'Draw the stars, c(stars) is the choice of color.
  41.         IF c(stars) < 75 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  42.         IF c(stars) > 74 AND c(stars) < 85 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  43.         IF c(stars) > 84 THEN CIRCLE (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  44.  
  45.         'If the size of the star is less than 1, skip paint.
  46.         IF sz(stars) < 1 THEN GOTO nopaint:
  47.  
  48.         'Paint the stars.
  49.         IF c(stars) < 75 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  50.         IF c(stars) > 74 AND c(stars) < 85 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  51.         IF c(stars) > 84 THEN PAINT (x(stars) + _WIDTH / 2, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  52.         nopaint:
  53.     NEXT stars
  54.  
  55.     'This stops flickering.
  56.     _DISPLAY
  57.  
  58.     'Erase the stars for motion but keep a transparent black for the trails.
  59.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  60.  
  61.  
  62. make:
  63.  
  64. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  65.  
  66. x(stars) = (RND - .5) * _WIDTH
  67.  
  68. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  69.  
  70. y(stars) = (RND - .5) * _HEIGHT
  71.  
  72. 'Get a random star size between .25 and 2.
  73.  
  74. sz(stars) = (RND * 2) + .25
  75.  
  76. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  77.  
  78. c(stars) = INT(RND * 100) + 1
  79.  
  80. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  81.  
  82. v = 5 + RND * 5
  83. dx(stars) = x(stars) * v
  84. dy(stars) = y(stars) * v
  85.  
  86.  
Title: Re: Help with Starfield
Post by: bplus on August 11, 2019, 12:59:30 am
Yep the change looks right to me, good night!
Title: Re: Help with Starfield
Post by: johnno56 on August 11, 2019, 04:51:43 am
Um... According to Trek-lore* warp speed of 10 cannot be achieved. If it could, then you could occupy every location in the universe, at the same time.
I wonder how that could be represented using QB64's graphics commands.... Now THAT would be cool....

J

* "The Star Trek Encyclopedia - A Reference Guide to the Future" page 372
Title: Re: Help with Starfield
Post by: SMcNeill on August 11, 2019, 05:40:45 am
....then you could occupy every location in the universe, at the same time.
I wonder how that could be represented using QB64's graphics commands....

SCREEN _NEWIMAGE(640,480,32)
CLS, -1
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 12:17:24 pm
SMcNeill, thanks for your math demonstration, I finally noticed it. Since there's no SQR command in the program, the programmer just decided to leave it out and have a GIGANTIC circle after all. LOL Still works though. :) Thanks, I'll keep your demonstration for future programs.
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 12:21:51 pm
LOL Johno. Well you are right, usually... except for 2 episodes I can think of. There's the one where the weird mind alien takes Picard and his crew past the known universe. Then there's this Voyager episode, where they do go to warp 10... https://en.wikipedia.org/wiki/Threshold_(Star_Trek:_Voyager)
Title: Re: Help with Starfield
Post by: OldMoses on August 11, 2019, 12:57:54 pm
Um... According to Trek-lore* warp speed of 10 cannot be achieved. If it could, then you could occupy every location in the universe, at the same time.
I wonder how that could be represented using QB64's graphics commands.... Now THAT would be cool....

J

* "The Star Trek Encyclopedia - A Reference Guide to the Future" page 372

Some of the old canon lore had warp factors being a cube root of the apparent velocity of warp speed. Warp 1 being light speed, 2 being 8 x c, warp 3 being 27 x c, etc. Even at high warp the show played pretty fast and loose with travel times. Warp 1 wouldn't get you anywhere worth going in less than several years... at warp 6 Proxima Centauri is a week away.

Most of our star field programs are really bookin'.

UPDATE:
Instead of just appearing, stars now do an apparent magnitude 'fade in', and stars in the near field increase in size.

Fixed it, now it's fully bidirectional.

Code: QB64: [Select]
  1. _TITLE "OldMoses' 3D StarField (+ & - speed) (left/right arrows turn)"
  2.  
  3. a& = _NEWIMAGE(600, 600, 32)
  4. TYPE star '                                                     define the star data type
  5.     x AS INTEGER
  6.     y AS INTEGER
  7.     z AS INTEGER
  8.     r AS INTEGER
  9.     g AS INTEGER
  10.     b AS INTEGER
  11.     xa AS INTEGER
  12.     ya AS INTEGER
  13.  
  14. DIM SHARED max AS INTEGER: max = 500
  15. DIM SHARED vprt AS INTEGER: vprt = 600 '                        set the viewport setback from viewer's eye
  16. DIM SHARED p(max) AS star '                                     dimension the star data array
  17. DIM SHARED speed AS INTEGER: speed = 2 '                        warp factor
  18.  
  19. PopVoid '                                                       OldMoses said "Let there be light" and the universe was, is and ever shall be
  20. WINDOW (-300, 300)-(300, -300) '                                create viewport window, Cap'n Kirk spends his days staring at this
  21.  
  22. DO '                                                            draw the stars
  23.     x$ = INKEY$
  24.     IF x$ = "" THEN
  25.         xch = 0: ych = 0
  26.     END IF
  27.     IF x$ = CHR$(43) THEN speed = speed + 1
  28.     IF x$ = CHR$(45) THEN speed = speed - 1
  29.     IF x$ = CHR$(0) + CHR$(75) THEN xch = 1
  30.     IF x$ = CHR$(0) + CHR$(77) THEN xch = -1
  31.     'IF x$ = CHR$(0) + CHR$(72) THEN ych = 1
  32.     'IF x$ = CHR$(0) + CHR$(80) THEN ych = -1
  33.     CLS
  34.     FOR x = 1 TO max '                                          iterate through all stars
  35.         dst = Pythagorus(p(x)) '                                distance to star
  36.         p(x).x = p(x).x + SinCalc(p(x).z, xch * 0.3)
  37.         'p(x).y = p(x).y + CosCalc(p(x).z, ych * 0.3) '          <<<this just doesn't work
  38.         p(x).xa = p(x).x / dst * vprt '                         get relative screen position from absolute position for x & y
  39.         p(x).ya = p(x).y / dst * vprt
  40.         IF ABS(p(x).xa) < 301 AND ABS(p(x).ya) < 301 THEN '     place the star if within the viewport
  41.             fdf& = (dst - 12952) / 8
  42.             IF fdf& < 0 THEN fdf& = 0
  43.             SELECT CASE dst
  44.                 CASE IS > 7500
  45.                     PSET (p(x).xa, p(x).ya), _RGBA32(p(x).r, p(x).g, p(x).b, 255 - fdf&)
  46.                 CASE ELSE
  47.                     FCirc p(x).xa, p(x).ya, 1, _RGBA32(p(x).r, p(x).g, p(x).b, 255)
  48.             END SELECT
  49.         END IF
  50.         p(x).z = p(x).z - speed '                               move the star closer to the viewer
  51.         IF speed < 0 THEN
  52.             IF p(x).z > 15000 THEN ReplaceStar x, 0
  53.         ELSE
  54.             IF p(x).z < 0 THEN ReplaceStar x, 15000 '                      add new stars as existing ones go behind the viewer
  55.         END IF
  56.     NEXT x
  57.     _DISPLAY '                                                  eliminate screen flicker
  58.     _LIMIT 500 '                                                smooth out the action
  59.  
  60.  
  61. SUB PopVoid '                                                   Do an initial population of stars
  62.  
  63.     FOR x = 1 TO max '                                          place a 'max' # of stars randomly in a 3D space
  64.         RANDOMIZE TIMER
  65.         p(x).x = INT(RND * 15000) - 7500
  66.         p(x).y = INT(RND * 15000) - 7500
  67.         p(x).z = INT(RND * 15000) + 1
  68.         t% = INT(RND * 110) - 55
  69.         ch = INT(RND * 6)
  70.         IF ch < 4 THEN
  71.             p(x).r = 200 + t%: p(x).b = 200 - t%
  72.         ELSE
  73.             p(x).r = 200 - t%: p(x).b = 200 + t%
  74.         END IF
  75.         p(x).g = 200
  76.     NEXT x
  77.  
  78. END SUB 'PopVoid
  79.  
  80.  
  81. FUNCTION Pythagorus (var1 AS star)
  82.  
  83.     horizontal = _HYPOT(ABS(var1.x), ABS(var1.y)) '             Use to find distance between star and origin (viewer)
  84.     Pythagorus = _HYPOT(horizontal, ABS(var1.z))
  85.  
  86. END FUNCTION 'Pythagorus
  87.  
  88.  
  89. SUB ReplaceStar (var AS INTEGER, insert AS INTEGER) '                              This replaces any star that goes behind the viewer
  90.  
  91.     p(var).x = INT(RND * 15000) - 7500 '                        New x,y,z but keep old color for simplicity sake
  92.     p(var).y = INT(RND * 15000) - 7500
  93.     p(var).z = insert
  94.  
  95. END SUB 'ReplaceStar
  96.  
  97. FUNCTION SinCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  98.  
  99.     'Polar coordinate X finder
  100.     'used to find X coordinate of a speed/distance (var1) and heading/azimuth (var2)
  101.     SinCalc = var1 * SIN(_D2R(var2))
  102.  
  103. END FUNCTION 'SinCalc
  104.  
  105.  
  106. FUNCTION CosCalc (var1 AS _INTEGER64, var2 AS SINGLE)
  107.  
  108.     'Polar coordinate Y finder
  109.     'used to find Y coordinate of a speed/distance (var1) and heading/azimuth (var2)
  110.     CosCalc = var1 * COS(_D2R(var2))
  111.  
  112. END FUNCTION 'CosCalc
  113.  
  114.  
  115. SUB FCirc (CX AS INTEGER, CY AS INTEGER, RR AS INTEGER, C AS _UNSIGNED LONG)
  116.     DIM R AS INTEGER, RError AS INTEGER
  117.     DIM X AS INTEGER, Y AS INTEGER
  118.  
  119.     R = ABS(RR)
  120.     RError = -R
  121.     X = R
  122.     Y = 0
  123.     IF R = 0 THEN PSET (CX, CY), C: EXIT SUB
  124.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  125.     WHILE X > Y
  126.         RError = RError + Y * 2 + 1
  127.         IF RError >= 0 THEN
  128.             IF X <> Y + 1 THEN
  129.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  130.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  131.             END IF
  132.             X = X - 1
  133.             RError = RError - X * 2
  134.         END IF
  135.         Y = Y + 1
  136.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  137.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  138.     WEND
  139. END SUB 'FCirc
  140.  
Title: Re: Help with Starfield
Post by: bplus on August 11, 2019, 03:21:50 pm
Hi Andy,

That has very nice 3D look! You have (probably) seen what happens when press - too long? :)
Title: Re: Help with Starfield
Post by: OldMoses on August 11, 2019, 03:48:20 pm
Hi Andy,

That has very nice 3D look! You have (probably) seen what happens when press - too long? :)

Yep, it swallows my universe into oblivion and it doesn't come back. I may have to work on that one. ;)

Update: simple fix, now it goes both ways.
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 04:38:24 pm
That's really cool looking OldMoses!
Title: Re: Help with Starfield
Post by: OldMoses on August 11, 2019, 05:02:11 pm
That's really cool looking OldMoses!

Thanks, when I wrote it, I was shocked at how simple the math was. It's basically a star "wind tunnel", where the stars stay locked in the x & y position and only their z axis position is advanced toward the viewer. Their actual x & y are translated to an apparent x & y that is plotted on a virtual viewport at z=600, while the stars themselves go as far out as z=15,000. It's the ratio of the distance to the star and the distance to the viewport that gives the "parallax" effect of nearer stars moving faster, when in fact they are all advancing at the same speed. I learned that trick of perspective while researching ray tracing algorithms recently.
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 06:40:57 pm
Amazing OldMoses.

Well, for the fun of it and the Star Trek geek I am, I added the mouse to mine where you can move the mouse left or right and see what the stars look like flying by on the side of you. Like when it shows the Star Trek people looking out a side window and the stars fly by. I had to add some numbers for the stars to last longer, but it was pretty easy.
Check it out:

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2.  
  3. _TITLE "Warp Speed  - Use Up and Down Arrow Keys"
  4. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  5.  
  6. SCREEN _NEWIMAGE(800, 800, 32)
  7.  
  8. 'Set the default speed, amount of stars, and then make the first stars.
  9. speed = .001
  10. amount = 200
  11. xx = 0
  12. FOR stars = 1 TO amount
  13.     GOSUB make:
  14. NEXT stars
  15.  
  16.     _LIMIT 1000
  17.     FOR stars = 1 TO amount
  18.         a$ = INKEY$
  19.         IF a$ = CHR$(27) THEN END
  20.         DO WHILE _MOUSEINPUT
  21.             mouseX = _MOUSEX
  22.             mouseY = _MOUSEY
  23.             mouseLeftButton = _MOUSEBUTTON(1)
  24.             mouseRightButton = _MOUSEBUTTON(2)
  25.             mouseMiddleButton = _MOUSEBUTTON(3)
  26.             mouseWheel = mouseWheel + _MOUSEWHEEL
  27.         LOOP
  28.         xx = (mouseX - 400) * 8
  29.         xx = xx * -1
  30.         'Detect the arrow keys to make it go faster or slower.
  31.         IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  32.         IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  33.         IF warp < .002 THEN warp = 0
  34.         IF warp > 10 THEN warp = 10
  35.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  36.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  37.         IF speed < .001 THEN speed = .001
  38.         IF speed > .01 THEN speed = .01
  39.  
  40.         'Move the stars.
  41.         x(stars) = x(stars) + dx(stars) * speed
  42.         y(stars) = y(stars) + dy(stars) * speed
  43.  
  44.         'Get a new star if one goes off the screen.
  45.         IF x(stars) < -6400 OR x(stars) > 6400 OR y(stars) < -400 OR y(stars) > 400 THEN GOSUB make:
  46.  
  47.         'Draw the stars, c(stars) is the choice of color.
  48.         IF sz(stars) > 2 THEN sz(stars) = 2
  49.         IF c(stars) < 65 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  50.         IF c(stars) > 64 AND c(stars) < 85 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  51.         IF c(stars) > 84 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  52.  
  53.         'If the size of the star is less than 1, skip paint.
  54.         IF sz(stars) < 1 THEN GOTO nopaint:
  55.  
  56.         'Paint the stars.
  57.         IF c(stars) < 65 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  58.         IF c(stars) > 64 AND c(stars) < 85 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  59.         IF c(stars) > 84 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  60.         nopaint:
  61.     NEXT stars
  62.  
  63.     'This stops flickering.
  64.     _DISPLAY
  65.  
  66.     'Erase the stars for motion but keep a transparent black for the trails.
  67.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  68.  
  69. make:
  70.  
  71. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  72.  
  73. x(stars) = (RND - .5) * _WIDTH
  74.  
  75. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  76.  
  77. y(stars) = (RND - .5) * _HEIGHT
  78.  
  79. 'Get a random star size between .25 and 2.
  80.  
  81. sz(stars) = (RND * 2) + .25
  82.  
  83. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  84.  
  85. c(stars) = INT(RND * 100) + 1
  86.  
  87. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  88.  
  89. v = 5 + RND * 5
  90. dx(stars) = x(stars) * v
  91. dy(stars) = y(stars) * v
  92.  
  93.  
  94.  

Title: Re: Help with Starfield
Post by: TempodiBasic on August 11, 2019, 07:11:20 pm
Hi SierraKen

fine and with a speedy change of direction by mouse!

if you like starfield and 4 direction of navigation take a look at this my code porting in QB64 a Java demo
Code: QB64: [Select]
  1. 'starfield in processing
  2. TYPE Star
  3.     x AS DOUBLE
  4.     y AS DOUBLE
  5.     z AS DOUBLE
  6. CONST True = -1, False = NOT True, radStar = 4, countStar = 800, HScreen = 500, WScreen = 800
  7. DIM SHARED a AS LONG, b AS LONG, Zvel AS INTEGER, WarpVel AS INTEGER, Yvel AS INTEGER, Xvel AS INTEGER
  8. DIM Stars(1 TO countStar) AS Star
  9.  
  10.  
  11.  
  12. ' we need two surface to avoid flickering that rises up painting directly on the screen
  13. a = _NEWIMAGE(WScreen, HScreen, 32) 'main screen
  14. b = _NEWIMAGE(WScreen, HScreen, 32) ' panel to draw screen before displaying it
  15.  
  16. WINDOW SCREEN(-WScreen / 2, -HScreen / 2)-(WScreen / 2, HScreen / 2)
  17.  
  18. InitStar Stars()
  19. Zvel = 1
  20. Xvel = 0
  21. Yvel = 0
  22. WarpVel = 1
  23. t# = TIMER
  24.     _LIMIT 120
  25.     DrawStars Stars()
  26.     UpDate Stars()
  27.  
  28.     ' Enter key = reset Key
  29.     IF _KEYDOWN(13) THEN
  30.         Xvel = 0
  31.         Yvel = 0
  32.         Zvel = 5
  33.         WarpVel = 1
  34.     END IF
  35.  
  36.     '19200
  37.     ' Left arrow
  38.     IF _KEYDOWN(19200) AND ABS(TIMER - t#) > .1 AND Xvel > -15 THEN
  39.         Xvel = Xvel - 1
  40.         t# = TIMER
  41.     END IF
  42.  
  43.     '19712
  44.     ' Right arrow
  45.     IF _KEYDOWN(19712) AND ABS(TIMER - t#) > .1 AND Xvel < 15 THEN
  46.         Xvel = Xvel + 1
  47.         t# = TIMER
  48.     END IF
  49.  
  50.  
  51.     '20480
  52.     ' Down arrow
  53.     IF _KEYDOWN(20480) AND ABS(TIMER - t#) > .1 AND Yvel < 15 THEN
  54.         Yvel = Yvel + 1
  55.         t# = TIMER
  56.     END IF
  57.  
  58.  
  59.     '18432
  60.     ' Up arrow
  61.     IF _KEYDOWN(18432) AND ABS(TIMER - t#) > .1 AND Yvel > -15 THEN
  62.         Yvel = Yvel - 1
  63.         t# = TIMER
  64.     END IF
  65.  
  66.     '+
  67.     IF _KEYDOWN(43) AND ABS(TIMER - t#) > .1 AND Zvel < 15 THEN
  68.         Zvel = Zvel + 1
  69.         t# = TIMER
  70.     END IF
  71.  
  72.  
  73.     '-
  74.     IF _KEYDOWN(45) AND ABS(TIMER - t#) > .1 AND Zvel > 0 THEN
  75.         Zvel = Zvel - 1
  76.         t# = TIMER
  77.     END IF
  78.  
  79.     ' WarpVel activate/deactivate the wake effect
  80.     ' w W
  81.     IF _KEYDOWN(87) OR _KEYDOWN(119) THEN
  82.         IF ABS(TIMER - t#) > .1 THEN
  83.             WarpVel = WarpVel * -1
  84.             t# = TIMER
  85.         END IF
  86.     END IF
  87.  
  88.     ' Zvel is min when _mouseX is min on the left and is max when _mouseX is max on the right
  89.     WHILE _MOUSEINPUT = -1
  90.         IF ABS(TIMER - t#) > .1 THEN
  91.             Zvel = map(_MOUSEX, 0, WScreen, 0, 15)
  92.             t# = TIMER
  93.         END IF
  94.     WEND
  95. LOOP UNTIL _KEYHIT = 32 ' stop pressing spacebar
  96.  
  97. SUB UpDate (starField() AS Star)
  98.     DIM i AS INTEGER
  99.  
  100.     FOR i = 1 TO countStar
  101.         starField(i).x = starField(i).x + Xvel
  102.         starField(i).y = starField(i).y + Yvel
  103.         starField(i).z = starField(i).z - Zvel
  104.         IF starField(i).z < 1 OR starField(i).y > HScreen OR starField(i).x > WScreen THEN
  105.             starField(i).z = WScreen
  106.             starField(i).x = MinMax(-WScreen, WScreen) ' new position x
  107.             starField(i).y = MinMax(-HScreen, HScreen) ' new position y
  108.         END IF
  109.     NEXT
  110.  
  111. SUB InitStar (starField() AS Star)
  112.     DIM i AS INTEGER
  113.  
  114.     FOR i = 1 TO countStar
  115.         starField(i).x = MinMax(-WScreen, WScreen)
  116.         starField(i).y = MinMax(-HScreen, HScreen)
  117.         starField(i).z = INT(RND * WScreen) + 1
  118.     NEXT
  119.  
  120. SUB DrawStars (starField() AS Star)
  121.     DIM i AS INTEGER
  122.     DIM sx AS DOUBLE, sy AS DOUBLE, sr AS DOUBLE, px AS DOUBLE, py AS DOUBLE
  123.     _DEST b
  124.     CLS
  125.     FOR i = 1 TO countStar
  126.         ' the ratio x/z is min when x is min and is max when x is max
  127.         sx = map(starField(i).x / starField(i).z, 0, 1, 0, WScreen)
  128.         ' the ratio y/z is min when y is min and is max when y is max
  129.         sy = map(starField(i).y / starField(i).z, 0, 1, 0, HScreen)
  130.         ' radius in warp speed is a point of 1 pixel
  131.         IF WarpVel = True THEN
  132.             sr = 1
  133.         ELSE
  134.             ' radius of circle is max when z is near 0 and min when z is max
  135.             sr = map(starField(i).z, 0, WScreen, radStar, 0)
  136.         END IF
  137.  
  138.         CIRCLE (sx, sy), sr, _RGB(255, 255, 255)
  139.         ' if radius of circle is more than 1 you can fill it else no
  140.         IF sr > 1 THEN PAINT STEP(0, 0), _RGB(255, 255, 255), _RGB(255, 255, 255)
  141.  
  142.         ' if we want draw the wake of the stars when we travel in warp speed
  143.         IF WarpVel = True THEN
  144.             px = map(starField(i).x / (starField(i).z + 25), 0, 1, 0, WScreen)
  145.             py = map(starField(i).y / (starField(i).z + 25), 0, 1, 0, HScreen)
  146.             LINE (sx, sy)-(px, py), _RGB(255, 255, 255)
  147.         END IF
  148.     NEXT
  149.     info
  150.     _DEST a
  151.     _SOURCE b
  152.     _PUTIMAGE
  153.  
  154. FUNCTION MinMax (Max%, Min%)
  155.     IF Max% < Min% THEN SWAP Max%, Min%
  156.     MinMax = INT(RND * (Max% - Min% + 1)) + Min%
  157.  
  158. ' p5.js Functions
  159. FUNCTION map! (value!, mianRange!, maxRange!, newMinRange!, newMaxRange!)
  160.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  161.  
  162. SUB info
  163.     LOCATE 1, 1: PRINT "Stop";
  164.     LOCATE 1, 98: PRINT "Run";
  165.  
  166.     LOCATE 2, 1: PRINT "Speed:"; Zvel;
  167.     IF WarpVel = True THEN PRINT "Mode Warp ON" ELSE PRINT "Mode Warp OFF"
  168.     LOCATE 2, 91: PRINT "Yvel "; Yvel;
  169.     LOCATE 2, 82: PRINT "Xvel "; Xvel;
  170.     LOCATE 30, 1: PRINT " Help: Spacebar = quit, Enter = reset, + = vel up , - = vel down, Arrows= directions, W = warp mode";
  171.  
  172.  

Thanks to share your code

PS is color of star random (with not specific meaning)?

Title: Re: Help with Starfield
Post by: OldMoses on August 11, 2019, 07:31:36 pm
Pretty cool use of the mouse. It took me a minute figure out that it was working with the width of screen, but after that there was no issues controlling it.
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 08:42:07 pm
Thanks OldMoses.

TempoidBasic, that's a really cool example! I am working on something similar but not that advanced. I'm going to change from the mouse to the arrow keys if I can figure it out. The mouse is just too touchy and is hard to get back to center, for the general public anyway.
Title: Re: Help with Starfield
Post by: SierraKen on August 11, 2019, 10:01:34 pm
I changed mine to use the arrow keys inside. Arrow keys make it easier to control. Also I made it so the Space Bar puts it back to center. :) One interesting thing I found out is that the xx variable I use to add or subtract from the center, can make it do weird things if it's in the negative lol. Like if you make xx negative, it will show the stars coming from each side of the screen instead and overlapping. lol I removed that part because it just didn't look right. LOL

This version is on my website now along with thanks to B+ and the guys on this forum, as well as a link to this forum. http://www.KensPrograms.com/

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2.  
  3. _TITLE "Warp Speed  - Use Up and Down Arrow Key for speed and Right and Left Arrows to view sides and Space Bar to center."
  4. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  5.  
  6. SCREEN _NEWIMAGE(800, 800, 32)
  7.  
  8. 'Set the default speed, amount of stars, and then make the first stars.
  9. speed = .001
  10. amount = 200
  11. xx = 0
  12. FOR stars = 1 TO amount
  13.     GOSUB make:
  14. NEXT stars
  15.  
  16.     _LIMIT 1000
  17.     FOR stars = 1 TO amount
  18.         a$ = INKEY$
  19.         IF a$ = CHR$(27) THEN END
  20.         IF a$ = CHR$(0) + CHR$(77) THEN xx = xx + 50
  21.         IF a$ = CHR$(0) + CHR$(75) THEN xx = xx - 50
  22.         IF a$ = " " THEN xx = 0
  23.  
  24.         IF xx > 1200 THEN xx = 1200
  25.         IF xx < -1200 THEN xx = -1200
  26.  
  27.         'Detect the arrow keys to make it go faster or slower.
  28.         IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  29.         IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  30.         IF warp < .002 THEN warp = 0
  31.         IF warp > 10 THEN warp = 10
  32.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  33.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  34.         IF speed < .001 THEN speed = .001
  35.         IF speed > .01 THEN speed = .01
  36.  
  37.         'Move the stars.
  38.         x(stars) = x(stars) + dx(stars) * speed
  39.         y(stars) = y(stars) + dy(stars) * speed
  40.  
  41.         'Get a new star if one goes off the screen.
  42.         IF x(stars) < -6400 OR x(stars) > 6400 OR y(stars) < -400 OR y(stars) > 400 THEN GOSUB make:
  43.  
  44.         'Draw the stars, c(stars) is the choice of color.
  45.         IF sz(stars) > 2 THEN sz(stars) = 2
  46.         IF c(stars) < 65 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  47.         IF c(stars) > 64 AND c(stars) < 85 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  48.         IF c(stars) > 84 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  49.  
  50.         'If the size of the star is less than 1, skip paint.
  51.         IF sz(stars) < 1 THEN GOTO nopaint:
  52.  
  53.         'Paint the stars.
  54.         IF c(stars) < 65 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  55.         IF c(stars) > 64 AND c(stars) < 85 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  56.         IF c(stars) > 84 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  57.         nopaint:
  58.     NEXT stars
  59.  
  60.     'This stops flickering.
  61.     _DISPLAY
  62.  
  63.     'Erase the stars for motion but keep a transparent black for the trails.
  64.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  65.  
  66. make:
  67.  
  68. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  69.  
  70. x(stars) = (RND - .5) * _WIDTH
  71.  
  72. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  73.  
  74. y(stars) = (RND - .5) * _HEIGHT
  75.  
  76. 'Get a random star size between .25 and 2.
  77.  
  78. sz(stars) = (RND * 2) + .25
  79.  
  80. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  81.  
  82. c(stars) = INT(RND * 100) + 1
  83.  
  84. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  85.  
  86. v = 5 + RND * 5
  87. dx(stars) = x(stars) * v
  88. dy(stars) = y(stars) * v
  89.  
  90.  
Title: Re: Help with Starfield
Post by: TempodiBasic on August 12, 2019, 06:20:29 pm
Sierraken
good and cool!

Well done.
Title: Re: Help with Starfield
Post by: TempodiBasic on August 12, 2019, 07:08:43 pm
Hi SierraKen

please read this second my feedback only if you want go further to the development of your creature otherwise go on another topic.
And thanks to let me read and try your code.

I can pass you some tips that at its time I got from Qb64 masters...

1.  smoother keyboard input with new QB64 function than Inkey$

see a mod of your program

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2. '2019-08-12 TDB mod introducing _keyhit and _Keyclear to a   smoother response to keyboard
  3.  
  4. _TITLE "Warp Speed  - Use Up and Down Arrow Key for speed and Right and Left Arrows to view sides and Space Bar to center."
  5. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  6.  
  7. SCREEN _NEWIMAGE(800, 800, 32)
  8.  
  9. 'Set the default speed, amount of stars, and then make the first stars.
  10. speed = .001
  11. amount = 200
  12. xx = 0
  13. FOR stars = 1 TO amount
  14.     GOSUB make:
  15. NEXT stars
  16.  
  17.     _LIMIT 30 ' <---- it seems enough in respect of 1000
  18.     FOR stars = 1 TO amount
  19.         ' a$ = INKEY$
  20.  
  21.         u = 0 ' a tricky way to reset the variable of input
  22.         u = _KEYHIT
  23.         IF u = 27 THEN END
  24.         IF u = 19200 THEN xx = xx - 50
  25.         IF u = 19712 THEN xx = xx + 50
  26.         IF u = 32 THEN xx = 0
  27.         ' IF a$ = CHR$(27) THEN END
  28.         ' IF a$ = CHR$(0) + CHR$(77) THEN xx = xx + 50
  29.         ' IF a$ = CHR$(0) + CHR$(75) THEN xx = xx - 50
  30.         ' IF a$ = " " THEN xx = 0
  31.  
  32.         IF xx > 1200 THEN xx = 1200
  33.         IF xx < -1200 THEN xx = -1200
  34.  
  35.         'Detect the arrow keys to make it go faster or slower.
  36.         IF u = 18432 THEN speed = speed + .001: warp = warp + 1
  37.         IF u = 20480 THEN speed = speed - .001: warp = warp - 1
  38.         REM _KEYCLEAR  '<---- you can get the same effect REMming u = 0 and activating this statement here
  39.  
  40.         'IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  41.         'IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  42.  
  43.         IF warp < .002 THEN warp = 0
  44.         IF warp > 10 THEN warp = 10
  45.         IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  46.         IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  47.         IF speed < .001 THEN speed = .001
  48.         IF speed > .01 THEN speed = .01
  49.  
  50.         'Move the stars.
  51.         x(stars) = x(stars) + dx(stars) * speed
  52.         y(stars) = y(stars) + dy(stars) * speed
  53.  
  54.         'Get a new star if one goes off the screen.
  55.         IF x(stars) < -6400 OR x(stars) > 6400 OR y(stars) < -400 OR y(stars) > 400 THEN GOSUB make:
  56.  
  57.         'Draw the stars, c(stars) is the choice of color.
  58.         IF sz(stars) > 2 THEN sz(stars) = 2
  59.         IF c(stars) < 65 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  60.         IF c(stars) > 64 AND c(stars) < 85 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  61.         IF c(stars) > 84 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  62.  
  63.         'If the size of the star is less than 1, skip paint.
  64.         IF sz(stars) < 1 THEN GOTO nopaint:
  65.  
  66.         'Paint the stars.
  67.         IF c(stars) < 65 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  68.         IF c(stars) > 64 AND c(stars) < 85 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  69.         IF c(stars) > 84 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  70.         nopaint:
  71.     NEXT stars
  72.  
  73.     'This stops flickering.
  74.     _DISPLAY
  75.  
  76.     'Erase the stars for motion but keep a transparent black for the trails.
  77.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  78.  
  79. make:
  80.  
  81. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  82.  
  83. x(stars) = (RND - .5) * _WIDTH
  84.  
  85. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  86.  
  87. y(stars) = (RND - .5) * _HEIGHT
  88.  
  89. 'Get a random star size between .25 and 2.
  90.  
  91. sz(stars) = (RND * 2) + .25
  92.  
  93. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  94.  
  95. c(stars) = INT(RND * 100) + 1
  96.  
  97. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  98.  
  99. v = 5 + RND * 5
  100. dx(stars) = x(stars) * v
  101. dy(stars) = y(stars) * v
  102.  
  103.  

2. less flickering or blinking of screen   (also with Inkey$ if you move fast to right or to left you got the stars jumping on the screen)
  2.1 an alternative (long?) way to manage output to screen with 2 panel for images
  2.2 an adjust of _limit value
  2.3 an adjust of how to move in the select direction the stars (50 is high, 20 seems better)

Code: QB64: [Select]
  1. 'Thank you to B+ and other guys from the QB64.org forum for their code examples to make this program!
  2. '2019-08-12 TDB mod introducing _keyhit and _Keyclear to a smoother response to keyboard
  3. '2019-08-12 TDB mod introducing the 2 panel tecnique for animation to avoid flickering and loose of images
  4. _TITLE "Warp Speed  - Use Up and Down Arrow Key for speed and Right and Left Arrows to view sides and Space Bar to center."
  5. DIM x(800), y(800), dx(800), dy(800), sz(800), c(800)
  6.  
  7. SCREEN _NEWIMAGE(800, 800, 32)
  8.  
  9. ' another way to avoid flickering is to use 2 panel 1st for screen output and 2nd for drawing
  10. ' so you draw on 2nd and copy to 1st to show
  11. Bpanel& = _NEWIMAGE(800, 800, 32)
  12.  
  13.  
  14. 'Set the default speed, amount of stars, and then make the first stars.
  15. speed = .001
  16. amount = 200
  17. xx = 0
  18. FOR stars = 1 TO amount
  19.     GOSUB make:
  20. NEXT stars
  21.  
  22.     _LIMIT 30 ' <---- it seems enough in respect of 1000
  23.     FOR stars = 1 TO amount
  24.         ' a$ = INKEY$
  25.  
  26.         u = 0 ' a tricky way to reset the variable of input
  27.         u = _KEYHIT
  28.         IF u = 27 THEN END
  29.         IF u = 19200 THEN xx = xx - 20 ' left key
  30.         IF u = 19712 THEN xx = xx + 20 ' right key
  31.         IF u = 32 THEN xx = 0
  32.         ' IF a$ = CHR$(27) THEN END
  33.         ' IF a$ = CHR$(0) + CHR$(77) THEN xx = xx + 50
  34.         ' IF a$ = CHR$(0) + CHR$(75) THEN xx = xx - 50
  35.         ' IF a$ = " " THEN xx = 0
  36.  
  37.         IF xx > 1200 THEN xx = 1200
  38.         IF xx < -1200 THEN xx = -1200
  39.  
  40.         'Detect the arrow keys to make it go faster or slower.
  41.         IF u = 18432 THEN speed = speed + .001: warp = warp + 1 ' up key
  42.         IF u = 20480 THEN speed = speed - .001: warp = warp - 1 ' down key
  43.         REM _KEYCLEAR  '<---- you can get the same effect REMming u = 0 and activating this statement here
  44.  
  45.         'IF a$ = CHR$(0) + CHR$(72) THEN speed = speed + .001: warp = warp + 1
  46.         'IF a$ = CHR$(0) + CHR$(80) THEN speed = speed - .001: warp = warp - 1
  47.  
  48.         IF warp < .002 THEN warp = 0
  49.         IF warp > 10 THEN warp = 10
  50.         'Why do you write on the screen 200 times the same text?
  51.         ' I  move the PRINT instruction in the area of output to screen one time out of for..next
  52.  
  53.         IF speed < .001 THEN speed = .001
  54.         IF speed > .01 THEN speed = .01
  55.  
  56.         'Move the stars.
  57.         x(stars) = x(stars) + dx(stars) * speed
  58.         y(stars) = y(stars) + dy(stars) * speed
  59.  
  60.         'Get a new star if one goes off the screen.
  61.         IF x(stars) < -6400 OR x(stars) > 6400 OR y(stars) < -400 OR y(stars) > 400 THEN GOSUB make:
  62.  
  63.  
  64.         _DEST Bpanel&
  65.         'Draw the stars, c(stars) is the choice of color.
  66.         IF sz(stars) > 2 THEN sz(stars) = 2
  67.         IF c(stars) < 65 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(255, 255, 255)
  68.         IF c(stars) > 64 AND c(stars) < 85 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(100, 10, 10)
  69.         IF c(stars) > 84 THEN CIRCLE ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), sz(stars), _RGB32(10, 10, 200)
  70.  
  71.         'If the size of the star is less than 1, skip paint.
  72.         IF sz(stars) < 1 THEN GOTO nopaint:
  73.  
  74.         'Paint the stars.
  75.         IF c(stars) < 65 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(255, 255, 255)
  76.         IF c(stars) > 64 AND c(stars) < 85 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(100, 10, 10)
  77.         IF c(stars) > 84 THEN PAINT ((x(stars) + _WIDTH / 2) + xx, -y(stars) + _HEIGHT / 2), _RGB32(10, 10, 200)
  78.         nopaint:
  79.     NEXT stars
  80.     ' here print one time info in text format on the screen
  81.     IF warp > 0 THEN LOCATE 1, 1: PRINT "Warp: "; warp
  82.     IF warp = 0 THEN LOCATE 1, 1: PRINT "Cruise Speed"
  83.     _SOURCE Bpanel&: _DEST 0
  84.     _PUTIMAGE
  85.  
  86.     'This stops flickering.
  87.     '   _DISPLAY              <--- the quick method
  88.  
  89.  
  90.     _DEST Bpanel&
  91.     'Erase the stars for motion but keep a transparent black for the trails.
  92.     CLS , _RGBA32(0, 0, 0, 30)
  93.     '    LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 30), BF
  94.  
  95. make:
  96.  
  97. 'Get a random X number using 2 decimal points - RND and .5 and times it by the width of the screen.
  98.  
  99. x(stars) = (RND - .5) * _WIDTH
  100.  
  101. 'Get a random Y number using 2 decimal points - RND and .5 and times it by the height of the screen.
  102.  
  103. y(stars) = (RND - .5) * _HEIGHT
  104.  
  105. 'Get a random star size between .25 and 2.
  106.  
  107. sz(stars) = (RND * 2) + .25
  108.  
  109. 'Get a random number between 1 and 100 to pick 1 of 3 different star colors in the main loop.
  110.  
  111. c(stars) = INT(RND * 100) + 1
  112.  
  113. 'Get any random number between 5 and 10, used for both X and Y, to use in the star movement in the main loop.
  114.  
  115. v = 5 + RND * 5
  116. dx(stars) = x(stars) * v
  117. dy(stars) = y(stars) * v
  118.  
  119.  
  120.  

and two glitches...
1 moving to the leftest position or the rightest position you get stars moving in the opposite extreme direction
2 moving fastly to left or to right from initial position you get some various movements of stars
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Thanks to read