Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Qwerkey

Pages: 1 2 [3] 4 5 ... 8
31
QB64 Discussion / Call for Samples and Games
« on: March 17, 2020, 06:22:18 am »
If you would like one of your Projects to be added to Our Samples or Games, please submit a request to the Library Staff.  Please see Instructions: https://www.qb64.org/forum/index.php?topic=178.0

We would particularly be interested in receiving submissions from our most prolific members.

@TempodiBasic @Cobalt @SierraKen @Petr @Dav @jack @[banned user] @SirCrow If you have a project (which is not a game) which you consider worthy of our Samples and which you would like us to consider, then please contact the Library Staff.

@SMcNeill @Pete @Cobalt @SierraKen @Petr @Dav @RhoSigma @Richard Frost @jack @[banned user] @SirCrow If you have a project which is a game and which you consider worthy of our Games and which you would like us to consider, then please contact the Library Staff.

You are under no obligation whatsoever.

Your Library Staff: @STxAxTIC @bplus @Qwerkey

32
SUB _GL / 3D Knots by Ashish
« on: March 14, 2020, 11:59:21 am »
3D Knots

Author: @Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=169.msg902#msg902
Version: 1
Tags: [3D], [Graphics], [Open_GL]

Description:
Some mathematical knots or geometry, effected by SUB _GL

