Author Topic: Higher/Smoother framerate movement  (Read 4942 times)

0 Members and 1 Guest are viewing this topic.

Offline Zeppelin

  • Newbie
  • Posts: 43
    • View Profile
    • Zeppelin Games ItchIo
Higher/Smoother framerate movement
« on: November 04, 2019, 08:55:58 pm »
Hey Guys,
Is it possible to achieve a higher/smoother framerate when moving sprites using _PUTIMAGE.
See file below.
To get to the demo go:
-Singleplayer
-Infinite
To exit the demo hit escape.

Thanks,
Zep
* SLAY V4.bas (Filesize: 19.03 KB, Downloads: 126)
* SLAY V4.exe (Filesize: 1.46 MB, Downloads: 127)
+[--->++<]>+.+++[->++++<]>.[--->+<]>+.-[---->+<]>++.+[->+++<]>+.+++++++++++.----------.[--->+<]>----.+[---->+<]>+++.---[->++++<]>.------------.+.++++++++++.+[---->+<]>+++.+[->+++<]>++.[--->+<]>+.[->+++<]>+.++++++++++.+.>++++++++++.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Higher/Smoother framerate movement
« Reply #1 on: November 05, 2019, 12:48:01 am »
Hi Z,

I assume this is the code in question:
Code: QB64: [Select]
  1. 'PRACTICE - GAMEMODE
  2. SUB Infinite
  3.     CLS
  4.     'DEFINE LOCAL VARS
  5.  
  6.     DIM health
  7.     DIM deltaTime
  8.  
  9.     playerSpeed = 500
  10.     health = 100
  11.     pX = _WIDTH / 2 - (playerScale * 2.5)
  12.     pY = _HEIGHT / 10 * 8
  13.  
  14.     sTime = TIMER
  15.  
  16.     DO
  17.         sTime = TIMER
  18.  
  19.         IF _KEYDOWN(100) = -1 THEN
  20.             pX = pX + (deltaTime * playerSpeed)
  21.         END IF
  22.         IF _KEYDOWN(97) = -1 THEN
  23.             pX = pX - (deltaTime * playerSpeed)
  24.         END IF
  25.  
  26.         IF pX < 1 THEN
  27.             pX = 1
  28.         END IF
  29.         IF pX > _WIDTH - playerScale * 5 - 1 THEN
  30.             pX = _WIDTH - playerScale * 5 - 1
  31.         END IF
  32.  
  33.         LINE (pX - (playerScale * 5) - 1, pY - (playerScale * 5) - 1)-(pX + ((playerScale * 5) * 2), pY + (playerScale * 5) + 1), _RGB(0, 0, 0), BF
  34.         PUT (pX, pY), player%()
  35.         _DISPLAY
  36.  
  37.  
  38.         eTime = TIMER
  39.         deltaTime = eTime - sTime
  40.     LOOP UNTIL health <= 0 OR INKEY$ = CHR$(27)
  41.     CLS
  42.     SaveGame
  43.     DrawMenu
  44.  

I have never seen a player moved according to elapsed time.

You might try setting a character moving in a direction x amount every frame (= loop) and only stop or change direction by key press detection. It is like the snake in the Snake Game though that never stops unless it crashes into something.

Code: QB64: [Select]
  1. 'PRACTICE - GAMEMODE
  2. SUB Infinite
  3.     CLS
  4.     'DEFINE LOCAL VARS
  5.  
  6.     DIM health
  7.     DIM deltaTime
  8.  
  9.     playerSpeed = 100
  10.     health = 100
  11.     pX = _WIDTH / 2 - (playerScale * 2.5)
  12.     pY = _HEIGHT / 10 * 8
  13.  
  14.     sTime = TIMER
  15.  
  16.     DO
  17.         IF _KEYDOWN(100) = -1 THEN Pdx = 1
  18.         IF _KEYDOWN(97) = -1 THEN Pdx = -1
  19.         pX = pX + Pdx
  20.         IF pX < 1 THEN
  21.             pX = 1
  22.         ELSEIF pX > _WIDTH - playerScale * 5 - 1 THEN
  23.             pX = _WIDTH - playerScale * 5 - 1
  24.         END IF
  25.         'black out character? not cls ??
  26.         LINE (pX - (playerScale * 5) - 1, pY - (playerScale * 5) - 1)-(pX + ((playerScale * 5) * 2), pY + (playerScale * 5) + 1), _RGB(0, 0, 0), BF
  27.         PUT (pX, pY), player%()
  28.         _DISPLAY
  29.         _LIMIT playerSpeed
  30.     LOOP UNTIL health <= 0 OR INKEY$ = CHR$(27)
  31.     CLS
  32.     SaveGame
  33.     DrawMenu
  34.  
« Last Edit: November 05, 2019, 01:04:04 am by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Higher/Smoother framerate movement
« Reply #2 on: November 05, 2019, 02:55:41 am »
Hi! You can use hardware images. It is very fast.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Higher/Smoother framerate movement
« Reply #3 on: November 05, 2019, 04:55:23 am »
I've been trying to get this thing running and so far haven't had any luck with it.  My initial feedback for the game:

1) In all those menu routines, change the SELECT CASE so that they work will upcase values as well as lower case, like so:
          SELECT CASE INKEY$
            CASE "s", "S" 'MOVE POINTER DOWN

My caps lock was on, and the game was simply unresponsive, with no indication that something was wrong with it.