Source Code:
Code: QB64: [Select]
  1. 'Coded in QB64 by Ashish on 9 March, 2018
  2. 'http://paulbourke.net/geometry/knots/
  3. _TITLE "3D Knot [Press space for next knot]"
  4.  
  5. SCREEN _NEWIMAGE(700, 700, 32)
  6.  
  7. TYPE vec3
  8.     x AS SINGLE
  9.     y AS SINGLE
  10.     z AS SINGLE
  11. DECLARE LIBRARY 'used for camera.
  12.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  13.  
  14. DIM SHARED glAllow AS _BYTE, knot_type, ma 'knot_type store the type knot being drawn. ma store percentage of knot which is being drawn.
  15. knot_type = 1
  16. glAllow = -1
  17.  
  18.     k& = _KEYHIT
  19.     IF k& = ASC(" ") THEN
  20.         knot_type = knot_type + 1
  21.         ma = 0
  22.         IF knot_type > 7 THEN knot_type = 1 '7 knots are there.
  23.     END IF
  24.     _LIMIT 60
  25.  
  26. SUB _GL ()
  27.     STATIC glInit, clock
  28.     ' static r, pos, theta, phi, beta
  29.  
  30.     IF NOT glAllow THEN EXIT SUB
  31.  
  32.     IF NOT glInit THEN
  33.         glInit = -1
  34.         aspect# = _WIDTH / _HEIGHT
  35.         _glViewport 0, 0, _WIDTH, _HEIGHT
  36.     END IF
  37.  
  38.     _glEnable _GL_DEPTH_TEST 'We are doing 3D. This enables Z-Buffer.
  39.  
  40.     'set perspective configuration
  41.     _glMatrixMode _GL_PROJECTION
  42.     _gluPerspective 45.0, aspect#, 1.0, 100.0
  43.  
  44.     _glMatrixMode _GL_MODELVIEW
  45.     ' gluLookAt 0,0,-1,0,0,0,0,1,0
  46.  
  47.     _glColor3f 1, 1, 1 'set color
  48.     _glTranslatef 0, 0, 0 'not require. becoz, origin is already at 0,0,0
  49.     _glRotatef clock * 90, 0, 1, 0 'rotation along Y-axis
  50.     _glLineWidth 3.0 'width of the line.
  51.  
  52.     SELECT CASE knot_type
  53.         CASE 7 'equations are knots are taken from paulbourke site
  54.             _glBegin _GL_LINE_STRIP
  55.             'for animation, value of ma is gradually increased till a certain constant. In this case, it is pi.
  56.             FOR beta = 0 TO ma STEP .005
  57.                 r = .3 + .6 * SIN(6 * beta)
  58.                 theta = 2 * beta
  59.                 phi = _PI(.6) * SIN(12 * beta)
  60.                 x = r * COS(phi) * COS(theta)
  61.                 y = r * COS(phi) * SIN(theta)
  62.                 z = r * SIN(phi)
  63.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  64.                 _glVertex3f x, y, z 'draws it.
  65.             NEXT
  66.             _glEnd
  67.             IF ma <= _PI THEN ma = ma + .005
  68.             'others are made to be rendered in the same way.
  69.         CASE 6
  70.             _glBegin _GL_LINE_STRIP
  71.             FOR beta = 0 TO ma STEP .005
  72.                 r = 1.2 * 0.6 * SIN(_PI(.5) * 6 * beta)
  73.                 theta = 4 * beta
  74.                 phi = _PI(.2) * SIN(6 * beta)
  75.                 x = r * COS(phi) * COS(theta)
  76.                 y = r * COS(phi) * SIN(theta)
  77.                 z = r * SIN(phi)
  78.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  79.                 _glVertex3f x, y, z
  80.             NEXT
  81.             _glEnd
  82.             IF ma <= _PI(2) THEN ma = ma + .005
  83.         CASE 5
  84.             k = 1
  85.             _glBegin _GL_LINE_STRIP
  86.             FOR u = 0 TO ma STEP .005
  87.                 x = COS(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  88.                 y = SIN(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  89.                 z = -SIN(2 * u / (2 * k + 1)) / 5
  90.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  91.                 _glVertex3f x, y, z
  92.             NEXT
  93.             _glEnd
  94.             IF ma < _PI(4 * k + 2) THEN ma = ma + .045
  95.         CASE 4
  96.             k = 2
  97.             _glBegin _GL_LINE_STRIP
  98.             FOR u = 0 TO ma STEP .005
  99.                 x = COS(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  100.                 y = SIN(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  101.                 z = -SIN(2 * u / (2 * k + 1)) / 5
  102.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  103.                 _glVertex3f x, y, z
  104.             NEXT
  105.             _glEnd
  106.             IF ma < _PI(4 * k + 2) THEN ma = ma + .045
  107.         CASE 3
  108.             k = 3
  109.             _glBegin _GL_LINE_STRIP
  110.             FOR u = 0 TO ma STEP .005
  111.                 x = COS(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  112.                 y = SIN(u) * (2 - COS(2 * u / (2 * k + 1))) / 5
  113.                 z = -SIN(2 * u / (2 * k + 1)) / 5
  114.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  115.                 _glVertex3f x, y, z
  116.             NEXT
  117.             _glEnd
  118.             IF ma < _PI(4 * k + 2) THEN ma = ma + .045
  119.         CASE 2
  120.             _glBegin _GL_LINE_STRIP
  121.             FOR u = 0 TO ma STEP .005
  122.                 x = (41 * COS(u) - 18 * SIN(u) - 83 * COS(2 * u) - 83 * SIN(2 * u) - 11 * COS(3 * u) + 27 * SIN(3 * u)) / 200
  123.                 y = (36 * COS(u) + 27 * SIN(u) - 113 * COS(2 * u) + 30 * SIN(2 * u) + 11 * COS(3 * u) - 27 * SIN(3 * u)) / 200
  124.                 z = (45 * SIN(u) - 30 * COS(2 * u) + 113 * SIN(2 * u) - 11 * COS(3 * u) + 27 * SIN(3 * u)) / 200
  125.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  126.                 _glVertex3f x, y, z
  127.             NEXT
  128.             _glEnd
  129.             IF ma < _PI(2) THEN ma = ma + .005
  130.         CASE 1
  131.             _glBegin _GL_LINE_STRIP
  132.             FOR u = 0 TO ma STEP .005
  133.                 x = (-22 * COS(u) - 128 * SIN(u) - 44 * COS(3 * u) - 78 * SIN(3 * u)) / 200
  134.                 y = (-10 * COS(2 * u) - 27 * SIN(2 * u) + 38 * COS(4 * u) + 46 * SIN(4 * u)) / 200
  135.                 z = (70 * COS(3 * u) - 40 * SIN(3 * u)) / 200
  136.                 _glColor3f map(x, -1, 1, 0, 1), map(y, -1, 1, 0, 1), map(z, -1, 1, 0, 1)
  137.                 _glVertex3f x, y, z
  138.             NEXT
  139.             _glEnd
  140.             IF ma < _PI(2) THEN ma = ma + .005
  141.     END SELECT
  142.     _glFlush
  143.  
  144.     clock = clock + .01
  145.  
  146. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  147.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  148.  

 
3D Knots Screenshot.jpg

33
SUB _GL / 3D : Sierpinski Cube by Ashish
« on: March 14, 2020, 08:56:11 am »
3D : Sierpinski Cube

Author: @Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2251.msg114913#msg114913
Version: 1
Tags: [3D], [Graphics], [Open_GL]

Description:
This fractal is popularly known as Menger Sponge. It looks beautiful.

Controls:
Move mouse for rotation.

Source Code:
Code: QB64: [Select]
  1. '@Author:Ashish Kushwaha
  2. '28 Feb, 2020s
  3. _TITLE "Menger Sponge"
  4. SCREEN _NEWIMAGE(600, 600, 32)
  5.  
  6. TYPE vec3
  7.     x AS SINGLE
  8.     y AS SINGLE
  9.     z AS SINGLE
  10.  
  11.     SUB glutSolidCube (BYVAL dsize AS DOUBLE) 'use to draw a solid cube by taking the side length as its arguement
  12.  
  13. 'Algorithm
  14. '1. We take a cube.
  15. '2. We divide it into 27 equal cubical parts.
  16. '3. Out of this 27 cubes, 7 cubes are removed.
  17. '4. In the remaining 20 cubes, Step-1 is repeated for each cube.
  18. iteration = 3 'no. of iteration. At each iteration, 7 cubes are removed from parent cube.
  19. size = 0.5 'the size of our first cube
  20. n = (20 ^ iteration) - 1
  21.  
  22. DIM SHARED glAllow, cubeLoc(n) AS vec3, fundamentalCubeSize 'cubeLoc array store the location of cubes to be rendered. They are the smallest cube which are formed in the last iteration
  23. fundamentalCubeSize = size / (3 ^ iteration) 'the size the smallest cube which is formed in the last iteration
  24. initFractal 0, 0, 0, size, iteration 'this sub done all calculation for cube location & other stuff.
  25.  
  26. PRINT (n + 1); " Cubes will rendered with total of "; 8 * (n + 1); " vertices"
  27. PRINT "Hit a Key"
  28. glAllow = 1 'to start rendering in the SUB _GL
  29.     _LIMIT 40
  30.  
  31. SUB _GL () STATIC
  32.     DIM clr(3)
  33.     IF glAllow = 0 THEN EXIT SUB 'So that rendering will start as soon as initialization is done.
  34.     IF glInit = 0 THEN
  35.         _glViewport 0, 0, _WIDTH, _HEIGHT 'this defines the area in the screen where GL rendering will occur
  36.         aspect# = _WIDTH / _HEIGHT
  37.  
  38.         glInit = 1
  39.     END IF
  40.  
  41.     _glEnable _GL_DEPTH_TEST 'this enable Z-buffer. So that we can do 3D things.
  42.     _glClear _GL_DEPTH_BUFFER_BIT OR _GL_COLOR_BUFFER_BIT 'Not required unless we do softwre rendering as well.
  43.  
  44.     'LIGHTS CONFIG
  45.     _glEnable _GL_LIGHTING 'this enable us to use light. There are max of 8 lights in GL
  46.     _glEnable _GL_LIGHT0
  47.     clr(0) = 0.2: clr(1) = 0.2: clr(2) = 0.2: clr(3) = 1
  48.     _glLightfv _GL_LIGHT0, _GL_AMBIENT, _OFFSET(clr()) 'this define the color of the material where light can hardly reach.
  49.     clr(0) = 0.8: clr(1) = 0.8: clr(2) = 0.8: clr(3) = 1
  50.     _glLightfv _GL_LIGHT0, _GL_SPECULAR, _OFFSET(clr()) 'this define the color of the material where light is directly reflected & reach your eye.
  51.     _glLightfv _GL_LIGHT0, _GL_DIFFUSE, _OFFSET(clr()) 'this define the default/usual color of the light on the material.
  52.     clr(0) = 0: clr(1) = 0: clr(2) = 0: clr(3) = 1
  53.     _glLightfv _GL_LIGHT0, _GL_POSITION, _OFFSET(clr()) 'use to define the direction of light when 4th component is 0. When 4th component is 1, it defines the position of light. In this case, the light looses its intensity as distance increases.
  54.  
  55.     _glMatrixMode _GL_PROJECTION 'usually used for setting up perspective etc.
  56.     _gluPerspective 60, aspect#, 0.1, 10 'first arguement tell angle for FOV (Field of View, for human it is round 70degree for one eye.LOL) next one aspect ratio, next 2 are near & far distance. Objects which are not between these distance are clipped. (or are not rendered.)
  57.  
  58.     _glMatrixMode _GL_MODELVIEW 'rendering takes place here
  59.  
  60.     _glTranslatef 0, 0, -1 'move the origin forward by 1 unit
  61.     _glRotatef _MOUSEX, 0, 1, 0 'these are for rotation by the movement of mouse.
  62.     _glRotatef _MOUSEY, 1, 0, 0
  63.  
  64.     drawFractal 'draws the fractal
  65.     _glFlush 'force all the GL command to complete in finite amount of time
  66.  
  67. SUB initFractal (x, y, z, s, N) 'x-position, y-position, z-position, size, N-> iteration
  68.     STATIC i
  69.     'As we divide the cube, value of N decreases.
  70.     IF N = 0 THEN 'when the division is done N times (no. of iteration)
  71.         cubeLoc(i).x = x 'store the coordinates of cube
  72.         cubeLoc(i).y = y
  73.         cubeLoc(i).z = z
  74.         i = i + 1
  75.         ' ? "Added #",i
  76.         ' sleep
  77.         EXIT SUB
  78.     END IF
  79.     'top section
  80.     'front row, left to right
  81.     initFractal (x - s / 3), (y + s / 3), (z + s / 3), s / 3, N - 1
  82.     initFractal (x), (y + s / 3), (z + s / 3), s / 3, N - 1
  83.     initFractal (x + s / 3), (y + s / 3), (z + s / 3), s / 3, N - 1
  84.     'behind the previous row, left to right
  85.     initFractal (x - s / 3), (y + s / 3), (z), s / 3, N - 1
  86.     initFractal (x + s / 3), (y + s / 3), (z), s / 3, N - 1
  87.     'behind the previous row, left to right
  88.     initFractal (x - s / 3), (y + s / 3), (z - s / 3), s / 3, N - 1
  89.     initFractal (x), (y + s / 3), (z - s / 3), s / 3, N - 1
  90.     initFractal (x + s / 3), (y + s / 3), (z - s / 3), s / 3, N - 1
  91.     'middle section
  92.     'front row, left to right
  93.     initFractal (x - s / 3), (y), (z + s / 3), s / 3, N - 1
  94.     initFractal (x + s / 3), (y), (z + s / 3), s / 3, N - 1
  95.     'behind the previous row (last one as middle one contain no cube ;) ), left to right
  96.     initFractal (x - s / 3), (y), (z - s / 3), s / 3, N - 1
  97.     initFractal (x + s / 3), (y), (z - s / 3), s / 3, N - 1
  98.     'bottom section
  99.     'front row, left to right
  100.     initFractal (x - s / 3), (y - s / 3), (z + s / 3), s / 3, N - 1
  101.     initFractal (x), (y - s / 3), (z + s / 3), s / 3, N - 1
  102.     initFractal (x + s / 3), (y - s / 3), (z + s / 3), s / 3, N - 1
  103.     'behind the previous row, left to right
  104.     initFractal (x - s / 3), (y - s / 3), (z), s / 3, N - 1
  105.     initFractal (x + s / 3), (y - s / 3), (z), s / 3, N - 1
  106.     'behind the previous row, left to right
  107.     initFractal (x - s / 3), (y - s / 3), (z - s / 3), s / 3, N - 1
  108.     initFractal (x), (y - s / 3), (z - s / 3), s / 3, N - 1
  109.     initFractal (x + s / 3), (y - s / 3), (z - s / 3), s / 3, N - 1 '20
  110.  
  111.  
  112. SUB drawFractal ()
  113.     FOR i = 0 TO UBOUND(cubeLoc)
  114.         _glPushMatrix 'save the previous transformation configuration
  115.         _glTranslatef cubeLoc(i).x, cubeLoc(i).y, cubeLoc(i).z 'move at given location
  116.         glutSolidCube fundamentalCubeSize 'draws the solid cube of smallest size which is formed in the last iteration
  117.         _glPopMatrix 'restore the original transformation configuration
  118.     NEXT
  119.  

 
Menger Sponge Screenshot.png

34
SUB _GL / 3D Double Pendulum by Ashish
« on: March 12, 2020, 12:53:56 pm »
3D Double Pendulum

Author: @ Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=153.msg828#msg828
Version: 1
Tags: [3D], [Graphics], [Open_GL]

Description:
A double pendulum swinging in 3D.

Source Code:
Code: QB64: [Select]
  1. 'Coded By Ashish on 4 March, 2018
  2.  
  3. _TITLE "3D Double Pendulum [Press Space for new settings]"
  4. SCREEN _NEWIMAGE(800, 600, 32)
  5.  
  6. TYPE vec3
  7.     x AS DOUBLE
  8.     y AS DOUBLE
  9.     z AS DOUBLE
  10.  
  11. TYPE pendlm
  12.     POS AS vec3
  13.     r AS DOUBLE
  14.     ang AS DOUBLE
  15.     angInc AS DOUBLE
  16.     angSize AS DOUBLE
  17.  
  18.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  19.     SUB glutSolidSphere (BYVAL radius AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  20.  
  21. DIM SHARED glAllow AS _BYTE
  22. DIM SHARED pendulum(1) AS pendlm, t1 AS vec3, t2 AS vec3
  23. DIM SHARED tracer(3000) AS vec3, tracerSize AS _UNSIGNED LONG
  24.  
  25. settings:
  26. tracerSize = 0
  27. g = 0
  28.  
  29. pendulum(0).POS.x = 0
  30. pendulum(0).POS.y = 0
  31. pendulum(0).POS.z = 0
  32. pendulum(0).r = p5random(.7, 1.1)
  33. pendulum(0).angInc = p5random(0, _PI(2))
  34. pendulum(0).angSize = p5random(_PI(.3), _PI(.6))
  35.  
  36. pendulum(1).r = p5random(.25, .5)
  37. pendulum(1).angInc = p5random(0, _PI(2))
  38. pendulum(1).angSize = p5random(_PI(.3), _PI(1.1))
  39.  
  40. glAllow = -1
  41.     k& = _KEYHIT
  42.     IF k& = ASC(" ") THEN GOTO settings
  43.     pendulum(0).ang = SIN(pendulum(0).angInc) * pendulum(0).angSize + _PI(.5)
  44.  
  45.     t1.x = COS(pendulum(0).ang) * pendulum(0).r + pendulum(0).POS.x
  46.     t1.y = SIN(pendulum(0).ang) * pendulum(0).r + pendulum(0).POS.y
  47.     t1.z = COS(pendulum(0).ang) * pendulum(0).r + pendulum(0).POS.z
  48.  
  49.     pendulum(1).POS = t1
  50.  
  51.     pendulum(1).ang = SIN(pendulum(1).angInc) * pendulum(1).angSize + pendulum(0).ang
  52.  
  53.     t2.x = COS(pendulum(1).ang) * pendulum(1).r + pendulum(1).POS.x
  54.     t2.y = SIN(pendulum(1).ang) * pendulum(1).r + pendulum(1).POS.y
  55.     t2.z = SIN(pendulum(1).ang) * pendulum(1).r + pendulum(1).POS.z
  56.  
  57.     pendulum(0).angInc = pendulum(0).angInc + .02
  58.     pendulum(1).angInc = pendulum(1).angInc + .043
  59.  
  60.     IF tracerSize < UBOUND(tracer) - 1 AND g > 40 THEN tracer(tracerSize) = t2
  61.     IF g > 40 AND tracerSize < UBOUND(tracer) - 1 THEN tracerSize = tracerSize + 1
  62.  
  63.     g = g + 1
  64.     _LIMIT 60
  65.  
  66. SUB _GL () STATIC
  67.     IF NOT glAllow THEN EXIT SUB
  68.  
  69.     IF NOT glInit THEN
  70.         glInit = -1
  71.         aspect# = _WIDTH / _HEIGHT
  72.         _glViewport 0, 0, _WIDTH, _HEIGHT
  73.     END IF
  74.  
  75.     _glEnable _GL_BLEND
  76.     _glEnable _GL_DEPTH_TEST
  77.  
  78.  
  79.     _glShadeModel _GL_SMOOTH
  80.  
  81.     _glMatrixMode _GL_PROJECTION
  82.     _gluPerspective 45.0, aspect#, 1.0, 1000.0
  83.  
  84.     _glMatrixMode _GL_MODELVIEW
  85.  
  86.     gluLookAt 0, 0, -4, 0, 1, 0, 0, -1, 0
  87.  
  88.     _glRotatef clock# * 90, 0, 1, 0
  89.     _glLineWidth 3.0
  90.  
  91.  
  92.     _glColor4f 1, 1, 1, .7
  93.  
  94.     _glBegin _GL_LINES
  95.     _glVertex3f pendulum(0).POS.x, pendulum(0).POS.y, pendulum(0).POS.z
  96.     _glVertex3f t1.x, t1.y, t1.z
  97.     _glEnd
  98.  
  99.  
  100.     _glBegin _GL_LINES
  101.     _glVertex3f t1.x, t1.y, t1.z
  102.     _glVertex3f t2.x, t2.y, t2.z
  103.     _glEnd
  104.  
  105.     IF tracerSize > 3 THEN
  106.         _glBegin _GL_LINES
  107.         FOR i = 0 TO tracerSize - 2
  108.             _glColor3f 0, map(tracer(i).x, -1, 1, .5, 1), map(tracer(i).y, -1, 1, .5, 1)
  109.             _glVertex3f tracer(i).x, tracer(i).y, tracer(i).z
  110.             _glColor3f 0, map(tracer(i + 1).x, -1, 1, .5, 1), map(tracer(i + 1).y, -1, 1, .5, 1)
  111.             _glVertex3f tracer(i + 1).x, tracer(i + 1).y, tracer(i + 1).z
  112.         NEXT
  113.         _glEnd
  114.     END IF
  115.  
  116.     _glEnable _GL_LIGHTING
  117.     _glEnable _GL_LIGHT0
  118.     _glTranslatef t1.x, t1.y, t1.z
  119.  
  120.     _glColor3f .8, .8, .8
  121.     glutSolidSphere .1, 15, 15
  122.  
  123.     _glTranslatef t2.x, t2.y, t2.z
  124.  
  125.     _glColor3f .8, .8, .8
  126.     glutSolidSphere .1, 15, 15
  127.  
  128.     clock# = clock# + .01
  129.  
  130.     _glFlush
  131.  
  132.  
  133.  
  134. 'taken from p5js.bas
  135. 'https://bit.y/p5jsbas
  136. FUNCTION p5random! (mn!, mx!)
  137.     IF mn! > mx! THEN
  138.         SWAP mn!, mx!
  139.     END IF
  140.     p5random! = RND * (mx! - mn!) + mn!
  141.  
  142. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  143.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  144.  

 
3D Double Pendulum Screenshot.jpg

35
SUB _GL / OpenGL Lights & Material by Ashish
« on: March 12, 2020, 05:37:47 am »
OpenGL Lights & Material

Author: @ Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2323.0
A full repository of QB64_OpenGL_Demos by Ashish Kingdom and Petr Preclik, which contains all the supplementary files/resources as well as screenshots and many other GL programs:
https://github.com/AshishKingdom/QB64_OpenGL_Demos/archive/master.zip
Version: 1
Tags: [3D], [Graphics], [Open_GL]

Description:
Stunning 3D effect of moving lights with reflections off the surface of a sphere

Source Code:
Code: QB64: [Select]
  1. 'OpenGL Lights & Material By Ashish
  2.  
  3. _TITLE "OpenGL Lights & Material"
  4.  
  5. SCREEN _NEWIMAGE(800, 600, 32)
  6.  
  7. DIM SHARED glAllow AS _BYTE
  8.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  9.     SUB glutSolidSphere (BYVAL radius AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  10.  
  11. 'Used by GLH RGB/etc helper functions
  12. DIM SHARED DONT_USE_GLH_COL_RGBA(1 TO 4) AS SINGLE
  13.  
  14. 'Used to manage textures
  15. TYPE DONT_USE_GLH_Handle_TYPE
  16.     in_use AS _BYTE
  17.     handle AS LONG
  18.  
  19. TYPE vec3
  20.     x AS SINGLE
  21.     y AS SINGLE
  22.     z AS SINGLE
  23.  
  24.  
  25. 'Used by GLH RGB/etc helper functions
  26. REDIM SHARED DONT_USE_GLH_Handle(1000) AS DONT_USE_GLH_Handle_TYPE
  27.  
  28. DIM SHARED redLight AS vec3
  29. DIM SHARED greenLight AS vec3
  30. DIM SHARED blueLight AS vec3
  31.  
  32.  
  33.  
  34. glAllow = -1
  35.     _LIMIT 40
  36. LOOP UNTIL k& = ASC(CHR$(27))
  37.  
  38.  
  39. SUB _GL () STATIC
  40.     IF NOT glAllow THEN EXIT SUB
  41.  
  42.     _glEnable _GL_DEPTH_TEST
  43.     _glEnable _GL_LIGHTING
  44.    
  45.     _glEnable _GL_LIGHT0 'we need three lights, each for red, green & blue.
  46.     _glEnable _GL_LIGHT1
  47.     _glEnable _GL_LIGHT2
  48.    
  49.     _glLightfv _GL_LIGHT0, _GL_AMBIENT, GLH_RGB(0, 0, 0)
  50.     _glLightfv _GL_LIGHT0, _GL_DIFFUSE, GLH_RGB(.5, 0, 0)
  51.     _glLightfv _GL_LIGHT0, _GL_SPECULAR, GLH_RGB(1, 0, 0)
  52.     _glLightfv _GL_LIGHT0, _GL_POSITION, GLH_RGBA(redLight.x, redLight.y, redLight.z, 0)
  53.    
  54.     _glLightfv _GL_LIGHT1, _GL_AMBIENT, GLH_RGB(0, 0, 0)
  55.     _glLightfv _GL_LIGHT1, _GL_DIFFUSE, GLH_RGB(0, .5, 0)
  56.     _glLightfv _GL_LIGHT1, _GL_SPECULAR, GLH_RGB(0, 1, 0)
  57.     _glLightfv _GL_LIGHT1, _GL_POSITION, GLH_RGBA(greenLight.x, greenLight.y, greenLight.z, 0)
  58.  
  59.     _glLightfv _GL_LIGHT2, _GL_AMBIENT, GLH_RGB(0, 0, 0)
  60.     _glLightfv _GL_LIGHT2, _GL_DIFFUSE, GLH_RGB(0, 0, .5)
  61.     _glLightfv _GL_LIGHT2, _GL_SPECULAR, GLH_RGB(0, 0, 1)
  62.     _glLightfv _GL_LIGHT2, _GL_POSITION, GLH_RGBA(blueLight.x, blueLight.y, blueLight.z, 0)
  63.    
  64.     _glMatrixMode _GL_PROJECTION
  65.    
  66.     IF NOT glSetup THEN
  67.         aspect# = _WIDTH / _HEIGHT
  68.         glSetup = -1
  69.         _glViewport 0, 0, _WIDTH, _HEIGHT
  70.     END IF
  71.    
  72.     _gluPerspective 45.0, aspect#, 1.0, 100.0
  73.    
  74.     _glMatrixMode _GL_MODELVIEW
  75.    
  76.     gluLookAt 0, 0, 5, 0, 0, 0, 0, 1, 0
  77.    
  78.     _glColor3f 0, 0, 0
  79.    
  80.     _glMaterialfv _GL_FRONT_AND_BACK, _GL_AMBIENT, GLH_RGB(0, 0, 0)
  81.     _glMaterialfv _GL_FRONT_AND_BACK, _GL_DIFFUSE, GLH_RGB(0.8, 0.8, 0.8)
  82.     _glMaterialfv _GL_FRONT_AND_BACK, _GL_SPECULAR, GLH_RGB(.86, .86, .86)
  83.     _glMaterialfv _GL_FRONT_AND_BACK, _GL_SHININESS, GLH_RGB(128 * .566, 0, 0)
  84.    
  85.     glutSolidSphere 1, 100, 100
  86.    
  87.     _glDisable _GL_LIGHTING
  88.    
  89.     _glTranslatef redLight.x, redLight.y, redLight.z
  90.     _glColor3f 1, 0, 0
  91.     glutSolidSphere .05, 20, 20
  92.    
  93.     _glTranslatef greenLight.x, greenLight.y, greenLight.z
  94.     _glColor3f 0, 1, 0
  95.     glutSolidSphere .05, 20, 20
  96.    
  97.     _glTranslatef blueLight.x, blueLight.y, .1
  98.     _glColor3f 0, 0, 1
  99.     glutSolidSphere .05, 20, 20
  100.    
  101.     _glFlush
  102.    
  103.     clock# = clock# + .01
  104.    
  105.     redLight.x = SIN(clock# * 1.5) * 1.5
  106.     redLight.z = COS(clock# * 1.5) * 1.5
  107.    
  108.     greenLight.y = COS(clock# * .8) * 1.5
  109.     greenLight.z = SIN(clock# * .8) * 1.5
  110.    
  111.     blueLight.x = SIN(clock#) * 1.5
  112.     blueLight.y = COS(clock#) * 1.5
  113.  
  114.  
  115. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  116.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  117.  
  118.  
  119. 'below, all functions are coded by Galleon
  120. FUNCTION GLH_Image_to_Texture (image_handle AS LONG) 'turn an image handle into a texture handle
  121.     IF image_handle >= 0 THEN ERROR 258: EXIT FUNCTION 'don't allow screen pages
  122.     DIM m AS _MEM
  123.     m = _MEMIMAGE(image_handle)
  124.     DIM h AS LONG
  125.     h = DONT_USE_GLH_New_Texture_Handle
  126.     GLH_Image_to_Texture = h
  127.     _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(h).handle
  128.     _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(image_handle), _HEIGHT(image_handle), 0, &H80E1&&, _GL_UNSIGNED_BYTE, m.OFFSET
  129.     _MEMFREE m
  130.  
  131. FUNCTION DONT_USE_GLH_New_Texture_Handle
  132.     handle&& = 0
  133.     _glGenTextures 1, _OFFSET(handle&&)
  134.     DONT_USE_GLH_New_Texture_Handle = handle&&
  135.     FOR h = 1 TO UBOUND(DONT_USE_GLH_Handle)
  136.         IF DONT_USE_GLH_Handle(h).in_use = 0 THEN
  137.             DONT_USE_GLH_Handle(h).in_use = 1
  138.             DONT_USE_GLH_Handle(h).handle = handle&&
  139.             DONT_USE_GLH_New_Texture_Handle = h
  140.             EXIT FUNCTION
  141.         END IF
  142.     NEXT
  143.     REDIM _PRESERVE DONT_USE_GLH_Handle(UBOUND(DONT_USE_GLH_HANDLE) * 2) AS DONT_USE_GLH_Handle_TYPE
  144.     DONT_USE_GLH_Handle(h).in_use = 1
  145.     DONT_USE_GLH_Handle(h).handle = handle&&
  146.     DONT_USE_GLH_New_Texture_Handle = h
  147.  
  148. SUB GLH_Select_Texture (texture_handle AS LONG) 'turn an image handle into a texture handle
  149.     IF texture_handle < 1 OR texture_handle > UBOUND(DONT_USE_GLH_HANDLE) THEN ERROR 258: EXIT FUNCTION
  150.     IF DONT_USE_GLH_Handle(texture_handle).in_use = 0 THEN ERROR 258: EXIT FUNCTION
  151.     _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(texture_handle).handle
  152.  
  153.  
  154. FUNCTION GLH_RGB%& (r AS SINGLE, g AS SINGLE, b AS SINGLE)
  155.     DONT_USE_GLH_COL_RGBA(1) = r
  156.     DONT_USE_GLH_COL_RGBA(2) = g
  157.     DONT_USE_GLH_COL_RGBA(3) = b
  158.     DONT_USE_GLH_COL_RGBA(4) = 1
  159.     GLH_RGB = _OFFSET(DONT_USE_GLH_COL_RGBA())
  160.  
  161. FUNCTION GLH_RGBA%& (r AS SINGLE, g AS SINGLE, b AS SINGLE, a AS SINGLE)
  162.     DONT_USE_GLH_COL_RGBA(1) = r
  163.     DONT_USE_GLH_COL_RGBA(2) = g
  164.     DONT_USE_GLH_COL_RGBA(3) = b
  165.     DONT_USE_GLH_COL_RGBA(4) = a
  166.     GLH_RGBA = _OFFSET(DONT_USE_GLH_COL_RGBA())

 
OpenGL Lights & Materials Screenshot.PNG

36
2D/3D Graphics / Lissajous Curve Table by FellippeHeitor
« on: March 10, 2020, 11:00:24 am »
Lissajous Curve Table

Author: @FellippeHeitor
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=683.0
Version: « Reply #8 on: October 09, 2018, 02:48:07 PM »
Tags: [2D], [Graphics], [Mathematics]

Description:
Graphical Lissajou's Figures.  For added eye-candy-ness, I've changed the plot line to paint using HSB colors so that ink color will vary according to the current rotational angle.

Source Code:
Code: QB64: [Select]
  1. _TITLE "Lissajous Curve Table"
  2.  
  3.  
  4. TYPE vector
  5.     x AS SINGLE
  6.     y AS SINGLE
  7.  
  8. DIM SHARED angle
  9. DIM SHARED rows, cols
  10.  
  11. SCREEN _NEWIMAGE(800, 800, 32)
  12.  
  13. setup:
  14. angle = 0
  15. w = 80
  16. rows = INT(_HEIGHT / w) - 1
  17. cols = INT(_WIDTH / w) - 1
  18. REDIM dot(rows, cols) AS vector
  19.  
  20. plot = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  21. _DEST plot
  22.  
  23.         oldScreen = _DEST
  24.         _FREEIMAGE oldScreen
  25.         _FREEIMAGE plot
  26.         GOTO setup
  27.     END IF
  28.  
  29.     _PUTIMAGE , plot
  30.  
  31.     d = w - 0.2 * w
  32.     r = d / 2
  33.  
  34.     FOR i = 0 TO cols
  35.         cx = w + i * w + w / 2
  36.         cy = w / 2
  37.         CIRCLE (cx, cy), r
  38.  
  39.         x = r * COS(angle * (i + 1) - _PI(.5))
  40.         y = r * SIN(angle * (i + 1) - _PI(.5))
  41.  
  42.         LINE (cx + x, 0)-(cx + x, _HEIGHT), _RGB32(127, 127, 127)
  43.         CircleFill cx + x, cy + y, 4, _RGB32(28, 222, 50)
  44.         CircleFill cx + x, cy + y, 2, _RGB32(11, 33, 249)
  45.  
  46.         FOR j = 0 TO rows
  47.             dot(j, i).x = cx + x
  48.         NEXT
  49.     NEXT
  50.  
  51.     FOR i = 0 TO rows
  52.         cx = w / 2
  53.         cy = w + i * w + w / 2
  54.         CIRCLE (cx, cy), r
  55.  
  56.         x = r * COS(angle * (i + 1) - _PI(.5))
  57.         y = r * SIN(angle * (i + 1) - _PI(.5))
  58.  
  59.         LINE (0, cy + y)-(_WIDTH, cy + y), _RGB32(127, 127, 127)
  60.         CircleFill cx + x, cy + y, 4, _RGB32(28, 222, 50)
  61.         CircleFill cx + x, cy + y, 2, _RGB32(11, 33, 249)
  62.  
  63.         FOR j = 0 TO cols
  64.             dot(i, j).y = cy + y
  65.         NEXT
  66.     NEXT
  67.  
  68.     _DEST plot
  69.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(0, 0, 0, 4), BF
  70.     FOR j = 0 TO rows
  71.         FOR i = 0 TO cols
  72.             CircleFill dot(j, i).x, dot(j, i).y, 1, hsb(_R2D(angle), 127, 127, 255)
  73.         NEXT
  74.     NEXT
  75.  
  76.     angle = angle + 0.01
  77.     IF angle > _PI(2) THEN angle = 0
  78.  
  79.     _DEST 0
  80.  
  81.     _DISPLAY
  82.     _LIMIT 30
  83.  
  84. SUB CircleFill (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG)
  85.     DIM x0 AS SINGLE, y0 AS SINGLE
  86.     DIM e AS SINGLE
  87.  
  88.     x0 = R
  89.     y0 = 0
  90.     e = -R
  91.     DO WHILE y0 < x0
  92.         IF e <= 0 THEN
  93.             y0 = y0 + 1
  94.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
  95.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
  96.             e = e + 2 * y0
  97.         ELSE
  98.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
  99.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
  100.             x0 = x0 - 1
  101.             e = e - 2 * x0
  102.         END IF
  103.     LOOP
  104.     LINE (x - R, y)-(x + R, y), C, BF
  105.  
  106. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  107.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  108.  
  109. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  110.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  111.  
  112.     H = map(__H, 0, 255, 0, 360)
  113.     S = map(__S, 0, 255, 0, 1)
  114.     B = map(__B, 0, 255, 0, 1)
  115.  
  116.     IF S = 0 THEN
  117.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  118.         EXIT FUNCTION
  119.     END IF
  120.  
  121.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  122.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  123.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  124.  
  125.     IF B > .5 THEN
  126.         fmx = B - (B * S) + S
  127.         fmn = B + (B * S) - S
  128.     ELSE
  129.         fmx = B + (B * S)
  130.         fmn = B - (B * S)
  131.     END IF
  132.  
  133.     iSextant = INT(H / 60)
  134.  
  135.     IF H >= 300 THEN
  136.         H = H - 360
  137.     END IF
  138.  
  139.     H = H / 60
  140.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  141.  
  142.     IF iSextant MOD 2 = 0 THEN
  143.         fmd = (H * (fmx - fmn)) + fmn
  144.     ELSE
  145.         fmd = fmn - (H * (fmx - fmn))
  146.     END IF
  147.  
  148.     imx = _ROUND(fmx * 255)
  149.     imd = _ROUND(fmd * 255)
  150.     imn = _ROUND(fmn * 255)
  151.  
  152.     SELECT CASE INT(iSextant)
  153.         CASE 1
  154.             hsb~& = _RGBA32(imd, imx, imn, A)
  155.         CASE 2
  156.             hsb~& = _RGBA32(imn, imx, imd, A)
  157.         CASE 3
  158.             hsb~& = _RGBA32(imn, imd, imx, A)
  159.         CASE 4
  160.             hsb~& = _RGBA32(imd, imn, imx, A)
  161.         CASE 5
  162.             hsb~& = _RGBA32(imx, imn, imd, A)
  163.         CASE ELSE
  164.             hsb~& = _RGBA32(imx, imd, imn, A)
  165.     END SELECT
  166.  
  167.  

 
Lissajou's Figures Screenshot.jpg

37
Games / Battleship with AI by bplus
« on: March 08, 2020, 06:32:03 am »
Battleship with AI

Author:  @bplus with @johnno56 and @Petr
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=218.0, « Reply #14 on: May 28, 2018, 08:14:32 AM »
Version: 5_AI
Tags: [2D], [Graphics]

Description:
Cool QB64 version of the classic game.  Just like human players, my AI tracks whether it has shot at a cell or not.

Source Code:
Code: QB64: [Select]
  1. _TITLE "Battleship 5_AI.bas by bplus"
  2. 'QB64 version 2017 1106/82 (the day before they switched to version 1.2)
  3. 'OK this version with AI works though AI needs a fix
  4. '2018-04-25 fixed the AI! yeah
  5. '2018-04-25 PM Show ONLY ships sunk! Post 2018-04-25PM update
  6. '2018-04-26PM add play again loop  Post v 2018-04-26
  7. '  use Johnno's assets, Thanks Johnno
  8. '  water = _loadimag("filename")
  9. ' _PUTIMAGE (x, y), water
  10. ' Add Petr's idea from today about Player option for automatic setup,
  11. ' Thanks Petr for sharing ideas.
  12. 'add Johnno's sounds
  13. '2018-05-02 AM for me  Johnno adds explode stuff
  14. '2018-05-02 9PM Battleship3 fix surprise screen shake
  15. '2018-05-12&13 Battleship 4
  16. ' added checkClick for improved getClick routine
  17. ' option to turn off effects, center text in text box
  18. ' install new color system, and showShips on Players Board
  19. ' cut 20 lines from autoset, removed fill circle drawing routine
  20. '2018-05-14 post version 05-14
  21. ' testing new shoot systems for getting first hits on ships
  22. '2018-05-18 added new shoot subroutine that mods according to ships sunk
  23. '2018-05-20 the 5_AI 5-20 version is working with new hit directions around first hit
  24. 'I am now going to add hitx(), hity(), ihit, rehit for going back into sunk ship area for more ships if currentHits <> 0
  25. 'it works, keeps hitting an area until currentHits = 0 or all previous hits have been surrounded with misses
  26. 'show boats not sunk!!!!
  27. ' try mod 3 coverage effectsON and AutosetON  to avoid questions when play a ton of games
  28. 'reviewed sound handling and changed to using handles
  29. 'changed grid color to blue
  30. ' cut m = 7 stuff from shoot reduced from 128 lines to nice size now!
  31. ' 5-AI 5-21 backup
  32. ' 2018-05-23 post 5_AI with this date
  33. ' remove playing soundfiles by handle& and go back to _SNDPLAYFILE but use volume!!!
  34. ' add splash screen
  35.  
  36. DIM SHARED main&
  37. CONST xmax = 800
  38. CONST ymax = 600
  39. main& = _NEWIMAGE(xmax, ymax, 32)
  40. SCREEN main&
  41. _SCREENMOVE 360, 60
  42.  
  43. 'setup boards
  44. CONST sq = 32
  45. CONST sqPerSide = 10
  46. CONST n1 = sqPerSide - 1
  47. 'screen offsets for AI board and player board
  48. CONST ax = 50
  49. CONST ay = 232
  50. CONST px = 420
  51. CONST py = 232
  52. 'setup ships
  53. CONST nShips = 10
  54. CONST ns2 = 5 '     number of ships divide by 2
  55. CONST ns2p1 = 6 '   number of ships divide by 2 plus 1
  56. CONST df = 1 '      delay time
  57. 'global arrays and variables
  58. DIM SHARED a(sqPerSide, sqPerSide), p(sqPerSide, sqPerSide), water&, waterHit&, waterMiss&, GameOn, e, pAuto
  59. DIM SHARED shipName$(nShips), shipLen(nShips), shipHits$(nShips), shipHor(nShips), shipX(nShips), shipY(nShips), shipSunk(nShips)
  60. 'hits array will track red and white pegs of hits and misses
  61. REDIM SHARED hits(n1, n1) 'hit = 1 and miss = -1 and no shot taken = 0
  62. DIM SHARED colA, row, col, bump
  63. DIM SHARED ihit, rehit 'more hit tracking, this is for making sure all ships sunk in a hit area
  64. REDIM SHARED hitx(0), hity(0)
  65. DIM SHARED x1, y1, bombx, bomby, dir, currentHits, hit2 'for deciding where to bomb next
  66. DIM SHARED carrier&, battleship&, cruiser&, submarine&, destroyer& 'to use in subs
  67. DIM SHARED explode&(16)
  68.  
  69. 'Johnno's Assets added to game
  70. banner& = _LOADIMAGE("title.bmp")
  71. water& = _LOADIMAGE("water.bmp")
  72. waterHit& = _LOADIMAGE("water-hit.bmp")
  73. waterMiss& = _LOADIMAGE("water-miss.bmp")
  74. metal& = _LOADIMAGE("frame1.bmp")
  75. setupships& = _LOADIMAGE("setupships.bmp")
  76. notpeek& = _LOADIMAGE("notpeek.bmp")
  77. carrier& = _LOADIMAGE("carrier.bmp")
  78. battleship& = _LOADIMAGE("battleship.bmp")
  79. cruiser& = _LOADIMAGE("cruiser.bmp")
  80. submarine& = _LOADIMAGE("submarine.bmp")
  81. destroyer& = _LOADIMAGE("destroyer.bmp")
  82. again& = _LOADIMAGE("again.bmp")
  83. loadExplode
  84.  
  85. shipLen(1) = 5: shipName$(1) = "   Carrier"
  86. shipLen(2) = 4: shipName$(2) = "Battleship"
  87. shipLen(3) = 3: shipName$(3) = "   Cruiser"
  88. shipLen(4) = 3: shipName$(4) = " Submarine"
  89. shipLen(5) = 2: shipName$(5) = " Destroyer"
  90. shipLen(6) = 5: shipName$(6) = "   Carrier"
  91. shipLen(7) = 4: shipName$(7) = "Battleship"
  92. shipLen(8) = 3: shipName$(8) = "   Cruiser"
  93. shipLen(9) = 3: shipName$(9) = " Submarine"
  94. shipLen(10) = 2: shipName$(10) = " Destroyer"
  95.  
  96.  
  97. shipblack& = _LOADIMAGE("ship-black.png")
  98. shipfire& = _LOADIMAGE("ship-wfire.png")
  99. xxmax = 640: yymax = 75 'pixels too slow
  100. xstep = 1: ystep = 1
  101. DIM pal&(300) 'pallette
  102. FOR i = 1 TO 100
  103.     fr = 240 * i / 100 + 15
  104.     pal&(i) = _RGB(fr, 0, 0)
  105.     pal&(i + 100) = _RGB(255, fr, 0)
  106.     pal&(i + 200) = _RGB(255, 255, fr)
  107. DIM f(xxmax, yymax + 2) 'fire array and seed
  108. FOR x = 0 TO xxmax
  109.     f(x, yymax + 1) = INT(RND * 2) * 300
  110.     f(x, yymax + 2) = 300
  111.  
  112. _PUTIMAGE , shipblack&
  113. getClick mx, my, q
  114. IF q = 27 THEN END
  115. ticker = 0
  116. WHILE ticker < 3
  117.     CLS
  118.     IF ticker < 2.95 THEN _PUTIMAGE , shipblack& ELSE _PUTIMAGE , shipfire&
  119.     FOR x = 1 TO xxmax - 1 'shift fire seed a bit
  120.         r = RND
  121.         IF r < .15 THEN
  122.             f(x, yymax + 1) = f(x - 1, yymax + 1)
  123.         ELSEIF r < .3 THEN
  124.             f(x, yymax + 1) = f(x + 1, yymax + 1)
  125.         ELSEIF r < .35 THEN
  126.             f(x, yymax + 1) = INT(RND * 2) * 300
  127.         END IF
  128.     NEXT
  129.     FOR y = 0 TO yymax 'fire based literally on 4 pixels below it like cellular automata
  130.         FOR x = 1 TO xxmax - 1
  131.             f(x, y) = max((f(x - 1, y + 1) + f(x, y + 1) + f(x + 1, y + 1) + f(x - 1, y + 2)) / 4 - 5, 0)
  132.             LINE (80 + x * xstep, 230 + y * ystep)-STEP(xstep, ystep), pal&(f(x, y)), BF
  133.         NEXT
  134.     NEXT
  135.     ticker = ticker + .025
  136.     _DISPLAY
  137.     _LIMIT 50
  138. _DELAY 1.5
  139. rgb 0
  140. LINE (0, 0)-(xmax, ymax), , BF
  141.  
  142. '   Display banner   and get the Players setting questions asked once and for all games until restart program
  143. _PUTIMAGE (220, 10), banner&
  144. TxtBx 509, "m", "Special Effects? press [y] yes or [n] no"
  145. IF GetYN$ = "y" THEN e = -1 ELSE e = 0
  146. ClearTextBox
  147. _PUTIMAGE (150, 155), setupships&
  148. IF GetYN$ = "y" THEN pAuto = -1 ELSE pAuto = 0
  149.  
  150.  
  151. restart: '===================================================== restart new game
  152.  
  153. 'reset all critical variables and arrays
  154. ERASE a, p, shipHor, shipX, shipY, shipSunk
  155. REDIM hits(n1, n1)
  156. FOR i = 1 TO nShips
  157.     shipHits$(i) = SPACE$(shipLen(i))
  158. 'AI tracking
  159. pTurn = 0: dir = 0: currentHits = 0: colA = -1
  160. 'start screen drawing
  161.  
  162. '   Display Grid frame
  163. _PUTIMAGE (18, 200), metal&
  164. rgb 9
  165. drawGrid ax, ay, sq, sqPerSide
  166. drawGrid px, py, sq, sqPerSide
  167. FOR bannerx = 220 TO 15 STEP -1
  168.     _PUTIMAGE (bannerx, 10), banner&
  169.     _DELAY 0.01
  170.  
  171. 'setup a board with ships, Computer or AI's setup
  172. autoset 1
  173.  
  174. 'setup player's ships
  175. IF pAuto THEN
  176.     ClearTextBox
  177.     _PUTIMAGE (277, 155), notpeek&
  178.     autoset 0
  179.     FOR s = ns2p1 TO nShips
  180.         showShip s, shipX(s), shipY(s), shipHor(s)
  181.     NEXT
  182.  
  183. ELSE 'player sets up his ships
  184.     FOR s = ns2p1 TO nShips
  185.         OK = 0
  186.         WHILE OK = 0
  187.             ClearTextBox
  188.             ClearUpdateBox
  189.             IF s = 1 OR s = 6 THEN _PUTIMAGE (480, 30), carrier&
  190.             IF s = 2 OR s = 7 THEN _PUTIMAGE (474, 45), battleship&
  191.             IF s = 3 OR s = 8 THEN _PUTIMAGE (496, 50), cruiser&
  192.             IF s = 4 OR s = 9 THEN _PUTIMAGE (496, 45), submarine&
  193.             IF s = 5 OR s = 10 THEN _PUTIMAGE (512, 50), destroyer&
  194.             rgb 990
  195.             '   Position text in UpdateTextBox beneath the ship.
  196.             _PRINTSTRING (430, 100), "Setting up the " + LTRIM$(shipName$(s)) + ":  Length of" + STR$(shipLen(s)) + "."
  197.             TxtBx 85, "t", "Position it Horizontally: Press [ H ]"
  198.             TxtBx 942, "b", "  Position it Vertically: Press [ V ]"
  199.             nogo = 1
  200.             WHILE nogo
  201.                 hor$ = INKEY$
  202.                 IF hor$ = "v" OR hor$ = "h" THEN nogo = 0
  203.                 _LIMIT 200
  204.             WEND
  205.             ClearTextBox
  206.             IF hor$ = "v" THEN
  207.                 TxtBx 942, "t", "Vertial it is."
  208.                 TxtBx 970, "b", "Now click the top most position of the ship."
  209.                 shipHor(s) = 0
  210.             ELSE
  211.                 TxtBx 85, "t", "Horizontal it is:"
  212.                 TxtBx 970, "b", "Now click the left most position of the ship."
  213.                 shipHor(s) = -1
  214.             END IF
  215.  
  216.             checkClick px, py, sq, sqPerSide, sx, sy, escape
  217.             IF escape THEN CLS: END
  218.  
  219.             IF shipHor(s) THEN
  220.                 IF sx <= sqPerSide - shipLen(s) THEN
  221.                     OK = 1
  222.                     FOR xx = 0 TO shipLen(s) - 1
  223.                         IF p(sx + xx, sy) < 0 THEN OK = 0: EXIT FOR
  224.                     NEXT
  225.                     IF OK THEN
  226.                         shipX(s) = sx: shipY(s) = sy
  227.                         FOR xx = 0 TO shipLen(s) - 1
  228.                             p(sx + xx, sy) = -1 * s
  229.                         NEXT
  230.                     END IF
  231.                 END IF
  232.             ELSE
  233.                 IF sy <= sqPerSide - shipLen(s) THEN
  234.                     OK = 1
  235.                     FOR yy = 0 TO shipLen(s) - 1
  236.                         IF p(sx, sy + yy) < 0 THEN OK = 0: EXIT FOR
  237.                     NEXT
  238.                     IF OK THEN
  239.                         shipX(s) = sx: shipY(s) = sy
  240.                         FOR yy = 0 TO shipLen(s) - 1
  241.                             p(sx, sy + yy) = -1 * s
  242.                         NEXT
  243.                     END IF
  244.                 END IF
  245.             END IF
  246.         WEND
  247.         'update player board
  248.         showShip s, shipX(s), shipY(s), shipHor(s)
  249.         _LIMIT 30
  250.     NEXT
  251.  
  252.  
  253. 'start the shooting match
  254. GameOn = 1
  255. WHILE GameOn
  256.     updateStatus
  257.     pTurn = 1 - pTurn
  258.  
  259.     IF pTurn THEN
  260.         TxtBx 63, "m", "Player. Your turn.  Click on the computer's board."
  261.         checkClick ax, ay, sq, sqPerSide, bx, by, escape
  262.         IF escape THEN CLS: END
  263.         IF e THEN
  264.             _SNDPLAYFILE ("launch-hi.wav"), , 1
  265.             _DELAY 3
  266.         END IF
  267.         IF a(bx, by) < 0 THEN
  268.             IF e THEN
  269.                 playPutExplode ax + bx * sq, ay + by * sq, 0
  270.                 '_DELAY df
  271.             END IF
  272.             _PUTIMAGE (ax + bx * sq, ay + by * sq), waterHit&
  273.             hitEval "a", bx, by 'game could end here
  274.         ELSE
  275.             _PUTIMAGE (ax + bx * sq, ay + by * sq), waterMiss&
  276.             IF e THEN
  277.                 _SNDPLAYFILE ("splash-hi.wav"), , .3
  278.                 _DELAY 1
  279.             END IF
  280.         END IF
  281.     ELSE
  282.         'AI's turn if it gets a hit it will bomb around the ship until it is finished
  283.         'could be trouble if 2 ships are next to each other, damn until just now I hadn't anticipated this
  284.         'hits board tracks red and white pegs like a human player for AI
  285.  
  286.         '   Try to display random computer messages before it fires! - Humour...
  287.         '   Possibly use select.. case.. end select?
  288.         ClearTextBox
  289.         choice = rand(1, 10)
  290.         SELECT CASE choice
  291.             CASE 1: m$ = "Hold onto something! My turn!"
  292.             CASE 2: m$ = "Are you sure you want to do this?"
  293.             CASE 3: m$ = "Close your eyes and start praying!"
  294.             CASE 4: m$ = "Are you ready for what's coming?"
  295.             CASE 5: m$ = "My turn! Buckle up Princess!"
  296.             CASE 6: m$ = "Prepare for a world of hurt!"
  297.             CASE 7: m$ = "Airmail... Special delivery!"
  298.             CASE 8: m$ = "You have nowhere to hide!"
  299.             CASE 9: m$ = "I have a surprise for you!"
  300.             CASE 10: m$ = "Let's play catch! My turn!"
  301.         END SELECT
  302.         TxtBx 970, "m", m$
  303.  
  304.         IF dir THEN 'we have a bomb location all set to test
  305.             IF p(bombx, bomby) < 0 THEN 'hit!
  306.                 IF e THEN
  307.                     _SNDPLAYFILE ("launch-hi.wav"), , .3
  308.                     _DELAY 3
  309.                     playPutExplode px + bombx * sq, py + bomby * sq, 1
  310.  
  311.                     ClearTextBox
  312.                     choice = rand(1, 10)
  313.                     SELECT CASE choice
  314.                         CASE 1: m$ = "No point crying about it!"
  315.                         CASE 2: m$ = "You'll get over it."
  316.                         CASE 3: m$ = "It's either you or me."
  317.                         CASE 4: m$ = "No pain. No gain."
  318.                         CASE 5: m$ = "Now that's gotta hurt!"
  319.                         CASE 6: m$ = "You can always go home!"
  320.                         CASE 7: m$ = "No shame in quitting."
  321.                         CASE 8: m$ = "It'll buff right out."
  322.                         CASE 9: m$ = "Side dish of scrap to go!"
  323.                         CASE 10: m$ = "May you rust in peace."
  324.                     END SELECT
  325.                     TxtBx 930, "m", m$
  326.                 END IF
  327.  
  328.                 hit2 = 1
  329.                 hits(bombx, bomby) = 1
  330.                 currentHits = currentHits + 1
  331.                 ihit = ihit + 1 'take a history  of hits since dir has been activated
  332.                 REDIM _PRESERVE hitx(ihit)
  333.                 REDIM _PRESERVE hity(ihit)
  334.                 hitx(ihit) = bombx
  335.                 hity(ihit) = bomby
  336.  
  337.                 _PUTIMAGE (px + bombx * sq, py + bomby * sq), waterHit&
  338.  
  339.                 'we need to know stuff but can't use this info for AI finding the ship
  340.                 'when hitEval announces a ship sunk we can reduce the currentHits count by that ships amount
  341.                 'if still have more current hits, continue bombing area as another ship is there
  342.                 hitEval "p", bombx, bomby 'this will reduce currentHits by the amount a ship could take when sunk
  343.                 IF currentHits = 0 THEN 'clear our checklist we sank all ships we hit, call off bombing of area
  344.                     x1 = 0: y1 = 0: dir = 0
  345.                 ELSE
  346.                     decideWhereToBombNext
  347.                 END IF
  348.             ELSE 'no hit from checklist scratch off one item
  349.                 IF e THEN
  350.                     _SNDPLAYFILE ("launch-hi.wav"), , .3
  351.                     _DELAY 3
  352.                 END IF
  353.                 hit2 = 0
  354.                 hits(bombx, bomby) = -1
  355.                 _PUTIMAGE (px + bombx * sq, py + bomby * sq), waterMiss&
  356.                 ClearTextBox
  357.                 TxtBx 509, "m", "MISSED!!"
  358.                 IF e THEN
  359.                     _SNDPLAYFILE ("splash-hi.wav"), , 1
  360.                     _DELAY 1
  361.                 END IF
  362.                 decideWhereToBombNext
  363.             END IF ' are we still working on hit
  364.  
  365.         ELSE
  366.             'not working on any hits x1, y1 = 0, dir = 0, currentHits might be = 0
  367.             'random but systematic shooting, bring up next good shooting location
  368.  
  369.             shoot tryx, tryy
  370.  
  371.             'consider that shot just fired was it a hit or miss
  372.             IF p(tryx, tryy) < 0 THEN ' test our shot just fired is hit!
  373.                 IF e THEN
  374.                     _SNDPLAYFILE ("launch-hi.wav"), , .3
  375.                     _DELAY 3
  376.                 END IF
  377.                 ClearTextBox
  378.                 x1 = tryx: y1 = tryy 'save first hit to come back to
  379.                 hits(x1, y1) = 1
  380.                 currentHits = currentHits + 1
  381.                 IF e THEN
  382.                     playPutExplode px + x1 * sq, py + y1 * sq, 1
  383.                 END IF
  384.                 _PUTIMAGE (px + x1 * sq, py + y1 * sq), waterHit&
  385.  
  386.                 'we need to know stuff but can't use this info for AI finding the ship
  387.                 'it's the same as for the player
  388.                 hitEval "p", x1, y1
  389.                 'did we just happen to finish off a ship?  current hits = 0
  390.                 IF currentHits = 0 THEN 'must of finished off an ship
  391.                     x1 = 0: x2 = 0: dir = 0 'we are done
  392.                 ELSE
  393.                     dir = -1
  394.                     decideWhereToBombNext
  395.                 END IF
  396.             ELSE 'no hit
  397.                 IF e THEN
  398.                     _SNDPLAYFILE ("launch-hi.wav"), , .3
  399.                     _DELAY 3
  400.                 END IF
  401.                 _PUTIMAGE (px + tryx * sq, py + tryy * sq), waterMiss&
  402.                 ClearTextBox
  403.                 TxtBx 509, "m", "MISSED!!"
  404.                 IF e THEN
  405.                     _SNDPLAYFILE ("splash-hi.wav"), , 1
  406.                     _DELAY 1
  407.                 END IF
  408.                 hits(tryx, tryy) = -1
  409.             END IF
  410.  
  411.         END IF 'rI (now tryx, tryy) was hit or not
  412.     END IF 'whose turn is it
  413.     _LIMIT 5
  414. _PUTIMAGE (125, 265), again&
  415. IF GetYN$ = "n" THEN CLS: END
  416. GOTO restart
  417.  
  418. SUB updateStatus
  419.     ClearTextBox
  420.     ClearUpdateBox
  421.     rgb 990
  422.     LOCATE 2, 70: PRINT "Computer"
  423.     rgb 63
  424.     LOCATE 2, 83: PRINT "Player"
  425.     FOR i = 1 TO 5
  426.         rgb 85: LOCATE i + 2, 55: PRINT shipName$(i)
  427.         IF shipSunk(i) THEN LOCATE i + 2, 72: rgb 940: PRINT "SUNK": rgb 999
  428.         IF shipSunk(i + ns2) THEN LOCATE i + 2, 84: rgb 940: PRINT "SUNK": rgb 999
  429.     NEXT
  430.  
  431. SUB decideWhereToBombNext
  432.     'find next good location, mark the direction we took
  433.     IF dir = -1 THEN '    we just got a fresh hit the rest of the ship is in 1 of 4 directions
  434.         'fresh slate
  435.         REDIM hitx(0): REDIM hity(0): ihit = 0: rehit = 0
  436.         redirect:
  437.         hit2 = 0 'when direction = 0 reset 2nd hit signal to 0
  438.         IF x1 + 1 <= n1 THEN
  439.             IF hits(x1 + 1, y1) = 0 THEN
  440.                 bombx = x1 + 1: bomby = y1: dir = 1: EXIT SUB 'always the first direction to try
  441.             END IF
  442.         END IF
  443.         'still here?
  444.         IF x1 - 1 >= 0 THEN
  445.             IF hits(x1 - 1, y1) = 0 THEN
  446.                 bombx = x1 - 1: bomby = y1: dir = 3: EXIT SUB
  447.             END IF
  448.         END IF
  449.         'still here?
  450.         IF y1 + 1 <= n1 THEN
  451.             IF hits(x1, y1 + 1) = 0 THEN
  452.                 bombx = x1: bomby = y1 + 1: dir = 2: EXIT SUB
  453.             END IF
  454.         END IF
  455.         'still here OK this has to do it!
  456.         IF y1 - 1 >= 0 THEN
  457.             IF hits(x1, y1 - 1) = 0 THEN
  458.                 bombx = x1: bomby = y1 - 1: dir = 4: EXIT SUB
  459.             END IF
  460.         END IF
  461.         'still here ???? damn! give up and go back to random shots
  462.         rehit = rehit + 1
  463.         IF rehit > ihit THEN
  464.             dir = 0: EXIT SUB 'back to random bombing
  465.         ELSE
  466.             x1 = hitx(rehit): y1 = hity(rehit)
  467.             GOTO redirect
  468.         END IF
  469.  
  470.         dir = 0: EXIT SUB '   <    this signals that
  471.     END IF
  472.  
  473.     'setup next bombx, bomby
  474.     IF hit2 THEN 'whatever direction we are taking, continue if we can
  475.         SELECT CASE dir
  476.             CASE 1
  477.                 IF bombx + 1 <= n1 THEN
  478.                     IF hits(bombx + 1, bomby) = 0 THEN
  479.                         bombx = bombx + 1: EXIT SUB
  480.                     END IF
  481.                 END IF
  482.             CASE 2
  483.                 IF bomby + 1 <= n1 THEN
  484.                     IF hits(bombx, bomby + 1) = 0 THEN
  485.                         bomby = bomby + 1: EXIT SUB
  486.                     END IF
  487.                 END IF
  488.             CASE 3
  489.                 IF bombx - 1 >= 0 THEN
  490.                     IF hits(bombx - 1, bomby) = 0 THEN
  491.                         bombx = bombx - 1: EXIT SUB
  492.                     END IF
  493.                 END IF
  494.             CASE 4
  495.                 IF bomby - 1 >= 0 THEN
  496.                     IF hits(bombx, bomby - 1) = 0 THEN
  497.                         bomby = bomby - 1: dir = 4: EXIT SUB
  498.                     END IF
  499.                 END IF
  500.         END SELECT
  501.     END IF
  502.  
  503.     'still here? then we have to change direction  and go back to x1, y1 the first hit
  504.     hit2 = 0 'reset this for the new direction check
  505.     WHILE dir < 4 AND dir > 0
  506.  
  507.         'dir = dir + 1   want to try 180 direction before changing 90
  508.  
  509.         IF dir = 1 THEN
  510.             dir = 3
  511.         ELSEIF dir = 2 THEN
  512.             dir = 4
  513.         ELSEIF dir = 3 THEN
  514.             dir = 2
  515.         ELSEIF dir = 4 THEN
  516.             rehit = rehit + 1
  517.             IF rehit > ihit THEN
  518.                 dir = 0: EXIT SUB 'back to random bombing
  519.             ELSE
  520.                 x1 = hitx(rehit): y1 = hity(rehit)
  521.                 GOTO redirect
  522.             END IF
  523.         END IF
  524.         SELECT CASE dir
  525.             CASE 2
  526.                 IF y1 + 1 <= n1 THEN
  527.                     IF hits(x1, y1 + 1) = 0 THEN
  528.                         bombx = x1: bomby = y1 + 1: EXIT SUB
  529.                     END IF
  530.                 END IF
  531.             CASE 3
  532.                 IF x1 - 1 >= 0 THEN
  533.                     IF hits(x1 - 1, y1) = 0 THEN
  534.                         bombx = x1 - 1: bomby = y1: EXIT SUB
  535.                     END IF
  536.                 END IF
  537.             CASE 4
  538.                 IF y1 - 1 >= 0 THEN
  539.                     IF hits(x1, y1 - 1) = 0 THEN
  540.                         bombx = x1: bomby = y1 - 1: EXIT SUB
  541.                     END IF
  542.                 END IF
  543.         END SELECT
  544.     WEND
  545.     'still here, well we've run out of directions
  546.     rehit = rehit + 1
  547.     IF rehit > ihit THEN
  548.         dir = 0: EXIT SUB 'back to random bombing
  549.     ELSE
  550.         x1 = hitx(rehit): y1 = hity(rehit)
  551.         GOTO redirect
  552.     END IF
  553.  
  554.     'dir = 0 'back to random bombing
  555.  
  556. SUB hitEval (board$, bbx, bby)
  557.     'this is like a referee / judge for both players  to announce a ship sunk and a game won?
  558.     IF board$ <> "p" THEN
  559.         s = -1 * a(bbx, bby)
  560.         you$ = "Player"
  561.         my$ = "Computer's"
  562.         istart = 1
  563.         istop = ns2
  564.     ELSE
  565.         s = -1 * p(bbx, bby)
  566.         you$ = "Computer"
  567.         my$ = "Player's"
  568.         istart = ns2p1
  569.         istop = nShips
  570.     END IF
  571.     IF shipHor(s) THEN d = bbx - shipX(s) + 1 ELSE d = bby - shipY(s) + 1
  572.     MID$(shipHits$(s), d) = "X"
  573.     IF shipHits$(s) = STRING$(shipLen(s), "X") THEN
  574.         IF board$ = "p" THEN currentHits = currentHits - shipLen(s)
  575.         updateStatus
  576.         TxtBx 995, "m", you$ + " sank the " + my$ + " " + LTRIM$(shipName$(s)) + "!"
  577.         _DELAY 1
  578.         shipSunk(s) = 1
  579.         tot = 0
  580.         FOR i = istart TO istop
  581.             IF shipSunk(i) = 1 THEN tot = tot + 1
  582.         NEXT
  583.         IF tot = ns2 THEN
  584.             updateStatus
  585.             TxtBx 995, "m", "Congratulations " + you$ + "!!  You sank the " + my$ + " fleet!  GameOver..."
  586.             IF you$ = "Computer" THEN
  587.                 FOR y = 0 TO sqPerSide - 1
  588.                     FOR x = 0 TO sqPerSide - 1
  589.                         IF a(x, y) < 0 THEN
  590.                             rgb 900
  591.                             FOR i = 1 TO 5 'show ships locations for Player that lost
  592.                                 IF i MOD 2 THEN rgb 900 ELSE rgb 999
  593.                                 LINE (ax + x * sq + i, ay + y * sq + i)-STEP(sq - 2 * i, sq - 2 * i), , B
  594.                             NEXT
  595.                         END IF
  596.                     NEXT
  597.                 NEXT
  598.                 _DELAY 5
  599.             END IF
  600.             _DELAY 4
  601.             GameOn = 0
  602.         END IF
  603.     END IF
  604.  
  605. SUB autoset (AItf) '  there is surely a shorter way to do this but I am eager to get on with other stuff
  606.     'setup a board with ships, AItf if true setup for Computer else for Player
  607.     FOR i = 1 TO ns2
  608.         IF AItf THEN s = i ELSE s = i + 5
  609.         OK = 0
  610.         WHILE OK = 0
  611.             shipHor(s) = rand(0, 1)
  612.             IF shipHor(s) THEN
  613.                 sy = rand(0, n1)
  614.                 sx = rand(0, sqPerSide - shipLen(s))
  615.                 OK = 1
  616.                 FOR xx = 0 TO shipLen(s) - 1
  617.                     IF AItf THEN
  618.                         IF a(sx + xx, sy) < 0 THEN OK = 0: EXIT FOR
  619.                     ELSE
  620.                         IF p(sx + xx, sy) < 0 THEN OK = 0: EXIT FOR
  621.                     END IF
  622.                 NEXT
  623.                 IF OK THEN
  624.                     shipX(s) = sx: shipY(s) = sy
  625.                     FOR xx = 0 TO shipLen(s) - 1
  626.                         IF AItf THEN
  627.                             a(sx + xx, sy) = -1 * s
  628.                         ELSE
  629.                             p(sx + xx, sy) = -1 * s
  630.                         END IF
  631.                     NEXT
  632.                 END IF
  633.             ELSE
  634.                 sx = rand(0, n1)
  635.                 sy = rand(0, sqPerSide - shipLen(s))
  636.                 OK = 1
  637.                 FOR yy = 0 TO shipLen(s) - 1
  638.                     IF AItf THEN
  639.                         IF a(sx, sy + yy) < 0 THEN OK = 0: EXIT FOR
  640.                     ELSE
  641.                         IF p(sx, sy + yy) < 0 THEN OK = 0: EXIT FOR
  642.                     END IF
  643.                 NEXT
  644.                 IF OK THEN
  645.                     shipX(s) = sx: shipY(s) = sy
  646.                     FOR yy = 0 TO shipLen(s) - 1
  647.                         IF AItf THEN
  648.                             a(sx, sy + yy) = -1 * s
  649.                         ELSE
  650.                             p(sx, sy + yy) = -1 * s
  651.                         END IF
  652.                     NEXT
  653.                 END IF
  654.             END IF
  655.         WEND
  656.     NEXT
  657.  
  658. SUB showShip (shipn, bxhead, byhead, hTF)
  659.     'setup to combine use with RotoZoom code Wiki
  660.     SELECT CASE shipn 'player's ships only, get ship len and
  661.         CASE 6: shipLen = 5: sh& = carrier&
  662.         CASE 7: shipLen = 4: sh& = battleship&
  663.         CASE 8: shipLen = 3: sh& = cruiser&
  664.         CASE 9: shipLen = 3: sh& = submarine&
  665.         CASE 10: shipLen = 2: sh& = destroyer&
  666.     END SELECT
  667.     IF hTF THEN 'horizontal True
  668.         dx1 = px + sq * bxhead + 1
  669.         dy1 = py + sq * byhead + 1
  670.         dx2 = px + sq * (bxhead + shipLen) - 1
  671.         dy2 = py + sq * (byhead + 1) - 1
  672.         _PUTIMAGE (dx1, dy1)-(dx2, dy2), sh&, main&
  673.     ELSE
  674.         DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  675.         W& = _WIDTH(sh&): H& = _HEIGHT(sh&)
  676.         px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  677.         px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  678.         sinr! = SIN(-90 / 57.2957795131): cosr! = COS(-90 / 57.2957795131)
  679.  
  680.         xsqlen = 30: ysqlen = 32 * shipLen - 2
  681.         xscale = xsqlen / H&: yscale = ysqlen / W&
  682.         xpivot = px + sq * bxhead + .5 * sq: ypivot = py + sq * byhead + .5 * sq * shipLen
  683.         FOR i& = 0 TO 3
  684.             x2& = (px(i&) * cosr! + sinr! * py(i&)) * xscale + xpivot: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yscale + ypivot
  685.             px(i&) = x2&: py(i&) = y2&
  686.         NEXT
  687.         _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), sh& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  688.         _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), sh& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  689.     END IF
  690.  
  691. 'want the board square bx, by from board with grid xoff, yoff, sq pixels, n x n square board
  692. SUB checkClick (xoff, yoff, sq, n, bx, by, escape)
  693.     WHILE 1
  694.         getClick mx, my, q ' get players move
  695.         IF q = 27 OR q = 113 OR q = 81 THEN escape = 1: EXIT SUB
  696.         row = (my - yoff) / sq
  697.         IF row > 0 AND row < n THEN
  698.             by = INT(row)
  699.             col = (mx - xoff) / sq
  700.             IF col > 0 AND col < n THEN
  701.                 bx = INT(col)
  702.                 EXIT WHILE
  703.             ELSE 'this is beeping right after setup (not after a click)
  704.                 IF mx <> -1 AND my <> -1 THEN BEEP
  705.             END IF
  706.         ELSE 'this is beeping right after setup (not after a click)
  707.             IF mx <> -1 AND my <> -1 THEN BEEP
  708.         END IF
  709.         _LIMIT 1000
  710.     WEND
  711.  
  712. SUB getClick (mx, my, q)
  713.     WHILE _MOUSEINPUT: WEND ' clear previous mouse activity
  714.     mx = -1: my = -1: q = 0
  715.     DO WHILE mx = -1 AND my = -1
  716.         q = _KEYHIT
  717.         IF q = 27 OR (q > 31 AND q < 126) THEN EXIT SUB
  718.         i = _MOUSEINPUT: mb = _MOUSEBUTTON(1)
  719.         IF mb THEN
  720.             DO WHILE mb 'wait for release
  721.                 q = _KEYHIT
  722.                 IF q = 27 OR (q > 31 AND q < 126) THEN EXIT SUB
  723.                 i = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  724.                 _LIMIT 1000
  725.             LOOP
  726.             EXIT SUB
  727.         END IF
  728.         _LIMIT 1000
  729.     LOOP
  730.  
  731. SUB drawGrid (x, y, sq, n)
  732.     d = sq * n
  733.     FOR i = 0 TO n
  734.         LINE (x + sq * i, y)-(x + sq * i, y + d)
  735.         LINE (x, y + sq * i)-(x + d, y + sq * i)
  736.     NEXT
  737.     FOR yy = 0 TO n - 1
  738.         FOR xx = 0 TO n - 1
  739.             _PUTIMAGE (x + sq * xx, y + sq * yy), water&
  740.         NEXT
  741.     NEXT
  742.  
  743. FUNCTION rand% (lo%, hi%)
  744.     rand% = INT(RND * (hi% - lo% + 1)) + lo%
  745.  
  746. SUB TxtBx (n, L$, Message$)
  747.     rgb n
  748.     IF L$ = "t" THEN y = 150
  749.     IF L$ = "m" THEN y = 160
  750.     IF L$ = "b" THEN y = 170
  751.     x = (769 - LEN(Message$) * 8) / 2 + 18
  752.     _PRINTSTRING (x, y), Message$
  753.  
  754. SUB ClearTextBox
  755.     rgb 0
  756.     LINE (18, 141)-(769, 194), , BF
  757.  
  758. SUB ClearUpdateBox
  759.     rgb 0
  760.     LINE (380, 11)-(769, 129), , BF
  761.  
  762. SUB loadExplode ()
  763.     FOR i = 1 TO 16
  764.         x$ = RIGHT$("0" + LTRIM$(STR$(i)), 2)
  765.         f$ = "exp_" + x$ + ".bmp"
  766.         explode&(i) = _LOADIMAGE(f$)
  767.         ' _PUTIMAGE (i * 32, i * 32), explode&(i)   '< test load of file
  768.     NEXT
  769.  
  770. SUB playPutExplode (x, y, shake)
  771.     IF shake THEN _SNDPLAYFILE ("explosion-hi.wav"), , 1 ELSE _SNDPLAYFILE ("explosion-hi.wav"), , .3
  772.     FOR i = 1 TO 16
  773.         _PUTIMAGE (x + 1, y + 1), explode&(i)
  774.         _DELAY .05
  775.         IF shake THEN
  776.             _SCREENMOVE 360 + rand(-10, 10), 60 + rand(-10, 10)
  777.             _SCREENMOVE 360 + rand(-10, 10), 60 + rand(-10, 10)
  778.         END IF
  779.     NEXT
  780.     IF shake THEN _SCREENMOVE 360, 60
  781.     _DELAY .1
  782.  
  783. SUB rgb (n) ' New (even less typing!) New Color System 1000 colors with up to 3 digits
  784.     s3$ = RIGHT$("000" + LTRIM$(STR$(n)), 3)
  785.     r = VAL(MID$(s3$, 1, 1)): IF r THEN r = 28 * r + 3
  786.     g = VAL(MID$(s3$, 2, 1)): IF g THEN g = 28 * g + 3
  787.     b = VAL(MID$(s3$, 3, 1)): IF b THEN b = 28 * b + 3
  788.     COLOR _RGB32(r, g, b)
  789.  
  790. FUNCTION GetYN$ ()
  791.     k$ = "": WHILE k$ <> "n" AND k$ <> "y": k$ = INKEY$: _LIMIT 200: WEND
  792.     GetYN$ = k$
  793.  
  794. SUB shoot (col, row) 'col, row aren't inputs so mush as outputs like a double function return wo input parameters
  795.     i = nShips
  796.     WHILE shipSunk(i) 'find smallest ship not sunk
  797.         i = i - 1
  798.     WEND
  799.     SELECT CASE i 'm for modulus, d for direction to run a check from
  800.         CASE nShips: m = 3 'still have destroyer, for more exciting game testng m = 3
  801.         CASE nShips - 1: m = 3 'still have sub
  802.         CASE nShips - 2: m = 3 'still have cruiser
  803.         CASE nShips - 3: m = 4 'still have battleship
  804.         CASE nShips - 4: m = 5 'still have carrier
  805.     END SELECT
  806.     bc = 0
  807.     IF colA = -1 THEN 'col the Attact starts from notice it is random so player can't anticipate
  808.         colA = rand%(0, n1): col = colA: row = rand(0, n1): bump = rand(0, m - 1)
  809.     END IF
  810.     WHILE bc < m
  811.         cc = 1
  812.         WHILE cc <= sqPerSide
  813.             rc = 0
  814.             WHILE rc <= sqPerSide 'find a space to hit if one left in this column
  815.                 IF cover(m, bump, col, row) THEN 'are we on a place to cover board
  816.                     IF hits(col, row) = 0 THEN EXIT SUB 'good to go!
  817.                 END IF
  818.                 row = (row + 1) MOD sqPerSide
  819.                 rc = rc + 1
  820.             WEND
  821.             row = row - 1
  822.             IF row < 0 THEN row = n1
  823.             'still here means we checked all rows in col so check next col
  824.             col = (col + 1) MOD sqPerSide
  825.             cc = cc + 1
  826.         WEND
  827.         'still here ? then up the bump
  828.         bump = (bump + 1) MOD m
  829.         bc = bc + 1
  830.     WEND
  831.  
  832. 'using a modulus m coverage with a bump so that opponent can't predict where
  833. 'the hardest place to plant the Detroyer
  834. FUNCTION cover (m, bump, c, r)
  835.     bm = bump MOD m 'make sure bump is in modulus
  836.     cm = (c + bm) MOD m
  837.     rm = r MOD m
  838.     IF rm = cm THEN cover = -1 ELSE cover = 0
  839.  
  840. FUNCTION max (a, b)
  841.     IF a > b THEN max = a ELSE max = b
  842.  

 
splash1.PNG


 
5-AI 2018-05-24.PNG


 

Bplus edit fixed download .zip

38
SUB _GL / Moving into the Matrix Rain by Ashish
« on: March 07, 2020, 10:11:51 am »
Author: @Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1453
Version: 1
Tags: [3D], [Graphics]

Description:
I was just inspired by Bplus's Matrix rain on this topic - https://www.qb64.org/forum/index.php?topic=1152.msg106362
So, I decided to create a similar matrix rain having depth effect.


Source Code:
Code: QB64: [Select]
  1. 'Moving into the Matrix Rain
  2. 'By Ashish Kushwaha
  3. '23 Jun, 2019
  4. '
  5. 'Inspire by B+ Matrix Rain.
  6. _TITLE "Moving into the Matrix Rain"
  7.  
  8.  
  9. SCREEN _NEWIMAGE(800, 600, 32)
  10.  
  11. TYPE matRain
  12.     x AS SINGLE 'x location
  13.     y AS SINGLE 'y location
  14.     z AS SINGLE 'z location
  15.     ay AS SINGLE 'rain velocity
  16.     strData AS STRING 'string data of each matrix rain
  17.  
  18. DIM SHARED charImg(74) AS LONG, matRainWidth, matRainHeight 'ascii char from 48 to 122, i.e, total 75 type of chars
  19. DIM SHARED glAllow AS _BYTE, matrixRain(700) AS matRain, matrixRainTex(74) AS LONG, mov
  20. matRainWidth = _FONTWIDTH * 0.005
  21. matRainHeight = _FONTHEIGHT * 0.005
  22. CLS , _RGB32(255)
  23. FOR i = 0 TO 74
  24.     charImg(i) = _NEWIMAGE(_FONTWIDTH * 5, _FONTHEIGHT * 5, 32)
  25.     _DEST tmp&
  26.     CLS , _RGBA(0, 0, 0, 0)
  27.     COLOR _RGB32(0, 255, 0), 1
  28.     _PRINTSTRING (0, 0), CHR$(i + 48)
  29.     _DEST charImg(i)
  30.     _PUTIMAGE , tmp&
  31.     _DEST 0
  32.  
  33.  
  34. glAllow = -1
  35.     FOR i = 0 TO UBOUND(matrixRain)
  36.         matrixRain(i).y = matrixRain(i).y - matrixRain(i).ay
  37.         IF RND > 0.9 THEN
  38.             d$ = ""
  39.             FOR k = 1 TO LEN(matrixRain(i).strData)
  40.                 d$ = d$ + CHR$(48 + p5random(0, 74)) 'change the character of rain randomly by a chance of 10%
  41.             NEXT
  42.             matrixRain(i).strData = d$
  43.         END IF
  44.         matrixRain(i).z = matrixRain(i).z + 0.00566 'move into the rain
  45.         IF matrixRain(i).z > 0.1 THEN 'when behind screen
  46.             matrixRain(i).x = p5random(-2, 2)
  47.             matrixRain(i).y = p5random(2, 3.7)
  48.             matrixRain(i).z = map((i / UBOUND(matrixRain)), 0, 1, -8, -0.2)
  49.             matrixRain(i).ay = p5random(0.006, 0.02)
  50.         END IF
  51.     NEXT
  52.     _LIMIT 60
  53.  
  54. SUB _GL ()
  55.     STATIC glInit
  56.     mov = mov + 0.01
  57.     IF NOT glAllow THEN EXIT SUB
  58.  
  59.     IF glInit = 0 THEN
  60.         glInit = 1
  61.  
  62.         FOR i = 0 TO UBOUND(matrixRainTex) 'create texture for each ascii character
  63.             _glGenTextures 1, _OFFSET(matrixRainTex(i))
  64.  
  65.             DIM m AS _MEM
  66.             m = _MEMIMAGE(charImg(i))
  67.  
  68.             _glBindTexture _GL_TEXTURE_2D, matrixRainTex(i)
  69.             _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(charImg(i)), _HEIGHT(charImg(i)), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  70.  
  71.             _MEMFREE m
  72.  
  73.             _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_NEAREST
  74.             _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  75.             _FREEIMAGE charImg(i)
  76.         NEXT
  77.  
  78.         FOR i = 0 TO UBOUND(matrixRain) 'initialization
  79.             n = p5random(1, 15)
  80.             FOR j = 1 TO n
  81.                 v$ = CHR$(p5random(48, 122))
  82.                 matrixRain(i).strData = matrixRain(i).strData + v$
  83.             NEXT
  84.             matrixRain(i).x = p5random(-2, 2)
  85.             matrixRain(i).y = p5random(2, 3.7)
  86.             matrixRain(i).z = map((i / UBOUND(matrixRain)), 0, 1, -8, -0.2)
  87.             matrixRain(i).ay = p5random(0.006, 0.02)
  88.         NEXT
  89.  
  90.         _glViewport 0, 0, _WIDTH, _HEIGHT
  91.     END IF
  92.  
  93.     _glEnable _GL_BLEND 'enabling necessary stuff
  94.     _glEnable _GL_DEPTH_TEST
  95.     _glEnable _GL_TEXTURE_2D
  96.  
  97.  
  98.     _glClearColor 0, 0, 0, 1
  99.     _glClear _GL_COLOR_BUFFER_BIT OR _GL_DEPTH_BUFFER_BIT
  100.  
  101.  
  102.     _glMatrixMode _GL_PROJECTION
  103.     _gluPerspective 60, _WIDTH / _HEIGHT, 0.01, 10.0
  104.  
  105.     _glRotatef SIN(mov) * 20, 1, 0, 0 'rotating x-axis a bit, just to get Depth effect.
  106.  
  107.  
  108.     _glMatrixMode _GL_MODELVIEW
  109.  
  110.     'rendering the rain
  111.     FOR i = 0 TO UBOUND(matrixRain)
  112.         n = LEN(matrixRain(i).strData)
  113.         FOR j = 1 TO n
  114.             ca$ = MID$(matrixRain(i).strData, j, 1)
  115.             'selecting texture on the basis of ascii code.
  116.             _glBindTexture _GL_TEXTURE_2D, matrixRainTex(ASC(ca$) - 48)
  117.             _glBegin _GL_QUADS
  118.             _glTexCoord2f 0, 1
  119.             _glVertex3f matrixRain(i).x - matRainWidth, matrixRain(i).y - matRainHeight + 2 * (j - 1) * matRainHeight, matrixRain(i).z
  120.             _glTexCoord2f 0, 0
  121.             _glVertex3f matrixRain(i).x - matRainWidth, matrixRain(i).y + matRainHeight + 2 * (j - 1) * matRainHeight, matrixRain(i).z
  122.             _glTexCoord2f 1, 0
  123.             _glVertex3f matrixRain(i).x + matRainWidth, matrixRain(i).y + matRainHeight + 2 * (j - 1) * matRainHeight, matrixRain(i).z
  124.             _glTexCoord2f 1, 1
  125.             _glVertex3f matrixRain(i).x + matRainWidth, matrixRain(i).y - matRainHeight + 2 * (j - 1) * matRainHeight, matrixRain(i).z
  126.             _glEnd
  127.         NEXT
  128.     NEXT
  129.  
  130.     _glFlush
  131.  
  132. 'taken from p5js.bas
  133. 'https://bit.ly/p5jsbas
  134. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  135.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  136.  
  137.  
  138. FUNCTION p5random! (mn!, mx!)
  139.     IF mn! > mx! THEN
  140.         SWAP mn!, mx!
  141.     END IF
  142.     p5random! = RND * (mx! - mn!) + mn!
  143.  

 
Moving into the Matrix Rain Screenshot.jpg

39
Games / Hunter's Revenge by Ashish
« on: March 05, 2020, 05:50:56 am »
Hunter's Revenge

Author: @Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=345.msg2322#msg2322
Version: « Reply #7 on: July 18, 2018, 12:48:12 PM »
Tags: [Graphics], [2D], [Shoot 'Em]

Description:
You got a gun, and what you have to do is shoot down the objects you see on screen.  The game have different weather conditions as well as different areas.

Controls:
Use mouse movement to change your target. Use left click to shoot and right click to change gun. Use 'Esc' or Middle button to pause during gameplay.

Source Code:
Code: QB64: [Select]
  1. '################################################################
  2. '      H U N T E R ' S    R E V E N G E    2 0 1 7 - 1 8
  3. '                  By Ashish Kushwaha
  4. '         **** Hit F5 and Enjoy the Game!! ****
  5. 'Note :-
  6. 'The executable should be inside Hunter-Revenge folder
  7. 'If you are facing any problem, report it at Qb64.org Forum
  8. '
  9. '*** Tell Me You You Think About This Game On Twitter with @KingOfCoders ***
  10. '
  11. '################################################################
  12.  
  13. '$CONSOLE
  14. '_CONSOLETITLE "Hunter's Revenge [DEBUG_OUTPUT]"
  15.  
  16. IF COMMAND$(1) = "--reset" THEN
  17.     INPUT "Are you sure that you want to reset the game? (Y/N) ", dummy$1
  18.     IF UCASE$(dummy$1) = "Y" THEN KILL "Save_Game/save.dat": createConfig: SYSTEM
  19.  
  20. 'App icon
  21. $EXEICON:'Hunter-Revenge-master/Images/game.ico'
  22. tmp_icon& = _LOADIMAGE("Images/cursor.png", 32)
  23. _CLEARCOLOR _RGB(255, 255, 255), tmp_icon&
  24. _ICON tmp_icon&
  25. _FREEIMAGE tmp_icon&
  26.  
  27. '$include:'Vendor/spritetop.bi'
  28.  
  29. _TITLE "Hunter's Revenge"
  30.  
  31. SCREEN _NEWIMAGE(800, 600, 32)
  32.  
  33. ' ON ERROR GOTO 404
  34.  
  35.  
  36. 'Notification Section
  37. DIM SHARED NEvent, NFPSCount%, NImage&, NText$, NShow AS _BYTE
  38.  
  39. 'Frame Rate Section
  40. DIM SHARED FPSEvent, FPSEvt, FPSCurrent%, FPSRate%, FPSBg&
  41.  
  42. 'Loader Section
  43. DIM SHARED Loader&, LoaderX%, LoaderY%, LoaderCF%, LoaderEvt!
  44. LoaderX% = 730: LoaderY% = 500
  45.  
  46. 'Game Types
  47. TYPE GameMenu
  48.     click AS _BYTE
  49.     hover AS _BYTE
  50.     y AS INTEGER
  51.     img AS LONG
  52.     img2 AS LONG 'software image
  53.  
  54. TYPE Mousetype
  55.     x AS INTEGER
  56.     y AS INTEGER
  57.     lclick AS _BYTE
  58.     rclick AS _BYTE
  59.     mclick AS _BYTE
  60.     cursor AS LONG
  61.     cursor2 AS LONG
  62.     hovering AS _BYTE
  63.  
  64. TYPE fonttype
  65.     smaller AS LONG
  66.     normal AS LONG
  67.     bigger AS LONG
  68.     biggest AS LONG
  69. 'game objects
  70.  
  71. TYPE explosiontype
  72.     x AS INTEGER
  73.     y AS INTEGER
  74.     img AS INTEGER
  75.     active AS _BYTE
  76.     currentFrame AS INTEGER
  77.     totalFrames AS INTEGER
  78.     f AS INTEGER
  79.     n AS INTEGER
  80.  
  81. TYPE guntype
  82.     name AS STRING * 32
  83.     damage AS INTEGER
  84.     id AS INTEGER
  85.     img AS LONG
  86.  
  87. TYPE Enemies
  88.     x AS INTEGER ' x position
  89.     y AS INTEGER ' y position
  90.     typ AS STRING * 16 'type of enemie
  91.     life AS INTEGER 'life of the enemie
  92.     life2 AS INTEGER 'backup of life
  93.     damage AS INTEGER 'useless
  94.     ending AS _BYTE 'enemie is dead or not
  95.     img AS INTEGER 'sprite handle
  96.     active AS _BYTE 'enemie is active or not
  97.     u AS LONG 'delay (in milliseconds) after which enemie will show up in his scene in gameplay
  98.     n AS INTEGER 'delay between change of frame of animation
  99.     f AS INTEGER 'increment varible, if greater than above 'n', then frame is change
  100.     m AS DOUBLE 'movement speed
  101.     points AS INTEGER 'holds point
  102.     scene AS INTEGER 'hold scene
  103.     snd AS LONG 'hold sound handle
  104.     sndPaused AS _BYTE ' = true when sound is paused.
  105.  
  106. TYPE Levels
  107.     enemies AS INTEGER 'total enemies in a level
  108.     scenes AS INTEGER 'total scenes in a level
  109.     currentScene AS INTEGER 'current scene of the gameplay
  110.     completed AS _BYTE 'level has been completed or not
  111.     u AS LONG 'current frame of the gameplay (always increases during gameplay)
  112.     over AS _BYTE ' level has been over or not
  113.     background AS STRING * 64 'background image path of the level
  114.     bg AS LONG 'background image handle of the level
  115.     mode AS INTEGER 'MODs of the game. Can be either THUNDERMODE, STORMMODE, FOGMODE, THUNDERMODE+FOGMODE, THUNDERMODE+STORMMODE
  116.     cancel AS _BYTE 'level has been cancel or not
  117.     time AS _UNSIGNED INTEGER 'number of seconds a level has to be completed in (in seconds).
  118.  
  119. TYPE fog
  120.     x AS INTEGER
  121.     move AS INTEGER
  122.     handle AS LONG
  123.  
  124. TYPE drops
  125.     x AS INTEGER
  126.     y AS INTEGER
  127.     z AS INTEGER
  128.     len AS DOUBLE
  129.     yspeed AS DOUBLE
  130.     gravity AS DOUBLE
  131.  
  132. TYPE Settings
  133.     fullscreen AS _BYTE
  134.     music AS _BYTE
  135.     sfx AS _BYTE
  136.     musicV AS DOUBLE
  137.     sfxV AS DOUBLE
  138.     SE AS _BYTE
  139.     fps AS INTEGER
  140.     done AS _BYTE
  141.  
  142. 'score flasher
  143. TYPE scoreFlasher
  144.     x AS SINGLE
  145.     y AS SINGLE
  146.     img AS LONG
  147.     active AS _BYTE
  148.     sclX AS SINGLE
  149.     sclY AS SINGLE
  150.     __ops AS SINGLE
  151.  
  152. ' TYPE Vector_Particles_Text_Type
  153. ' x AS SINGLE 'x position
  154. ' y AS SINGLE 'y position
  155. ' vx AS SINGLE 'visual x
  156. ' vy AS SINGLE 'visual y
  157. ' delX AS SINGLE 'delta velocity
  158. ' delY AS SINGLE 'delta velocity
  159. ' dist AS SINGLE 'distance
  160. ' distX AS SINGLE ' distance x
  161. ' distY AS SINGLE 'distance y
  162. ' k AS SINGLE
  163. ' END TYPE
  164.  
  165. '$DYNAMIC
  166.  
  167. DIM SHARED W AS Settings
  168. readConfig
  169.  
  170. 'DIM SHARED Paused AS _BYTE
  171.  
  172. 'REDIM SHARED Text_Particles(1) AS Vector_Particles_Text_Type
  173.  
  174. 'DIM SHARED Text_Particles_Status, Text_Particles_Color AS _UNSIGNED LONG
  175.  
  176. DIM SHARED randomLevels AS _BYTE 'Computer chooses level! ^_*
  177.  
  178. DIM SHARED Menubg&, GlobalEvent, TimerEvent, GameRenderingEvent, Minutes%, Seconds%
  179.  
  180. DIM SHARED Mouse AS Mousetype
  181.  
  182. DIM SHARED Fonts AS fonttype
  183.  
  184. DIM SHARED GameMenus(19) AS GameMenu
  185.  
  186. DIM SHARED MenuBlood%, MenuChoice
  187.  
  188. DIM SHARED ShotScore(5) AS scoreFlasher
  189.  
  190. DIM SHARED explosions(20) AS explosiontype, Gun AS guntype, Bloods(50) AS explosiontype
  191.  
  192. DIM SHARED Level AS Levels
  193.  
  194. DIM SHARED HighScore%, LevelStage%, LevelStage2%, CurrentScore%
  195.  
  196. DIM SHARED ScoreBoard&, GunImg&(1), OldScore%, OldSeconds%
  197.  
  198. DIM SHARED Musics&(2)
  199.  
  200. 'Rains
  201. DIM SHARED Drop(700) AS drops
  202. DIM SHARED Rainx8&, Rainx16&, RainLight&, RainSound&, RainVol#, ThunderCount, ThunderEvent
  203.  
  204.  
  205.  
  206. 'max level
  207. CONST MAX_LEVEL = 14
  208. 'storm
  209. DIM SHARED StormImg&, StormX%
  210.  
  211. 'Sparks
  212. DIM SHARED ExplosionsZ(1) AS explosiontype
  213.  
  214. 'MODS
  215. CONST FOGMODE = 1
  216. CONST THUNDERMODE = 3
  217. CONST STORMMODE = 5
  218. DIM SHARED Fogs AS fog
  219.  
  220. 'SFXs
  221. DIM SHARED Eagle&
  222. DIM SHARED Bird&
  223. DIM SHARED Crow&
  224. DIM SHARED Expos&
  225. DIM SHARED Jet&
  226. DIM SHARED Gun1&
  227. DIM SHARED Gun2&
  228.  
  229. 'Enemies scores image
  230. DIM SHARED scoresImage(5) AS LONG
  231.  
  232. REDIM SHARED Enemie(0) AS Enemies
  233.  
  234. DIM SHARED Jet1_Sheet%
  235. DIM SHARED Jet2_Sheet%
  236. DIM SHARED Jet3_Sheet%
  237. DIM SHARED Bird_Sheet%
  238. DIM SHARED Crow_Sheet%
  239. DIM SHARED eagle_Sheet%
  240. DIM SHARED blood_Sheet%
  241. DIM SHARED explosion_Sheet%
  242. DIM SHARED spark_Sheet%
  243. DIM SHARED lifeBars(99) AS LONG
  244.  
  245. FPSEvent = _FREETIMER 'Event for showing current FPS (Frame Per Second)
  246. FPSEvt = _FREETIMER 'Event for calculating current FPS (Frame Per Second)
  247. GlobalEvent = _FREETIMER 'Event for game main menu
  248. TimerEvent = _FREETIMER 'Event of timer which is displayed during gameplay
  249. GameRenderingEvent = _FREETIMER 'Event in which level objects are rendered.
  250. NEvent = _FREETIMER ' Global Event for notification
  251.  
  252. 'Splash Screen
  253.  
  254. Splash
  255.  
  256.  
  257. LoaderStart
  258.  
  259. loadComponents
  260. 'cursors
  261. Mouse.cursor = _LOADIMAGE("Images/cursor.png", 33)
  262. Mouse.cursor2 = _LOADIMAGE("Images/cursor2.png", 33)
  263.  
  264. 'fonts
  265. Fonts.biggest = _LOADFONT("Font/ARDESTINE.ttf", 68)
  266. Fonts.bigger = _LOADFONT("Font/ARDESTINE.ttf", 40)
  267. Fonts.smaller = _LOADFONT("Font/arial.ttf", 12, "dontblend")
  268. Fonts.normal = _LOADFONT("Font/ARDESTINE.ttf", 24)
  269.  
  270. 'scores image
  271.  
  272. scoresImage(0) = _LOADIMAGE("Images/10.png", 33)
  273. scoresImage(1) = _LOADIMAGE("Images/20.png", 33)
  274. scoresImage(2) = _LOADIMAGE("Images/35.png", 33)
  275. scoresImage(3) = _LOADIMAGE("Images/50.png", 33)
  276. scoresImage(4) = _LOADIMAGE("Images/75.png", 33)
  277. scoresImage(5) = _LOADIMAGE("Images/100.png", 33)
  278.  
  279. 'fogs
  280. Fogs.x = 0
  281. Fogs.move = 1
  282. Fogs.handle = _LOADIMAGE("Images/fogs_.png", 33)
  283.  
  284. 'rains
  285. Rainx8& = _LOADIMAGE("Images/rainx8.png", 33)
  286. Rainx16& = _LOADIMAGE("Images/rainx16.png", 33)
  287.  
  288.  
  289. 'storm
  290. StormImg& = _LOADIMAGE("Images\storm.png", 33) 'we're using hardware image
  291.  
  292. 'LifeBars
  293. FOR i = 0 TO 99
  294.     lifeBars(i) = _NEWIMAGE(100, 6, 32)
  295.     _DEST lifeBars(i)
  296.     r = p5map(i + 1, 1, 100, 255, 0)
  297.     g = p5map(i + 1, 1, 100, 0, 255)
  298.     LINE (0, 0)-(100, 6), _RGB(0, 0, 0), BF
  299.     LINE (0, 0)-(i + 1, 6), _RGB(r, g, 0), BF
  300.     LINE (0, 0)-(99, 5), _RGB(255, 255, 255), B
  301.     _DEST 0
  302.  
  303. DIM tmp&
  304. FOR i = 0 TO 99
  305.     tmp& = _COPYIMAGE(lifeBars(i))
  306.     _FREEIMAGE lifeBars(i)
  307.     lifeBars(i) = _COPYIMAGE(tmp&, 33)
  308.     _FREEIMAGE tmp&
  309.  
  310. Gun.damage = 3
  311. Gun.id = 1
  312. Gun.name = "Shot Gun"
  313.  
  314. Menubg& = _LOADIMAGE("Images\farm1.jpg")
  315. GunImg&(0) = _LOADIMAGE("Images\gun_shot.png")
  316. GunImg&(1) = _LOADIMAGE("Images\Gun_ak-47.png")
  317. ScoreBoard& = _LOADIMAGE("Images\score_board.png")
  318.  
  319. blood_Sheet% = SPRITESHEETLOAD("Images\blood.png", 64, 62, _RGB(0, 0, 0))
  320. Jet1_Sheet% = SPRITESHEETLOAD("Images\Jet.png", 120, 122, _RGB(0, 0, 0))
  321. Jet2_Sheet% = SPRITESHEETLOAD("Images\Jet_2.png", 120, 122, _RGB(0, 0, 0))
  322. Jet3_Sheet% = SPRITESHEETLOAD("Images\Jet_3.png", 150, 122, _RGB(0, 0, 0))
  323. eagle_Sheet% = SPRITESHEETLOAD("Images\eagle.png", 40, 40, _RGB(0, 0, 0))
  324. Crow_Sheet% = SPRITESHEETLOAD("Images\crow.png", 97, 120, _RGB(0, 0, 0))
  325. Bird_Sheet% = SPRITESHEETLOAD("Images\bird.png", 180, 170, _RGB(0, 0, 0))
  326.  
  327. explosion_Sheet% = SPRITESHEETLOAD("Images\explosion.png", 100, 100, _RGB(0, 0, 0))
  328.  
  329. FOR i = 0 TO 1
  330.     ExplosionsZ(i).img = SPRITENEW(explosion_Sheet%, 1, SAVE)
  331.     SPRITEANIMATESET ExplosionsZ(i).img, 1, 81
  332.     ExplosionsZ(i).y = 300
  333.  
  334. ExplosionsZ(0).x = 100: ExplosionsZ(1).x = 700
  335.  
  336. FOR i = 0 TO 20
  337.     Bloods(i).img = SPRITENEW(blood_Sheet%, 1, SAVE)
  338.     SPRITEANIMATESET Bloods(i).img, 1, 6
  339.     explosions(i).img = SPRITENEW(explosion_Sheet%, 1, SAVE)
  340.     SPRITEANIMATESET explosions(i).img, 1, 81
  341.     Bloods(i).totalFrames = 6
  342.     Bloods(i).n = 5
  343.     explosions(i).totalFrames = 81
  344.     explosions(i).n = 4
  345. MenuBlood% = SPRITENEW(blood_Sheet%, 1, SAVE)
  346. SPRITEANIMATESET MenuBlood%, 1, 6
  347.  
  348.  
  349.  
  350. 'Setup Notificaton stuff
  351. ON TIMER(NEvent, .013) Notify
  352. TIMER(NEvent) ON
  353.  
  354. _FONT Fonts.bigger
  355.  
  356. tmp& = _NEWIMAGE(400, 60, 32)
  357. _DEST tmp&
  358. _FONT Fonts.bigger
  359. COLOR , _RGBA(0, 0, 0, 0)
  360. _PRINTSTRING (CenterPrintX("Play"), 0), "Play"
  361. GameMenus(0).img = _COPYIMAGE(tmp&, 33)
  362. GameMenus(0).img2 = _COPYIMAGE(tmp&, 32)
  363. GameMenus(0).y = 150
  364.  
  365. tmp& = _NEWIMAGE(400, 60, 32)
  366. _DEST tmp&
  367. _FONT Fonts.bigger
  368. COLOR , _RGBA(0, 0, 0, 0)
  369. _PRINTSTRING (CenterPrintX("Options"), 0), "Options"
  370. GameMenus(1).img = _COPYIMAGE(tmp&, 33)
  371. GameMenus(1).img2 = _COPYIMAGE(tmp&, 32)
  372. GameMenus(1).y = GameMenus(0).y + 60
  373.  
  374. tmp& = _NEWIMAGE(400, 60, 32)
  375. _DEST tmp&
  376. _FONT Fonts.bigger
  377. COLOR , _RGBA(0, 0, 0, 0)
  378. _PRINTSTRING (CenterPrintX("Help"), 0), "Help"
  379. GameMenus(2).img = _COPYIMAGE(tmp&, 33)
  380. GameMenus(2).img2 = _COPYIMAGE(tmp&, 32)
  381. GameMenus(2).y = GameMenus(1).y + 60
  382.  
  383. tmp& = _NEWIMAGE(400, 60, 32)
  384. _DEST tmp&
  385. _FONT Fonts.bigger
  386. COLOR , _RGBA(0, 0, 0, 0)
  387. _PRINTSTRING (CenterPrintX("Credits"), 0), "Credits"
  388. GameMenus(3).img = _COPYIMAGE(tmp&, 33)
  389. GameMenus(3).img2 = _COPYIMAGE(tmp&, 32)
  390. GameMenus(3).y = GameMenus(2).y + 60
  391.  
  392. tmp& = _NEWIMAGE(400, 60, 32)
  393. _DEST tmp&
  394. _FONT Fonts.bigger
  395. COLOR , _RGBA(0, 0, 0, 0)
  396. _PRINTSTRING (CenterPrintX("Exit"), 0), "Exit"
  397. GameMenus(4).img = _COPYIMAGE(tmp&, 33)
  398. GameMenus(4).img2 = _COPYIMAGE(tmp&, 32)
  399. GameMenus(4).y = GameMenus(3).y + 60
  400.  
  401.  
  402. tmp& = _NEWIMAGE(400, 30, 32)
  403. _DEST tmp&
  404. COLOR , _RGBA(0, 0, 0, 0)
  405. _FONT Fonts.normal
  406. _PRINTSTRING (20, 0), "Fullscreen"
  407. GameMenus(5).img = _COPYIMAGE(tmp&, 33)
  408. GameMenus(5).img2 = _COPYIMAGE(tmp&, 32)
  409. GameMenus(5).y = 113
  410.  
  411. tmp& = _NEWIMAGE(400, 30, 32)
  412. _DEST tmp&
  413. COLOR , _RGBA(0, 0, 0, 0)
  414. _FONT Fonts.normal
  415. _PRINTSTRING (20, 0), "Fullscreen Method "
  416. GameMenus(6).img = _COPYIMAGE(tmp&, 33)
  417. GameMenus(6).img2 = _COPYIMAGE(tmp&, 32)
  418. GameMenus(6).y = GameMenus(5).y + 34
  419.  
  420. tmp& = _NEWIMAGE(400, 30, 32)
  421. _DEST tmp&
  422. COLOR , _RGBA(0, 0, 0, 0)
  423. _FONT Fonts.normal
  424. _PRINTSTRING (20, 0), "Music "
  425. GameMenus(7).img = _COPYIMAGE(tmp&, 33)
  426. GameMenus(7).img2 = _COPYIMAGE(tmp&, 32)
  427. GameMenus(7).y = GameMenus(6).y + 34
  428.  
  429. tmp& = _NEWIMAGE(400, 30, 32)
  430. _DEST tmp&
  431. COLOR , _RGBA(0, 0, 0, 0)
  432. _FONT Fonts.normal
  433. _PRINTSTRING (20, 0), "SFX "
  434. GameMenus(8).img = _COPYIMAGE(tmp&, 33)
  435. GameMenus(8).img2 = _COPYIMAGE(tmp&, 32)
  436. GameMenus(8).y = GameMenus(7).y + 34
  437.  
  438. tmp& = _NEWIMAGE(400, 30, 32)
  439. _DEST tmp&
  440. COLOR , _RGBA(0, 0, 0, 0)
  441. _FONT Fonts.normal
  442. _PRINTSTRING (20, 0), "Music Volume "
  443. GameMenus(9).img = _COPYIMAGE(tmp&, 33)
  444. GameMenus(9).img2 = _COPYIMAGE(tmp&, 32)
  445. GameMenus(9).y = GameMenus(8).y + 34
  446.  
  447. tmp& = _NEWIMAGE(400, 30, 32)
  448. _DEST tmp&
  449. COLOR , _RGBA(0, 0, 0, 0)
  450. _FONT Fonts.normal
  451. _PRINTSTRING (20, 0), "SFX Volume"
  452. GameMenus(10).img = _COPYIMAGE(tmp&, 33)
  453. GameMenus(10).img2 = _COPYIMAGE(tmp&, 32)
  454. GameMenus(10).y = GameMenus(9).y + 34
  455.  
  456. tmp& = _NEWIMAGE(400, 30, 32)
  457. _DEST tmp&
  458. COLOR , _RGBA(0, 0, 0, 0)
  459. _FONT Fonts.normal
  460. _PRINTSTRING (20, 0), "3D Sound Effect"
  461. GameMenus(11).img = _COPYIMAGE(tmp&, 33)
  462. GameMenus(11).img2 = _COPYIMAGE(tmp&, 32)
  463. GameMenus(11).y = GameMenus(10).y + 34
  464.  
  465. tmp& = _NEWIMAGE(400, 30, 32)
  466. _DEST tmp&
  467. COLOR , _RGBA(0, 0, 0, 0)
  468. _FONT Fonts.normal
  469. _PRINTSTRING (20, 0), "Frame Rate "
  470. GameMenus(12).img = _COPYIMAGE(tmp&, 33)
  471. GameMenus(12).img2 = _COPYIMAGE(tmp&, 32)
  472. GameMenus(12).y = GameMenus(11).y + 34
  473.  
  474. tmp& = _NEWIMAGE(500, 30, 32)
  475. _DEST tmp&
  476. COLOR , _RGBA(0, 0, 0, 0)
  477. _FONT Fonts.normal
  478. _PRINTSTRING (CenterPrintX("Default Settings"), 0), "Default Settings"
  479. GameMenus(13).img = _COPYIMAGE(tmp&, 33)
  480. GameMenus(13).img2 = _COPYIMAGE(tmp&, 32)
  481. GameMenus(13).y = GameMenus(12).y + 34
  482.  
  483. tmp& = _NEWIMAGE(500, 200, 32)
  484. _DEST tmp&
  485. COLOR , _RGBA(0, 0, 0, 0)
  486. _FONT Fonts.normal
  487. _PRINTSTRING (CenterPrintX("Apply Settings"), 0), "Apply Settings"
  488. GameMenus(14).img = _COPYIMAGE(tmp&, 33)
  489. GameMenus(14).img2 = _COPYIMAGE(tmp&, 32)
  490. GameMenus(14).y = GameMenus(13).y + 34
  491.  
  492. tmp& = _NEWIMAGE(500, 200, 32)
  493. _DEST tmp&
  494. COLOR , _RGBA(0, 0, 0, 0)
  495. _FONT Fonts.normal
  496. _PRINTSTRING (CenterPrintX("Go Back To Main Menu"), 0), "Go Back To Main Menu"
  497. GameMenus(15).img = _COPYIMAGE(tmp&, 33)
  498. GameMenus(15).img2 = _COPYIMAGE(tmp&, 32)
  499. GameMenus(15).y = GameMenus(14).y + 34
  500.  
  501. tmp& = _NEWIMAGE(500, 200, 32)
  502. _DEST tmp&
  503. COLOR , _RGBA(0, 0, 0, 0)
  504. _FONT Fonts.normal
  505. _PRINTSTRING (20, 0), "Fullscreen"
  506. GameMenus(16).img = _COPYIMAGE(tmp&, 33)
  507. GameMenus(16).img2 = _COPYIMAGE(tmp&, 32)
  508. GameMenus(16).y = 232
  509.  
  510. tmp& = _NEWIMAGE(500, 200, 32)
  511. _DEST tmp&
  512. COLOR , _RGBA(0, 0, 0, 0)
  513. _FONT Fonts.normal
  514. _PRINTSTRING (20, 0), "Music Volume"
  515. GameMenus(17).img = _COPYIMAGE(tmp&, 33)
  516. GameMenus(17).img2 = _COPYIMAGE(tmp&, 32)
  517. GameMenus(17).y = GameMenus(16).y + 34
  518.  
  519. tmp& = _NEWIMAGE(500, 200, 32)
  520. _DEST tmp&
  521. COLOR , _RGBA(0, 0, 0, 0)
  522. _FONT Fonts.normal
  523. _PRINTSTRING (20, 0), "SFX Volume"
  524. GameMenus(18).img = _COPYIMAGE(tmp&, 33)
  525. GameMenus(18).img2 = _COPYIMAGE(tmp&, 32)
  526. GameMenus(18).y = GameMenus(17).y + 34
  527.  
  528. tmp& = _NEWIMAGE(500, 200, 32)
  529. _DEST tmp&
  530. COLOR , _RGBA(0, 0, 0, 0)
  531. _FONT Fonts.normal
  532. _PRINTSTRING (CenterPrintX("Exit to Main Menu"), 0), "Exit to Main Menu"
  533. GameMenus(19).img = _COPYIMAGE(tmp&, 33)
  534. GameMenus(19).img2 = _COPYIMAGE(tmp&, 32)
  535. GameMenus(19).y = GameMenus(18).y + 34
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542. LoaderEnd
  543.  
  544. start:
  545.  
  546. COLOR _RGB(255, 255, 255), _RGBA(0, 0, 0, 0)
  547.  
  548. ' echo COMMAND$(1)
  549. ' echo COMMAND$(2)
  550. ' IF COMMAND$(1) = "-loadlevel" AND VAL(COMMAND$(2)) > 0 THEN
  551. ' LevelStage% = VAL(COMMAND$(2))
  552. ' LevelStage2% = LevelStage%
  553. ' GOTO newgame
  554. ' END IF
  555.  
  556. GameMenu
  557.  
  558.  
  559.  
  560.  
  561. IF MenuChoice = 1 THEN MenuChoice = 0: GOTO newgame
  562. IF MenuChoice = 2 THEN
  563.     MenuChoice = 0
  564.  
  565.     'save current settings in dummy variable :P
  566.     DIM preConfig AS Settings
  567.     preConfig = W ' W is a global variable which stored all game settings
  568.  
  569.     DIM on_switch&, off_switch&, bd&, cj&, gfx&, ac& 'images surface
  570.     on_switch& = _LOADIMAGE("Images/on.png", 33)
  571.     off_switch& = _LOADIMAGE("Images/off.png", 33)
  572.     FOR i = 0 TO 4
  573.         _PUTIMAGE (200, GameMenus(i).y), GameMenus(i).img2
  574.     NEXT
  575.  
  576.     bd& = _COPYIMAGE(0)
  577.     cj& = _COPYIMAGE(bd&)
  578.  
  579.     BLURIMAGE cj&, 5
  580.     gfx& = _NEWIMAGE(500, 340, 32)
  581.     _DEST gfx&
  582.     CLS , 0 'make it transparent
  583.     LINE (0, 0)-STEP(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 150), BF
  584.     FOR i = 5 TO 14
  585.         _PUTIMAGE (0, GameMenus(i).y - 103), GameMenus(i).img2
  586.     NEXT
  587.  
  588.     _DEST 0
  589.  
  590.     FOR i = 0 TO 255 STEP 10
  591.         _SETALPHA i, , cj&
  592.         _PUTIMAGE , bd&
  593.         _PUTIMAGE , cj&
  594.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 3), BF
  595.         _PUTIMAGE (150, 103), gfx&, 0, (0, 0)-(500, p5map(i, 0, 255, 0, 340))
  596.         _DISPLAY
  597.     NEXT
  598.     ac& = _COPYIMAGE(cj&)
  599.     _DEST ac&
  600.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 85), BF
  601.     _DEST 0
  602.     DO
  603.         WHILE _MOUSEINPUT: WEND
  604.         Mouse.x = _MOUSEX: Mouse.y = _MOUSEY
  605.         Mouse.lclick = 0
  606.         Mouse.rclick = 0
  607.         IF _MOUSEBUTTON(1) THEN
  608.             WHILE _MOUSEBUTTON(1): WHILE _MOUSEINPUT: WEND: WEND
  609.             Mouse.lclick = -1
  610.         END IF
  611.         IF _MOUSEBUTTON(2) THEN
  612.             WHILE _MOUSEBUTTON(2): WHILE _MOUSEINPUT: WEND: WEND
  613.             Mouse.rclick = -1
  614.         END IF
  615.         _PUTIMAGE , ac&
  616.         LINE (150, 103)-STEP(500, 374), _RGBA(0, 0, 0, 150), BF
  617.         FOR i = 5 TO 15
  618.             IF Mouse.x > 150 AND Mouse.x < 650 AND Mouse.y > GameMenus(i).y - 10 AND Mouse.y < GameMenus(i).y + 24 THEN
  619.                 LINE (150, GameMenus(i).y - 10)-(650, GameMenus(i).y + 24), _RGBA(255, 100, 0, 100), BF
  620.                 IF Mouse.lclick THEN
  621.                     SELECT CASE i
  622.                         CASE 5
  623.                             IF W.fullscreen > 0 THEN W.fullscreen = 0 ELSE W.fullscreen = 1
  624.                         CASE 6
  625.                             W.fullscreen = W.fullscreen + 1
  626.                             IF W.fullscreen > 2 THEN W.fullscreen = 1
  627.                         CASE 7
  628.                             IF W.music THEN W.music = 0 ELSE W.music = -1
  629.                         CASE 8
  630.                             IF W.sfx THEN W.sfx = 0 ELSE W.sfx = -1
  631.                         CASE 9
  632.                             W.musicV = W.musicV + .1
  633.                             IF W.musicV > 1.0 THEN W.musicV = .1
  634.                         CASE 10
  635.                             W.sfxV = W.sfxV + .1
  636.                             IF W.sfxV > 1 THEN W.sfxV = 0.1
  637.                         CASE 11
  638.                             IF W.SE THEN W.SE = 0 ELSE W.SE = -1
  639.                         CASE 12
  640.                             W.fps = W.fps + 30
  641.                             IF W.fps > 240 THEN W.fps = 30
  642.                         CASE 13
  643.                             W.fullscreen = 0
  644.                             W.music = -1
  645.                             W.sfx = -1
  646.                             W.musicV = 1
  647.                             W.sfxV = 1
  648.                             W.SE = -1
  649.                             W.fps = 30
  650.                         CASE 14
  651.                             writeConfig
  652.                             loadComponents
  653.                             showNotification "Settings have been applied."
  654.                         CASE 15
  655.                             EXIT DO
  656.                     END SELECT
  657.                 END IF
  658.             END IF
  659.             _PUTIMAGE (150, GameMenus(i).y), GameMenus(i).img
  660.             SELECT CASE i
  661.                 CASE 5
  662.                     IF W.fullscreen > 0 THEN _PUTIMAGE (580, GameMenus(i).y - 3), on_switch& ELSE _PUTIMAGE (580, GameMenus(i).y - 3), off_switch&
  663.                 CASE 6
  664.                     _FONT Fonts.normal
  665.                     SELECT CASE W.fullscreen
  666.                         CASE 1
  667.                             _PRINTSTRING (630 - txtWidth("Stretch"), GameMenus(i).y), "Stretch"
  668.                         CASE 2
  669.                             _PRINTSTRING (630 - txtWidth("Square Pixels"), GameMenus(i).y), "Square Pixels"
  670.                         CASE ELSE
  671.                             _PRINTSTRING (630 - txtWidth("Disable"), GameMenus(i).y), "Disable"
  672.                     END SELECT
  673.                 CASE 7
  674.                     IF W.music THEN _PUTIMAGE (580, GameMenus(i).y - 3), on_switch& ELSE _PUTIMAGE (580, GameMenus(i).y - 3), off_switch&
  675.                 CASE 8
  676.                     IF W.sfx THEN _PUTIMAGE (580, GameMenus(i).y - 3), on_switch& ELSE _PUTIMAGE (580, GameMenus(i).y - 3), off_switch&
  677.                 CASE 9
  678.                     _FONT Fonts.normal
  679.                     IF W.musicV > .9 THEN
  680.                         _PRINTSTRING (630 - txtWidth(" 10"), GameMenus(i).y), " 10 "
  681.                     ELSE
  682.                         _PRINTSTRING (630 - txtWidth(STR$(INT(W.musicV * 10))), GameMenus(i).y), STR$(INT(W.musicV * 10))
  683.                     END IF
  684.                 CASE 10
  685.                     _FONT Fonts.normal
  686.                     IF W.sfxV > .9 THEN
  687.                         _PRINTSTRING (630 - txtWidth(" 10"), GameMenus(i).y), " 10 "
  688.                     ELSE
  689.                         _PRINTSTRING (630 - txtWidth(STR$(INT(W.sfxV * 10))), GameMenus(i).y), STR$(INT(W.sfxV * 10))
  690.                     END IF
  691.                 CASE 11
  692.                     IF W.SE THEN _PUTIMAGE (580, GameMenus(i).y - 3), on_switch& ELSE _PUTIMAGE (580, GameMenus(i).y - 3), off_switch&
  693.                 CASE 12
  694.                     _FONT Fonts.normal
  695.                     _PRINTSTRING (630 - txtWidth(STR$(W.fps)), GameMenus(i).y), STR$(W.fps)
  696.             END SELECT
  697.         NEXT
  698.         _LIMIT W.fps
  699.         IF Mouse.hovering THEN
  700.             _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor2
  701.             _DISPLAY
  702.         ELSE
  703.             _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor
  704.             _DISPLAY
  705.         END IF
  706.  
  707.     LOOP
  708.     FOR i = 255 TO 0 STEP -10
  709.         _SETALPHA i, , cj&
  710.         _PUTIMAGE , bd&
  711.         _PUTIMAGE , cj&
  712.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 3), BF
  713.         _PUTIMAGE (150, 103), gfx&, 0, (0, 0)-(500, p5map(i, 0, 255, 0, 340))
  714.         _DISPLAY
  715.     NEXT
  716.     _FREEIMAGE bd&
  717.     _FREEIMAGE cj&
  718.     _FREEIMAGE ac&
  719.     _FREEIMAGE gfx&
  720.     _FREEIMAGE on_switch&
  721.     _FREEIMAGE off_switch&
  722.     GOTO start
  723. IF MenuChoice = 3 THEN
  724.     MenuChoice = 0
  725.     FOR i = 0 TO 4
  726.         _PUTIMAGE (200, GameMenus(i).y), GameMenus(i).img2
  727.     NEXT
  728.     bd& = _COPYIMAGE(0)
  729.     cj& = _COPYIMAGE(bd&)
  730.  
  731.     BLURIMAGE cj&, 5
  732.     DIM k&
  733.     k& = _LOADIMAGE("Images\help.png")
  734.  
  735.     FOR i = 0 TO 255 STEP 10
  736.         _SETALPHA i, , cj&
  737.         _PUTIMAGE , bd&
  738.         _PUTIMAGE , cj&
  739.         _SETALPHA i / 1.25, , k&
  740.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 5), BF
  741.         centerImage k&
  742.         _DISPLAY
  743.     NEXT
  744.  
  745.     DO
  746.         'mouse input
  747.         WHILE _MOUSEINPUT: WEND
  748.         Mouse.x = _MOUSEX: Mouse.y = _MOUSEY
  749.  
  750.         IF _MOUSEBUTTON(1) THEN
  751.             WHILE _MOUSEBUTTON(1): WHILE _MOUSEINPUT: WEND: WEND
  752.             Mouse.lclick = -1
  753.         ELSE
  754.             Mouse.lclick = 0
  755.         END IF
  756.  
  757.         IF _MOUSEBUTTON(2) THEN
  758.             WHILE _MOUSEBUTTON(2): WHILE _MOUSEINPUT: WEND: WEND
  759.             Mouse.rclick = -1
  760.         ELSE
  761.             Mouse.rclick = 0
  762.         END IF
  763.  
  764.         _LIMIT W.fps
  765.  
  766.         _DISPLAY
  767.  
  768.         IF Mouse.lclick OR Mouse.rclick OR _KEYHIT = 27 THEN EXIT DO
  769.     LOOP
  770.  
  771.     FOR i = 255 TO 0 STEP -10
  772.         _SETALPHA i, , cj&
  773.         _PUTIMAGE , bd&
  774.         _PUTIMAGE , cj&
  775.         _SETALPHA i / 1.25, , k&
  776.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 5), BF
  777.         centerImage k&
  778.         _DISPLAY
  779.     NEXT
  780.  
  781.     _PUTIMAGE , bd&
  782.     _FREEIMAGE bd&
  783.     _FREEIMAGE cj&
  784.     _FREEIMAGE k&
  785.     GOTO start
  786.  
  787.  
  788. IF MenuChoice = 4 THEN
  789.     FOR i = 0 TO 4
  790.         _PUTIMAGE (200, GameMenus(i).y), GameMenus(i).img2
  791.     NEXT
  792.  
  793.     bd& = _COPYIMAGE(0)
  794.  
  795.     FOR i = 0 TO 255 STEP 5
  796.         _PUTIMAGE , bd&
  797.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i), BF
  798.         _DISPLAY
  799.     NEXT
  800.  
  801.     showCredits
  802.  
  803.     FOR i = 255 TO 0 STEP -5
  804.         _PUTIMAGE , bd&
  805.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i), BF
  806.         _DISPLAY
  807.     NEXT
  808.  
  809.     _FREEIMAGE bd&
  810.     MenuChoice = 0
  811.     GOTO start
  812.  
  813.  
  814. IF MenuChoice = 5 THEN SYSTEM 1
  815. MenuChoice = 0
  816. newgame:
  817.  
  818.  
  819.  
  820. LoaderStart
  821. SetupRain
  822. IF COMMAND$(1) = "-loadlevel" THEN
  823.     LoadLevel
  824.     IF getCurrentLevel > MAX_LEVEL THEN randomLevels = -1 ELSE randomLevels = 0: LoadLevel
  825.  
  826.  
  827. _FONT Fonts.bigger
  828.  
  829. '################### Random Levels ################################
  830. IF randomLevels THEN
  831.     Level.completed = 0
  832.     Level.over = 0
  833.     LevelStage% = p5random(1, MAX_LEVEL)
  834.     F = FREEFILE
  835.     'LevelStage% = VAL(COMMAND$(2))
  836.     OPEN "stages/stage" + RTRIM$(LTRIM$(STR$(LevelStage%))) + ".dat" FOR INPUT AS #F
  837.     INPUT #F, Level.enemies
  838.     INPUT #F, Level.scenes
  839.     INPUT #F, Seconds%
  840.     INPUT #F, Level.mode
  841.     INPUT #F, Level.background
  842.     CLOSE #F
  843.     Level.bg = _LOADIMAGE("Images\" + RTRIM$(Level.background))
  844.     OldSeconds% = Seconds%
  845.  
  846. IF randomLevels THEN _PRINTSTRING (CenterPrintX("Random Levels"), 300), "Random Levels" ELSE _PRINTSTRING (CenterPrintX("Stage " + LTRIM$(RTRIM$(STR$(LevelStage%)))), 300), "Stage " + LTRIM$(RTRIM$(STR$(LevelStage%)))
  847.  
  848.  
  849. ' if randomLevels then LoaderEnd : goto game_rendering_begin
  850. ' _DELAY 0.5
  851.  
  852.  
  853. '############################# Custom Levels #############################
  854.  
  855. ERASE Enemie 'clear all previous enemie data
  856.  
  857. REDIM SHARED Enemie(Level.enemies) AS Enemies
  858.  
  859. 'Enemie Configuirations
  860.  
  861. Level.completed = 0
  862. Level.over = 0
  863. Level.cancel = 0
  864. CurrentScore% = 0
  865. Level.u = 0
  866. Level.currentScene = 1
  867.  
  868. OPEN "Stages\Stage" + LTRIM$(RTRIM$(STR$(LevelStage%))) + ".lvl" FOR INPUT AS #F
  869.  
  870. FOR i = 1 TO Level.enemies
  871.     INPUT #F, Enemie(i).typ
  872.  
  873.     SELECT CASE RTRIM$(Enemie(i).typ)
  874.  
  875.         CASE "bird"
  876.             Enemie(i).img = SPRITENEW(Bird_Sheet%, 1, SAVE)
  877.             SPRITEANIMATESET Enemie(i).img, 1, 14
  878.             SPRITEZOOM Enemie(i).img, 50
  879.             Enemie(i).n = 6
  880.             Enemie(i).points = 10
  881.             Enemie(i).life = 4
  882.             Enemie(i).life2 = Enemie(i).life
  883.             Enemie(i).snd = _SNDCOPY(Bird&)
  884.         CASE "crow"
  885.             Enemie(i).img = SPRITENEW(Crow_Sheet%, 1, SAVE)
  886.             SPRITEANIMATESET Enemie(i).img, 1, 4
  887.             SPRITEZOOM Enemie(i).img, 70
  888.             Enemie(i).n = 12
  889.             Enemie(i).points = 20
  890.             Enemie(i).life = 7
  891.             Enemie(i).life2 = Enemie(i).life
  892.             Enemie(i).snd = _SNDCOPY(Crow&)
  893.         CASE "eagle"
  894.             Enemie(i).img = SPRITENEW(eagle_Sheet%, 7, SAVE)
  895.             SPRITEANIMATESET Enemie(i).img, 7, 9
  896.             Enemie(i).n = 12
  897.             Enemie(i).points = 35
  898.             Enemie(i).life = 14
  899.             Enemie(i).life2 = Enemie(i).life
  900.             Enemie(i).snd = _SNDCOPY(Eagle&)
  901.         CASE "jet1"
  902.             Enemie(i).img = SPRITENEW(Jet1_Sheet%, 1, SAVE)
  903.             SPRITEANIMATESET Enemie(i).img, 1, 3
  904.             SPRITEZOOM Enemie(i).img, 70
  905.             Enemie(i).n = 10
  906.             Enemie(i).points = 50
  907.             Enemie(i).life = 30
  908.             Enemie(i).life2 = Enemie(i).life
  909.             Enemie(i).snd = _SNDCOPY(Jet&)
  910.         CASE "jet2"
  911.             Enemie(i).img = SPRITENEW(Jet2_Sheet%, 1, SAVE)
  912.             SPRITEANIMATESET Enemie(i).img, 1, 3
  913.             SPRITEZOOM Enemie(i).img, 70
  914.             Enemie(i).n = 10
  915.             Enemie(i).points = 75
  916.             Enemie(i).life = 45
  917.             Enemie(i).life2 = Enemie(i).life
  918.             Enemie(i).snd = _SNDCOPY(Jet&)
  919.         CASE "jet3"
  920.             Enemie(i).img = SPRITENEW(Jet3_Sheet%, 1, SAVE)
  921.             SPRITEANIMATESET Enemie(i).img, 1, 3
  922.             SPRITEZOOM Enemie(i).img, 70
  923.             Enemie(i).n = 10
  924.             Enemie(i).points = 100
  925.             Enemie(i).life = 70
  926.             Enemie(i).life2 = Enemie(i).life
  927.             Enemie(i).snd = _SNDCOPY(Jet&)
  928.     END SELECT
  929.     INPUT #F, Enemie(i).u
  930.     INPUT #F, Enemie(i).y
  931.     INPUT #F, Enemie(i).m
  932.     IF Enemie(i).m < 0 THEN Enemie(i).x = _WIDTH: SPRITEFLIP Enemie(i).img, HORIZONTAL ELSE Enemie(i).x = 0
  933.  
  934.     INPUT #F, Enemie(i).scene
  935.  
  936.  
  937. LoaderEnd
  938.  
  939. game_rendering_begin:::
  940.  
  941. _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), Level.bg
  942. _PUTIMAGE (0, 520), ScoreBoard&
  943. _PUTIMAGE (50, 550)-(170, 590), GunImg&(Gun.id - 1)
  944. _FONT Fonts.smaller
  945. _PRINTSTRING (40, 580), RTRIM$(Gun.name)
  946. _FONT Fonts.normal
  947.  
  948. IF randomLevels THEN _PRINTSTRING (CenterPrintX("Random Levels"), 560), "Random Levels" ELSE _PRINTSTRING (CenterPrintX("Stage " + STR$(LevelStage%)), 560), "Stage " + STR$(LevelStage%)
  949. _FONT Fonts.smaller
  950.  
  951. Minutes% = (Seconds% - (Seconds% MOD 60)) / 60
  952. t = Seconds% MOD 60
  953.  
  954. _PRINTSTRING (600, 560), "Score - " + STR$(CurrentScore%)
  955. _PRINTSTRING (600, 580), "Time Left -" + STR$(Minutes%) + ":" + STR$(t)
  956. StartLevel
  957.  
  958. FOR i = 1 TO Level.enemies 'free all the sound buffer stream (sound stream will reload again when next gameplay starts.
  959.     _SNDCLOSE Enemie(i).snd
  960.  
  961. COLOR _RGB(255, 255, 255), _RGBA(0, 0, 0, 0)
  962. 'checking if the level has benn canceled by the user.
  963. IF Level.cancel THEN
  964.     'free the level background image
  965.     _FREEIMAGE Level.bg
  966.     Level.cancel = 0
  967.     GOTO start
  968.  
  969. 'checking if game is completed
  970.  
  971. IF Level.completed THEN
  972.     ' IF COMMAND$(1) = "-loadlevel" THEN
  973.     ' echo "Level : " + STR$(LevelStage%)
  974.     ' echo "Time taken to complete : " + STR$(Level.time - Seconds%)
  975.     ' END IF
  976.  
  977.     _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), Level.bg
  978.  
  979.     'crosfading start here -
  980.     DIM blured&
  981.  
  982.     blured& = _COPYIMAGE(Level.bg)
  983.     BLURIMAGE blured&, 5
  984.     FOR i = 1 TO 255 STEP 20
  985.         _SETALPHA i, , blured&
  986.         _PUTIMAGE , Level.bg
  987.         _PUTIMAGE , blured&
  988.         _DISPLAY
  989.     NEXT
  990.  
  991.     _FREEIMAGE blured&
  992.  
  993.     LINE (200, 200)-(_WIDTH - 200, _HEIGHT - 200), _RGBA(0, 0, 0, 180), BF
  994.     _FONT Fonts.normal
  995.     _PRINTSTRING (CenterPrintX("Stage " + STR$(LevelStage%) + "Completed!"), 210), "Stage " + STR$(LevelStage%) + " Completed"
  996.     _FONT Fonts.smaller
  997.     DIM a$
  998.     a$ = "Congratulations!! You created new high score!"
  999.  
  1000.     IF CurrentScore% > HighScore% THEN _PRINTSTRING (CenterPrintX(a$), 250), a$
  1001.  
  1002.     _PRINTSTRING (CenterPrintX("Score - " + STR$(CurrentScore%)), 300), "Score - " + STR$(CurrentScore%)
  1003.     _PRINTSTRING (CenterPrintX("Bonus Score - " + STR$(Seconds% * 2)), 320), "Bonus Score - " + STR$(Seconds% * 2)
  1004.     _PRINTSTRING (CenterPrintX("Total Score - " + STR$(Seconds% * 2 + CurrentScore%)), 340), "Total Score - " + STR$(Seconds% * 2 + CurrentScore%)
  1005.  
  1006.     IF LevelStage% = MAX_LEVEL THEN a$ = "Game Completed" ELSE a$ = "Be ready for next stage. Wait a moment..."
  1007.     _PRINTSTRING (CenterPrintX(a$), 380), a$
  1008.  
  1009.     DO
  1010.         IF F = 1 THEN SPRITESHOW ExplosionsZ(0).img: SPRITESHOW ExplosionsZ(1).img
  1011.         FOR i = 0 TO 1
  1012.             SPRITENEXT ExplosionsZ(i).img
  1013.             SPRITEPUT ExplosionsZ(i).x, ExplosionsZ(i).y, ExplosionsZ(i).img
  1014.         NEXT
  1015.         _LIMIT W.fps
  1016.         _DISPLAY
  1017.         F = F + 1
  1018.     LOOP UNTIL F > 180
  1019.     SPRITEHIDE ExplosionsZ(0).img
  1020.     SPRITEHIDE ExplosionsZ(1).img
  1021.    
  1022.     F = 0
  1023.     IF COMMAND$(1) = "-loadlevel" THEN SYSTEM
  1024.     SaveGame
  1025.  
  1026.     IF LevelStage% > MAX_LEVEL THEN
  1027.         bd& = _COPYIMAGE(0)
  1028.         FOR i = 0 TO 255 STEP 5
  1029.             _PUTIMAGE , bd&
  1030.             LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i), BF
  1031.             _DISPLAY
  1032.         NEXT
  1033.         showCredits
  1034.  
  1035.         GOTO start
  1036.     END IF
  1037.     'free the level background image
  1038.     _FREEIMAGE Level.bg
  1039.  
  1040.     GOTO newgame
  1041. IF Level.over THEN
  1042.     COLOR _RGB(255, 0, 0)
  1043.     ' IF COMMAND$(1) = "-loadlevel" THEN
  1044.     ' echo "Level failed to compete"
  1045.     ' END IF
  1046.  
  1047.     _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), Level.bg
  1048.     'crosfading start here -
  1049.     blured& = _COPYIMAGE(Level.bg)
  1050.     BLURIMAGE blured&, 5
  1051.     FOR i = 1 TO 255 STEP 20
  1052.         _SETALPHA i, , blured&
  1053.         _PUTIMAGE , Level.bg
  1054.         _PUTIMAGE , blured&
  1055.         _DISPLAY
  1056.     NEXT
  1057.  
  1058.     _FREEIMAGE blured&
  1059.     LINE (200, 250)-(_WIDTH - 200, _HEIGHT - 250), _RGBA(0, 0, 0, 180), BF
  1060.     _FONT Fonts.bigger
  1061.     _PRINTSTRING (CenterPrintX("Game Over"), 260), "Game Over"
  1062.     _FONT Fonts.smaller
  1063.     _PRINTSTRING (CenterPrintX("Click To Continue..."), _HEIGHT - 280), "Click to Continue..."
  1064.     _DISPLAY
  1065.  
  1066.     DO
  1067.         WHILE _MOUSEINPUT: WEND
  1068.         IF _MOUSEBUTTON(1) THEN
  1069.             WHILE _MOUSEBUTTON(1): WHILE _MOUSEINPUT: WEND: WEND
  1070.             EXIT DO
  1071.         END IF
  1072.         _LIMIT 30
  1073.     LOOP
  1074.     GOTO start
  1075.     'free the level background image
  1076.     _FREEIMAGE Level.bg
  1077.  
  1078.  
  1079. 404
  1080. COLOR _RGB(255, 255, 255)
  1081. CIRCLE (_WIDTH / 2, 200), 100
  1082. CIRCLE (_WIDTH / 2 - 50, 150), 5
  1083. CIRCLE (_WIDTH / 2 + 50, 150), 5
  1084. CIRCLE (_WIDTH / 2, 250), 50, , 0, _PI
  1085.  
  1086. centerPrint "An Error has ocurred!", 350
  1087. centerPrint "Error Code - " + STR$(ERR), 366
  1088.     centerPrint "Error File - " + _INCLERRORFILE$, 382
  1089.     centerPrint "Error Line - " + STR$(_INCLERRORLINE), 398
  1090.     centerPrint "Error File - Main_File", 382
  1091.     centerPrint "Error Line - " + STR$(_ERRORLINE), 398
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099. SUB echo (m$) 'always write to console
  1100.     DIM preDest AS LONG
  1101.     preDest = _DEST
  1102.     PRINT m$
  1103.     _DEST preDest
  1104.  
  1105. SUB showNotification (message$)
  1106.     NText$ = message$
  1107.     NShow = -1
  1108.  
  1109. SUB Notify ()
  1110.     STATIC imgy
  1111.     IF NShow = -1 THEN
  1112.         IF NFPSCount% = 0 THEN
  1113.             _FONT 16
  1114.             DIM __w AS INTEGER, h AS INTEGER, tmp&, preDest AS LONG
  1115.             __w = LEN(NText$) * 8 + 40
  1116.             h = 36
  1117.  
  1118.             tmp& = _NEWIMAGE(__w, h, 32)
  1119.  
  1120.             preDest = _DEST
  1121.             _DEST tmp&
  1122.  
  1123.             COLOR _RGB(10, 10, 10), _RGB(355, 245, 245)
  1124.             CLS , _RGB(255, 245, 245)
  1125.             _PRINTSTRING (20, 10), NText$
  1126.  
  1127.             _DEST preDest
  1128.             NImage& = _COPYIMAGE(tmp&, 33)
  1129.             _FREEIMAGE tmp&
  1130.  
  1131.             imgy = -40
  1132.         END IF
  1133.         IF NFPSCount% > 0 AND NFPSCount% < 40 THEN
  1134.             imgy = imgy + 1
  1135.             _PUTIMAGE (_WIDTH / 2 - _WIDTH(NImage&) / 2, imgy), NImage&
  1136.         END IF
  1137.         IF NFPSCount% > 40 AND NFPSCount% < 160 THEN
  1138.             _PUTIMAGE (_WIDTH / 2 - _WIDTH(NImage&) / 2, imgy), NImage&
  1139.         END IF
  1140.         IF NFPSCount% > 160 AND NFPSCount% < 200 THEN
  1141.             _PUTIMAGE (_WIDTH / 2 - _WIDTH(NImage&) / 2, imgy), NImage&
  1142.             imgy = imgy - 1
  1143.         END IF
  1144.         NFPSCount% = NFPSCount% + 1
  1145.         IF NFPSCount% > 200 THEN
  1146.             _FREEIMAGE NImage&
  1147.             NFPSCount% = 0
  1148.             NShow = 0
  1149.         END IF
  1150.     END IF
  1151.  
  1152.  
  1153. SUB readConfig ()
  1154.     DIM F AS INTEGER
  1155.  
  1156.     IF NOT _FILEEXISTS("Settings/settings.dat") THEN writeConfig
  1157.     F = FREEFILE
  1158.     OPEN "Settings/settings.dat" FOR INPUT AS #F
  1159.     INPUT #F, W.fullscreen
  1160.     INPUT #F, W.music
  1161.     INPUT #F, W.sfx
  1162.     INPUT #F, W.musicV
  1163.     INPUT #F, W.sfxV
  1164.     INPUT #F, W.SE
  1165.     INPUT #F, W.fps
  1166.     CLOSE #F
  1167.  
  1168. SUB writeConfig ()
  1169.     DIM f AS INTEGER
  1170.  
  1171.     f = FREEFILE
  1172.     OPEN "Settings/settings.dat" FOR OUTPUT AS #f
  1173.     PRINT #f, W.fullscreen
  1174.     PRINT #f, W.music
  1175.     PRINT #f, W.sfx
  1176.     PRINT #f, W.musicV
  1177.     PRINT #f, W.sfxV
  1178.     PRINT #f, W.SE
  1179.     PRINT #f, W.fps
  1180.     CLOSE #f
  1181.  
  1182. SUB createConfig ()
  1183.     W.fullscreen = 0
  1184.     W.music = -1
  1185.     W.sfx = -1
  1186.     W.musicV = 1
  1187.     W.sfxV = 1
  1188.     W.SE = -1
  1189.     W.fps = 90
  1190.     writeConfig
  1191.  
  1192. SUB loadComponents ()
  1193.     IF W.fullscreen = 0 THEN
  1194.     ELSEIF W.fullscreen = 1 THEN
  1195.     ELSEIF W.fullscreen = 2 THEN
  1196.     END IF
  1197.  
  1198.     'SFXs
  1199.     ' screen_conf:
  1200.     IF Gun1& = 0 THEN Gun1& = _SNDOPEN("SFX/Gun1.ogg", "sync,vol,pause")
  1201.     IF Gun2& = 0 THEN Gun2& = _SNDOPEN("SFX/Gun2.ogg", "sync,vol,pause")
  1202.     IF Bird& = 0 THEN Bird& = _SNDOPEN("SFX/bird.ogg", "sync,vol,pause")
  1203.     IF Crow& = 0 THEN Crow& = _SNDOPEN("SFX/Crow.ogg", "sync,vol,pause")
  1204.     IF Eagle& = 0 THEN Eagle& = _SNDOPEN("SFX/Eagle.ogg", "sync,vol,pause")
  1205.     IF Expos& = 0 THEN Expos& = _SNDOPEN("SFX/Explosion.mp3", "sync,vol,pause")
  1206.     IF Jet& = 0 THEN Jet& = _SNDOPEN("SFX/Jet.ogg", "sync,vol,pause")
  1207.     IF RainSound& = 0 THEN RainSound& = _SNDOPEN("SFX/Rain.mp3", "vol,sync,pause")
  1208.  
  1209.     IF Musics&(0) = 0 THEN Musics&(0) = _SNDOPEN("Musics/Hunter's_Revenge-Against_Evil.mp3", "sync,vol,pause")
  1210.     IF Musics&(1) = 0 THEN Musics&(1) = _SNDOPEN("Musics/Hunter's_Revenge-End_Of_Game.mp3", "sync,vol,pause")
  1211.     IF Musics&(2) = 0 THEN Musics&(2) = _SNDOPEN("Musics/Hunter's_Revenge-Who's_Next.mp3", "sync,vol,pause")
  1212.  
  1213.     setMusicVol W.musicV
  1214.     IF NOT W.music THEN 'if menu background music disable, then stop the musics, regardless of whether the are being played or not.
  1215.         _SNDSTOP Musics&(0)
  1216.         _SNDSTOP Musics&(1)
  1217.         _SNDSTOP Musics&(2)
  1218.     END IF
  1219.  
  1220.     W.done = -1
  1221.  
  1222. SUB Splash ()
  1223.  
  1224.     CLS
  1225.  
  1226.     DIM stars&, x AS INTEGER, y AS INTEGER, F AS INTEGER
  1227.  
  1228.     stars& = _NEWIMAGE(_WIDTH * 2, _HEIGHT, 32)
  1229.     _DEST stars&
  1230.     DO
  1231.         x = INT(RND * _WIDTH(stars&))
  1232.         y = INT(RND * _HEIGHT)
  1233.         PSET (x, y), _RGB(255, 255, 255)
  1234.         F = F + 1
  1235.     LOOP UNTIL F > 700
  1236.  
  1237.     DIM spT&, sp&, eft1&, p AS INTEGER, a AS INTEGER, xx AS INTEGER
  1238.  
  1239.     _DEST 0
  1240.     spT& = _LOADIMAGE("Images\splash.png")
  1241.     _CLEARCOLOR _RGB(0, 0, 0), spT&
  1242.     sp& = _COPYIMAGE(spT&, 33)
  1243.     F = 0
  1244.     eft1& = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  1245.     _DEST eft1&
  1246.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGB(0, 0, 50), BF
  1247.     _DEST 0
  1248.  
  1249.     p = 6
  1250.     FPSStart
  1251.     DO
  1252.         _SETALPHA a, , eft1&: _PUTIMAGE , eft1&
  1253.         _PUTIMAGE (xx, 0), stars&
  1254.         _PUTIMAGE , sp&
  1255.         xx = xx - 1
  1256.         IF xx < -_WIDTH - 2 THEN xx = 0
  1257.         _LIMIT 60
  1258.         a = a + p
  1259.         IF a > 250 THEN p = -p
  1260.         IF a < 6 THEN p = 6
  1261.         _DISPLAY
  1262.         F% = F% + 1
  1263.         FPSCurrent% = FPSCurrent% + 1
  1264.     LOOP UNTIL F% > 360
  1265.  
  1266.     FPSEnd
  1267.     CLS
  1268.  
  1269.     _FREEIMAGE sp&
  1270.     _FREEIMAGE spT&
  1271.     _FREEIMAGE eft1&
  1272.     _FREEIMAGE stars&
  1273.  
  1274. SUB FPSStart ()
  1275.     ON TIMER(FPSEvent, 1) FPS
  1276.     ON TIMER(FPSEvt, 0.01) FPSShow
  1277.     TIMER(FPSEvent) ON
  1278.     TIMER(FPSEvt) ON
  1279.  
  1280. SUB FPS ()
  1281.     FPSRate% = FPSCurrent%
  1282.     FPSCurrent% = 0
  1283.  
  1284. SUB FPSShow ()
  1285.     COLOR _RGB(255, 255, 255)
  1286.     _PRINTSTRING (720, 0), STR$(FPSRate%) + " FPS"
  1287.  
  1288. SUB FPSEnd ()
  1289.     TIMER(FPSEvent) OFF
  1290.     TIMER(FPSEvt) OFF
  1291.  
  1292. SUB LoaderStart ()
  1293.     Loader& = _LOADIMAGE("Images\loader.gif", 33)
  1294.     LoaderEvt! = _FREETIMER
  1295.     ON TIMER(LoaderEvt!, 0.1) ShowLoader
  1296.     TIMER(LoaderEvt!) ON
  1297.  
  1298. SUB LoaderEnd ()
  1299.     TIMER(LoaderEvt!) OFF
  1300.     _FREEIMAGE Loader&
  1301.  
  1302. SUB ShowLoader ()
  1303.     IF LoaderCF% = 0 THEN LoaderCF% = 1
  1304.     _PUTIMAGE (LoaderX%, LoaderY%), Loader&, 0, (LoaderCF% * 48 - 48, 0)-(LoaderCF% * 48 - 1, 48)
  1305.     LoaderCF% = LoaderCF% + 1
  1306.     IF LoaderCF% > 8 THEN LoaderCF% = 1
  1307.     _DISPLAY
  1308.  
  1309. ' SUB PlayMovie (m$)
  1310. ' LoaderStart
  1311.  
  1312. ' DIM f AS INTEGER, n AS LONG, i AS LONG, k AS INTEGER
  1313.  
  1314. ' f = FREEFILE
  1315. ' OPEN "Movies\" + m$ + "\" + m$ + ".txt" FOR INPUT AS #f
  1316. ' INPUT #f, n
  1317. ' CLOSE #f
  1318. ' DIM Temps_Buffers&(n)
  1319. ' FOR i = 1 TO n
  1320. ' Temps_Buffers&(i) = _LOADIMAGE("Movies\" + m$ + "\produce" + LTRIM$(RTRIM$(STR$(i))) + ".jpg", 33)
  1321. ' NEXT
  1322. ' LoaderEnd
  1323. ' FOR i = 1 TO n
  1324. ' FOR k = 1 TO 3
  1325. ' _PUTIMAGE , Temps_Buffers&(i)
  1326. ' _DISPLAY
  1327. ' NEXT
  1328. ' _DELAY .05
  1329. ' _FREEIMAGE Temps_Buffers&(i)
  1330. ' NEXT
  1331. ' ERASE Temps_Buffers&
  1332. ' END SUB
  1333.  
  1334. SUB GameMenu ()
  1335.     _PUTIMAGE , Menubg&
  1336.     DIM n%
  1337.     'Menu background music
  1338.     IF W.music THEN
  1339.         n% = p5random(0, 2)
  1340.         IF NOT (_SNDPLAYING(Musics&(0)) OR _SNDPLAYING(Musics&(1)) OR _SNDPLAYING(Musics&(2))) THEN _SNDPLAY Musics&(n%)
  1341.     END IF
  1342.  
  1343.     ON TIMER(GlobalEvent, 0.01) GameMenu2
  1344.     TIMER(GlobalEvent) ON
  1345.     DO
  1346.         WHILE _MOUSEINPUT: WEND
  1347.         Mouse.x = _MOUSEX: Mouse.y = _MOUSEY
  1348.         Mouse.lclick = _MOUSEBUTTON(1)
  1349.         _LIMIT W.fps
  1350.         IF MenuChoice > 0 THEN EXIT DO
  1351.     LOOP
  1352.     TIMER(GlobalEvent) OFF
  1353.  
  1354. SUB GameMenu2 ()
  1355.  
  1356.     _PUTIMAGE , Menubg&
  1357.     LINE (200, 130)-(_WIDTH - 200, 450), _RGBA(0, 0, 0, 150), BF
  1358.  
  1359.     DIM i AS INTEGER
  1360.  
  1361.     FOR i = 0 TO 4
  1362.         COLOR _RGB(255, 255, 255), _RGBA(0, 0, 0, 0)
  1363.         IF Mouse.x > 200 AND Mouse.x < 600 AND Mouse.y > GameMenus(i).y - 20 AND Mouse.y < GameMenus(i).y + _FONTHEIGHT(Fonts.bigger) THEN
  1364.             LINE (200, GameMenus(i).y - 20)-(600, GameMenus(i).y + _FONTHEIGHT(Fonts.bigger)), _RGBA(255, 100, 0, 100), BF
  1365.             SPRITEPUT 150, GameMenus(i).y + 20, MenuBlood%
  1366.             SPRITENEXT MenuBlood%
  1367.             '       _PRINTSTRING (GameMenus(i).x, GameMenus(i).y), RTRIM$(GameMenus(i).text)
  1368.             _PUTIMAGE (200, GameMenus(i).y), GameMenus(i).img
  1369.             IF Mouse.lclick THEN
  1370.                 TIMER(GlobalEvent!) OFF
  1371.                 SELECT CASE i
  1372.                     CASE 0
  1373.                         MenuChoice = 1
  1374.                     CASE 1
  1375.                         MenuChoice = 2
  1376.                     CASE 2
  1377.                         MenuChoice = 3
  1378.                     CASE 3
  1379.                         MenuChoice = 4
  1380.                     CASE 4
  1381.                         MenuChoice = 5
  1382.  
  1383.                 END SELECT
  1384.             END IF
  1385.         ELSE
  1386.             '      _PRINTSTRING (GameMenus(i).x, GameMenus(i).y), RTRIM$(GameMenus(i).text)
  1387.             _PUTIMAGE (200, GameMenus(i).y), GameMenus(i).img
  1388.         END IF
  1389.     NEXT
  1390.     IF Mouse.hovering THEN
  1391.         _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor2
  1392.         _DISPLAY
  1393.     ELSE
  1394.         _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor
  1395.         _DISPLAY
  1396.     END IF
  1397.  
  1398.  
  1399.  
  1400. FUNCTION CenterPrintX (m$)
  1401.     DIM i AS INTEGER, a AS INTEGER
  1402.     FOR i = 1 TO LEN(m$)
  1403.         a = a + _PRINTWIDTH(MID$(m$, i, 1))
  1404.     NEXT
  1405.     CenterPrintX = (_WIDTH / 2) - (a / 2)
  1406.  
  1407. FUNCTION getCurrentLevel% ()
  1408.     IF NOT _FILEEXISTS("Save_Game/save.dat") THEN getCurrentLevel% = 1: EXIT FUNCTION
  1409.     DIM F AS INTEGER
  1410.     F = FREEFILE
  1411.     OPEN "Save_Game\save.dat" FOR BINARY AS #F
  1412.     SEEK F, 3
  1413.     GET #F, , getCurrentLevel%
  1414.     CLOSE #F
  1415.  
  1416. SUB LoadLevel ()
  1417.     Level.completed = 0
  1418.     Level.over = 0
  1419.     DIM F AS INTEGER
  1420.     F = FREEFILE
  1421.     ' IF COMMAND$(1) = "-loadlevel" THEN
  1422.     ' GOTO skip_game_save_info
  1423.     ' END IF
  1424.     IF NOT _FILEEXISTS("Save_Game\save.dat") THEN
  1425.         OPEN "Save_Game\save.dat" FOR BINARY AS #F
  1426.         LevelStage% = 1
  1427.         HighScore% = 0
  1428.         PUT #F, , HighScore%
  1429.         PUT #F, , LevelStage%
  1430.         CLOSE #F
  1431.     ELSE
  1432.         OPEN "Save_Game\save.dat" FOR BINARY AS #F
  1433.         GET #F, , HighScore%
  1434.         GET #F, , LevelStage%
  1435.         CLOSE #F
  1436.     END IF
  1437.     skip_game_save_info:::
  1438.     ' echo "loading level/stage : " + STR$(LevelStage%)
  1439.     OPEN "Stages\Stage" + RTRIM$(LTRIM$(STR$(LevelStage%))) + ".dat" FOR INPUT AS #F
  1440.     INPUT #F, Level.enemies
  1441.     INPUT #F, Level.scenes
  1442.     INPUT #F, Level.time
  1443.     INPUT #F, Level.mode
  1444.     INPUT #F, Level.background
  1445.     CLOSE #F
  1446.     LevelStage2% = LevelStage%
  1447.     Level.bg = _LOADIMAGE("Images\" + RTRIM$(Level.background))
  1448.     Seconds% = Level.time
  1449.     OldSeconds% = Seconds%
  1450.     'LevelStage% = clevel%
  1451.  
  1452. SUB StartLevel ()
  1453.  
  1454.     'Stop music during gameplay
  1455.     DIM i AS INTEGER, k&, onn&, offf&, bd&, bd2&, ac&, gfx&
  1456.     IF W.music THEN
  1457.         FOR i = 0 TO 2
  1458.             _SNDSTOP Musics&(i)
  1459.         NEXT 'stops all musics
  1460.     END IF
  1461.     IF W.sfx THEN updateSfxVolume
  1462.  
  1463.     ON TIMER(GameRenderingEvent, 1 / W.fps) UpdateStatus
  1464.     ON TIMER(TimerEvent, 1) UpdateTime
  1465.     TIMER(GameRenderingEvent) ON
  1466.     TIMER(TimerEvent) ON
  1467.     Mouse.lclick = 0
  1468.     Mouse.rclick = 0
  1469.     Mouse.mclick = 0
  1470.     DO
  1471.         WHILE _MOUSEINPUT: WEND
  1472.  
  1473.         Mouse.x = _MOUSEX: Mouse.y = _MOUSEY
  1474.         IF _MOUSEBUTTON(1) THEN
  1475.             WHILE _MOUSEBUTTON(1): WHILE _MOUSEINPUT: WEND: WEND
  1476.             Mouse.lclick = -1
  1477.         END IF
  1478.         IF _MOUSEBUTTON(2) THEN
  1479.             WHILE _MOUSEBUTTON(2): WHILE _MOUSEINPUT: WEND: WEND
  1480.             Mouse.rclick = -1
  1481.         END IF
  1482.         IF _MOUSEBUTTON(3) THEN
  1483.             WHILE _MOUSEBUTTON(3): WHILE _MOUSEINPUT: WEND: WEND
  1484.             Mouse.mclick = -1
  1485.         ELSE Mouse.mclick = 0
  1486.         END IF
  1487.  
  1488.         k& = _KEYHIT
  1489.         IF k& = 27 OR Mouse.mclick THEN
  1490.             TIMER(GameRenderingEvent) OFF
  1491.             TIMER(TimerEvent) OFF
  1492.             IF W.sfx THEN PauseSound 'Pause the sounds
  1493.  
  1494.             onn& = _LOADIMAGE("Images/on.png", 33)
  1495.             offf& = _LOADIMAGE("Images/off.png", 33)
  1496.  
  1497.             bd& = _COPYIMAGE(0)
  1498.             bd2& = _COPYIMAGE(0)
  1499.  
  1500.             BLURIMAGE bd2&, 5
  1501.             gfx& = _NEWIMAGE(500, 156, 32)
  1502.             _DEST gfx&
  1503.             CLS , 0 'make it transparent
  1504.             LINE (0, 0)-STEP(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 150), BF
  1505.             FOR i = 16 TO 19
  1506.                 _PUTIMAGE (0, GameMenus(i).y - 222), GameMenus(i).img2
  1507.             NEXT
  1508.             _DEST 0
  1509.  
  1510.             FOR i = 0 TO 255 STEP 10
  1511.                 _SETALPHA i, , bd2&
  1512.                 _PUTIMAGE , bd&
  1513.                 _PUTIMAGE , bd2&
  1514.                 LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 3), BF
  1515.                 _PUTIMAGE (150, 222), gfx&, 0, (0, 0)-(500, p5map(i, 0, 255, 0, 136))
  1516.                 _DISPLAY
  1517.             NEXT
  1518.             ac& = _COPYIMAGE(0)
  1519.             DO
  1520.                 WHILE _MOUSEINPUT: WEND
  1521.                 Mouse.x = _MOUSEX: Mouse.y = _MOUSEY
  1522.                 Mouse.lclick = 0
  1523.                 Mouse.rclick = 0
  1524.                 IF _MOUSEBUTTON(1) THEN
  1525.                     WHILE _MOUSEBUTTON(1): WHILE _MOUSEINPUT: WEND: WEND
  1526.                     Mouse.lclick = -1
  1527.                 END IF
  1528.                 IF _MOUSEBUTTON(2) THEN
  1529.                     WHILE _MOUSEBUTTON(2): WHILE _MOUSEINPUT: WEND: WEND
  1530.                     Mouse.rclick = -1
  1531.                 END IF
  1532.  
  1533.                 _PUTIMAGE , ac&
  1534.                 LINE (150, 222)-STEP(500, 136), _RGBA(0, 0, 0, 50), BF
  1535.                 FOR i = 16 TO 19
  1536.                     IF Mouse.x > 150 AND Mouse.x < 650 AND Mouse.y > GameMenus(i).y - 10 AND Mouse.y < GameMenus(i).y + 24 THEN
  1537.                         IF Mouse.lclick THEN
  1538.                             SELECT CASE i
  1539.                                 CASE 16
  1540.                                     IF W.fullscreen > 0 THEN W.fullscreen = 0 ELSE W.fullscreen = 1
  1541.                                 CASE 17
  1542.                                     W.musicV = W.musicV + .1
  1543.                                     IF W.musicV > 1 THEN W.musicV = .1
  1544.                                 CASE 18
  1545.                                     W.sfxV = W.sfxV + .1
  1546.                                     IF W.sfxV > 1 THEN W.sfxV = .1
  1547.                                 CASE 19
  1548.                                     Level.cancel = -1
  1549.                                     EXIT DO
  1550.                             END SELECT
  1551.                         END IF
  1552.                         LINE (150, GameMenus(i).y - 10)-(650, GameMenus(i).y + 24), _RGBA(255, 100, 0, 100), BF
  1553.                     END IF
  1554.                     _PUTIMAGE (150, GameMenus(i).y), GameMenus(i).img
  1555.                     SELECT CASE i
  1556.                         CASE 16
  1557.                             IF W.fullscreen > 0 THEN _PUTIMAGE (580, GameMenus(i).y - 3), onn& ELSE _PUTIMAGE (580, GameMenus(i).y - 3), offf&
  1558.                         CASE 17
  1559.                             _FONT Fonts.normal
  1560.                             IF W.musicV > .9 THEN
  1561.                                 _PRINTSTRING (630 - txtWidth(" 10"), GameMenus(i).y), " 10 "
  1562.                             ELSE
  1563.                                 _PRINTSTRING (630 - txtWidth(STR$(INT(W.musicV * 10))), GameMenus(i).y), STR$(INT(W.musicV * 10))
  1564.                             END IF
  1565.                         CASE 18
  1566.                             _FONT Fonts.normal
  1567.                             IF W.sfxV > .9 THEN
  1568.                                 _PRINTSTRING (630 - txtWidth(" 10"), GameMenus(i).y), " 10 "
  1569.                             ELSE
  1570.                                 _PRINTSTRING (630 - txtWidth(STR$(INT(W.sfxV * 10))), GameMenus(i).y), STR$(INT(W.sfxV * 10))
  1571.                             END IF
  1572.                     END SELECT
  1573.                 NEXT
  1574.                 IF _KEYHIT = 27 OR _MOUSEBUTTON(3) THEN EXIT DO
  1575.                 _LIMIT W.fps
  1576.                 _PUTIMAGE (Mouse.x - 8, Mouse.y - 8), Mouse.cursor
  1577.                 _DISPLAY
  1578.             LOOP
  1579.             FOR i = 255 TO 0 STEP -10
  1580.                 _SETALPHA i, , bd2&
  1581.                 _PUTIMAGE , bd&
  1582.                 _PUTIMAGE , bd2&
  1583.                 LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, i / 3), BF
  1584.                 _PUTIMAGE (150, 222), gfx&, 0, (0, 0)-(500, p5map(i, 0, 255, 0, 222))
  1585.                 _DISPLAY
  1586.             NEXT
  1587.  
  1588.             _PUTIMAGE , bd& 'Erase that menu line
  1589.             _FREEIMAGE bd&
  1590.             _FREEIMAGE bd2&
  1591.             _FREEIMAGE ac&
  1592.             _FREEIMAGE gfx&
  1593.             _FREEIMAGE onn&
  1594.             _FREEIMAGE offf&
  1595.             loadComponents
  1596.  
  1597.             IF W.sfx THEN 'update the sfx volume and play the paused sound.
  1598.                 updateSfxVolume
  1599.                 IF NOT Level.cancel THEN PlayPausedSound
  1600.             END IF
  1601.  
  1602.             TIMER(GameRenderingEvent) ON
  1603.             TIMER(TimerEvent) ON
  1604.  
  1605.             IF Level.cancel THEN EXIT DO
  1606.         END IF
  1607.         _LIMIT W.fps
  1608.     LOOP UNTIL Level.completed OR Level.over
  1609.     TIMER(GameRenderingEvent) OFF
  1610.     CloseTime
  1611.     FOR i = 0 TO 20
  1612.         IF Bloods(i).active THEN
  1613.             Bloods(i).active = 0
  1614.             SPRITEHIDE Bloods(i).img
  1615.         END IF
  1616.         IF explosions(i).active THEN
  1617.             explosions(i).active = 0
  1618.             SPRITEHIDE explosions(i).img
  1619.         END IF
  1620.     NEXT
  1621.     FOR i = 0 TO UBOUND(ShotScore)
  1622.         ShotScore(i).active = 0
  1623.     NEXT
  1624.  
  1625. SUB UpdateStatus ()
  1626.     ' $checking:off
  1627.     STATIC thunder_f_count, thunder_ha_count, thunder_ha_count_limit
  1628.     DIM i AS INTEGER, t AS INTEGER, tmp&, tmp2&
  1629.  
  1630.     IF Seconds% < OldSeconds% OR OldScore% < CurrentScore% THEN _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), Level.bg
  1631.  
  1632.     FOR i = 1 TO Level.enemies
  1633.         IF Enemie(i).u = Level.u AND Enemie(i).active = 0 AND Enemie(i).scene = Level.currentScene THEN
  1634.             Enemie(i).active = -1
  1635.             PlayEnemieMusic i
  1636.             'echo "[New Enemie] (Scene " + STR$(Level.currentScene) + ")"
  1637.             'echo "Type : " + Enemie(i).typ
  1638.             'echo "u : " + STR$(Enemie(i).u)
  1639.             'echo "Current u : " + STR$(Enemie(i).u)
  1640.             'echo " Enemie Scene : " + STR$(Enemie(i).scene)
  1641.             'echo "Enemie Movement : " + STR$(Enemie(i).m)
  1642.         END IF
  1643.     NEXT
  1644.     FOR i = 1 TO Level.enemies
  1645.         IF Enemie(i).active AND Enemie(i).scene = Level.currentScene THEN
  1646.             'IF Enemie(i).u = Level.u THEN
  1647.             '    echo "Rendered"
  1648.             '    echo "********************************************************************************"
  1649.             'END IF
  1650.             IF Enemie(i).f > Enemie(i).n THEN SPRITENEXT Enemie(i).img: Enemie(i).f = 0
  1651.  
  1652.             SPRITEPUT Enemie(i).x, Enemie(i).y, Enemie(i).img
  1653.  
  1654.             Enemie(i).x = Enemie(i).x + Enemie(i).m
  1655.             Enemie(i).f = Enemie(i).f + 1
  1656.  
  1657.             IF W.SE THEN _SNDBAL Enemie(i).snd, p5map(Enemie(i).x, 0, _WIDTH, -1, 1), p5map(Enemie(i).y, 0, _HEIGHT, 1, -1), , 2
  1658.  
  1659.             IF Enemie(i).x > _WIDTH + SPRITECURRENTWIDTH(Enemie(i).img) THEN Enemie(i).m = -Enemie(i).m: SPRITEFLIP Enemie(i).img, HORIZONTAL: PlayEnemieMusic i
  1660.             IF Enemie(i).x < -SPRITECURRENTWIDTH(Enemie(i).img) THEN Enemie(i).m = -Enemie(i).m: SPRITEFLIP Enemie(i).img, NONE: PlayEnemieMusic i
  1661.  
  1662.             IF Mouse.x > SPRITEX1(Enemie(i).img) AND Mouse.x < SPRITEX2(Enemie(i).img) AND Mouse.y > SPRITEY1(Enemie(i).img) AND Mouse.y < SPRITEY2(Enemie(i).img) THEN
  1663.                 Mouse.hovering = -1
  1664.  
  1665.                 IF Mouse.lclick THEN Enemie(i).life = Enemie(i).life - Gun.damage
  1666.                 IF Enemie(i).life < 0 THEN Enemie(i).life = 0
  1667.  
  1668.                 'Showing Enemie current life with life bar
  1669.                 IF Enemie(i).life = 0 THEN
  1670.                     _PUTIMAGE (Enemie(i).x - SPRITECURRENTWIDTH(Enemie(i).img) / 2, Enemie(i).y - 30), lifeBars(0)
  1671.                 ELSE
  1672.                     _PUTIMAGE (Enemie(i).x - SPRITECURRENTWIDTH(Enemie(i).img) / 2, Enemie(i).y - 30), lifeBars(INT(Enemie(i).life / Enemie(i).life2 * 100) - 1) 'shows life bar :)
  1673.                 END IF
  1674.             END IF
  1675.             'checking if any enemie is dead :D
  1676.             IF Enemie(i).life = 0 THEN
  1677.                 SPRITEHIDE Enemie(i).img
  1678.                 Enemie(i).ending = -1
  1679.                 Enemie(i).active = 0
  1680.                 StopEnemieMusic i
  1681.                 'echo "[Enemie Dead]"
  1682.                 'echo "Type : " + Enemie(i).typ
  1683.                 'echo "Enemie Scene" + STR$(Enemie(i).scene)
  1684.                 'echo "--------------------------------------------------------------------------------------"
  1685.                 'You will get more score with ShotGun :P
  1686.  
  1687.                 IF Gun.id = 1 THEN CurrentScore% = CurrentScore% + INT(Enemie(i).points * 1.4)
  1688.  
  1689.                 MakeScoreFlash Enemie(i).x, Enemie(i).y, Enemie(i).points
  1690.                 CurrentScore% = CurrentScore% + Enemie(i).points
  1691.                 MakeBloods Enemie(i).x, Enemie(i).y, Enemie(i).typ
  1692.             END IF
  1693.         END IF
  1694.     NEXT
  1695.  
  1696.     IF Mouse.rclick THEN
  1697.         IF Gun.id = 1 THEN Gun.id = 2: Gun.name = "Ak-47": Gun.damage = 6 ELSE Gun.id = 1: Gun.name = "Shot Gun": Gun.damage = 3
  1698.         Mouse.rclick = 0
  1699.     END IF
  1700.     FOR i = 0 TO 20
  1701.         IF Bloods(i).active THEN
  1702.             IF Bloods(i).f > Bloods(i).n THEN SPRITENEXT Bloods(i).img: Bloods(i).f = 0: Bloods(i).currentFrame = Bloods(i).currentFrame + 1
  1703.             Bloods(i).f = Bloods(i).f + 1
  1704.             SPRITEPUT Bloods(i).x, Bloods(i).y, Bloods(i).img
  1705.             IF Bloods(i).currentFrame > Bloods(i).totalFrames * 2 THEN Bloods(i).active = 0: SPRITEHIDE Bloods(i).img
  1706.         END IF
  1707.     NEXT
  1708.     FOR i = 0 TO 20
  1709.         IF explosions(i).active THEN
  1710.             IF explosions(i).f > explosions(i).n THEN SPRITENEXT explosions(i).img: explosions(i).f = 0: explosions(i).currentFrame = explosions(i).currentFrame + 1
  1711.             explosions(i).f = explosions(i).f + 1
  1712.             SPRITEPUT explosions(i).x, explosions(i).y, explosions(i).img
  1713.             IF explosions(i).currentFrame > explosions(i).totalFrames THEN explosions(i).active = 0: SPRITEHIDE explosions(i).img
  1714.         END IF
  1715.     NEXT
  1716.  
  1717.     IF Seconds% < OldSeconds% OR OldScore% < CurrentScore% THEN
  1718.         IF Seconds% < 1 THEN Level.over = -1
  1719.         OldSeconds% = Seconds%
  1720.         OldScore% = CurrentScore%
  1721.         IF Seconds% < 11 THEN COLOR _RGB(255, 0, 0) ELSE COLOR _RGB(255, 255, 255)
  1722.         'redraw scoreboard
  1723.         _PUTIMAGE (0, 520), ScoreBoard&
  1724.         _PUTIMAGE (50, 550)-(170, 590), GunImg&(Gun.id - 1)
  1725.         _FONT Fonts.smaller
  1726.         _PRINTSTRING (40, 580), RTRIM$(Gun.name)
  1727.         _PRINTSTRING (600, 560), "Score - " + STR$(CurrentScore%)
  1728.         IF Seconds% >= 60 THEN t = Seconds% MOD 60 ELSE t = Seconds%
  1729.         _PRINTSTRING (600, 580), "Time left - " + STR$(Minutes%) + ":" + STR$(t)
  1730.         _FONT Fonts.normal
  1731.         IF randomLevels THEN _PRINTSTRING (CenterPrintX("Random Levels"), 560), "Random Levels" ELSE _PRINTSTRING (CenterPrintX("Stage " + STR$(LevelStage%)), 560), "Stage " + STR$(LevelStage%)
  1732.  
  1733.     END IF
  1734.  
  1735.     Level.u = Level.u + 1
  1736.     'creating new game scene
  1737.     IF SceneEnd(Level.currentScene) THEN
  1738.         Level.currentScene = Level.currentScene + 1
  1739.         Level.u = 0
  1740.         'echo "Current Scene : " + STR$(Level.currentScene)
  1741.         IF Level.currentScene > Level.scenes THEN Level.completed = -1
  1742.     END IF
  1743.  
  1744.     'game MODS
  1745.     SELECT CASE Level.mode
  1746.         CASE FOGMODE
  1747.             Fogs.x = Fogs.x - Fogs.move
  1748.             IF Fogs.x < -1600 OR Fogs.x > 0 THEN Fogs.move = -Fogs.move
  1749.             _PUTIMAGE (Fogs.x, 0), Fogs.handle
  1750.  
  1751.         CASE THUNDERMODE
  1752.             FallDrops
  1753.             DrawDrops
  1754.  
  1755.         CASE STORMMODE
  1756.             _PUTIMAGE (StormX%, 0), StormImg&
  1757.             StormX% = StormX% - 1
  1758.             IF StormX% < -2300 THEN StormX% = 0
  1759.  
  1760.         CASE FOGMODE + THUNDERMODE
  1761.             Fogs.x = Fogs.x - Fogs.move
  1762.             IF Fogs.x < -1600 OR Fogs.x > 0 THEN Fogs.move = -Fogs.move
  1763.             _PUTIMAGE (Fogs.x, 0), Fogs.handle
  1764.  
  1765.             FallDrops
  1766.             DrawDrops
  1767.  
  1768.         CASE FOGMODE + THUNDERMODE + 7
  1769.             Fogs.x = Fogs.x - Fogs.move
  1770.             IF Fogs.x < -1600 OR Fogs.x > 0 THEN Fogs.move = -Fogs.move
  1771.             _PUTIMAGE (Fogs.x, 0), Fogs.handle
  1772.  
  1773.             FallDrops
  1774.             DrawDrops
  1775.         CASE STORMMODE + THUNDERMODE
  1776.             _PUTIMAGE (StormX%, 0), StormImg&
  1777.             StormX% = StormX% - 1
  1778.             IF StormX% < -2300 THEN StormX% = 0
  1779.  
  1780.             FallDrops
  1781.             DrawDrops
  1782.  
  1783.         CASE STORMMODE + FOGMODE + THUNDERMODE
  1784.             Fogs.x = Fogs.x - Fogs.move
  1785.             IF Fogs.x < -1600 OR Fogs.x > 0 THEN Fogs.move = -Fogs.move
  1786.             _PUTIMAGE (Fogs.x, 0), Fogs.handle
  1787.  
  1788.             _PUTIMAGE (StormX%, 0), StormImg&
  1789.             StormX% = StormX% - 1
  1790.             IF StormX% < -2300 THEN StormX% = 0
  1791.  
  1792.             FallDrops
  1793.             DrawDrops
  1794.  
  1795.     END SELECT
  1796.  
  1797.     'scores effect
  1798.     FOR i = 0 TO UBOUND(ShotScore)
  1799.         IF ShotScore(i).active = -1 THEN
  1800.             ShotScore(i).sclX = SIN(ShotScore(i).__ops) * .5 + .5
  1801.             _PUTIMAGE (ShotScore(i).x - (ShotScore(i).sclX * _WIDTH(ShotScore(i).img) / 2), ShotScore(i).y - (ShotScore(i).sclX * _HEIGHT(ShotScore(i).img)) / 2)-(ShotScore(i).x + (ShotScore(i).sclX * _WIDTH(ShotScore(i).img)) / 2, ShotScore(i).y + (ShotScore(i).sclX * _HEIGHT(ShotScore(i).img)) / 2), ShotScore(i).img
  1802.             ShotScore(i).__ops = ShotScore(i).__ops + .1
  1803.             IF ShotScore(i).__ops > _PI(1.5) THEN
  1804.                 ShotScore(i).active = 0
  1805.             END IF
  1806.         END IF
  1807.     NEXT
  1808.  
  1809.     'countdown when game time is less or equal to 10s
  1810.     IF Seconds% < 11 THEN
  1811.         COLOR _RGB(255, 0, 0)
  1812.         _FONT Fonts.biggest
  1813.         _PRINTSTRING (CenterPrintX(RTRIM$(LTRIM$(STR$(Seconds%)))), _HEIGHT / 2 - _FONTHEIGHT / 2), RTRIM$(LTRIM$(STR$(Seconds%)))
  1814.     END IF
  1815.  
  1816.     'cursors
  1817.     IF Mouse.lclick THEN
  1818.         Mouse.lclick = 0
  1819.         IF W.sfx THEN
  1820.             IF Gun.id = 1 THEN _SNDPLAYCOPY Gun1& ELSE _SNDPLAYCOPY Gun2&
  1821.         END IF
  1822.     END IF
  1823.     IF Mouse.hovering THEN
  1824.         Mouse.hovering = 0
  1825.         _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor2
  1826.     ELSE
  1827.         _PUTIMAGE (Mouse.x - 16, Mouse.y - 16), Mouse.cursor
  1828.     END IF
  1829.  
  1830.     IF Level.mode = THUNDERMODE OR Level.mode = THUNDERMODE + FOGMODE + 7 THEN
  1831.         IF thunder_ha_count_limit = 0 THEN thunder_ha_count_limit = p5random(1, 4)
  1832.         IF ThunderEvent = 0 THEN ThunderEvent = p5random(30, 340)
  1833.         ThunderCount = ThunderCount + 1
  1834.         IF ThunderCount > ThunderEvent THEN
  1835.             thunder_f_count = thunder_f_count + 1
  1836.             tmp& = _COPYIMAGE(0)
  1837.             tmp2& = _COPYIMAGE(0)
  1838.             MakeThunderImage tmp&
  1839.             _PUTIMAGE , tmp&
  1840.             _DISPLAY
  1841.             _PUTIMAGE , tmp2&
  1842.             _FREEIMAGE tmp&
  1843.             _FREEIMAGE tmp2&
  1844.             IF thunder_f_count > 3 THEN
  1845.                 IF thunder_ha_count < thunder_ha_count_limit THEN
  1846.                     ' ThunderCount = 0
  1847.                     thunder_f_count = 0
  1848.                     ThunderEvent = ThunderEvent + p5random(4, 25) + 3
  1849.                     thunder_ha_count = thunder_ha_count + 1
  1850.                 ELSE
  1851.                     thunder_ha_count = 0
  1852.                     thunder_f_count = 0
  1853.                     ThunderEvent = 0
  1854.                     ThunderCount = 0
  1855.                     thunder_ha_count_limit = p5random(1, 4)
  1856.                 END IF
  1857.             END IF
  1858.         ELSE
  1859.             _DISPLAY
  1860.         END IF
  1861.     ELSE
  1862.         _DISPLAY
  1863.     END IF
  1864.     ' $checking:on
  1865.  
  1866. SUB MakeBloods (x, y, typ AS STRING * 16)
  1867.     SELECT CASE RTRIM$(typ)
  1868.         CASE "jet1", "jet2", "jet3"
  1869.             MakeExplosions x, y
  1870.             EXIT SUB
  1871.     END SELECT
  1872.     DIM i AS INTEGER
  1873.     FOR i = 0 TO 20
  1874.         IF Bloods(i).active = 0 THEN
  1875.             Bloods(i).active = -1
  1876.             Bloods(i).x = x
  1877.             Bloods(i).y = y
  1878.             Bloods(i).currentFrame = 1
  1879.             SPRITESHOW Bloods(i).img
  1880.             EXIT SUB
  1881.         END IF
  1882.     NEXT
  1883.  
  1884. SUB MakeExplosions (x, y)
  1885.     DIM i AS INTEGER
  1886.     FOR i = 0 TO 20
  1887.         IF explosions(i).active = 0 THEN
  1888.             explosions(i).active = -1
  1889.             explosions(i).x = x
  1890.             explosions(i).y = y
  1891.             explosions(i).currentFrame = 1
  1892.             SPRITESHOW explosions(i).img
  1893.             IF W.sfx THEN _SNDPLAY Expos&
  1894.             EXIT SUB
  1895.         END IF
  1896.     NEXT
  1897.  
  1898. SUB MakeScoreFlash (x, y, s)
  1899.     DIM i AS INTEGER
  1900.     FOR i = 0 TO UBOUND(ShotScore)
  1901.         IF ShotScore(i).active = 0 THEN
  1902.             ShotScore(i).active = -1
  1903.             ShotScore(i).x = x
  1904.             ShotScore(i).y = y
  1905.             ShotScore(i).__ops = -_PI(.5)
  1906.             SELECT CASE s
  1907.                 CASE 10
  1908.                     ShotScore(i).img = scoresImage(0)
  1909.                 CASE 20
  1910.                     ShotScore(i).img = scoresImage(1)
  1911.                 CASE 35
  1912.                     ShotScore(i).img = scoresImage(2)
  1913.                 CASE 50
  1914.                     ShotScore(i).img = scoresImage(3)
  1915.                 CASE 75
  1916.                     ShotScore(i).img = scoresImage(4)
  1917.                 CASE 100
  1918.                     ShotScore(i).img = scoresImage(5)
  1919.             END SELECT
  1920.         END IF
  1921.     NEXT
  1922.  
  1923. SUB UpdateTime ()
  1924.     Seconds% = Seconds% - 1
  1925.     Minutes% = (Seconds% - (Seconds% MOD 60)) / 60
  1926.  
  1927. SUB CloseTime
  1928.     TIMER(TimerEvent) OFF
  1929.  
  1930. SUB PlayEnemieMusic (which&)
  1931.     IF W.sfx = 0 THEN EXIT SUB
  1932.  
  1933.     _SNDPLAY Enemie(which&).snd
  1934.  
  1935. SUB StopEnemieMusic (which&)
  1936.     _SNDSTOP Enemie(which&).snd
  1937.     Enemie(which&).sndPaused = 2 '2 for stop and 1 for paused
  1938.  
  1939. SUB updateSfxVolume ()
  1940.     IF NOT W.sfx THEN EXIT SUB
  1941.  
  1942.     DIM i AS INTEGER
  1943.     FOR i = 1 TO Level.enemies
  1944.         _SNDVOL Enemie(i).snd, W.sfxV
  1945.     NEXT
  1946.     _SNDVOL RainSound&, W.sfxV
  1947.  
  1948. SUB setMusicVol (v!)
  1949.     IF NOT W.music THEN EXIT SUB
  1950.     _SNDVOL Musics&(0), v!
  1951.     _SNDVOL Musics&(1), v!
  1952.     _SNDVOL Musics&(2), v!
  1953.  
  1954. SUB PlayPausedSound ()
  1955.     DIM i AS INTEGER
  1956.     FOR i = 1 TO Level.enemies
  1957.         IF Enemie(i).sndPaused = 1 THEN Enemie(i).sndPaused = 0: _SNDPLAY Enemie(i).snd
  1958.     NEXT
  1959.     IF Level.mode = THUNDERMODE OR Level.mode = FOGMODE + THUNDERMODE THEN
  1960.         IF NOT _SNDPLAYING(RainSound&) THEN _SNDPLAY RainSound&
  1961.     END IF
  1962.  
  1963. SUB PauseSound ()
  1964.  
  1965.     DIM i AS INTEGER
  1966.     FOR i = 1 TO Level.enemies
  1967.         IF Enemie(i).sndPaused = 0 THEN _SNDSTOP Enemie(i).snd: Enemie(i).sndPaused = 1
  1968.     NEXT
  1969.  
  1970.     IF _SNDPLAYING(RainSound&) THEN _SNDSTOP RainSound&
  1971.  
  1972.  
  1973. FUNCTION SceneEnd (which%)
  1974.     DIM i AS INTEGER, d AS _BYTE
  1975.  
  1976.     FOR i = 1 TO Level.enemies
  1977.         IF Enemie(i).ending = 0 AND Enemie(i).scene = which% THEN d = -1: EXIT FOR
  1978.     NEXT
  1979.     IF d = 0 THEN SceneEnd = -1 ELSE SceneEnd = 0
  1980.  
  1981. SUB SaveGame ()
  1982.     DIM a$, F AS INTEGER
  1983.     a$ = "Save_Game\save.dat"
  1984.     KILL a$
  1985.     F = FREEFILE
  1986.     LevelStage% = LevelStage% + 1
  1987.     OPEN a$ FOR BINARY AS #F
  1988.     IF HighScore% < CurrentScore% THEN PUT #F, , CurrentScore% ELSE PUT #F, , HighScore%
  1989.     PUT #F, , LevelStage%
  1990.     CLOSE #F
  1991.  
  1992. SUB SetupRain ()
  1993.     DIM i AS INTEGER
  1994.     FOR i = 0 TO UBOUND(Drop)
  1995.         Drop(i).x = RND * _WIDTH
  1996.         Drop(i).y = -(RND * (_HEIGHT * 3))
  1997.         Drop(i).z = INT(RND * 1)
  1998.         Drop(i).yspeed = Map(Drop(i).z, 0, 1, 1, 2)
  1999.         Drop(i).len = Map(Drop(i).z, 0, 1, 8, 16)
  2000.         Drop(i).gravity = Map(Drop(i).z, 0, 1, 0.1, 0.3)
  2001.     NEXT
  2002.     RainVol# = -1.0
  2003.  
  2004. SUB FallDrops ()
  2005.     DIM i AS INTEGER
  2006.     FOR i = 0 TO UBOUND(drop)
  2007.         Drop(i).y = Drop(i).y + Drop(i).yspeed
  2008.         Drop(i).yspeed = Drop(i).yspeed + Drop(i).gravity
  2009.         IF Drop(i).y > _HEIGHT THEN Drop(i).y = RND * -400: Drop(i).yspeed = Map(Drop(i).z, 0, 1, 1, 2)
  2010.     NEXT
  2011.  
  2012. SUB DrawDrops ()
  2013.     DIM i AS INTEGER
  2014.     IF W.sfx THEN
  2015.         ' IF RainVol# < .98 THEN RainVol# = RainVol# + 0.01: _SNDBAL RainSound&, 0, 0, RainVol#
  2016.         IF NOT _SNDPLAYING(RainSound&) THEN _SNDPLAY RainSound&
  2017.     END IF
  2018.     FOR i = 0 TO UBOUND(drop)
  2019.         IF Drop(i).z = 0 THEN _PUTIMAGE (Drop(i).x, Drop(i).y), Rainx8& ELSE _PUTIMAGE (Drop(i).x, Drop(i).y), Rainx16&
  2020.     NEXT
  2021.  
  2022.  
  2023.  
  2024. FUNCTION Map (value, r1, r2, e1, e2)
  2025.     IF value = r1 THEN Map = e1
  2026.     IF value = r2 THEN Map = e2
  2027.  
  2028. SUB MakeThunderImage (original_img&)
  2029.     IF original_img& = -1 THEN EXIT SUB
  2030.  
  2031.     DIM buffer AS _MEM, o AS _OFFSET, o2 AS _OFFSET
  2032.     n = p5random(30, 120)
  2033.  
  2034.     buffer = _MEMIMAGE(original_img&)
  2035.     o = buffer.OFFSET
  2036.     o2 = o + _WIDTH(original_img&) * _HEIGHT(original_img&) * 4
  2037.     DO
  2038.         ' echo str$(o)
  2039.         b = _MEMGET(buffer, o, _UNSIGNED _BYTE)
  2040.         IF b + n < 256 THEN b = b + n ELSE b = 255
  2041.         _MEMPUT buffer, o, b AS _UNSIGNED _BYTE
  2042.         b = _MEMGET(buffer, o + 1, _UNSIGNED _BYTE)
  2043.         IF b + n < 256 THEN b = b + n ELSE b = 255
  2044.         _MEMPUT buffer, o + 1, b AS _UNSIGNED _BYTE
  2045.         b = _MEMGET(buffer, o + 2, _UNSIGNED _BYTE)
  2046.         IF b + n < 256 THEN b = b + n ELSE b = 255
  2047.         _MEMPUT buffer, o + 2, b AS _UNSIGNED _BYTE
  2048.         o = o + 4
  2049.     LOOP UNTIL o = o2
  2050.     _MEMFREE buffer
  2051.  
  2052. SUB centerImage (img&)
  2053.     _PUTIMAGE ((_WIDTH / 2) - (_WIDTH(img&) / 2), (_HEIGHT / 2) - (_HEIGHT(img&) / 2))-STEP(_WIDTH(img&), _HEIGHT(img&)), img&
  2054.  
  2055. SUB showCredits ()
  2056.     DIM k&, f&, i AS INTEGER, f2&, yy AS INTEGER
  2057.  
  2058.     k& = _LOADIMAGE("Images/credits.png", 33)
  2059.     f& = _NEWIMAGE(_WIDTH(k&), _HEIGHT(k&), 32)
  2060.     _DEST f&
  2061.     FOR i = 0 TO 255
  2062.         LINE (0, (_HEIGHT - 255) + i)-(_WIDTH, (_HEIGHT - 255) + i), _RGBA(0, 0, 0, i)
  2063.         LINE (0, 255 - i)-(_WIDTH, 255 - i), _RGBA(0, 0, 0, i)
  2064.     NEXT
  2065.     _DEST 0
  2066.     f2& = _COPYIMAGE(f&, 33)
  2067.     SWAP f&, f2&
  2068.     _FREEIMAGE f2&
  2069.     yy = _HEIGHT + 50
  2070.     DO
  2071.  
  2072.         _PUTIMAGE (50, yy), k&
  2073.         _PUTIMAGE , f&
  2074.         yy = yy - 1
  2075.  
  2076.         _DISPLAY
  2077.         _LIMIT W.fps
  2078.     LOOP UNTIL yy < -_HEIGHT(k&)
  2079.     _FREEIMAGE f&
  2080.     _FREEIMAGE k&
  2081.  
  2082. ' SUB showCredits2 ()
  2083. ' CLS
  2084. ' _FONT Fonts.bigger
  2085. ' _PRINTSTRING (CenterPrintX("Super Hunters 2017-18"), 250), "Super Hunters 2017-18"
  2086. ' _FONT Fonts.normal
  2087. ' _PRINTSTRING (CenterPrintX("By Ashish Kushwaha"), 290), "By Ashish Kushwaha"
  2088. ' initTextParticles _RGB(255, 255, 255)
  2089. ' CLS
  2090. ' DO
  2091. ' CLS
  2092. ' moveTextParticles
  2093. ' _LIMIT W.fps
  2094. ' _DISPLAY
  2095. ' LOOP UNTIL Text_Particles_Status = 1
  2096. ' _DELAY 1
  2097. ' fallTextParticles "fall"
  2098. ' CLS
  2099. ' _FONT Fonts.bigger
  2100. ' _PRINTSTRING (CenterPrintX("Programmer"), 250), "Programmer"
  2101. ' _FONT Fonts.normal
  2102. ' _PRINTSTRING (CenterPrintX("Ashish Kushwaha"), 290), "Ashish Kushwaha"
  2103. ' initTextParticles _RGB(255, 255, 255)
  2104. ' ' _DISPLAY: SLEEP
  2105. ' CLS
  2106. ' DO
  2107. ' CLS
  2108. ' moveTextParticles
  2109. ' _LIMIT W.fps
  2110. ' _DISPLAY
  2111. ' LOOP UNTIL Text_Particles_Status = 1
  2112. ' _DELAY 1
  2113. ' fallTextParticles "lessgravity"
  2114. ' CLS
  2115. ' _FONT Fonts.bigger
  2116. ' _PRINTSTRING (CenterPrintX("Graphic Designer"), 250), "Graphic Designer"
  2117. ' _FONT Fonts.normal
  2118. ' _PRINTSTRING (CenterPrintX("Google Images & Ashish Kushwaha"), 290), "Google Images & Ashish Kushwaha"
  2119. ' initTextParticles _RGB(255, 255, 255)
  2120. ' CLS
  2121. ' DO
  2122. ' CLS
  2123. ' moveTextParticles
  2124. ' _LIMIT W.fps
  2125. ' _DISPLAY
  2126. ' LOOP UNTIL Text_Particles_Status = 1
  2127. ' _DELAY 1
  2128. ' fallTextParticles "explode"
  2129. ' CLS
  2130. ' _FONT Fonts.bigger
  2131. ' _PRINTSTRING (CenterPrintX("Level Designer"), 250), "Level Designer"
  2132. ' _FONT Fonts.normal
  2133. ' _PRINTSTRING (CenterPrintX("Ashish Kushwaha"), 290), "Ashish Kushwaha"
  2134. ' initTextParticles _RGB(255, 255, 255)
  2135. ' CLS
  2136. ' DO
  2137. ' CLS
  2138. ' moveTextParticles
  2139. ' _LIMIT W.fps
  2140. ' _DISPLAY
  2141. ' LOOP UNTIL Text_Particles_Status = 1
  2142. ' _DELAY 1
  2143. ' fallTextParticles "horizontal"
  2144. ' CLS
  2145. ' _FONT Fonts.bigger
  2146. ' _PRINTSTRING (CenterPrintX("Special Thanks -"), 230), "Special Thanks -"
  2147. ' _FONT Fonts.normal
  2148. ' _PRINTSTRING (CenterPrintX("Terry Ritchie for sprite library"), 270), "Terry Ritchie for sprite library"
  2149. ' _PRINTSTRING (CenterPrintX("Unseenmachine & [banned user] for BlurImage"), 320), "Unseenmachine & [banned user] for BlurImage"
  2150. ' _PRINTSTRING (CenterPrintX("and player of this game!"), 345), "and player of this game!"
  2151. ' initTextParticles _RGB(255, 255, 255)
  2152. ' CLS
  2153. ' DO
  2154. ' CLS
  2155. ' moveTextParticles
  2156. ' _LIMIT W.fps
  2157. ' _DISPLAY
  2158. ' LOOP UNTIL Text_Particles_Status = 1
  2159. ' _DELAY 1
  2160. ' fallTextParticles "boom"
  2161.  
  2162. ' END SUB
  2163.  
  2164. ' SUB initTextParticles (which~&)
  2165. ' SHARED Text_Particles() AS Vector_Particles_Text_Type
  2166. ' FOR y = 0 TO _HEIGHT - 1
  2167. ' FOR x = 0 TO _WIDTH - 1
  2168. ' col~& = POINT(x, y)
  2169. ' IF col~& = which~& THEN n = n + 1
  2170. ' NEXT x, y
  2171.  
  2172. ' REDIM Text_Particles(n) AS Vector_Particles_Text_Type
  2173. ' n = 0
  2174. ' Text_Particles_Color = which~&
  2175. ' FOR x = 0 TO _WIDTH - 1
  2176. ' FOR y = 0 TO _HEIGHT - 1
  2177. ' col~& = POINT(x, y)
  2178. ' IF col~& = which~& THEN
  2179. ' Text_Particles(n).x = x
  2180. ' Text_Particles(n).y = y
  2181. ' Text_Particles(n).vx = p5random(0, _WIDTH)
  2182. ' Text_Particles(n).vy = p5random(0, _HEIGHT)
  2183. ' Text_Particles(n).dist = dist(Text_Particles(n).vx, Text_Particles(n).vy, Text_Particles(n).x, Text_Particles(n).y)
  2184. ' Text_Particles(n).distX = ABS(Text_Particles(n).x - Text_Particles(n).vx)
  2185. ' Text_Particles(n).distY = ABS(Text_Particles(n).y - Text_Particles(n).vy)
  2186. ' n = n + 1
  2187. ' END IF
  2188. ' NEXT y, x
  2189. ' END SUB
  2190.  
  2191. ' SUB moveTextParticles ()
  2192. ' SHARED Text_Particles() AS Vector_Particles_Text_Type
  2193. ' FOR i = 0 TO UBOUND(Text_Particles)
  2194. ' IF Text_Particles(i).k < Text_Particles(i).dist THEN
  2195. ' PSET (Text_Particles(i).vx + Text_Particles(i).delX, Text_Particles(i).vy + Text_Particles(i).delY), Text_Particles_Color
  2196. ' IF Text_Particles(i).vx > Text_Particles(i).x THEN Text_Particles(i).delX = Text_Particles(i).delX - Text_Particles(i).distX / Text_Particles(i).dist ELSE Text_Particles(i).delX = Text_Particles(i).delX + Text_Particles(i).distX / Text_Particles(i).dist
  2197. ' IF Text_Particles(i).vy > Text_Particles(i).y THEN Text_Particles(i).delY = Text_Particles(i).delY - Text_Particles(i).distY / Text_Particles(i).dist ELSE Text_Particles(i).delY = Text_Particles(i).delY + Text_Particles(i).distY / Text_Particles(i).dist
  2198. ' Text_Particles(i).k = Text_Particles(i).k + 1
  2199. ' ELSE
  2200. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2201. ' check = check + 1
  2202. ' END IF
  2203. ' NEXT
  2204. ' IF check >= UBOUND(text_particles) THEN Text_Particles_Status = 1: EXIT SUB ELSE Text_Particles_Status = 0
  2205.  
  2206. ' END SUB
  2207.  
  2208. ' SUB fallTextParticles (typ$)
  2209. ' SHARED Text_Particles() AS Vector_Particles_Text_Type
  2210. ' typ$ = LCASE$(typ$)
  2211. ' SELECT CASE typ$
  2212. ' CASE "explode"
  2213. ' FOR i = 0 TO UBOUND(Text_Particles)
  2214. ' Text_Particles(i).vx = 0
  2215. ' Text_Particles(i).vy = 0
  2216. ' Text_Particles(i).delX = p5random(-0.1, 0.1)
  2217. ' Text_Particles(i).delY = p5random(-0.1, 0.1)
  2218. ' NEXT
  2219. ' DO
  2220. ' CLS
  2221. ' z = 0
  2222. ' FOR i = 0 TO UBOUND(Text_Particles)
  2223.  
  2224. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2225. ' IF i < array_len THEN
  2226. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2227. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2228. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2229. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2230. ' END IF
  2231. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN z = z + 1
  2232. ' NEXT
  2233. ' IF array_len < UBOUND(Text_Particles) THEN array_len = array_len + steps
  2234. ' _DISPLAY
  2235. ' _LIMIT W.fps
  2236. ' steps = steps + 1
  2237. ' IF z > UBOUND(Text_Particles) THEN EXIT DO
  2238. ' LOOP UNTIL INKEY$ <> ""
  2239. ' EXIT SUB
  2240. ' CASE "fall"
  2241. ' FOR i = 0 TO UBOUND(text_particles)
  2242. ' Text_Particles(i).vx = 0
  2243. ' Text_Particles(i).vy = 0
  2244. ' Text_Particles(i).delX = p5random(-.02, .02)
  2245. ' Text_Particles(i).delY = p5random(0.1, 0.2)
  2246. ' NEXT
  2247. ' DO
  2248. ' CLS
  2249. ' z = 0
  2250. ' FOR i = 0 TO UBOUND(text_particles)
  2251. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2252. ' IF i < array_len THEN
  2253. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2254. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2255. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2256. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2257. ' END IF
  2258. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN z = z + 1
  2259. ' NEXT
  2260. ' IF array_len < UBOUND(text_particles) THEN array_len = array_len + steps
  2261. ' _DISPLAY
  2262. ' _LIMIT W.fps
  2263. ' steps = steps + 1
  2264. ' IF z = UBOUND(text_particles) THEN EXIT DO
  2265. ' LOOP
  2266. ' EXIT SUB
  2267.  
  2268. ' CASE "lessgravity"
  2269. ' FOR i = 0 TO UBOUND(Text_Particles)
  2270. ' Text_Particles(i).vx = 0
  2271. ' Text_Particles(i).vy = 0
  2272. ' Text_Particles(i).delX = p5random(-.02, .02)
  2273. ' Text_Particles(i).delY = p5random(-0.1, -0.2)
  2274. ' NEXT
  2275. ' DO
  2276. ' CLS
  2277. ' z = 0
  2278. ' FOR i = 0 TO UBOUND(Text_Particles)
  2279. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2280. ' IF i < array_len THEN
  2281. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2282. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2283. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2284. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2285. ' END IF
  2286. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN z = z + 1
  2287. ' NEXT
  2288. ' IF array_len < UBOUND(Text_Particles) THEN array_len = array_len + steps
  2289. ' _DISPLAY
  2290. ' _LIMIT W.fps
  2291. ' steps = steps + 1
  2292. ' LOOP UNTIL INKEY$ <> "" OR z >= UBOUND(text_particles)
  2293. ' EXIT SUB
  2294. ' CASE "horizontal"
  2295. ' FOR i = 0 TO UBOUND(Text_Particles)
  2296. ' Text_Particles(i).vx = 0
  2297. ' Text_Particles(i).vy = 0
  2298. ' Text_Particles(i).delX = p5random(-.2, .2)
  2299. ' Text_Particles(i).delY = 0
  2300. ' NEXT
  2301. ' DO
  2302. ' CLS
  2303. ' z = 0
  2304. ' FOR i = 0 TO UBOUND(Text_Particles)
  2305. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2306. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2307. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2308. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2309. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2310. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN z = z + 1
  2311. ' NEXT
  2312. ' _DISPLAY
  2313. ' _LIMIT W.fps
  2314. ' LOOP UNTIL INKEY$ <> "" OR z >= UBOUND(text_particles)
  2315. ' EXIT SUB
  2316. ' CASE "vertical"
  2317. ' FOR i = 0 TO UBOUND(Text_Particles)
  2318. ' Text_Particles(i).vx = 0
  2319. ' Text_Particles(i).vy = 0
  2320. ' Text_Particles(i).delX = 0
  2321. ' Text_Particles(i).delY = p5random(-0.2, 0.2)
  2322. ' NEXT
  2323. ' DO
  2324. ' CLS
  2325. ' z = 0
  2326. ' FOR i = 0 TO UBOUND(Text_Particles)
  2327. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2328.  
  2329. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2330. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2331. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2332. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2333.  
  2334. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN z = z + 1
  2335. ' NEXT
  2336. ' _DISPLAY
  2337. ' _LIMIT W.fps
  2338. ' LOOP UNTIL INKEY$ <> "" OR z >= UBOUND(text_particles)
  2339. ' EXIT SUB
  2340.  
  2341. ' CASE "boom"
  2342. ' FOR i = 0 TO UBOUND(Text_Particles)
  2343. ' Text_Particles(i).vx = 0
  2344. ' Text_Particles(i).vy = 0
  2345. ' Text_Particles(i).delX = p5random(-.1, .1)
  2346. ' Text_Particles(i).delY = p5random(-0.1, 0.1)
  2347. ' NEXT
  2348. ' DO
  2349. ' CLS
  2350. ' steps = 0
  2351. ' FOR i = 0 TO UBOUND(Text_Particles)
  2352. ' PSET (Text_Particles(i).x, Text_Particles(i).y), Text_Particles_Color
  2353. ' Text_Particles(i).x = Text_Particles(i).x + Text_Particles(i).vx
  2354. ' Text_Particles(i).y = Text_Particles(i).y + Text_Particles(i).vy
  2355. ' Text_Particles(i).vx = Text_Particles(i).vx + Text_Particles(i).delX
  2356. ' Text_Particles(i).vy = Text_Particles(i).vy + Text_Particles(i).delY
  2357. ' IF Text_Particles(i).x > _WIDTH OR Text_Particles(i).x < 0 OR Text_Particles(i).y > _HEIGHT OR Text_Particles(i).y < 0 THEN steps = steps + 1
  2358. ' NEXT
  2359. ' _DISPLAY
  2360. ' _LIMIT W.fps
  2361. ' IF steps > UBOUND(Text_Particles) THEN EXIT DO
  2362. ' LOOP UNTIL INKEY$ <> "" OR steps > UBOUND(text_particles)
  2363. ' EXIT SUB
  2364. ' END SELECT
  2365. ' END SUB
  2366.  
  2367. SUB centerPrint (a$, b)
  2368.     DIM i AS INTEGER, v AS INTEGER
  2369.     FOR i = 1 TO LEN(a$)
  2370.         v = v + _PRINTWIDTH(MID$(a$, i, 1))
  2371.     NEXT
  2372.     _PRINTSTRING (_WIDTH / 2 - v / 2, b), a$
  2373.  
  2374. FUNCTION txtWidth (a$)
  2375.     DIM i AS INTEGER, v AS INTEGER, g AS INTEGER
  2376.     FOR i = 1 TO LEN(a$)
  2377.         g = _PRINTWIDTH(MID$(a$, i, 1))
  2378.         v = v + g
  2379.     NEXT
  2380.     txtWidth = v
  2381. 'these p5random(), p5map! (original map!) and dist() functions are taken from p5js.bas
  2382. FUNCTION p5random! (mn!, mx!)
  2383.     DIM tmp!
  2384.  
  2385.     IF mn! > mx! THEN
  2386.         tmp! = mn!
  2387.         mn! = mx!
  2388.         mx! = tmp!
  2389.     END IF
  2390.     p5random! = RND * (mx! - mn!) + mn!
  2391.  
  2392. FUNCTION dist! (x1!, y1!, x2!, y2!)
  2393.     dist! = SQR((x2! - x1!) ^ 2 + (y2! - y1!) ^ 2)
  2394.  
  2395. FUNCTION p5map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  2396.     p5map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  2397.  
  2398.  
  2399. 'By UnseenMachine & [banned user]
  2400. 'http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=12658
  2401. SUB BLURIMAGE (Image AS LONG, Blurs AS _UNSIGNED INTEGER)
  2402.  
  2403.     DIM ImageMemory AS _MEM
  2404.     DIM ImageOffsetCurrent AS _OFFSET
  2405.     DIM ImageOffsetStart AS _OFFSET
  2406.     DIM ImageOffsetEnd AS _OFFSET
  2407.  
  2408.     DIM TopOffset AS _OFFSET
  2409.     DIM LeftOffset AS _OFFSET
  2410.     DIM RightOffset AS _OFFSET
  2411.     DIM BottomOffset AS _OFFSET
  2412.  
  2413.     DIM Red1 AS _UNSIGNED _BYTE
  2414.     DIM Green1 AS _UNSIGNED _BYTE
  2415.     DIM Blue1 AS _UNSIGNED _BYTE
  2416.     DIM Alpha1 AS _UNSIGNED _BYTE
  2417.  
  2418.     DIM Red2 AS _UNSIGNED _BYTE
  2419.     DIM Green2 AS _UNSIGNED _BYTE
  2420.     DIM Blue2 AS _UNSIGNED _BYTE
  2421.     DIM Alpha2 AS _UNSIGNED _BYTE
  2422.  
  2423.     DIM Red3 AS _UNSIGNED _BYTE
  2424.     DIM Green3 AS _UNSIGNED _BYTE
  2425.     DIM Blue3 AS _UNSIGNED _BYTE
  2426.     DIM Alpha3 AS _UNSIGNED _BYTE
  2427.  
  2428.     DIM Red4 AS _UNSIGNED _BYTE
  2429.     DIM Green4 AS _UNSIGNED _BYTE
  2430.     DIM Blue4 AS _UNSIGNED _BYTE
  2431.     DIM Alpha4 AS _UNSIGNED _BYTE
  2432.  
  2433.     ImageMemory = _MEMIMAGE(Image)
  2434.  
  2435.  
  2436.     DIM iterations%
  2437.  
  2438.     FOR iterations% = 0 TO Blurs - 1
  2439.  
  2440.         ImageOffsetStart = ImageMemory.OFFSET
  2441.         ImageOffsetCurrent = ImageOffsetStart
  2442.         ImageOffsetEnd = ImageOffsetStart + _WIDTH(Image) * _HEIGHT(Image) * 4
  2443.  
  2444.         DO
  2445.             TopOffset = ImageOffsetCurrent - _WIDTH(Image) * 4
  2446.             LeftOffset = ImageOffsetCurrent - 4
  2447.             RightOffset = ImageOffsetCurrent + 4
  2448.             BottomOffset = ImageOffsetCurrent + _WIDTH(Image) * 4
  2449.  
  2450.             ' *** Let's go ahead and set the color values to zero, and only change them when required.
  2451.             Red1 = 0: Green1 = 0: Blue1 = 0: Alpha1 = 0
  2452.             Red2 = 0: Green2 = 0: Blue2 = 0: Alpha2 = 0
  2453.             Red3 = 0: Green3 = 0: Blue3 = 0: Alpha3 = 0
  2454.             Red4 = 0: Green4 = 0: Blue4 = 0: Alpha4 = 0
  2455.  
  2456.             ' *** Get the color values from the pixel above the current pixel, if it is with the image.
  2457.             IF TopOffset >= ImageOffsetStart THEN
  2458.                 Red1 = _MEMGET(ImageMemory, TopOffset + 2, _UNSIGNED _BYTE)
  2459.                 Green1 = _MEMGET(ImageMemory, TopOffset + 1, _UNSIGNED _BYTE)
  2460.                 Blue1 = _MEMGET(ImageMemory, TopOffset, _UNSIGNED _BYTE)
  2461.                 Alpha1 = _MEMGET(ImageMemory, TopOffset + 3, _UNSIGNED _BYTE)
  2462.             END IF
  2463.  
  2464.             ' *** Get the color values from the pixel to the left of the current pixel, if it is with the image.
  2465.             IF ((((LeftOffset - ImageOffsetStart) / 4) MOD _WIDTH(Image)) < (((ImageOffsetCurrent - ImageOffsetStart) / 4) MOD _WIDTH(Image))) THEN
  2466.                 Red2 = _MEMGET(ImageMemory, LeftOffset + 2, _UNSIGNED _BYTE)
  2467.                 Green2 = _MEMGET(ImageMemory, LeftOffset + 1, _UNSIGNED _BYTE)
  2468.                 Blue2 = _MEMGET(ImageMemory, LeftOffset, _UNSIGNED _BYTE)
  2469.                 Alpha2 = _MEMGET(ImageMemory, LeftOffset + 3, _UNSIGNED _BYTE)
  2470.             END IF
  2471.  
  2472.             ' *** Get the color values from the pixel to the right of the current pixel, if it is with the image.
  2473.             IF ((((RightOffset - ImageOffsetStart) / 4) MOD _WIDTH(Image)) > (((ImageOffsetCurrent - ImageOffsetStart) / 4) MOD _WIDTH(Image))) THEN
  2474.                 Red3 = _MEMGET(ImageMemory, RightOffset + 2, _UNSIGNED _BYTE)
  2475.                 Green3 = _MEMGET(ImageMemory, RightOffset + 1, _UNSIGNED _BYTE)
  2476.                 Blue3 = _MEMGET(ImageMemory, RightOffset, _UNSIGNED _BYTE)
  2477.                 Alpha3 = _MEMGET(ImageMemory, RightOffset + 3, _UNSIGNED _BYTE)
  2478.             END IF
  2479.  
  2480.             ' *** Get the color values from the pixel below the current pixel, if it is with the image.
  2481.             IF BottomOffset < ImageOffsetEnd THEN
  2482.                 Red4 = _MEMGET(ImageMemory, BottomOffset + 2, _UNSIGNED _BYTE)
  2483.                 Green4 = _MEMGET(ImageMemory, BottomOffset + 1, _UNSIGNED _BYTE)
  2484.                 Blue4 = _MEMGET(ImageMemory, BottomOffset, _UNSIGNED _BYTE)
  2485.                 Alpha4 = _MEMGET(ImageMemory, BottomOffset + 3, _UNSIGNED _BYTE)
  2486.             END IF
  2487.  
  2488.             ' *** draw the current pixel with a newly defined _RGBA color value.
  2489.             _MEMPUT ImageMemory, ImageOffsetCurrent, _RGBA((Red1 + Red2 + Red3 + Red4) / 4, (Green1 + Green2 + Green3 + Green4) / 4, (Blue1 + Blue2 + Blue3 + Blue4) / 4, (Alpha1 + Alpha2 + Alpha3 + Alpha4) / 4) AS _UNSIGNED LONG
  2490.  
  2491.             '' *** These are here for fun nd testing purposes.
  2492.             '_MEMPUT ImageMemory, ImageOffsetCurrent, _RGBA((Red1 + Red2 + Red3 + Red4) / 4, (Green1 + Green2 + Green3 + Green4) / 4, (Blue1 + Blue2 + Blue3 + Blue4) / 4, 255) AS _UNSIGNED LONG
  2493.             '_MEMPUT ImageMemory, ImageOffsetCurrent, _RGBA(0, 0, (Blue1 + Blue2 + Blue3 + Blue4) / 4, 255) AS _UNSIGNED LONG
  2494.             '_MEMPUT ImageMemory, ImageOffsetCurrent, _RGBA(0, (Green1 + Green2 + Green3 + Green4) / 4, 0, 255) AS _UNSIGNED LONG
  2495.             '_MEMPUT ImageMemory, ImageOffsetCurrent, _RGBA((Red1 + Red2 + Red3 + Red4) / 4, 0, 0, 255) AS _UNSIGNED LONG
  2496.  
  2497.             ImageOffsetCurrent = ImageOffsetCurrent + 4
  2498.  
  2499.         LOOP UNTIL ImageOffsetCurrent = ImageOffsetEnd
  2500.  
  2501.     NEXT
  2502.  
  2503.     _MEMFREE ImageMemory
  2504.  
  2505. '$include:'Vendor\sprite.bi'
  2506.  
  2507. 'End of Code ! :)
  2508.  

 
Hunter's Revenge Screenshot.jpg

40
General, Math & Geometry / Dropping Balls by bplus
« on: March 05, 2020, 05:10:08 am »
Dropping Balls

Author: @bplus
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=194.0
Version: 2020
Tags: [gravity], [spherical collisions]

Description:
Dropping Balls an attempt to build a pile by adjusting drop rate, elasticity, and gravity.
Bplus used tools from SMcNeill for fill circle and STxAxTIC for non-overlapping balls.

This thread is a fun continuation of ball collision experiments from a number of members including: @_vince who offered an hourglass challenge, @[banned user], @SMcNeill, @STxAxTIC, creating a collection of interesting variations. The code given here is just one program from a variety produced.  Look through the whole of the designated thread, it continues into Hourglass thread linked near end of URL above.


Source Code:
Code: QB64: [Select]
  1.     _TITLE "Dropping Balls: Pile Attempt #3" ' bplus started 2018-04-03"
  2.     ' Attempt to build a pile by adjusting drop rate, elasticity, and gravity.
  3.     ' Built from Dropping balls 4 w snd and STATIC created 2018-04-3
  4.     ' Add STATIC's ball moving before figuring any bounce from collision
  5.     ' which was a mod in Dropping Balls 2 w sound posted 2018-03-31.
  6.     ' 2020-03-04 Pile Attempt #3 revive and tidy up
  7.      
  8.     CONST xmax = 750, ymax = 720, elastic = .8, gravity = .75, balls = 400, br = 15
  9.     SCREEN _NEWIMAGE(xmax, ymax, 32)
  10.     _SCREENMOVE 360, 20
  11.     DIM x(balls), y(balls), dx(balls), dy(balls), a(balls), rr(balls), gg(balls), bb(balls)
  12.     FOR i = 1 TO balls 'initialize balls to drop
  13.         x(i) = xmax / 2 + (i MOD 2) * 8 - 4: y(i) = 0 '                                     location
  14.         dx(i) = 0: dy(i) = 3 '                                                        change on axis
  15.         rr(i) = 150 + RND * 100: gg(i) = 150 + RND * 100: bb(i) = 150 + RND * 100 '        rgb color
  16.     NEXT
  17.     WHILE 1
  18.         CLS
  19.         loopCnt = loopCnt + 1 '                   drop ball every 17 loops so previous ball is clear
  20.         IF loopCnt MOD 17 = 0 THEN
  21.             IF maxBall < balls THEN maxBall = maxBall + 1
  22.         END IF
  23.         _PRINTSTRING (100, 10), "Balls:" + STR$(maxBall)
  24.         FOR i = 1 TO maxBall
  25.             'ready for collision
  26.             dy(i) = dy(i) + gravity '                               gravity increase update on y axis
  27.             a(i) = _ATAN2(dy(i), dx(i)) '                                       angle ball is heading
  28.             imoved = 0
  29.             FOR j = i + 1 TO maxBall
  30.                 '      The following is STxAxTIC's adjustment of ball positions if overlapping before
  31.                 ' calculation of new positions from collision. Displacement vector and its magnitude:
  32.                 nx = x(j) - x(i): ny = y(j) - y(i)
  33.                 nm = SQR(nx ^ 2 + ny ^ 2)
  34.                 IF nm < 1 + 2 * br THEN
  35.                     nx = nx / nm: ny = ny / nm
  36.                     ' Regardless of momentum exchange, separate balls along the line connecting them.
  37.                     DO WHILE nm < 1 + 2 * br
  38.                         flub = .001
  39.                         x(j) = x(j) + flub * nx: y(j) = y(j) + flub * ny
  40.                         x(i) = x(i) - flub * nx: y(i) = y(i) - flub * ny
  41.                         nx = x(j) - x(i): ny = y(j) - y(i)
  42.                         nm = SQR(nx ^ 2 + ny ^ 2)
  43.                         nx = nx / nm: ny = ny / nm
  44.                     LOOP
  45.                     imoved = 1
  46.                     a(i) = _ATAN2(y(i) - y(j), x(i) - x(j))
  47.                     a(j) = _ATAN2(y(j) - y(i), x(j) - x(i))
  48.                     power1 = (dx(i) ^ 2 + dy(i) ^ 2) ^ .5 '       update new dx, dy for i and j balls
  49.                     power2 = (dx(j) ^ 2 + dy(j) ^ 2) ^ .5
  50.                     power = elastic * (power1 + power2) / 2
  51.                     dx(i) = power * COS(a(i)): dy(i) = power * SIN(a(i))
  52.                     dx(j) = power * COS(a(j)): dy(j) = power * SIN(a(j))
  53.                     x(i) = x(i) + dx(i): y(i) = y(i) + dy(i)
  54.                     x(j) = x(j) + dx(j): y(j) = y(j) + dy(j)
  55.                 END IF '                                                              Thanks STxAxTIC
  56.             NEXT
  57.             IF imoved = 0 THEN x(i) = x(i) + dx(i): y(i) = y(i) + dy(i)
  58.             IF x(i) - br < 0 OR x(i) + br > xmax THEN '       keep balls inside sides and bottom edge
  59.                 dx(i) = -dx(i)
  60.                 IF x(i) - br < 0 THEN x(i) = br
  61.                 IF x(i) + br > xmax THEN x(i) = xmax - br
  62.             END IF
  63.             IF y(i) + br > ymax THEN y(i) = ymax - br: dy(i) = -dy(i) * elastic
  64.             FOR rad = br TO 1 STEP -1 '                                         finally draw the ball
  65.                 fcirc x(i), y(i), rad, _RGB32(rr(i) - 10 * rad, gg(i) - 10 * rad, bb(i) - 10 * rad)
  66.             NEXT
  67.         NEXT
  68.         _DISPLAY
  69.         _LIMIT 20
  70.     WEND
  71.      
  72.     SUB fcirc (CX AS LONG, CY AS LONG, R AS LONG, C AS _UNSIGNED LONG) '       SMcNeill's fill circle
  73.         DIM subRadius AS LONG, RadiusError AS LONG, X AS LONG, Y AS LONG
  74.         subRadius = ABS(R): RadiusError = -subRadius: X = subRadius: Y = 0
  75.         IF subRadius = 0 THEN PSET (CX, CY): EXIT SUB
  76.         LINE (CX - X, CY)-(CX + X, CY), C, BF
  77.         WHILE X > Y
  78.             RadiusError = RadiusError + Y * 2 + 1
  79.             IF RadiusError >= 0 THEN
  80.                 IF X <> Y + 1 THEN
  81.                     LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  82.                     LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  83.                 END IF
  84.                 X = X - 1
  85.                 RadiusError = RadiusError - X * 2
  86.             END IF
  87.             Y = Y + 1
  88.             LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  89.             LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  90.         WEND
  91.     END SUB
  92.  