2) Add a _LIMIT into each of those menu routines.  As they currently exist, they run CPU usage up to incredible levels and make the fans in my PC sound like an airplane engine as they try to keep the system cool.  Something low is more than enough in this case, as people don't type at 1000 characters per second, and the program is only actually looking for a few keypresses here to progress.  I'd go with a _LIMIT 30 or so, as that's all you really seem to need.

    DO
        _LIMIT 30
        LINE (w / 2 - 90, h / 10 * 4.5)-(w / 2 - 110, h / 10 * 7), col, BF 'CLEAR PAST POINTERS
        _PRINTSTRING (w / 2 - 100, h / 10 * (4.6 + (0.52 * opt))), ">" 'DISPLAY POINTER

        _DISPLAY 'REDUCE FLICKERING



Edit:

Like bplus, I also think that a _LIMIT of some sort should be set inside the loop, rather than trying to base movement upon elapsed time.

However, I think that the limit should be a set amount, with the ability to modify the movement as needed via the playerSpeed variable, rather than messing with the limit as his code would. 

Code: QB64: [Select]
  1. SUB Infinite
  2.     CLS
  3.     'DEFINE LOCAL VARS
  4.  
  5.     DIM health
  6.     DIM deltaTime
  7.  
  8.     playerSpeed = 500
  9.     health = 100
  10.     pX = _WIDTH / 2 - (playerScale * 2.5)
  11.     pY = _HEIGHT / 10 * 8
  12.  
  13.     sTime = TIMER
  14.  
  15.     DO
  16.         _LIMIT 120
  17.  
  18.         sTime = TIMER(0.001)
  19.         IF _KEYDOWN(ASC("+")) OR _KEYDOWN(ASC("=")) THEN 'plus key
  20.             playerSpeed = playerSpeed + 50 'adjustable speed for testing with the player
  21.             IF playerSpeed > 1000 THEN playerSpeed = 1000
  22.             _DELAY .1 ' small pause to register/release the key
  23.         END IF
  24.         IF _KEYDOWN(ASC("-")) OR _KEYDOWN(ASC("_")) THEN 'minus key
  25.             playerSpeed = playerSpeed - 50
  26.             IF playerSpeed < 100 THEN playerSpeed = 100
  27.             _DELAY .1
  28.         END IF
  29.         IF _KEYDOWN(100) THEN
  30.             pX = pX + playerSpeed / 100
  31.             IF pX > _WIDTH - playerScale * 5 - 1 THEN pX = _WIDTH - playerScale * 5 - 1
  32.         END IF
  33.         IF _KEYDOWN(97) THEN
  34.             pX = pX - playerSpeed / 100
  35.             IF pX < 1 THEN pX = 1
  36.         END IF
  37.  
  38.  
  39.         LOCATE 1, 1: PRINT playerSpeed
  40.         LINE (pX - (playerScale * 5) - 1, pY - (playerScale * 5) - 1)-(pX + ((playerScale * 5) * 2), pY + (playerScale * 5) + 1), _RGB(0, 0, 0), BF
  41.         PUT (pX, pY), player%()
  42.         _DISPLAY
  43.  
  44.  
  45.         eTime = TIMER(0.001)
  46.         deltaTime = eTime - sTime
  47.     LOOP UNTIL health <= 0 OR INKEY$ = CHR$(27)
  48.     CLS
  49.     SaveGame
  50.     DrawMenu

Like this, you can set the speed of the program so that it'll have a maximum movement with _LIMIT on very fast computers, and you can increase the playerSpeed as necessary to keep game flow steady if it's ever ran on very old/slow computers.  (Just add a condition to check for your FPS, which should always be within 1 of your limit, and then you can adjust the player and opponent speed to skip a few frames if the values get too low,  to keep the game moving at the same rate, which is what I think you were wanting to do with deltatime as you implemented it.)
« Last Edit: November 05, 2019, 05:35:43 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Zeppelin

  • Newbie
  • Posts: 43
    • View Profile
    • Zeppelin Games ItchIo
Re: Higher/Smoother framerate movement
« Reply #4 on: November 05, 2019, 05:20:21 pm »
Like this, you can set the speed of the program so that it'll have a maximum movement with _LIMIT on very fast computers, and you can increase the playerSpeed as necessary to keep game flow steady if it's ever ran on very old/slow computers.  (Just add a condition to check for your FPS, which should always be within 1 of your limit, and then you can adjust the player and opponent speed to skip a few frames if the values get too low,  to keep the game moving at the same rate, which is what I think you were wanting to do with deltatime as you implemented it.)
I usually program in c# with Unity, so the deltatime was to try keep a consistent movement speed disregarding framerate (to some degree).
I will add limits to all loops (completely forgot, sorry about the egg-cooking CPU).

Thanks,
Zep
+[--->++<]>+.+++[->++++<]>.[--->+<]>+.-[---->+<]>++.+[->+++<]>+.+++++++++++.----------.[--->+<]>----.+[---->+<]>+++.---[->++++<]>.------------.+.++++++++++.+[---->+<]>+++.+[->+++<]>++.[--->+<]>+.[->+++<]>+.++++++++++.+.>++++++++++.

Offline MrFreyer

  • Newbie
  • Posts: 34
    • View Profile
Re: Higher/Smoother framerate movement
« Reply #5 on: November 05, 2019, 05:52:49 pm »
...something smooth like this?