Dropping Balls Screensheet.jpg

41
QB64 Discussion / Samples Gallery
« on: February 25, 2020, 05:48:33 am »
In our 500Up! thread, bplus made the suggestion that we might nominate (and vote for) members and their programs for inclusion in the Samples Gallery (which at present is a little bare – Ursa Minor! *).  That method would perhaps be a little cumbersome and folks don't want to spend time doing that.

Here's my suggestion - STxAxTIC has suggested having Junior Librarians to help him:

A Junior Librarian (who has been given the necessary permission) would contact the Top 20 Starters by e-mail - these folk must be the most deserving - and request that they select one Program which they would like to submit to the Samples Gallery.  The Junior Librarian, when he has satisfied himself/herself that the Program meets STxAxTIC's selection criteria will then add this to the Gallery.  This method would be in addition to the existing method of self-application to the Head Librarian.

As we currently have 16 samples, this would bring us up to about 35 and should give a broader range of applications.

I assume that the Junior Librarian would be able to access a more complete set of Site Statistics so that he/she can determine who the Top 20 Starters are (only 10 are visible in the normal stats).

This is a sufficiently non-technical task that I'd volunteer for this job.

Separately there could be a similar Junior Librarian Post for Toolbox which would be sufficiently technical that I would not qualify.

Worthy of pursuing, or another duff Qwerkey suggestion?

* Sorry, I couldn't resist the temptation of an astronomical pun.

42
QB64 Discussion / CINT Oddity (and Slightly Incorrect _ROUND Wiki?)
« on: February 15, 2020, 07:48:10 am »
The definition of _ROUND in the Wiki gives:

The _ROUND function rounds to the closest even INTEGER, LONG or _INTEGER64 numerical value.


Thinking to myself "Why would anybody want to round to the nearest even integer (that is to say one that is divisible by 2)?", I think that this sentence is wrong and should not contain the word "even".  _ROUND rounds to the nearest integer:
Code: QB64: [Select]
  1. PRINT _ROUND(5.501)
  2. PRINT _ROUND(5.499)
gives 6, 6, 5 as expected (not 6, 6, 6!).

Meanwhile I thought that I'd demonstrate to myself that CINT always behaves properly, but:
Code: QB64: [Select]
  1. PRINT CINT(-6.5)
  2. PRINT CINT(-5.5)
  3. PRINT CINT(-4.5)
  4. PRINT CINT(-3.5)
  5. PRINT CINT(-2.5)
  6. PRINT CINT(-1.5)
  7. PRINT CINT(-0.5)
  8. PRINT CINT(0.5)
  9. PRINT CINT(1.5)
  10. PRINT CINT(2.5)
  11. PRINT CINT(3.5)
  12. PRINT CINT(4.5)
  13. PRINT CINT(5.5)
  14. PRINT CINT(6.5)