Code: QB64: [Select]
  1. '+-------------------+
  2. '        SLAY
  3. ' ZEPPELIN GAMES 2019
  4. '+-------------------+
  5.  
  6. _TITLE "SLAY" 'SET TITLE
  7. _FULLSCREEN 'SET FULLSCREEN
  8. SCREEN _NEWIMAGE(1200, 800, 256)
  9.  
  10. DIM sTime AS DOUBLE 'NEW NEW NEW ####################################
  11. DIM eTime AS DOUBLE 'NEW NEW NEW ####################################
  12. DIM deltaTime AS SINGLE 'NEW NEW NEW ####################################
  13.  
  14. 'DECLARE VARIABLES
  15. 'SAVE DATA VARS
  16. DIM SHARED saveData$(1000)
  17.  
  18. 'PLAYER VARS
  19. DIM SHARED player%(10000)
  20. DIM SHARED player.health AS INTEGER
  21. DIM SHARED player.basehealth AS INTEGER
  22. DIM SHARED playerScale AS INTEGER
  23. playerScale = 15
  24.  
  25.  
  26. 'PLAYER STATS
  27. DIM SHARED stats.enemyskilled AS INTEGER
  28. DIM SHARED stats.totaldeaths AS INTEGER
  29.  
  30. 'SCREEN AND FORMATTING VARS
  31.  
  32.  
  33. 'GET THE SCREEN DIMSENSIONS
  34. w = _WIDTH
  35.  
  36. 'FONT DATA
  37.  
  38. 'SET THE COLOR
  39. col = _RGBA(255, 255, 255, 255)
  40.  
  41. 'START GAME
  42. LoadData
  43.  
  44. SUB LoadData
  45.     'LOAD SAVE DATA
  46.  
  47.     'LOAD PLAYER SPRITE
  48.     LoadSprite player%(), playerScale
  49.  
  50.     IF _FILEEXISTS("SlayV4SaveData.txt") THEN 'SEE IF THE FILE EXISTS
  51.         OPEN "SlayV4SaveData.txt" FOR INPUT AS #1
  52.         DO UNTIL EOF(1) 'LOOP UNTIL END OF FILE
  53.             filecount = filecount + 1 'COUNT AMOUNT OF LINES
  54.             LINE INPUT #1, file$
  55.             saveData$(filecount) = file$
  56.         LOOP
  57.         CLOSE #1
  58.  
  59.         IF filecount > 2 THEN
  60.             'PLAYER
  61.  
  62.             'DECRYPT NAME
  63.             name$ = ""
  64.             FOR n = 1 TO LEN(saveData$(1)) STEP 2
  65.                 name$ = name$ + CHR$(ASC(MID$(saveData$(1), n, 1)) - 4)
  66.             NEXT n
  67.  
  68.             'DECRYPT STATS
  69.             'HEALTH
  70.             health$ = ""
  71.             FOR n = 1 TO LEN(saveData$(2)) STEP 2
  72.                 health$ = health$ + CHR$(ASC(MID$(saveData$(2), n, 1)) - 4)
  73.             NEXT n
  74.  
  75.             player.name = UCASE$(name$) 'LOAD NAME
  76.             player.basehealth = VAL(health$) 'LOAD BASE HEALTH
  77.             player.health = player.basehealth 'SET PLAYER HEALTH
  78.             'SAVE DATA
  79.             save.point = VAL(saveData$(3)) 'LOAD SAVE POINT
  80.             'STATS
  81.             stats.enemyskilled = VAL(saveData$(4)) 'ENEMYS KILLED
  82.             stats.totaldeaths = VAL(saveData$(5)) 'TOTAL DEATHS
  83.         ELSE
  84.             CreateNewSave
  85.         END IF
  86.     ELSE
  87.         CreateNewSave
  88.     END IF
  89.  
  90.     'START GAME
  91.     _DELAY (1)
  92.     DrawLogo
  93.  
  94. SUB CreateNewSave
  95.     'CREATE NEW SAVE FILE
  96.     scaledText w / 2 - 65, h / 2 + 8, 16, _RGBA(255, 255, 255, 255), "Enter your name: "
  97.     DO
  98.         LOCATE (h / 2 - 248) / fh + hf, (w / 2 - 50) / fw + fw: INPUT "", name$
  99.     LOOP UNTIL LEN(name$) > 1
  100.     IF LEN(name$) > 16 THEN
  101.         CLS
  102.         _PRINTSTRING (w / 2 - 150, h / 2), "Name length should be less than 16 characters"
  103.         _DELAY (2)
  104.         CLS
  105.         LoadData
  106.     END IF
  107.  
  108.     'SET VARS
  109.     player.name = UCASE$(name$)
  110.     player.health = 100
  111.  
  112.     save.point = 0
  113.     stats.enemyskilled = 0
  114.     stats.totaldeaths = 0
  115.  
  116.     'ENCRYPT SAVE DATA
  117.     'NAME
  118.     DIM nameArray$(16)
  119.     FOR n = 1 TO LEN(player.name)
  120.         nameArray$(n) = MID$(player.name, n, 1)
  121.     NEXT n
  122.  
  123.     FOR n = 1 TO LEN(player.name)
  124.         tempName$ = tempName$ + CHR$(ASC(nameArray$(n)) + 4)
  125.         tempName$ = tempName$ + CHR$(INT(RND * 100) + 100)
  126.     NEXT n
  127.  
  128.     name$ = tempName$
  129.  
  130.     'ENCRYPT STATS
  131.     'HEALTH
  132.     DIM healthArray$(5)
  133.     FOR n = 1 TO LEN(STR$(player.health))
  134.         healthArray$(n) = MID$(STR$(player.health), n, 1)
  135.     NEXT n
  136.  
  137.     FOR n = 1 TO LEN(STR$(player.health))
  138.         tempHealth$ = tempHealth$ + CHR$(ASC(healthArray$(n)) + 4)
  139.         tempHealth$ = tempHealth$ + CHR$(INT(RND * 100) + 100)
  140.     NEXT n
  141.  
  142.     'SAVE VARS TO TXT
  143.     OPEN "SlayV4SaveData.txt" FOR OUTPUT AS #1
  144.     'PLAYER
  145.     PRINT #1, name$
  146.     PRINT #1, tempHealth$
  147.     'SAVE DATA
  148.     PRINT #1, save.point
  149.     'STATS
  150.     PRINT #1, stats.enemyskilled
  151.     PRINT #1, stats.totaldeaths
  152.     CLOSE #1
  153.     CLS
  154.  
  155. SUB DrawLogo
  156.     'FADE LOGO IN
  157.     FOR n = 0 TO 255
  158.         'LIMIT FPS
  159.         _LIMIT 1000
  160.         'TOP LINE
  161.         LINE (w / 6 * 2, h / 6 * 1.5)-(w / 6 * 4, h / 6 * 2), col, BF
  162.         LINE (w / 6 * 1.8, h / 6 * 1.5)-(w / 6 * 4.25, h / 6 * 1.75), col, BF
  163.  
  164.         'MIDDLE
  165.         LINE (w / 6 * 3.5, h / 6 * 2)-(w / 6 * 4, h / 6 * 2.5), col, BF
  166.         LINE (w / 6 * 3.25, h / 6 * 2.25)-(w / 6 * 3.75, h / 6 * 3), col, BF
  167.         LINE (w / 6 * 2.75, h / 6 * 2.75)-(w / 6 * 3.5, h / 6 * 3.25), col, BF
  168.         LINE (w / 6 * 2.25, h / 6 * 3)-(w / 6 * 3.25, h / 6 * 3.5), col, BF
  169.         LINE (w / 6 * 2, h / 6 * 3.25)-(w / 6 * 2.5, h / 6 * 3.75), col, BF
  170.  
  171.         'BOTTOM LINE
  172.         LINE (w / 6 * 1.75, h / 6 * 3.75)-(w / 6 * 4.25, h / 6 * 4.25), col, BF
  173.         LINE (w / 6 * 1.5, h / 6 * 4)-(w / 6 * 4.5, h / 6 * 4.25), col, BF
  174.         col = _RGB(n, n, n)
  175.         _DISPLAY
  176.     NEXT n
  177.  
  178.  
  179.     'DRAW LOGO
  180.     LINE (w / 6 * 2, h / 6 * 1.5)-(w / 6 * 4, h / 6 * 2), col, BF
  181.     LINE (w / 6 * 1.8, h / 6 * 1.5)-(w / 6 * 4.25, h / 6 * 1.75), col, BF
  182.  
  183.     'MIDDLE
  184.     LINE (w / 6 * 3.5, h / 6 * 2)-(w / 6 * 4, h / 6 * 2.5), col, BF
  185.     LINE (w / 6 * 3.25, h / 6 * 2.25)-(w / 6 * 3.75, h / 6 * 3), col, BF
  186.     LINE (w / 6 * 2.75, h / 6 * 2.75)-(w / 6 * 3.5, h / 6 * 3.25), col, BF
  187.     LINE (w / 6 * 2.25, h / 6 * 3)-(w / 6 * 3.25, h / 6 * 3.5), col, BF
  188.     LINE (w / 6 * 2, h / 6 * 3.25)-(w / 6 * 2.5, h / 6 * 3.75), col, BF
  189.  
  190.     'BOTTOM LINE
  191.     LINE (w / 6 * 1.75, h / 6 * 3.75)-(w / 6 * 4.25, h / 6 * 4.25), col, BF
  192.     LINE (w / 6 * 1.5, h / 6 * 4)-(w / 6 * 4.5, h / 6 * 4.25), col, BF
  193.  
  194.     scaledText w / 2, h / 6 * 4.5, 50, _RGBA(255, 255, 255, 255), "ZEPPELIN GAMES"
  195.     _DISPLAY
  196.     _DELAY (3) 'WAIT A BIT
  197.  
  198.     'FADE THE LOGO AND TEXT OUT
  199.     FOR n = 0 TO 255
  200.         'LIMIT FPS
  201.         _LIMIT 1000
  202.         'TOP LINE
  203.         LINE (w / 6 * 2, h / 6 * 1.5)-(w / 6 * 4, h / 6 * 2), col, BF
  204.         LINE (w / 6 * 1.8, h / 6 * 1.5)-(w / 6 * 4.25, h / 6 * 1.75), col, BF
  205.  
  206.         'MIDDLE
  207.         LINE (w / 6 * 3.5, h / 6 * 2)-(w / 6 * 4, h / 6 * 2.5), col, BF
  208.         LINE (w / 6 * 3.25, h / 6 * 2.25)-(w / 6 * 3.75, h / 6 * 3), col, BF
  209.         LINE (w / 6 * 2.75, h / 6 * 2.75)-(w / 6 * 3.5, h / 6 * 3.25), col, BF
  210.         LINE (w / 6 * 2.25, h / 6 * 3)-(w / 6 * 3.25, h / 6 * 3.5), col, BF
  211.         LINE (w / 6 * 2, h / 6 * 3.25)-(w / 6 * 2.5, h / 6 * 3.75), col, BF
  212.  
  213.         'BOTTOM LINE
  214.         LINE (w / 6 * 1.75, h / 6 * 3.75)-(w / 6 * 4.25, h / 6 * 4.25), col, BF
  215.         LINE (w / 6 * 1.5, h / 6 * 4)-(w / 6 * 4.5, h / 6 * 4.25), col, BF
  216.         col = _RGB(255 - n, 255 - n, 255 - n)
  217.  
  218.         LINE (w / 10 * 2, h / 10 * 7)-(w / 10 * 8, h / 10 * 8), _RGB(0, 0, 0), BF
  219.         scaledText w / 2, h / 6 * 4.5, 50, _RGBA(255, 255, 255, 255 - n), "ZEPPELIN GAMES"
  220.         _DISPLAY
  221.     NEXT n
  222.     CLS
  223.     _DISPLAY
  224.     _DELAY (2)
  225.     DrawMenu
  226.  
  227. SUB DrawMenu
  228.     'FADE IN MENU SCREEN
  229.     FOR n = 0 TO 255
  230.         _LIMIT 1000
  231.         'S
  232.         LINE (w / 10 * 2.75, h / 10 * 1.5)-(w / 10 * 3.5, h / 10 * 1.75), col, BF '1ST ACROSS
  233.         LINE (w / 10 * 2.75, h / 10 * 1.5)-(w / 10 * 3, h / 10 * 2.5), col, BF '1ST DOWN
  234.         LINE (w / 10 * 2.75, h / 10 * 2.5)-(w / 10 * 3.45, h / 10 * 2.75), col, BF '2ND ACROSS
  235.         LINE (w / 10 * 3.2, h / 10 * 2.75)-(w / 10 * 3.45, h / 10 * 2.9), col, BF '2ND DOWN
  236.         LINE (w / 10 * 3.2, h / 10 * 3.35)-(w / 10 * 3.45, h / 10 * 3.75), col, BF 'EXTENDED 2ND DOWN
  237.         LINE (w / 10 * 2.65, h / 10 * 3.75)-(w / 10 * 3.45, h / 10 * 4.1), col, BF '3RD ACROSS
  238.  
  239.         'L
  240.         LINE (w / 10 * 3.8, h / 10 * 1.5)-(w / 10 * 4.05, h / 10 * 2.65), col, BF '1ST DOWN
  241.         LINE (w / 10 * 3.8, h / 10 * 3.6)-(w / 10 * 4.05, h / 10 * 3.75), col, BF 'EXTENDED 1ST DOWN
  242.         LINE (w / 10 * 3.8, h / 10 * 3.75)-(w / 10 * 4.6, h / 10 * 4.1), col, BF '1ST ACROSS
  243.  
  244.         'A
  245.         LINE (w / 10 * 4.85, h / 10 * 1.5)-(w / 10 * 5.1, h / 10 * 2.7), col, BF 'LEFT DOWN
  246.         LINE (w / 10 * 4.85, h / 10 * 1.5)-(w / 10 * 5.75, h / 10 * 1.8), col, BF 'TOP LINE
  247.         LINE (w / 10 * 5.5, h / 10 * 1.5)-(w / 10 * 5.75, h / 10 * 2.7), col, BF 'RIGHT DOWN
  248.         LINE (w / 10 * 5.55, h / 10 * 1.5)-(w / 10 * 5.75, h / 10 * 2.9), col, BF 'RIGHT DOWN EDGE
  249.         LINE (w / 10 * 4.85, h / 10 * 2.4)-(w / 10 * 5.75, h / 10 * 2.65), col, BF 'MIDDLE LINE
  250.         LINE (w / 10 * 4.85, h / 10 * 3.5)-(w / 10 * 5.1, h / 10 * 4.1), col, BF 'EXTENDED LEFT DOWN
  251.         LINE (w / 10 * 5.5, h / 10 * 3.5)-(w / 10 * 5.75, h / 10 * 4.1), col, BF 'EXTENDED RIGHT DOWN
  252.         LINE (w / 10 * 5.55, h / 10 * 3.35)-(w / 10 * 5.75, h / 10 * 4.1), col, BF 'EXTENDED RIGHT DOWN EDGE
  253.  
  254.         'Y
  255.         LINE (w / 10 * 6, h / 10 * 1.5)-(w / 10 * 6.25, h / 10 * 2.75), col, BF 'LEFT DOWN
  256.         LINE (w / 10 * 6.75, h / 10 * 1.5)-(w / 10 * 7, h / 10 * 3), col, BF 'RIGHT DOWN
  257.         LINE (w / 10 * 6, h / 10 * 2.5)-(w / 10 * 7, h / 10 * 2.85), col, BF '1ST ACROSS
  258.         LINE (w / 10 * 6.75, h / 10 * 3.25)-(w / 10 * 7, h / 10 * 4.1), col, BF 'EXTENDED RIGHT DOWN
  259.         LINE (w / 10 * 6, h / 10 * 3.8)-(w / 10 * 7, h / 10 * 4.1), col, BF 'BOTTOM LINE
  260.  
  261.         'SWORD
  262.         LINE (w / 10 * 3, h / 10 * 3)-(w / 10 * 6.5, h / 10 * 3.25), col, BF 'HILT
  263.         LINE (w / 10 * 3.5, h / 10 * 2.5)-(w / 10 * 3.75, h / 10 * 3.75), col, BF 'Hand Guard
  264.         LINE (w / 10 * 3.75, h / 10 * 2.75)-(w / 10 * 4.75, h / 10 * 3.50), col, BF 'Blade First Layer
  265.         LINE (w / 10 * 4.75, h / 10 * 2.85)-(w / 10 * 5.5, h / 10 * 3.4), col, BF 'Blade 2nd Layer
  266.         LINE (w / 10 * 5.5, h / 10 * 3.10)-(w / 10 * 7, h / 10 * 3.15), col, BF 'Tip of Blade
  267.  
  268.         col = _RGB(n, n, n)
  269.     NEXT n
  270.  
  271.     col = _RGB(0, 0, 0)
  272.     LINE (w / 10, h / 10 * 4.5)-(w, h / 10 * 7), col, BF 'CLEAR OPTIONS
  273.  
  274.     'SHOW ACCOUNT
  275.     _PRINTSTRING (5, 5), player.name
  276.  
  277.     'PRINT MENU OPTIONS
  278.     scaledText w / 2, h / 10 * 4.75, 25, _RGBA(255, 255, 255, 255), "SINGLE-PLAYER"
  279.     scaledText w / 2, h / 10 * 5.25, 25, _RGBA(255, 255, 255, 255), "MULTI-PLAYER"
  280.     scaledText w / 2, h / 10 * 5.75, 25, _RGBA(255, 255, 255, 255), "OPTIONS"
  281.     scaledText w / 2, h / 10 * 6.25, 25, _RGBA(255, 255, 255, 255), "QUIT"
  282.     scaledText w / 2, h / 10 * 9.5, 14, _RGBA(255, 255, 255, 255), "TIP: USE 'w' AND 's' TO NAVIGATE. PRESS 'ENTER' TO SELCT"
  283.  
  284.     'PICK MENU OPTION
  285.     opt = 0
  286.     col = _RGB(0, 0, 0)
  287.     DO
  288.         LINE (w / 2 - 90, h / 10 * 4.5)-(w / 2 - 110, h / 10 * 7), col, BF 'CLEAR PAST POINTERS
  289.         _PRINTSTRING (w / 2 - 100, h / 10 * (4.6 + (0.52 * opt))), ">" 'DISPLAY POINTER
  290.         _DISPLAY 'REDUCE FLICKERING
  291.  
  292.         SELECT CASE INKEY$
  293.             CASE "s" 'MOVE POINTER DOWN
  294.                 IF opt + 1 = 4 THEN
  295.                     opt = 0
  296.                 ELSE
  297.                     opt = opt + 1
  298.                 END IF
  299.  
  300.             CASE "w" 'MOVE POINTER UP
  301.                 IF opt - 1 = -1 THEN
  302.                     opt = 3
  303.                 ELSE
  304.                     opt = opt - 1
  305.                 END IF
  306.  
  307.             CASE CHR$(13) 'ENTER KEY
  308.                 'SINGLE-PLAYER SELECTED
  309.                 IF opt = 0 THEN
  310.                     SinglePlayerMenu
  311.                 END IF
  312.  
  313.                 'MULTI-PLAYER SELECTED
  314.                 IF opt = 1 THEN
  315.                     MultiplayerGameMenu
  316.                 END IF
  317.  
  318.                 'OPTIONS SELETED
  319.                 IF opt = 2 THEN
  320.                     OptionsMenu
  321.                 END IF
  322.  
  323.                 'QUIT SELECTED
  324.                 IF opt = 3 THEN
  325.                     SYSTEM
  326.                 END IF
  327.         END SELECT
  328.     LOOP
  329.  
  330.  
  331. SUB OptionsMenu
  332.     LINE (w / 10, h / 10 * 4.5)-(w, h / 10 * 7), col, BF 'CLEAR OPTIONS
  333.     scaledText w / 2, h / 10 * 4.75, 25, _RGBA(255, 255, 255, 255), "INFO"
  334.     scaledText w / 2, h / 10 * 5.25, 25, _RGBA(255, 255, 255, 255), "RESET GAME"
  335.     scaledText w / 2, h / 10 * 5.75, 25, _RGBA(255, 255, 255, 255), "BACK"
  336.     scaledText w / 2, h / 10 * 9.5, 14, _RGBA(255, 255, 255, 255), "TIP: USE 'w' AND 's' TO NAVIGATE. PRESS 'ENTER' TO SELCT"
  337.  
  338.     opt = 0
  339.     DO
  340.         LINE (w / 2 - 90, h / 10 * 4.5)-(w / 2 - 110, h / 10 * 7), col, BF 'CLEAR PAST POINTERS
  341.         _PRINTSTRING (w / 2 - 100, h / 10 * (4.6 + (0.52 * opt))), ">" 'DISPLAY POINTER
  342.  
  343.         _DISPLAY 'REDUCE FLICKERING
  344.  
  345.         SELECT CASE INKEY$
  346.             CASE "s" 'MOVE POINTER DOWN
  347.                 IF opt + 1 = 3 THEN
  348.                     opt = 0
  349.                 ELSE
  350.                     opt = opt + 1
  351.                 END IF
  352.  
  353.             CASE "w" 'MOVE POINTER UP
  354.                 IF opt - 1 = -1 THEN
  355.                     opt = 2
  356.                 ELSE
  357.                     opt = opt - 1
  358.                 END IF
  359.             CASE CHR$(13) 'ENTER PRESSED
  360.                 IF opt = 0 THEN 'GAME INFO
  361.                     LINE (0, h / 10 * 4.7)-(w, h), col, BF 'CLEAR OPTIONS
  362.                     scaledText w / 2, h / 10 * 4.75, 25, _RGBA(255, 255, 255, 255), "ZEPPELIN GAMES 2018"
  363.                     scaledText w / 2, h / 10 * 5.25, 25, _RGBA(255, 255, 255, 255), "SLAY V4"
  364.                     scaledText w / 2, h / 10 * 6.25, 25, _RGBA(255, 255, 255, 255), "ENEMIES KILLED: " + STR$(stats.enemyskilled)
  365.                     scaledText w / 2, h / 10 * 6.75, 25, _RGBA(255, 255, 255, 255), "TOTAL DEATHS: " + STR$(stats.totaldeaths)
  366.                     scaledText w / 2, h / 10 * 9.25, 14, _RGBA(255, 255, 255, 255), "PRESS ANY KEY TO CONTINUE"
  367.  
  368.                     _DISPLAY
  369.                     DO WHILE INKEY$ = ""
  370.                     LOOP
  371.                     LINE (0, h / 10 * 4.7)-(w, h), col, BF 'CLEAR OPTIONS
  372.                     OptionsMenu
  373.                 END IF
  374.                 IF opt = 1 THEN 'RESET GAME
  375.                     OPEN "SlayV4SaveData.txt" FOR OUTPUT AS #1
  376.                     PRINT #1, ""
  377.                     CLOSE #1
  378.                     CLS
  379.                     RUN "SLAY V4.exe"
  380.                 END IF
  381.                 IF opt = 2 THEN 'BACK
  382.                     DrawMenu
  383.                 END IF
  384.         END SELECT
  385.     LOOP
  386.  
  387. SUB SinglePlayerMenu
  388.     LINE (w / 10, h / 10 * 4.5)-(w, h / 10 * 7), col, BF 'CLEAR OPTIONS
  389.     scaledText w / 2, h / 10 * 4.75, 25, _RGBA(255, 255, 255, 255), "CAMPAIGN"
  390.     scaledText w / 2, h / 10 * 5.25, 25, _RGBA(255, 255, 255, 255), "INFINITE"
  391.     scaledText w / 2, h / 10 * 5.75, 25, _RGBA(255, 255, 255, 255), "BACK"
  392.     scaledText w / 2, h / 10 * 9.5, 14, _RGBA(255, 255, 255, 255), "TIP: USE 'w' AND 's' TO NAVIGATE. PRESS 'ENTER' TO SELCT"
  393.  
  394.     opt = 0
  395.     DO
  396.         LINE (w / 2 - 90, h / 10 * 4.5)-(w / 2 - 110, h / 10 * 7), col, BF 'CLEAR PAST POINTERS
  397.         _PRINTSTRING (w / 2 - 100, h / 10 * (4.6 + (0.52 * opt))), ">" 'DISPLAY POINTER
  398.  
  399.         _DISPLAY 'REDUCE FLICKERING
  400.  
  401.         SELECT CASE INKEY$
  402.             CASE "s" 'MOVE POINTER DOWN
  403.                 IF opt + 1 = 3 THEN
  404.                     opt = 0
  405.                 ELSE
  406.                     opt = opt + 1
  407.                 END IF
  408.  
  409.             CASE "w" 'MOVE POINTER UP
  410.                 IF opt - 1 = -1 THEN
  411.                     opt = 2
  412.                 ELSE
  413.                     opt = opt - 1
  414.                 END IF
  415.             CASE CHR$(13) 'ENTER PRESSED
  416.                 IF opt = 0 THEN
  417.                     Campaign
  418.                 END IF
  419.                 IF opt = 1 THEN
  420.                     Infinite
  421.                 END IF
  422.                 IF opt = 2 THEN
  423.                     DrawMenu
  424.                 END IF
  425.         END SELECT
  426.     LOOP
  427.  
  428. 'CAMPAIGN - STORY
  429. SUB Campaign
  430.  
  431.  
  432. 'PRACTICE - GAMEMODE
  433. SUB Infinite
  434.     CLS
  435.     'DEFINE LOCAL VARS
  436.  
  437.     DIM health
  438.     DIM deltaTime
  439.  
  440.     playerSpeed = 500
  441.     health = 100
  442.     pX = _WIDTH / 2 - (playerScale * 2.5)
  443.     pY = _HEIGHT / 10 * 8
  444.  
  445.     sTime = TIMER(.001) 'NEW NEW NEW ####################################
  446.  
  447.     DO
  448.         sTime = TIMER(.001) 'NEW NEW NEW ####################################
  449.  
  450.         IF _KEYDOWN(100) = -1 THEN
  451.             pX = pX + (deltaTime * playerSpeed)
  452.         END IF
  453.         IF _KEYDOWN(97) = -1 THEN
  454.             pX = pX - (deltaTime * playerSpeed)
  455.         END IF
  456.  
  457.         IF pX < 1 THEN
  458.             pX = 1
  459.         END IF
  460.         IF pX > _WIDTH - playerScale * 5 - 1 THEN
  461.             pX = _WIDTH - playerScale * 5 - 1
  462.         END IF
  463.  
  464.         LINE (pX - (playerScale * 5) - 1, pY - (playerScale * 5) - 1)-(pX + ((playerScale * 5) * 2), pY + (playerScale * 5) + 1), _RGB(0, 0, 0), BF
  465.         PUT (pX, pY), player%()
  466.         _DISPLAY
  467.  
  468.  
  469.         eTime = TIMER(.001) 'NEW NEW NEW ####################################
  470.         deltaTime = eTime - sTime
  471.     LOOP UNTIL health <= 0 OR INKEY$ = CHR$(27)
  472.     CLS
  473.     SaveGame
  474.     DrawMenu
  475.  
  476. 'MULTIPLAYER GAME MENU
  477. SUB MultiplayerGameMenu
  478.     LINE (w / 10, h / 10 * 4.7)-(w, h / 10 * 7), col, BF 'CLEAR OPTIONS
  479.     _PRINTSTRING (w / 2 - 40, h / 10 * 4.75), "LOCAL"
  480.     _PRINTSTRING (w / 2 - 34, h / 10 * 5.25), "LAN"
  481.     _PRINTSTRING (w / 2 - 37, h / 10 * 5.75), "BACK"
  482.  
  483.     opt = 0
  484.     DO
  485.         LINE (w / 2 - 58, h / 10 * 4.7)-(w / 2 - 70, h / 10 * 7), col, BF 'CLEAR PAST POINTERS
  486.         _PRINTSTRING (w / 2 - 65, h / 10 * (4.75 + (0.5 * opt))), ">" 'DISPLAY POINTER
  487.  
  488.         _DISPLAY 'REDUCE FLICKERING
  489.  
  490.         SELECT CASE INKEY$
  491.             CASE "s" 'MOVE POINTER DOWN
  492.                 IF opt + 1 = 3 THEN
  493.                     opt = 0
  494.                 ELSE
  495.                     opt = opt + 1
  496.                 END IF
  497.  
  498.             CASE "w" 'MOVE POINTER UP
  499.                 IF opt - 1 = -1 THEN
  500.                     opt = 2
  501.                 ELSE
  502.                     opt = opt - 1
  503.                 END IF
  504.             CASE CHR$(13) 'ENTER KEY
  505.                 IF opt = 0 THEN
  506.                     LocalMultiplayer
  507.                 ELSEIF opt = 1 THEN
  508.                     LANMultiplayer
  509.                 ELSEIF opt = 2 THEN
  510.                     DrawMenu
  511.                 END IF
  512.         END SELECT
  513.     LOOP UNTIL INKEY$ = CHR$(13)
  514.  
  515.  
  516. 'MULTIPLAYER ON SAME DEVICE
  517. SUB LocalMultiplayer
  518.  
  519.  
  520. 'MULTIPLAYER OVER WIFI CONNECTION
  521. SUB LANMultiplayer
  522.  
  523.  
  524.  
  525. SUB SaveGame
  526.     'SAVE VARS TO TXT
  527.     OPEN "SlayV4SaveData.txt" FOR OUTPUT AS #1
  528.     'PLAYER
  529.     PRINT #1, name$
  530.     PRINT #1, player.health
  531.     'SAVE DATA
  532.     PRINT #1, save.point
  533.     'STATS
  534.     PRINT #1, stats.enemyskilled
  535.     PRINT #1, stats.totaldeaths
  536.     CLOSE #1
  537.  
  538. SUB LoadSprite (sp%(), scale)
  539.     DIM sprite(4, 4)
  540.     FOR y = 0 TO 4
  541.         FOR x = 0 TO 4
  542.             READ sprite(x, y) 'Read the data
  543.         NEXT x
  544.     NEXT y
  545.  
  546.     FOR y = 0 TO 4 * scale STEP scale 'Factor in the scale
  547.         FOR x = 0 TO 4 * scale STEP scale
  548.             spriteCol = sprite(x / scale, y / scale)
  549.             LINE (x, y)-(x + scale, y + scale), _RGB(spriteCol * 255, spriteCol * 255, spriteCol * 255), BF 'Draw each pixel
  550.         NEXT x
  551.     NEXT y
  552.  
  553.     GET (0, 0)-(scale * 5, scale * 5), sp%()
  554.     CLS
  555.  
  556.     'Player Data
  557.     DATA 0,1,1,1,0
  558.     DATA 0,1,1,1,0
  559.     DATA 1,1,1,1,1
  560.     DATA 0,1,1,1,0
  561.     DATA 0,1,0,1,0
  562.  
  563.  
  564. SUB scaledText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  565.     fg = _DEFAULTCOLOR
  566.     'screen snapshot
  567.     cur& = _DEST
  568.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 256)
  569.     _DEST I&
  570.     COLOR K, _RGBA(0, 0, 0, 0)
  571.     _PRINTSTRING (0, 0), txt$
  572.     mult = textHeight / 16
  573.     xlen = LEN(txt$) * 8 * mult
  574.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  575.     COLOR fg
  576.     _FREEIMAGE I&
  577.  

(all changes marked with  'NEW NEW NEW ####################################) :D

EDIT: some other were faster, sorry
« Last Edit: November 05, 2019, 06:03:46 pm by MrFreyer »