gives:                   -6, -6, -4, -4, -2, -2,  0, 0, 2, 2, 4, 4, 6, 6
I'd have expected: -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7

Actually, I'm not quite sure what I'd have expected for the negative numbers (!), so I'll stick with the positive numbers.

We normally round 6.5 to 7.  This is because the numbers 0 to 9 split in half as:

0,1,2,3,4
5,6,7,8,9

so any decimal number 6.0..., 6.1..., 6.2..., 6.3..., 6.4... rounds down to 6

and any decimal number 6.5..., 6.6..., 6.7..., 6.8..., 6.9... rounds up to 7

6.5 exactly may be a moot point as it is, of course, exactly half way between 6 and 7, but by convention (I thought) 6.5 rounds up to 7.

I would not expect 5.5 (rounds UP) to behave differently to 6.5 (rounds DOWN).

I suppose that this oddity is because of the conversions to binary.  By the way my few brain cells can never actually envisage a decimal in binary but that's just one of my problems.

Any comments on CINT(n.5) always rounding to an even integer??  I suspect that any oddity is in the person writing this!

43
Programs / 3D Stereo Discs Graphics Program
« on: February 10, 2020, 10:36:28 am »
Back in the days of [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] (ah, this seems an eternity ago!) I wrote a program which displayed balls in stereoscopic 3D.  In the stereo imaging used, the viewer could actually "see" near objects coming right out of the screen and far object set back from the screen.  The method used was to alternate red and blue images offset in x- by a stereo angle amount.  The program was able to give the stereoscopic behaviour when using Red/Blue 3D glasses.

The method of alternating red and blue images made the viewed image jittery.  I tried to synchronise the alternation with screen refresh rate, but nothing I tried would allow the removal of the jitteriness.  The project was abandoned incomplete.

What I really wanted to do was to display both the red and the blue images together without the second image overwriting the first.  A method to do this is _MEM processing (thanks again to Steve McNeill for his tutorials) where you can simultaneously alter the _RED, _GREEN, _BLUE and _ALHPA parameters of each image picture element.

The program here implements the _MEM method accordingly.  There are 10 images of a disc, each of which moves in the x-, y- and z- directions.  The displacement of the red and blue (green is not used) images is linearly dependent upon the z- position, and this gives the stereoscopic behaviour.  _MAPTRIANGLE(3D) is used to map each image and this handles all the perspective effects (I say, once again, what a marvellous, marvellous QB64 function this is).

If you run this program with Red/Blue 3D glasses (Blue over the right eye), you will see all the normal behaviour of _MAPTRIANGLE(3D), but in addition the discs will appear to move in and out of the screen.  Without the glasses you will see red and blue images overlapping (and giving magenta) with red/blue poking out sideways dependent upon z- position.

I realise that this program will have very limited interest: the number of QB64 members is not large, members who have red/blue glasses and who have an interest in such graphics will be a very select group.  For this reason I leave the program as a curiosity here in this state (there could be improvements which I will not attempt).  The 10 images are formed as separate software objects which are then individually _MEM processed, those images are copied to hardware and then those images displayed and then image-freed.  There will be a method to directly address the screen pixels, but this is a skill level beyond my limited ability.  It works anyway!
Code: QB64: [Select]
  1. '3D Stereo Discs Graphics Program v1 by Qwerkey 10/02/20
  2. '
  3.  
  4. CONST False = 0, True = NOT False, XScreen% = 1100, YScreen% = 800, PiConst! = 4 * ATN(1), ZOffset% = -620
  5. CONST Xst%% = 5, Stereo! = (5 * 2) / YScreen%, Rad%% = 50, Zf! = 1
  6. 'All perspective behaviour handled by _maptriangle(3D), stereo effect x-separation linear with z-
  7. 'Software Images (for _MEM processing).  Hardware images for display
  8.  
  9. DIM CMem(9) AS _MEM, COff AS _OFFSET, Balls!(9, 12), SoftImg&(9), HardImg&(9)
  10.  
  11. FOR K%% = 0 TO 9
  12.     Balls!(K%%, 0) = RND * XScreen% / 2
  13.     Balls!(K%%, 1) = RND * YScreen% / 2
  14.     Balls!(K%%, 2) = RND * YScreen% / 2
  15.     Balls!(K%%, 3) = 2 * PiConst! * (RND - 0.5)
  16.     Balls!(K%%, 4) = 2 * PiConst! * (RND - 0.5)
  17.     Balls!(K%%, 5) = 2 * PiConst! * (RND - 0.5)
  18.     Balls!(K%%, 6) = 0.007 + RND * 0.02
  19.     IF RND > 0.5 THEN Balls!(K%%, 6) = -Balls!(K%%, 6)
  20.     Balls!(K%%, 7) = 0.007 + RND * 0.02
  21.     IF RND > 0.5 THEN Balls!(K%%, 7) = -Balls!(K%%, 7)
  22.     Balls!(K%%, 8) = 0.007 + RND * 0.02
  23.     IF RND > 0.5 THEN Balls!(K%%, 8) = -Balls!(K%%, 8)
  24.     Balls!(K%%, 9) = Stereo! * Balls!(K%%, 2) * SIN(Balls!(K%%, 5))
  25.     SoftImg&(K%%) = _NEWIMAGE(2 * (Rad%% + Xst%%) + 1, 2 * Rad%% + 1, 32)
  26.     CMem(K%%) = _MEMIMAGE(SoftImg&(K%%))
  27.     FOR N% = 0 TO 2 * (Rad%% + Xst%%)
  28.         FOR M% = 0 TO 2 * Rad%%
  29.             COff = 4 * (N% + M% * 2 * (Rad%% + Xst%%) + 1) + CMem(K%%).OFFSET
  30.             _MEMPUT CMem(K%%), COff + 3, 255 AS _UNSIGNED _BYTE
  31.         NEXT M%
  32.     NEXT N%
  33.     HardImg&(K%%) = _COPYIMAGE(SoftImg&(K%%), 33)
  34. NEXT K%%
  35.  
  36. 'Screen (Hardware Only)
  37. SCREEN _NEWIMAGE(XScreen%, YScreen%, 32)
  38. 'Checking off in fully working
  39.  
  40.     _LIMIT 30
  41.  
  42.     FOR K%% = 0 TO 9
  43.         Balls!(K%%, 3) = PiBand!(Balls!(K%%, 3) + Balls!(K%%, 6))
  44.         Balls!(K%%, 4) = PiBand!(Balls!(K%%, 4) + Balls!(K%%, 7))
  45.         Balls!(K%%, 5) = PiBand!(Balls!(K%%, 5) + Balls!(K%%, 8))
  46.         Balls!(K%%, 9) = Stereo! * Balls!(K%%, 2) * SIN(Balls!(K%%, 5))
  47.         FOR N% = 0 TO 2 * (Rad%% + Xst%%)
  48.             FOR M% = 0 TO 2 * Rad%%
  49.                 COff = 4 * (N% + M% * (2 * (Rad%% + Xst%%) + 1)) + CMem(K%%).OFFSET
  50.                 _MEMPUT CMem(K%%), COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha - first set all pixels to transparent
  51.                 Q0% = N% - (Rad%% + Xst%% + Balls!(K%%, 9))
  52.                 Q1% = M% - Rad%%
  53.                 IF SQR(Q0% * Q0% + Q1% * Q1%) <= Rad%% THEN
  54.                     _MEMPUT CMem(K%%), COff + 2, 255 AS _UNSIGNED _BYTE 'Red
  55.                     _MEMPUT CMem(K%%), COff + 3, 255 AS _UNSIGNED _BYTE
  56.                 ELSE
  57.                     _MEMPUT CMem(K%%), COff + 2, 0 AS _UNSIGNED _BYTE 'Red
  58.                 END IF
  59.                 Q0% = N% - (Rad%% + Xst%% - Balls!(K%%, 9))
  60.  
  61.                 IF SQR(Q0% * Q0% + Q1% * Q1%) <= Rad%% THEN
  62.                     _MEMPUT CMem(K%%), COff, 255 AS _UNSIGNED _BYTE 'Blue
  63.                     _MEMPUT CMem(K%%), COff + 3, 255 AS _UNSIGNED _BYTE
  64.                 ELSE
  65.                     _MEMPUT CMem(K%%), COff, 0 AS _UNSIGNED _BYTE 'Blue
  66.                 END IF
  67.             NEXT M%
  68.         NEXT N%
  69.         HardImg&(K%%) = _COPYIMAGE(SoftImg&(K%%), 33)
  70.         Zpos! = Balls!(K%%, 2) * SIN(Balls!(K%%, 5)) * Zf! + ZOffset%
  71.         X1! = Balls!(K%%, 0) * SIN(Balls!(K%%, 3)) + Rad%% + Xst%%
  72.         X0! = Balls!(K%%, 0) * SIN(Balls!(K%%, 3)) - (Rad%% + Xst%%)
  73.         Y1! = Balls!(K%%, 1) * SIN(Balls!(K%%, 4)) - Rad%%
  74.         Y0! = Balls!(K%%, 1) * SIN(Balls!(K%%, 4)) + Rad%%
  75.         _MAPTRIANGLE (0, 0)-(2 * (Rad%% + Xst%%), 0)-(0, 2 * Rad%%), HardImg&(K%%) TO(X0!, Y0!, Zpos!)-(X1!, Y0!, Zpos!)-(X0!, Y1!, Zpos!)
  76.         _MAPTRIANGLE (2 * (Rad%% + Xst%%), 2 * Rad%%)-(0, 2 * Rad%%)-(2 * (Rad%% + Xst%%), 0), HardImg&(K%%) TO(X1!, Y1!, Zpos!)-(X0!, Y1!, Zpos!)-(X1!, Y0!, Zpos!)
  77.         _FREEIMAGE HardImg&(K%%)
  78.     NEXT K%%
  79.     _DISPLAY
  80.  
  81.  
  82. FUNCTION PiBand! (PiAngle!)
  83.     SELECT CASE PiAngle!
  84.         CASE IS < -_PI
  85.             PiBand! = PiAngle! + _PI(2)
  86.         CASE IS > _PI
  87.             PiBand! = PiAngle! - _PI(2)
  88.         CASE ELSE
  89.             PiBand! = PiAngle!
  90.     END SELECT
  91.  

44
Programs / Palindromic Dates
« on: February 05, 2020, 07:48:48 am »
Apparently February 2nd was "International Palindrome Day" because the date was 02/02/2020.  Luckily this is palindromic in both British configuration (DD/MM/YYYY) and American configuration (MM/DD/YYYY).

So I thought that I'd find out which dates have been palindromic.  The program gives a list of palindromic dates from year 0 to 2100.  British date configuration is used, but you can easily adapt it to American configuration.  A text file is created as well as print to screen as there are, not surprisingly, quite a few such dates.

Code: QB64: [Select]
  1. 'Palindromic Dates (British Date Configuration DDMMYYYY) 05/02/2020 by Qwerkey
  2. '02022020 was palindromic
  3. 'Do up to 2100 (assuming gregorian calendar goes back to zero)
  4.  
  5. CONST False = 0, True = NOT False
  6.  
  7. DIM Months%%(12)
  8. FOR N%% = 1 TO 12
  9.     READ Months%%(N%%)
  10. NEXT N%%
  11.  
  12. OPEN "palindate.txt" FOR OUTPUT AS #1
  13.  
  14. Day%% = 1
  15. Month%% = 1
  16. Year% = 0
  17.  
  18. WHILE Year% < 2101
  19.     Palin$ = DayMonth$(Day%%) + DayMonth$(Month%%) + Annus$(Year%)
  20.     IF IsPalindromic%%(Palin$) THEN
  21.         PRINT Palin$
  22.         PRINT #1, Palin$
  23.     END IF
  24.     Day%% = Day%% + 1
  25.     IF Day%% > Months%%(Month%%) THEN
  26.         Day%% = 1
  27.         Month%% = Month%% + 1
  28.         IF Month%% > 12 THEN
  29.             Month%% = 1
  30.             Year% = Year% + 1
  31.             'Modification for leap years:
  32.             IF Year% \ 4 = Year% / 4 THEN
  33.                 Months%%(2) = 29
  34.                 IF Year% \ 400 = Year% / 400 THEN Months%%(2) = 28
  35.             ELSE
  36.                 Months%%(2) = 28
  37.             END IF
  38.         END IF
  39.     END IF
  40.  
  41.  
  42. FUNCTION IsPalindromic%% (P$)
  43.     IsPalindromic%% = True
  44.     M%% = 1
  45.     WHILE M%% <= 4 AND IsPalindromic%%
  46.         IF MID$(P$, M%%, 1) <> MID$(P$, 9 - M%%, 1) THEN IsPalindromic%% = False
  47.         M%% = M%% + 1
  48.     WEND
  49.  
  50. FUNCTION DayMonth$ (M%%)
  51.     S$ = LTRIM$(STR$(M%%))
  52.     IF M%% < 10 THEN
  53.         DayMonth$ = "0" + S$
  54.     ELSE
  55.         DayMonth$ = S$
  56.     END IF
  57.  
  58. FUNCTION Annus$ (Y%)
  59.     A$ = LTRIM$(STR$(Y%))
  60.     IF Y% < 10 THEN
  61.         Annus$ = "000" + A$
  62.     ELSEIF Y% < 100 THEN
  63.         Annus$ = "00" + A$
  64.     ELSEIF Y% < 1000 THEN
  65.         Annus$ = "0" + A$
  66.     ELSE
  67.         Annus$ = A$
  68.     END IF
  69.  
  70. DATA 31,28,31,30,31,30,31,31,30,31,30,31
  71.  

45
Steve, I'm about to start a project where I will put images to the screen using _MEM processing.  I'll view again your videos 1&2 to remind myself of the exact methods to change the RGB values of individual pixels.  But I'm wondering when the actual screen gets updated with the new values.  If I were using _HARDWARE imaging, I'd have a _DISPLAY at every processing loop to update the screen, but I assume that _DISPLAY is not required (and is inappropriate) for _MEM screen methods.  Do I just set the _LIMIT value of my program to whatever is required for the correct processing rate and the screen will get updated at the computer/screen refresh rate, ie we leave the graphics setting at the default  _AUTODISPLAY? - Qwerkey's dim question of the week no. 20,348!

Pages: 1 2 [3] 4 5 ... 8