QB64.org Forum

Active Forums => Programs => Topic started by: FellippeHeitor on October 18, 2020, 11:43:54 am

Title: Pretentious not-yet-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 18, 2020, 11:43:54 am
Watch as I talk about Among Us while writing something that vaguely resembles a player moving around a map.



Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 800, 32)
  2.  
  3. TYPE object
  4.     x AS SINGLE
  5.     y AS SINGLE
  6.  
  7. DIM SHARED player AS object
  8. DIM SHARED camera AS object
  9. DIM playerSpeed AS SINGLE
  10.  
  11. map = _NEWIMAGE(_WIDTH * 3, _HEIGHT * 2, 32)
  12. _DEST map
  13. FOR i = 1 TO 50
  14.     CircleFill _WIDTH * RND, _HEIGHT * RND, 1000 * RND, _RGB32(255 * RND, 255 * RND, 255 * RND, 255 * RND)
  15.  
  16. player.x = _WIDTH / 2
  17. player.y = _HEIGHT / 2
  18.  
  19. playerSpeed = 5
  20.  
  21. CONST keyUP = 18432
  22. CONST keyDOWN = 20480
  23. CONST keyLEFT = 19200
  24. CONST keyRIGHT = 19712
  25.  
  26.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  27.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  28.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  29.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  30.  
  31.     IF player.x < 0 THEN player.x = 0
  32.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  33.     IF player.y < 0 THEN player.y = 0
  34.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  35.  
  36.     adjustCamera
  37.     CLS
  38.     _PUTIMAGE (camera.x, camera.y), map
  39.  
  40.     CircleFill player.x + camera.x, player.y + camera.y, 20, _RGB32(255)
  41.     _DISPLAY
  42.     _LIMIT 60
  43.  
  44. SUB adjustCamera
  45.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  46.         camera.x = _WIDTH / 2 - player.x
  47.     END IF
  48.     IF camera.x > 0 THEN camera.x = 0
  49.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  50.  
  51.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  52.         camera.y = _HEIGHT / 2 - player.y
  53.     END IF
  54.     IF camera.y > 0 THEN camera.y = 0
  55.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  56.  
  57. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  58.     ' CX = center x coordinate
  59.     ' CY = center y coordinate
  60.     '  R = radius
  61.     '  C = fill color
  62.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  63.     DIM X AS INTEGER, Y AS INTEGER
  64.     Radius = ABS(R)
  65.     RadiusError = -Radius
  66.     X = Radius
  67.     Y = 0
  68.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  69.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  70.     WHILE X > Y
  71.         RadiusError = RadiusError + Y * 2 + 1
  72.         IF RadiusError >= 0 THEN
  73.             IF X <> Y + 1 THEN
  74.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  75.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  76.             END IF
  77.             X = X - 1
  78.             RadiusError = RadiusError - X * 2
  79.         END IF
  80.         Y = Y + 1
  81.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  82.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  83.     WEND
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Dav on October 18, 2020, 04:03:50 pm
Lol.  Thanks for leaving in the blooper.  I needed a laugh.. 

- Dav
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: bplus on October 18, 2020, 04:43:59 pm
Wow just add image of a map and player is walking around map, nice!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 19, 2020, 04:29:25 pm
@Dav glad it was entertaining!

@bplus the illusion is the key, thanks for checking it out!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 20, 2020, 12:53:07 pm
Run this and choose "Connect to server" - arbitrarily limited to 10 simultaneous "players" for now.

It's the map+player code of the first post, with networking added. Still not a game, but you can see other players in real time, which is cool.

If you have trouble connecting to 98.29.249.134 (kindly hosted by SpriggsySprigs in the US), replace that on line 97 with alephc.xyz (kindly hosted by Luke in Australia).

Code: QB64: [Select]
  1.  
  2. $LET DEBUGGING = FALSE
  3. $IF DEBUGGING = TRUE THEN
  4.     $CONSOLE
  5.  
  6. CONST True = -1, False = 0
  7. CONST mode_freeplay = 0
  8. CONST mode_localhost = 1
  9. CONST mode_localclient = 2
  10. CONST mode_onlinehost = 3
  11. CONST mode_onlineclient = 4
  12.  
  13. TYPE object
  14.     name AS STRING
  15.     handle AS LONG
  16.     x AS SINGLE
  17.     y AS SINGLE
  18.     state AS INTEGER
  19.     basicInfoSent AS _BYTE
  20.     ping AS SINGLE
  21.  
  22. DIM SHARED totalClients AS INTEGER
  23. DIM SHARED playerStream(1 TO 10) AS STRING
  24. DIM SHARED serverStream AS STRING
  25. DIM SHARED player(1 TO 10) AS object, me AS INTEGER
  26. DIM SHARED warning(1 TO 30) AS object
  27. DIM idSet AS _BYTE
  28. DIM newClient AS LONG
  29. DIM serverPing AS SINGLE
  30. DIM key$, value$
  31.  
  32. DIM SHARED endSignal AS STRING
  33. endSignal = "<" + CHR$(254) + ">"
  34.  
  35. vgaPalette:
  36. DATA 0,0,170
  37. DATA 0,170,0
  38. DATA 0,170,170
  39. DATA 170,0,0
  40. DATA 170,0,170
  41. DATA 170,85,0
  42. DATA 170,170,170
  43. DATA 85,85,85
  44. DATA 85,85,255
  45. DATA 85,255,85
  46. DATA 85,255,255
  47. DATA 255,85,85
  48. DATA 255,85,255
  49. DATA 255,255,85
  50. DATA 255,255,255
  51.  
  52. RESTORE vgaPalette
  53. FOR i = 1 TO 15
  54.     READ r%, g%, b%
  55.     colors(i) = _RGB32(r%, g%, b%)
  56.  
  57. CONST timeout = 30
  58. DIM userName$, userColor%
  59. INPUT "Name: ", userName$
  60.     INPUT "Color (1-15): ", userColor%
  61. LOOP WHILE userColor% < 1 OR userColor% > 15
  62.  
  63.     COLOR 15
  64.     PRINT "-------------------------"
  65.     PRINT "(1) Free play"
  66.     PRINT "(2) Connect to server"
  67.  
  68.     DIM choice AS STRING
  69.     DO
  70.         choice = INKEY$
  71.         _LIMIT 30
  72.     LOOP UNTIL choice >= "1" AND choice <= "5"
  73.  
  74.     DIM SHARED server AS object, host AS LONG
  75.     DIM c AS INTEGER, attempt AS INTEGER
  76.     CONST maxAttempts = 100
  77.     SELECT CASE VAL(choice)
  78.         CASE 1
  79.             EXIT DO
  80.         CASE 2
  81.             COLOR 7
  82.             PRINT "Attempting to connect to local host... ";
  83.             r = CSRLIN: c = POS(1)
  84.             attempt = 0
  85.             DO
  86.                 server.handle = 0
  87.                 server.handle = _OPENCLIENT("TCP/IP:51512:98.29.249.134")
  88.                 IF server.handle THEN EXIT DO
  89.                 attempt = attempt + 1
  90.                 LOCATE r, c: PRINT USING "###%"; (attempt / maxAttempts) * 100;
  91.                 _LIMIT 30
  92.             LOOP WHILE attempt < 100
  93.             IF server.handle THEN serverPing = TIMER: mode = mode_localclient: EXIT DO
  94.             PRINT: COLOR 14: PRINT "/\ ";: COLOR 12
  95.             PRINT "Failed to connect to local host."
  96.             CLOSE server.handle
  97.     END SELECT
  98.  
  99. SCREEN _NEWIMAGE(800, 600, 32)
  100.  
  101. DIM SHARED playerSpeed AS SINGLE
  102. DIM SHARED camera AS object
  103.  
  104. map = _NEWIMAGE(_WIDTH * 3, _HEIGHT * 2, 32)
  105. _DEST map
  106. FOR i = 1 TO 50
  107.     CircleFill RND * _WIDTH, RND * _HEIGHT, RND * 1000, _RGB32(RND * 255, RND * 255, RND * 255, RND * 150)
  108.  
  109. CONST keyUP = 18432
  110. CONST keyDOWN = 20480
  111. CONST keyLEFT = 19200
  112. CONST keyRIGHT = 19712
  113. CONST keyLSHIFT = 100304
  114. CONST keyRSHIFT = 100303
  115.  
  116. CONST cameraWindow = 100
  117.  
  118. CONST minSpeed = 3
  119. CONST maxSpeed = 5
  120.  
  121. playerSpeed = maxSpeed
  122.  
  123. IF mode > 1 THEN
  124.     idSet = False
  125.     idSet = True
  126.     me = 1
  127.     player(me).name = userName$
  128.     player(me).x = _WIDTH / 2 + COS(RND * _PI) * (RND * 100)
  129.     player(me).y = _HEIGHT / 2 + SIN(RND * _PI) * (RND * 100)
  130.     player(me).state = True
  131.     player(me).color = userColor%
  132.     SELECT CASE mode
  133.         CASE mode_localhost
  134.             'check for new connections (unless already at max)
  135.             IF idSet = False THEN
  136.                 idSet = True
  137.                 me = 1
  138.                 player(me).name = userName$
  139.                 player(me).x = _WIDTH / 2 + COS(RND * _PI) * (RND * 100)
  140.                 player(me).y = _HEIGHT / 2 + SIN(RND * _PI) * (RND * 100)
  141.                 player(me).state = True
  142.                 player(me).color = userColor%
  143.             END IF
  144.  
  145.             IF totalClients < UBOUND(player) THEN
  146.                 newClient = 0
  147.                 newClient = _OPENCONNECTION(host)
  148.                 IF newClient THEN
  149.                     totalClients = totalClients + 1
  150.                     FOR i = 1 TO UBOUND(player)
  151.                         IF player(i).state = False THEN
  152.                             player(i).color = 0
  153.                             player(i).handle = newClient
  154.                             player(i).state = True
  155.                             sendData player(i), "ID", MKI$(i)
  156.                             player(i).ping = TIMER
  157.                             EXIT FOR
  158.                         END IF
  159.                     NEXT
  160.                 END IF
  161.             END IF
  162.  
  163.             FOR i = 1 TO UBOUND(player)
  164.                 IF player(i).state = False OR i = me THEN _CONTINUE
  165.                 IF TIMER - player(i).ping > timeout THEN
  166.                     'player inactive
  167.                     player(i).state = False
  168.                     CLOSE player(i).handle
  169.                     addWarning player(i).name + " lost connection."
  170.                     totalClients = totalClients - 1
  171.                     _CONTINUE
  172.                 END IF
  173.  
  174.                 getData player(i), playerStream(i)
  175.  
  176.                 DO WHILE parse(playerStream(i), key$, value$)
  177.                     player(i).ping = TIMER
  178.                     SELECT CASE key$
  179.                         CASE "NAME"
  180.                             player(i).name = value$
  181.                         CASE "COLOR" 'received once per player
  182.                             DIM newcolor AS INTEGER, changed AS _BYTE
  183.                             newcolor = CVI(value$)
  184.                             changed = False
  185.                             'check if this color is already in use, so a random one can be assigned
  186.                             FOR j = 1 TO UBOUND(player)
  187.                                 IF player(j).state = True AND player(j).color = newcolor THEN
  188.                                     newcolor = newcolor + 1
  189.                                     IF newcolor > UBOUND(colors) THEN newcolor = 1
  190.                                     changed = True
  191.                                     j = 0 'check again
  192.                                 END IF
  193.                             NEXT
  194.                             player(i).color = newcolor
  195.                             IF changed THEN
  196.                                 sendData player(i), "COLOR", MKI$(newcolor)
  197.                             END IF
  198.                         CASE "POS"
  199.                             player(i).x = CVI(LEFT$(value$, 2))
  200.                             player(i).y = CVI(RIGHT$(value$, 2))
  201.                     END SELECT
  202.                 LOOP
  203.  
  204.                 'send ping
  205.                 sendData player(i), "PING", ""
  206.  
  207.                 'send all players' data
  208.                 FOR j = 1 TO UBOUND(player)
  209.                     IF j = i THEN _CONTINUE
  210.                     IF player(j).state = True THEN
  211.                         sendData player(i), "PLAYERCOLOR", MKI$(j) + MKI$(player(j).color)
  212.                         sendData player(i), "PLAYERPOS", MKI$(j) + MKS$(player(j).x) + MKS$(player(j).y)
  213.                         sendData player(i), "PLAYERNAME", MKI$(j) + player(j).name
  214.                     ELSE
  215.                         sendData player(i), "PLAYEROFFLINE", MKI$(j)
  216.                     END IF
  217.                 NEXT
  218.             NEXT
  219.  
  220.         CASE mode_localclient, mode_onlineclient
  221.             IF idSet THEN
  222.                 IF player(me).basicInfoSent = False THEN
  223.                     player(me).basicInfoSent = True
  224.                     sendData server, "COLOR", MKI$(player(me).color)
  225.                     sendData server, "NAME", player(me).name
  226.                 END IF
  227.  
  228.                 sendData server, "POS", MKI$(player(me).x) + MKI$(player(me).y)
  229.             END IF
  230.  
  231.             getData server, serverStream
  232.             DO WHILE parse(serverStream, key$, value$)
  233.                 SELECT CASE key$
  234.                     CASE "ID" 'first info sent by server
  235.                         idSet = True
  236.                         me = CVI(value$)
  237.                         player(me).name = userName$
  238.                         player(me).x = _WIDTH / 2 + COS(RND * _PI) * (RND * 100)
  239.                         player(me).y = _HEIGHT / 2 + SIN(RND * _PI) * (RND * 100)
  240.                         player(me).state = True
  241.                         player(me).color = userColor%
  242.                     CASE "COLOR" 'server color changes must always be applied
  243.                         player(me).color = CVI(value$)
  244.                     CASE "PLAYERCOLOR"
  245.                         player(CVI(LEFT$(value$, 2))).color = CVI(RIGHT$(value$, 2))
  246.                     CASE "PLAYERPOS"
  247.                         player(CVI(LEFT$(value$, 2))).state = True
  248.                         player(CVI(LEFT$(value$, 2))).ping = TIMER
  249.                         player(CVI(LEFT$(value$, 2))).x = CVS(MID$(value$, 3, 4))
  250.                         player(CVI(LEFT$(value$, 2))).y = CVS(RIGHT$(value$, 4))
  251.                     CASE "PLAYERNAME"
  252.                         player(CVI(LEFT$(value$, 2))).name = MID$(value$, 3)
  253.                     CASE "PLAYEROFFLINE"
  254.                         IF player(CVI(value$)).state = True THEN
  255.                             player(CVI(value$)).state = False
  256.                             addWarning player(CVI(value$)).name + " left the game."
  257.                         END IF
  258.                     CASE "PING"
  259.                         serverPing = TIMER
  260.                 END SELECT
  261.             LOOP
  262.     END SELECT
  263.  
  264.     IF playerSpeed < minSpeed THEN playerSpeed = minSpeed
  265.     IF playerSpeed > maxSpeed THEN playerSpeed = maxSpeed
  266.  
  267.     IF idSet THEN
  268.         IF _KEYDOWN(keyUP) THEN player(me).y = player(me).y - playerSpeed
  269.         IF _KEYDOWN(keyDOWN) THEN player(me).y = player(me).y + playerSpeed
  270.         IF _KEYDOWN(keyLEFT) THEN player(me).x = player(me).x - playerSpeed
  271.         IF _KEYDOWN(keyRIGHT) THEN player(me).x = player(me).x + playerSpeed
  272.  
  273.         IF player(me).x < 0 THEN player(me).x = 0
  274.         IF player(me).y < 0 THEN player(me).y = 0
  275.         IF player(me).x > _WIDTH(map) THEN player(me).x = _WIDTH(map)
  276.         IF player(me).y > _HEIGHT(map) THEN player(me).y = _HEIGHT(map)
  277.  
  278.         adjustCamera
  279.     END IF
  280.  
  281.     CLS
  282.  
  283.     DIM shipFlotation AS SINGLE, shipFloatIntensity AS SINGLE
  284.     shipFlotation = shipFlotation + .05
  285.     IF shipFlotation > _PI(2) THEN shipFlotation = shipFlotation - _PI(2)
  286.     shipFloatIntensity = 1.5
  287.  
  288.     _PUTIMAGE (camera.x + COS(shipFlotation) * shipFloatIntensity, camera.y + SIN(shipFlotation) * shipFloatIntensity), map
  289.     _BLEND
  290.  
  291.     IF (mode = mode_localclient OR mode = mode_onlineclient) THEN
  292.         IF TIMER - serverPing > timeout THEN
  293.             SCREEN 0
  294.             PRINT: COLOR 14: PRINT "/\ ";: COLOR 12
  295.             PRINT "Disconnected from host."
  296.             END
  297.         ELSE
  298.             PRINT USING "###ms"; ((TIMER - serverPing) - FIX(TIMER - serverPing)) * 1000;
  299.         END IF
  300.     END IF
  301.  
  302.     DIM x AS SINGLE, y AS SINGLE
  303.     FOR i = 1 TO UBOUND(player)
  304.         IF player(i).state = False OR player(i).color = 0 THEN _CONTINUE
  305.         x = player(i).x + camera.x + COS(shipFlotation) * shipFloatIntensity
  306.         y = player(i).y + camera.y + SIN(shipFlotation) * shipFloatIntensity
  307.         CircleFill x, y + 6, 15, _RGB32(0, 50)
  308.         CircleFill x, y, 15, _RGB32(0)
  309.         CircleFill x, y, 10, colors(player(i).color)
  310.         COLOR _RGB32(0)
  311.         _PRINTSTRING (1 + x - _PRINTWIDTH(player(i).name) / 2, 1 + y - 20), player(i).name
  312.         COLOR _RGB32(255)
  313.         _PRINTSTRING (x - _PRINTWIDTH(player(i).name) / 2, y - 20), player(i).name
  314.     NEXT
  315.     'LINE (_WIDTH / 2 - cameraWindow, _HEIGHT / 2 - cameraWindow)-STEP(cameraWindow * 2, cameraWindow * 2), , B
  316.  
  317.     'display warnings
  318.     FOR i = 1 TO UBOUND(warning)
  319.         COLOR _RGB32(128, 50, 22)
  320.         IF warning(i).state = True THEN
  321.             _PRINTSTRING (10, _HEIGHT / 2 + _FONTHEIGHT * i), warning(i).name
  322.             IF TIMER - warning(i).ping > 2 THEN warning(i).state = False
  323.         END IF
  324.     NEXT
  325.  
  326.     _DISPLAY
  327.     _LIMIT 60
  328.  
  329. SUB addWarning (text$)
  330.     DIM i AS INTEGER
  331.     FOR i = 1 TO UBOUND(warning)
  332.         IF warning(i).state = False THEN
  333.             warning(i).state = True
  334.             warning(i).name = text$
  335.             warning(i).ping = TIMER
  336.             EXIT FOR
  337.         END IF
  338.     NEXT
  339.  
  340. SUB sendData (client AS object, id$, value$)
  341.     DIM key$
  342.     key$ = id$ + ">" + value$ + endSignal
  343.     PUT #client.handle, , key$
  344.  
  345. SUB getData (client AS object, buffer AS STRING)
  346.     DIM incoming$
  347.     GET #client.handle, , incoming$
  348.     buffer = buffer + incoming$
  349.  
  350. FUNCTION parse%% (buffer AS STRING, key$, value$)
  351.     DIM endMarker AS LONG
  352.     endMarker = INSTR(buffer, endSignal)
  353.     IF endMarker THEN
  354.         key$ = LEFT$(buffer, endMarker - 1)
  355.         buffer = MID$(buffer, endMarker + LEN(endSignal))
  356.         endMarker = INSTR(key$, ">")
  357.         value$ = MID$(key$, endMarker + 1)
  358.         key$ = LEFT$(key$, endMarker - 1)
  359.         parse%% = True
  360.     END IF
  361.  
  362. SUB adjustCamera
  363.     IF player(me).x + camera.x > _WIDTH / 2 + cameraWindow THEN
  364.         camera.x = _WIDTH / 2 - player(me).x + cameraWindow
  365.     ELSEIF player(me).x + camera.x < _WIDTH / 2 - cameraWindow THEN
  366.         camera.x = _WIDTH / 2 - player(me).x - cameraWindow
  367.     END IF
  368.     IF camera.x > 0 THEN camera.x = 0
  369.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  370.  
  371.     IF player(me).y + camera.y > _HEIGHT / 2 + cameraWindow THEN
  372.         camera.y = _HEIGHT / 2 - player(me).y + cameraWindow
  373.     ELSEIF player(me).y + camera.y < _HEIGHT / 2 - cameraWindow THEN
  374.         camera.y = _HEIGHT / 2 - player(me).y - cameraWindow
  375.     END IF
  376.     IF camera.y > 0 THEN camera.y = 0
  377.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  378.  
  379.  
  380. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  381.     ' CX = center x coordinate
  382.     ' CY = center y coordinate
  383.     '  R = radius
  384.     '  C = fill color
  385.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  386.     DIM X AS INTEGER, Y AS INTEGER
  387.     Radius = ABS(R)
  388.     RadiusError = -Radius
  389.     X = Radius
  390.     Y = 0
  391.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  392.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  393.     WHILE X > Y
  394.         RadiusError = RadiusError + Y * 2 + 1
  395.         IF RadiusError >= 0 THEN
  396.             IF X <> Y + 1 THEN
  397.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  398.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  399.             END IF
  400.             X = X - 1
  401.             RadiusError = RadiusError - X * 2
  402.         END IF
  403.         Y = Y + 1
  404.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  405.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  406.     WEND
  407.  
  408. SUB db (text$)
  409.     $IF DEBUGGING = TRUE THEN
  410.         _ECHO text$
  411.     $ELSE
  412.         DIM dummy$
  413.         dummy$ = text$
  414.     $END IF
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Rubidium on October 20, 2020, 05:16:44 pm
Impressive! do you have the code for the server as well? I'd like to try playing around with it :D
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 20, 2020, 05:29:17 pm
It's all included above, actually!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Rubidium on October 20, 2020, 06:09:22 pm
Really cool. With some messenger features and a few collision objects, a lot of kids could get so into this! -for getting into qb64- :D
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 01:08:11 pm
True! I'm hoping to turn it into a real game soon.

If anyone decides to try the room and eventually finds no one currently logged in, just open two instances of the code above to see two instances of yourself running around.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 21, 2020, 04:04:11 pm
This is great Felippe! I've been wondering how to do this for awhile. I'll try to learn it. I might also drop the CHR$(0) and inkey$ I use for the arrow keys, yours probably works better. Someone could make a really great dungeon type game this way. Thanks!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 04:08:07 pm
Thanks, Ken! Glad you enjoyed it.

Did you have luck joining either server? They've both been up since yesterday.

The advantage of using _KEYDOWN for character movement is that all directions can coexist simultaneously and there's no buffer. Once released, the keys immediately stop coming.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 21, 2020, 05:33:55 pm
LOL I see you! I wonder if we can add chat to it? Like text over your nickname.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 05:34:35 pm
I'll be implementing chat soon, but for now there's no length limit for player name - it's a rudimentary messaging system as is!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Dav on October 21, 2020, 05:55:40 pm
Works for me.  Connected as is.  Code is so easy to understand. What a great learning example. 

- Dav 
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 05:57:39 pm
Damn, I missed you! Australia or US?
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Dav on October 21, 2020, 05:58:28 pm
US (North Carolina).

Edit: I saw you there.  I just wandered around a while and left.

- Dav
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 06:01:35 pm
Glad to see you around!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: johnno56 on October 21, 2020, 06:41:52 pm
This concept (A background larger than the main window) reminded me of the game Agario (homework...) but this method could easily be used for a 'space shooter'. Instead of a circular player; a ship. Instead of random circles; a star-field....

You did an excellent job in explaining everything... even 'I' could understand it... lol

Well done!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 21, 2020, 10:07:18 pm
Felippe, I'm working on a game right now using your code. But I need help detecting colors on the map. I can't seem to figure out the coordinates to use with the POINT command when your guy goes over a certain color. I have deleted my attempts at the code. I've even tried specific variable detection but the problem is, the camera variable goes into negative numbers and the player.x and player.y variables only change when the map stops moving and your guy moves. I'm not sure what to use. Here is the game I have so far. You have to find the GOLD bar and then I want it to go to the next level. Instead of all circles I use filled-in squares and blue circular lakes. Plus I made the map 8x so it's fairly big. It might take a couple of seconds to load from the black screen. I'm using your first code you posted on this thread, not the one with Internet access.

Code: QB64: [Select]
  1.  
  2. SCREEN _NEWIMAGE(1000, 800, 32)
  3.  
  4. TYPE object
  5.     x AS SINGLE
  6.     y AS SINGLE
  7.  
  8. DIM SHARED player AS object
  9. DIM SHARED camera AS object
  10. DIM playerSpeed AS SINGLE
  11.  
  12. start:
  13. player.x = _WIDTH / 2
  14. player.y = _HEIGHT / 2
  15.  
  16. map = _NEWIMAGE(_WIDTH * 7, _HEIGHT * 7, 32)
  17. _DEST map
  18. PAINT (2, 2), _RGB32(0, 200, 0)
  19.  
  20. FOR blocks = 1 TO 400
  21.     blocks:
  22.     xx = (RND * _WIDTH)
  23.     yy = (RND * _HEIGHT)
  24.     sz = INT(RND * 50) + 10
  25.     c1 = INT(RND * 155) + 100
  26.     c2 = INT(RND * 155) + 100
  27.     c3 = INT(RND * 155) + 100
  28.     LINE (xx, yy)-(xx + sz, yy + sz), _RGB32(c1, c2, c3), BF
  29.     IF POINT(_WIDTH / 2, _HEIGHT / 2) = _RGB32(c1, c2, c3) THEN GOTO blocks:
  30. FOR lakes = 1 TO 10
  31.     w = RND
  32.     h = RND
  33.     sze = (RND * 150) + 50
  34.     FOR sz = .25 TO sze STEP .25
  35.         CIRCLE (w * _WIDTH, h * _HEIGHT), sz, _RGB32(0, 0, 255)
  36.     NEXT sz
  37. NEXT lakes
  38. w2 = INT(RND * _WIDTH) - 14
  39. h2 = INT(RND * _HEIGHT) - 7
  40.  
  41. 'Gold
  42. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 128)
  43. _PRINTSTRING (w2, h2), "GOLD"
  44.  
  45.  
  46. playerSpeed = 5
  47.  
  48. CONST keyUP = 18432
  49. CONST keyDOWN = 20480
  50. CONST keyLEFT = 19200
  51. CONST keyRIGHT = 19712
  52.  
  53.     CLS
  54.  
  55.     _PUTIMAGE (camera.x, camera.y), map
  56.  
  57.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  58.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  59.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  60.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  61.  
  62.     IF player.x < 0 THEN player.x = 0
  63.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  64.     IF player.y < 0 THEN player.y = 0
  65.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  66.  
  67.     adjustCamera
  68.  
  69.     'Draw Head
  70.     FOR sz = .25 TO 10 STEP .25
  71.         CIRCLE (player.x + camera.x, player.y + camera.y), sz, _RGB32(255, 166, 127)
  72.     NEXT sz
  73.     'Draw Smile
  74.     CIRCLE (player.x + camera.x, player.y + camera.y + 2), 7, _RGB32(255, 0, 0), _PI, 2 * _PI, .5
  75.     'Draw Eyes
  76.     CIRCLE (player.x + camera.x - 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  77.     CIRCLE (player.x + camera.x + 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  78.     'hat
  79.     LINE (player.x + camera.x - 10, player.y + camera.y - 10)-(player.x + camera.x + 10, player.y + camera.y - 9), _RGB32(155, 0, 0), BF
  80.     LINE (player.x + camera.x - 5, player.y + camera.y - 9)-(player.x + camera.x + 5, player.y + camera.y - 15), _RGB32(155, 0, 0), BF
  81.  
  82.  
  83.     _DISPLAY
  84.     _LIMIT 60
  85.  
  86. SUB adjustCamera
  87.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  88.         camera.x = _WIDTH / 2 - player.x
  89.     END IF
  90.     IF camera.x > 0 THEN camera.x = 0
  91.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  92.  
  93.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  94.         camera.y = _HEIGHT / 2 - player.y
  95.     END IF
  96.     IF camera.y > 0 THEN camera.y = 0
  97.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  98.  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: bplus on October 21, 2020, 10:10:31 pm
Try setting _SOURCE to image handle before using POINT.

Oh coordinates should be same as camera + player?
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 10:14:01 pm
In your case, like bplus said, you will need to set _SOURCE first:

Code: QB64: [Select]

This way you can read its pixels with POINT().

Since your player will roam around the map, you will use player.x and player.y to read POINT with, you can ignore the camera variable.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 21, 2020, 10:54:18 pm
I did it!!! Thanks guys!!!

This is an example game, which is my first mapped out game like this. I hope to expand it sometime soon and make it more fun. For now, you can move your cowboy around and find one gold bar per map. When you move your guy next to or on the bar, it gives you 100 points and starts over with a brand new map. If I expand on this game, I'll make a new forum thread for it. But this is what I have so far. I also doubled the cowboy speed from my last post. Oh also, the gold bar is labeled "GOLD" so you know what it is.

Code: QB64: [Select]
  1. 'Find the Gold! by SierraKen
  2. 'October 21, 2020
  3. 'Thanks for the great mapping code by FellipeHeitor and help from B+!
  4. 'This is mostly an example game, I hope to expand on it sometime soon.
  5.  
  6.  
  7. SCREEN _NEWIMAGE(1000, 800, 32)
  8.  
  9. TYPE object
  10.     x AS SINGLE
  11.     y AS SINGLE
  12.  
  13. DIM SHARED player AS object
  14. DIM SHARED camera AS object
  15. DIM playerSpeed AS SINGLE
  16.  
  17. _TITLE "Find The Gold! One gold bar per map. Use your arrow keys."
  18.  
  19. start:
  20. player.x = _WIDTH / 2
  21. player.y = _HEIGHT / 2
  22.  
  23. map = _NEWIMAGE(_WIDTH * 7, _HEIGHT * 7, 32)
  24.  
  25. _DEST map
  26. PAINT (2, 2), _RGB32(0, 200, 0)
  27.  
  28. FOR blocks = 1 TO 400
  29.     blocks:
  30.     xx = (RND * _WIDTH)
  31.     yy = (RND * _HEIGHT)
  32.     sz = INT(RND * 50) + 10
  33.     c1 = INT(RND * 155) + 100
  34.     c2 = INT(RND * 155) + 100
  35.     c3 = INT(RND * 155) + 100
  36.     LINE (xx, yy)-(xx + sz, yy + sz), _RGB32(c1, c2, c3), BF
  37.     IF POINT(_WIDTH / 2, _HEIGHT / 2) = _RGB32(c1, c2, c3) THEN GOTO blocks:
  38. FOR lakes = 1 TO 10
  39.     w = RND
  40.     h = RND
  41.     sze = (RND * 150) + 50
  42.     FOR sz = .25 TO sze STEP .25
  43.         CIRCLE (w * _WIDTH, h * _HEIGHT), sz, _RGB32(0, 0, 255)
  44.     NEXT sz
  45. NEXT lakes
  46. w2 = INT(RND * _WIDTH) - 15
  47. h2 = INT(RND * _HEIGHT) - 10
  48. IF w2 < 15 THEN w2 = 15
  49. IF h2 < 10 THEN h2 = 10
  50.  
  51. 'Gold
  52. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 128)
  53. _PRINTSTRING (w2, h2), "GOLD"
  54.  
  55.  
  56.  
  57. playerSpeed = 10
  58.  
  59. CONST keyUP = 18432
  60. CONST keyDOWN = 20480
  61. CONST keyLEFT = 19200
  62. CONST keyRIGHT = 19712
  63.  
  64.     CLS
  65.  
  66.     _PUTIMAGE (camera.x, camera.y), map
  67.  
  68.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  69.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  70.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  71.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  72.  
  73.     IF player.x < 0 THEN player.x = 0
  74.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  75.     IF player.y < 0 THEN player.y = 0
  76.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  77.  
  78.     adjustCamera
  79.  
  80.     'Draw Head
  81.     FOR sz = .25 TO 10 STEP .25
  82.         CIRCLE (player.x + camera.x, player.y + camera.y), sz, _RGB32(255, 166, 127)
  83.     NEXT sz
  84.     'Draw Smile
  85.     CIRCLE (player.x + camera.x, player.y + camera.y + 2), 7, _RGB32(255, 0, 0), _PI, 2 * _PI, .5
  86.     'Draw Eyes
  87.     CIRCLE (player.x + camera.x - 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  88.     CIRCLE (player.x + camera.x + 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  89.     'hat
  90.     LINE (player.x + camera.x - 10, player.y + camera.y - 10)-(player.x + camera.x + 10, player.y + camera.y - 9), _RGB32(155, 0, 0), BF
  91.     LINE (player.x + camera.x - 5, player.y + camera.y - 9)-(player.x + camera.x + 5, player.y + camera.y - 15), _RGB32(155, 0, 0), BF
  92.     FOR check = -15 TO 15
  93.         IF POINT(player.x + check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  94.         IF POINT(player.x + check, player.y - check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  95.         IF POINT(player.x - check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  96.     NEXT check
  97.  
  98.     _DISPLAY
  99.     _LIMIT 60
  100.  
  101. SUB adjustCamera
  102.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  103.         camera.x = _WIDTH / 2 - player.x
  104.     END IF
  105.     IF camera.x > 0 THEN camera.x = 0
  106.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  107.  
  108.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  109.         camera.y = _HEIGHT / 2 - player.y
  110.     END IF
  111.     IF camera.y > 0 THEN camera.y = 0
  112.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  113.  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 21, 2020, 11:14:10 pm
Cool mod, Ken!

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 21, 2020, 11:41:26 pm
Thanks Felippe, glad you like it. :)). I can add all kinds of stuff to the map now that I have color detection. :))). Can also make enemies where if you see one on your screen, they come after you. lol I hope I can do that anyway. :) I hope to work on it sometime soon.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 22, 2020, 03:22:08 am
New version updated with chat!

https://github.com/FellippeHeitor/amongus/blob/main/amongst.bas

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: SierraKen on October 22, 2020, 01:20:19 pm
Felippe that is totally cool! I felt like I was in a tank game chatting with my counterpart. lol
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: qbkiller101 on October 22, 2020, 02:03:01 pm
I did it!!! Thanks guys!!!

This is an example game, which is my first mapped out game like this. I hope to expand it sometime soon and make it more fun. For now, you can move your cowboy around and find one gold bar per map. When you move your guy next to or on the bar, it gives you 100 points and starts over with a brand new map. If I expand on this game, I'll make a new forum thread for it. But this is what I have so far. I also doubled the cowboy speed from my last post. Oh also, the gold bar is labeled "GOLD" so you know what it is.

Code: QB64: [Select]
  1. 'Find the Gold! by SierraKen
  2. 'October 21, 2020
  3. 'Thanks for the great mapping code by FellipeHeitor and help from B+!
  4. 'This is mostly an example game, I hope to expand on it sometime soon.
  5.  
  6.  
  7. SCREEN _NEWIMAGE(1000, 800, 32)
  8.  
  9. TYPE object
  10.     x AS SINGLE
  11.     y AS SINGLE
  12.  
  13. DIM SHARED player AS object
  14. DIM SHARED camera AS object
  15. DIM playerSpeed AS SINGLE
  16.  
  17. _TITLE "Find The Gold! One gold bar per map. Use your arrow keys."
  18.  
  19. start:
  20. player.x = _WIDTH / 2
  21. player.y = _HEIGHT / 2
  22.  
  23. map = _NEWIMAGE(_WIDTH * 7, _HEIGHT * 7, 32)
  24.  
  25. _DEST map
  26. PAINT (2, 2), _RGB32(0, 200, 0)
  27.  
  28. FOR blocks = 1 TO 400
  29.     blocks:
  30.     xx = (RND * _WIDTH)
  31.     yy = (RND * _HEIGHT)
  32.     sz = INT(RND * 50) + 10
  33.     c1 = INT(RND * 155) + 100
  34.     c2 = INT(RND * 155) + 100
  35.     c3 = INT(RND * 155) + 100
  36.     LINE (xx, yy)-(xx + sz, yy + sz), _RGB32(c1, c2, c3), BF
  37.     IF POINT(_WIDTH / 2, _HEIGHT / 2) = _RGB32(c1, c2, c3) THEN GOTO blocks:
  38. FOR lakes = 1 TO 10
  39.     w = RND
  40.     h = RND
  41.     sze = (RND * 150) + 50
  42.     FOR sz = .25 TO sze STEP .25
  43.         CIRCLE (w * _WIDTH, h * _HEIGHT), sz, _RGB32(0, 0, 255)
  44.     NEXT sz
  45. NEXT lakes
  46. w2 = INT(RND * _WIDTH) - 15
  47. h2 = INT(RND * _HEIGHT) - 10
  48. IF w2 < 15 THEN w2 = 15
  49. IF h2 < 10 THEN h2 = 10
  50.  
  51. 'Gold
  52. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 128)
  53. _PRINTSTRING (w2, h2), "GOLD"
  54.  
  55.  
  56.  
  57. playerSpeed = 10
  58.  
  59. CONST keyUP = 18432
  60. CONST keyDOWN = 20480
  61. CONST keyLEFT = 19200
  62. CONST keyRIGHT = 19712
  63.  
  64.     CLS
  65.  
  66.     _PUTIMAGE (camera.x, camera.y), map
  67.  
  68.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  69.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  70.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  71.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  72.  
  73.     IF player.x < 0 THEN player.x = 0
  74.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  75.     IF player.y < 0 THEN player.y = 0
  76.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  77.  
  78.     adjustCamera
  79.  
  80.     'Draw Head
  81.     FOR sz = .25 TO 10 STEP .25
  82.         CIRCLE (player.x + camera.x, player.y + camera.y), sz, _RGB32(255, 166, 127)
  83.     NEXT sz
  84.     'Draw Smile
  85.     CIRCLE (player.x + camera.x, player.y + camera.y + 2), 7, _RGB32(255, 0, 0), _PI, 2 * _PI, .5
  86.     'Draw Eyes
  87.     CIRCLE (player.x + camera.x - 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  88.     CIRCLE (player.x + camera.x + 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  89.     'hat
  90.     LINE (player.x + camera.x - 10, player.y + camera.y - 10)-(player.x + camera.x + 10, player.y + camera.y - 9), _RGB32(155, 0, 0), BF
  91.     LINE (player.x + camera.x - 5, player.y + camera.y - 9)-(player.x + camera.x + 5, player.y + camera.y - 15), _RGB32(155, 0, 0), BF
  92.     FOR check = -15 TO 15
  93.         IF POINT(player.x + check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  94.         IF POINT(player.x + check, player.y - check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  95.         IF POINT(player.x - check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  96.     NEXT check
  97.  
  98.     _DISPLAY
  99.     _LIMIT 60
  100.  
  101. SUB adjustCamera
  102.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  103.         camera.x = _WIDTH / 2 - player.x
  104.     END IF
  105.     IF camera.x > 0 THEN camera.x = 0
  106.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  107.  
  108.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  109.         camera.y = _HEIGHT / 2 - player.y
  110.     END IF
  111.     IF camera.y > 0 THEN camera.y = 0
  112.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  113.  

I added 4 lines for wasd at 79 to 82
but, as always, BUGS:
pressing both keys of movement in specific direction: e.g. w and right arrow, maks faster movement
ITS A FEATURE
Code: QB64: [Select]
  1. 'Find the Gold! by SierraKen
  2. 'October 21, 2020
  3. 'Thanks for the great mapping code by FellipeHeitor and help from B+!
  4. 'This is mostly an example game, I hope to expand on it sometime soon.
  5.  
  6.  
  7. SCREEN _NEWIMAGE(800, 600, 32)
  8.  
  9. TYPE object
  10.     x AS SINGLE
  11.     y AS SINGLE
  12.  
  13. DIM SHARED player AS object
  14. DIM SHARED camera AS object
  15. DIM playerSpeed AS SINGLE
  16.  
  17. _TITLE "Find The Gold! One gold bar per map. Use your arrow keys."
  18.  
  19. start:
  20. player.x = _WIDTH / 2
  21. player.y = _HEIGHT / 2
  22.  
  23. map = _NEWIMAGE(_WIDTH * 7, _HEIGHT * 7, 32)
  24.  
  25. _DEST map
  26. PAINT (2, 2), _RGB32(0, 200, 0)
  27.  
  28. FOR blocks = 1 TO 400
  29.     blocks:
  30.     xx = (RND * _WIDTH)
  31.     yy = (RND * _HEIGHT)
  32.     sz = INT(RND * 50) + 10
  33.     c1 = INT(RND * 155) + 100
  34.     c2 = INT(RND * 155) + 100
  35.     c3 = INT(RND * 155) + 100
  36.     LINE (xx, yy)-(xx + sz, yy + sz), _RGB32(c1, c2, c3), BF
  37.     IF POINT(_WIDTH / 2, _HEIGHT / 2) = _RGB32(c1, c2, c3) THEN GOTO blocks:
  38. FOR lakes = 1 TO 10
  39.     w = RND
  40.     h = RND
  41.     sze = (RND * 150) + 50
  42.     FOR sz = .25 TO sze STEP .25
  43.         CIRCLE (w * _WIDTH, h * _HEIGHT), sz, _RGB32(0, 0, 255)
  44.     NEXT sz
  45. NEXT lakes
  46. w2 = INT(RND * _WIDTH) - 15
  47. h2 = INT(RND * _HEIGHT) - 10
  48. IF w2 < 15 THEN w2 = 15
  49. IF h2 < 10 THEN h2 = 10
  50.  
  51. 'Gold
  52. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 128)
  53. _PRINTSTRING (w2, h2), "GOLD"
  54.  
  55.  
  56.  
  57. playerSpeed = 10
  58.  
  59. CONST keyUP = 18432
  60. CONST keyDOWN = 20480
  61. CONST keyLEFT = 19200
  62. CONST keyRIGHT = 19712
  63.  
  64.     CLS
  65.  
  66.     _PUTIMAGE (camera.x, camera.y), map
  67.  
  68.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  69.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  70.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  71.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  72.     IF _KEYDOWN(119) THEN player.y = player.y - playerSpeed 'Omer Hijazi
  73.     IF _KEYDOWN(115) THEN player.y = player.y + playerSpeed 'Omer Hijazi
  74.     IF _KEYDOWN(97) THEN player.x = player.x - playerSpeed 'Omer Hijazi
  75.     IF _KEYDOWN(100) THEN player.x = player.x + playerSpeed 'Omer Hijazi
  76.  
  77.  
  78.     IF player.x < 0 THEN player.x = 0
  79.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  80.     IF player.y < 0 THEN player.y = 0
  81.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  82.  
  83.     adjustCamera
  84.  
  85.     'Draw Head
  86.     FOR sz = .25 TO 10 STEP .25
  87.         CIRCLE (player.x + camera.x, player.y + camera.y), sz, _RGB32(255, 166, 127)
  88.     NEXT sz
  89.     'Draw Smile
  90.     CIRCLE (player.x + camera.x, player.y + camera.y + 2), 7, _RGB32(255, 0, 0), _PI, 2 * _PI, .5
  91.     'Draw Eyes
  92.     CIRCLE (player.x + camera.x - 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  93.     CIRCLE (player.x + camera.x + 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  94.     'hat
  95.     LINE (player.x + camera.x - 10, player.y + camera.y - 10)-(player.x + camera.x + 10, player.y + camera.y - 9), _RGB32(155, 0, 0), BF
  96.     LINE (player.x + camera.x - 5, player.y + camera.y - 9)-(player.x + camera.x + 5, player.y + camera.y - 15), _RGB32(155, 0, 0), BF
  97.     FOR check = -15 TO 15
  98.         IF POINT(player.x + check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  99.         IF POINT(player.x + check, player.y - check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  100.         IF POINT(player.x - check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  101.     NEXT check
  102.  
  103.     _DISPLAY
  104.     _LIMIT 60
  105.  
  106. SUB adjustCamera
  107.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  108.         camera.x = _WIDTH / 2 - player.x
  109.     END IF
  110.     IF camera.x > 0 THEN camera.x = 0
  111.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  112.  
  113.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  114.         camera.y = _HEIGHT / 2 - player.y
  115.     END IF
  116.     IF camera.y > 0 THEN camera.y = 0
  117.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  118.  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Petr on October 22, 2020, 03:00:12 pm
Perfect work, Fellippe. I like this.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 22, 2020, 03:01:08 pm
@SierraKen lol, I was away from the keyboard and I just saw your messages in the game chat! Glad you enjoyed it.

@qbkiller101 that doesn't qualify as a bug - you are indeed reading two keys and changing the player's position, so it all seems to be working exactly as you wrote it ;-)

@Petr glad you enjoyed it! You just helped me find a bug just by joining the US server, thank you for trying it :-)
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Petr on October 22, 2020, 03:07:07 pm
Really? Which bug? I don´t see none bug :)
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 22, 2020, 03:10:36 pm
The messages sent earlier by SierraKen were registered to you when you joined, because you used up his free slot.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Petr on October 22, 2020, 03:14:06 pm
It is possible. I ran the first version without chat.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: Ashish on October 23, 2020, 03:20:15 am
GREAT JOB!!! :D
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: qbkiller101 on October 23, 2020, 10:18:38 am
Added choosing the dimensions, working on wasd mode and arrow keys mode:
Code: QB64: [Select]
  1. 'Find the Gold! by SierraKen
  2. 'October 21, 2020
  3. 'Thanks for the great mapping code by FellipeHeitor and help from B+!
  4. 'This is mostly an example game, I hope to expand on it sometime soon.
  5. 'October 22, 2020
  6. 'Edits by Omer H., or qbkiller101 in the forums
  7. 'Added wasd support, fast and normal mode (see 113), and choosing
  8. 'dimensions for people with small screens (like me)
  9.  
  10.  
  11. SCREEN _NEWIMAGE(500, 400, 256)
  12. LINE (125, 100)-(375, 175), 15, BF
  13. LINE (125, 225)-(375, 300), 15, BF
  14. _PRINTSTRING (150, 0), "Choose the dimensions:"
  15. _PRINTSTRING (210, 125), "800 x 600"
  16. _PRINTSTRING (175, 250), "Default (1000 x 800)"
  17. dimx% = 800
  18. dimy% = 600
  19. ischosen = false
  20. WHILE ischosen = false
  21.         IF _MOUSEX > 125 AND _MOUSEX < 375 THEN
  22.             IF _MOUSEY > 100 AND _MOUSEY < 175 THEN
  23.                 IF _MOUSEBUTTON(1) = -1 THEN
  24.                     dimx% = 800
  25.                     dimy% = 600
  26.                     ischosen = true
  27.                     EXIT WHILE
  28.                 END IF
  29.             END IF
  30.         END IF
  31.         IF _MOUSEX > 125 AND _MOUSEX < 375 THEN
  32.             IF _MOUSEY > 225 AND _MOUSEY < 300 THEN
  33.                 IF _MOUSEBUTTON(1) = -1 THEN
  34.                     dimx% = 1000
  35.                     dimy% = 800
  36.                     ischosen = true
  37.                     EXIT WHILE
  38.                 END IF
  39.             END IF
  40.         END IF
  41.  
  42.     LOOP
  43. SCREEN _NEWIMAGE(dimx%, dimy%, 32)
  44.  
  45. TYPE object
  46.     x AS SINGLE
  47.     y AS SINGLE
  48.  
  49. DIM SHARED player AS object
  50. DIM SHARED camera AS object
  51. DIM playerSpeed AS SINGLE
  52.  
  53. _TITLE "Find The Gold! One gold bar per map. Use your arrow keys."
  54.  
  55. start:
  56. player.x = _WIDTH / 2
  57. player.y = _HEIGHT / 2
  58.  
  59. map = _NEWIMAGE(_WIDTH * 7, _HEIGHT * 7, 32)
  60.  
  61. _DEST map
  62. PAINT (2, 2), _RGB32(0, 200, 0)
  63.  
  64. FOR blocks = 1 TO 400
  65.     blocks:
  66.     xx = (RND * _WIDTH)
  67.     yy = (RND * _HEIGHT)
  68.     sz = INT(RND * 50) + 10
  69.     c1 = INT(RND * 155) + 100
  70.     c2 = INT(RND * 155) + 100
  71.     c3 = INT(RND * 155) + 100
  72.     LINE (xx, yy)-(xx + sz, yy + sz), _RGB32(c1, c2, c3), BF
  73.     IF POINT(_WIDTH / 2, _HEIGHT / 2) = _RGB32(c1, c2, c3) THEN GOTO blocks:
  74. FOR lakes = 1 TO 10
  75.     w = RND
  76.     h = RND
  77.     sze = (RND * 150) + 50
  78.     FOR sz = .25 TO sze STEP .25
  79.         CIRCLE (w * _WIDTH, h * _HEIGHT), sz, _RGB32(0, 0, 255)
  80.     NEXT sz
  81. NEXT lakes
  82. w2 = INT(RND * _WIDTH) - 15
  83. h2 = INT(RND * _HEIGHT) - 10
  84. IF w2 < 15 THEN w2 = 15
  85. IF h2 < 10 THEN h2 = 10
  86.  
  87. 'Gold
  88. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 128)
  89. _PRINTSTRING (w2, h2), "GOLD"
  90.  
  91.  
  92.  
  93. playerSpeed = 10
  94.  
  95. CONST keyUP = 18432
  96. CONST keyDOWN = 20480
  97. CONST keyLEFT = 19200
  98. CONST keyRIGHT = 19712
  99.  
  100.     CLS
  101.  
  102.     _PUTIMAGE (camera.x, camera.y), map
  103.  
  104.     IF _KEYDOWN(keyUP) THEN player.y = player.y - playerSpeed
  105.     IF _KEYDOWN(keyDOWN) THEN player.y = player.y + playerSpeed
  106.     IF _KEYDOWN(keyLEFT) THEN player.x = player.x - playerSpeed
  107.     IF _KEYDOWN(keyRIGHT) THEN player.x = player.x + playerSpeed
  108.     IF _KEYDOWN(119) THEN player.y = player.y - playerSpeed 'Omer Hijazi
  109.     IF _KEYDOWN(115) THEN player.y = player.y + playerSpeed 'Omer Hijazi
  110.     IF _KEYDOWN(97) THEN player.x = player.x - playerSpeed 'Omer Hijazi
  111.     IF _KEYDOWN(100) THEN player.x = player.x + playerSpeed 'Omer Hijazi
  112.  
  113.  
  114.     IF player.x < 0 THEN player.x = 0
  115.     IF player.x > _WIDTH(map) THEN player.x = _WIDTH(map)
  116.     IF player.y < 0 THEN player.y = 0
  117.     IF player.y > _HEIGHT(map) THEN player.y = _HEIGHT(map)
  118.  
  119.     adjustCamera
  120.  
  121.     'Draw Head
  122.     FOR sz = .25 TO 10 STEP .25
  123.         CIRCLE (player.x + camera.x, player.y + camera.y), sz, _RGB32(255, 166, 127)
  124.     NEXT sz
  125.     'Draw Smile
  126.     CIRCLE (player.x + camera.x, player.y + camera.y + 2), 7, _RGB32(255, 0, 0), _PI, 2 * _PI, .5
  127.     'Draw Eyes
  128.     CIRCLE (player.x + camera.x - 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  129.     CIRCLE (player.x + camera.x + 4, player.y + camera.y - 2), 1, _RGB32(0, 0, 255)
  130.     'hat
  131.     LINE (player.x + camera.x - 10, player.y + camera.y - 10)-(player.x + camera.x + 10, player.y + camera.y - 9), _RGB32(155, 0, 0), BF
  132.     LINE (player.x + camera.x - 5, player.y + camera.y - 9)-(player.x + camera.x + 5, player.y + camera.y - 15), _RGB32(155, 0, 0), BF
  133.     FOR check = -15 TO 15
  134.         IF POINT(player.x + check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  135.         IF POINT(player.x + check, player.y - check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  136.         IF POINT(player.x - check, player.y + check) = _RGB32(255, 255, 128) THEN SOUND 500, .5: score = score + 100: score$ = STR$(score): _TITLE "Score: " + score$: GOTO start:
  137.     NEXT check
  138.  
  139.     _DISPLAY
  140.     _LIMIT 60
  141.  
  142. SUB adjustCamera
  143.     IF player.x + camera.x > _WIDTH / 2 OR player.x + camera.x < _WIDTH / 2 THEN
  144.         camera.x = _WIDTH / 2 - player.x
  145.     END IF
  146.     IF camera.x > 0 THEN camera.x = 0
  147.     IF camera.x < -(_WIDTH(map) - _WIDTH) THEN camera.x = -(_WIDTH(map) - _WIDTH)
  148.  
  149.     IF player.y + camera.y > _HEIGHT / 2 OR player.y + camera.y < _HEIGHT / 2 THEN
  150.         camera.y = _HEIGHT / 2 - player.y
  151.     END IF
  152.     IF camera.y > 0 THEN camera.y = 0
  153.     IF camera.y < -(_HEIGHT(map) - _HEIGHT) THEN camera.y = -(_HEIGHT(map) - _HEIGHT)
  154.  
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: TempodiBasic on October 24, 2020, 02:33:47 pm
Hi Guys
Hi Fellippe

1. I think that this your project that you share and let be our is wonderful!!!!!!!!!!!

2.  I find wonderful also your video that brings the audience with you along the developing of the first version of the game

3. some feedback (I hope these are useful!)
I have tryed to run the first online version and I got a strange result ( I have used US server but trying also on Australia server it is the same result)  after a while I run happy on the map I lost connection to the server. And I'm the one on that map. It happens also when I do a double connection (as you have suggested I have run two instances of the same .EXE).
Another strange result is this showed into this screenshot.
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Now I try to donwload the version with chat from your github!

Thanks to share!!!!
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 24, 2020, 02:37:17 pm
The client in this thread is slightly outdated now. We're working on getting the servers updated with the latest version and will update you guys here too.
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 24, 2020, 02:38:14 pm
In the meantime, you can get the new server+client files from the repository and run a local instance. Just run the server then run the client and choose "local host".

https://github.com/FellippeHeitor/amongus
Title: Re: Pretentious not-really-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 24, 2020, 04:17:55 pm
Server in Brazil updated. Here's the latest client:

Code: QB64: [Select]
  1.  
  2. DIM SHARED gameVersion AS INTEGER
  3. 'this is to be increased everytime the client
  4. 'becomes incompatible with previous versions
  5. gameVersion = 2
  6.  
  7. $LET DEBUGGING = FALSE
  8. $IF DEBUGGING = TRUE THEN
  9.     $CONSOLE
  10.  
  11. CONST True = -1, False = 0
  12. CONST mode_freeplay = 0
  13. CONST mode_onlineclient = 1
  14.  
  15. CONST id_SERVERFULL = 1
  16. CONST id_PING = 2
  17. CONST id_ID = 3
  18. CONST id_NEWCOLOR = 4
  19. CONST id_NEWNAME = 5
  20. CONST id_COLOR = 6
  21. CONST id_POS = 7
  22. CONST id_NAME = 8
  23. CONST id_CHAT = 9
  24. CONST id_PLAYERONLINE = 10
  25. CONST id_PLAYEROFFLINE = 11
  26. CONST id_PONG = 12
  27. CONST id_PLAYERQUIT = 13
  28. CONST id_GAMEVERSION = 14
  29. CONST id_SHOOT = 15
  30. CONST id_SIZE = 16
  31. CONST id_UPDATESERVER = 17
  32. CONST id_KICK = 18
  33.  
  34. CONST timeout = 10
  35.  
  36. CONST windowWidth = 800
  37. CONST windowHeight = 600
  38.  
  39. TYPE object
  40.     name AS STRING
  41.     handle AS LONG
  42.     x AS SINGLE
  43.     prevX AS SINGLE
  44.     y AS SINGLE
  45.     prevY AS SINGLE
  46.     xv AS SINGLE
  47.     yv AS SINGLE
  48.     xa AS SINGLE
  49.     ya AS SINGLE
  50.     w AS INTEGER
  51.     h AS INTEGER
  52.     state AS INTEGER
  53.     start AS SINGLE
  54.     duration AS SINGLE
  55.     basicInfoSent AS _BYTE
  56.     broadcastOffline AS _BYTE
  57.     ping AS SINGLE
  58.     id AS INTEGER
  59.     text AS STRING
  60.     size AS INTEGER
  61.     r AS INTEGER
  62.     g AS INTEGER
  63.     b AS INTEGER
  64.  
  65. DIM SHARED particle(1000) AS object
  66. DIM SHARED totalClients AS INTEGER
  67. DIM SHARED serverStream AS STRING
  68. DIM SHARED player(1 TO 10) AS object, me AS INTEGER
  69. 'DIM SHARED playerStream(1 TO 10) AS STRING
  70. DIM SHARED warning(1 TO 30) AS object
  71. DIM SHARED chat(1 TO 14) AS object, hasUnreadMessages AS _BYTE, chatOpen AS _BYTE
  72. DIM idSet AS _BYTE
  73. DIM shipMovement AS _BYTE
  74. DIM serverPing AS SINGLE, currentPing AS SINGLE, waitingForPong AS _BYTE
  75. DIM id AS INTEGER, value$
  76. DIM choice AS STRING
  77. DIM exitSign AS INTEGER
  78. DIM target AS INTEGER
  79. DIM score AS LONG
  80.  
  81. DIM SHARED ui(1 TO 1) AS object, focus AS INTEGER
  82.  
  83. DIM serverList(1 TO 4) AS STRING, chosenServer$
  84. i = 0
  85. i = i + 1: serverList(i) = "localhost Local host"
  86. i = i + 1: serverList(i) = "spriggsyspriggs.ddns.net North America"
  87. i = i + 1: serverList(i) = "alephc.xyz Australia"
  88. i = i + 1: serverList(i) = "187.94.219.178 Brazil"
  89.  
  90. DIM SHARED endSignal AS STRING
  91. endSignal = CHR$(253) + CHR$(254) + CHR$(255)
  92.  
  93. playerColorPalette:
  94. DATA 195,17,16
  95. DATA 14,51,196
  96. DATA 18,125,46
  97. DATA 236,84,187
  98. DATA 239,125,17
  99. DATA 248,245,91
  100. DATA 62,71,77
  101. DATA 216,225,241
  102. DATA 107,48,187
  103. DATA 112,73,28
  104. DATA 93,250,220
  105. DATA 79,240,58
  106.  
  107. RESTORE playerColorPalette
  108. FOR i = 1 TO UBOUND(colors)
  109.     READ r%, g%, b%
  110.     colors(i) = _RGB32(r%, g%, b%)
  111.  
  112. DIM SHARED mainWindow AS LONG
  113. DIM SHARED mapImage AS LONG
  114. DIM SHARED messageIcon AS LONG
  115.  
  116. mainWindow = _NEWIMAGE(windowWidth, windowHeight, 32)
  117.  
  118. mapImage = _NEWIMAGE(windowWidth * 4, windowHeight * 3, 32)
  119. _DEST mapImage
  120. 'FOR i = 1 TO 500
  121. '    CircleFill RND * _WIDTH, RND * _HEIGHT, RND * 2, _RGB32(255, 80)
  122. 'NEXT
  123. FOR i = 1 TO 50
  124.     CircleFill RND * _WIDTH, RND * _HEIGHT, RND * 1000, _RGB32(RND * 255, RND * 255, RND * 255, RND * 150)
  125.  
  126. messageIcon = _NEWIMAGE(32, 32, 32)
  127. _DEST messageIcon
  128. LINE (0, 0)-(31, 31), _RGB32(0), BF
  129. LINE (4, 4)-(27, 27), _RGB32(200), BF
  130. FOR i = 8 TO 23 STEP 5
  131.     LINE (5, i)-(25, i), _RGB32(0)
  132. ui(1).name = "messageicon"
  133. ui(1).x = windowWidth - 50
  134. ui(1).y = 10
  135. ui(1).w = _WIDTH
  136. ui(1).h = _HEIGHT
  137.  
  138.  
  139. DIM userName$, userColor%
  140.     GET #1, , i
  141.     userName$ = SPACE$(i)
  142.     GET #1, , userName$
  143.     GET #1, , userColor%
  144.     CLOSE #1
  145.     choice = "1"
  146.     GOTO clientTemp
  147.     INPUT "Name: ", userName$
  148.     userName$ = LEFT$(userName$, 20)
  149.     DO
  150.         PRINT "Color (1-"; LTRIM$(STR$(UBOUND(colors))); "): ";
  151.         INPUT "", userColor%
  152.     LOOP WHILE userColor% < 1 OR userColor% > UBOUND(colors)
  153.  
  154. start:
  155.     COLOR 15
  156.     PRINT "-------------------------"
  157.     PRINT "(1) Free play"
  158.     PRINT "(2) Connect to server"
  159.  
  160.     DO
  161.         choice = INKEY$
  162.  
  163.         exitSign = _EXIT
  164.         IF exitSign THEN
  165.             SYSTEM
  166.         END IF
  167.  
  168.         _LIMIT 30
  169.     LOOP UNTIL choice >= "1" AND choice <= "3"
  170.  
  171.     DIM SHARED server AS object
  172.     DIM c AS INTEGER, attempt AS INTEGER
  173.     SELECT CASE VAL(choice)
  174.         CASE 1
  175.             mode = mode_freeplay
  176.             EXIT DO
  177.         CASE 2
  178.             COLOR 7
  179.             PRINT "Choose a server: "
  180.             FOR i = 1 TO UBOUND(serverList)
  181.                 PRINT i; " " + MID$(serverList(i), INSTR(serverList(i), " ") + 1)
  182.             NEXT
  183.             DO
  184.                 choice = INKEY$
  185.  
  186.                 exitSign = _EXIT
  187.                 IF exitSign THEN
  188.                     SYSTEM
  189.                 END IF
  190.  
  191.                 _LIMIT 30
  192.             LOOP UNTIL VAL(choice) >= 1 AND VAL(choice) <= UBOUND(serverList)
  193.             clientTemp:
  194.             chosenServer$ = LEFT$(serverList(VAL(choice)), INSTR(serverList(VAL(choice)), " ") - 1)
  195.  
  196.             PRINT "Attempting to connect to server... ";
  197.             r = CSRLIN: c = POS(1)
  198.             CONST maxAttempts = 100
  199.             attempt = 0
  200.             DO
  201.                 server.handle = 0
  202.                 server.handle = _OPENCLIENT("TCP/IP:51512:" + chosenServer$)
  203.                 IF server.handle THEN EXIT DO
  204.                 attempt = attempt + 1
  205.                 LOCATE r, c: PRINT USING "###%"; (attempt / maxAttempts) * 100;
  206.  
  207.                 exitSign = _EXIT
  208.                 IF exitSign THEN
  209.                     SYSTEM
  210.                 END IF
  211.  
  212.                 _LIMIT 30
  213.             LOOP WHILE attempt < maxAttempts
  214.             IF server.handle THEN
  215.                 mode = mode_onlineclient
  216.                 serverStream = ""
  217.                 EXIT DO
  218.             END IF
  219.             CLS
  220.             COLOR 14: PRINT "/\ ";: COLOR 12
  221.             PRINT "Failed to connect to server."
  222.     END SELECT
  223.  
  224. IF mode = mode_onlineclient THEN
  225.     serverPing = TIMER
  226.     DO
  227.         getData server, serverStream
  228.         WHILE parse(serverStream, id, value$)
  229.             SELECT CASE id
  230.                 CASE id_SERVERFULL
  231.                     CLS
  232.                     COLOR 14: PRINT "/\ ";: COLOR 12
  233.                     PRINT "Server full."
  234.                     CLOSE server.handle
  235.                     GOTO start
  236.                 CASE id_GAMEVERSION
  237.                     IF CVI(value$) <> gameVersion THEN
  238.                         CLS
  239.                         COLOR 14: PRINT "/\ ";: COLOR 12
  240.                         PRINT "Server version incompatible."
  241.                         sendData server, id_GAMEVERSION, ""
  242.                         sendData server, id_PLAYERQUIT, ""
  243.                         CLOSE server.handle
  244.                         GOTO start
  245.                     ELSE
  246.                         EXIT DO
  247.                     END IF
  248.             END SELECT
  249.         WEND
  250.         IF TIMER - serverPing > 10 THEN
  251.             CLS
  252.             COLOR 14: PRINT "/\ ";: COLOR 12
  253.             PRINT "No response from server."
  254.             GOTO start
  255.         END IF
  256.         _LIMIT 30
  257.     LOOP
  258.  
  259. SCREEN mainWindow
  260.  
  261. DIM SHARED playerSpeed AS SINGLE
  262. DIM SHARED camera AS object
  263.  
  264.  
  265. CONST keyUP = 18432
  266. CONST keyDOWN = 20480
  267. CONST keyLEFT = 19200
  268. CONST keyRIGHT = 19712
  269. CONST keySPACE = 32
  270.  
  271. CONST cameraWindow = 100
  272.  
  273. CONST minSpeed = 3
  274. CONST maxSpeed = 5
  275.  
  276. playerSpeed = maxSpeed
  277. shipMovement = True
  278.  
  279. IF mode > 0 THEN
  280.     idSet = False
  281.     idSet = True
  282.     me = 1
  283.     player(me).name = userName$
  284.     player(me).x = _WIDTH / 2 + COS(RND * _PI) * (RND * 100)
  285.     player(me).y = _HEIGHT / 2 + SIN(RND * _PI) * (RND * 100)
  286.     player(me).state = True
  287.     player(me).color = userColor%
  288.     player(me).size = 15
  289.     CLS
  290.  
  291.     DIM shipFlotation AS SINGLE, shipFloatAmplitude AS SINGLE
  292.     IF shipMovement THEN
  293.         shipFlotation = shipFlotation + .05
  294.         IF shipFlotation > _PI(2) THEN shipFlotation = shipFlotation - _PI(2)
  295.         shipFloatAmplitude = 1.5
  296.     END IF
  297.  
  298.     _PUTIMAGE (camera.x + COS(shipFlotation) * shipFloatAmplitude, camera.y + SIN(shipFlotation) * shipFloatAmplitude), mapImage
  299.     _BLEND
  300.  
  301.     SELECT CASE mode
  302.         CASE mode_onlineclient
  303.             IF waitingForPong = False THEN
  304.                 serverPing = TIMER
  305.                 sendData server, id_PING, ""
  306.                 waitingForPong = True
  307.             END IF
  308.  
  309.             getData server, serverStream
  310.             DO WHILE parse(serverStream, id, value$)
  311.                 SELECT EVERYCASE id
  312.                     CASE id_ID 'first piece of data sent by server if not full
  313.                         idSet = True
  314.                         me = CVI(value$)
  315.                         player(me).name = userName$
  316.                         player(me).x = _WIDTH / 2 + COS(RND * _PI) * (RND * 100)
  317.                         player(me).y = _HEIGHT / 2 + SIN(RND * _PI) * (RND * 100)
  318.                         player(me).state = True
  319.                         player(me).color = userColor%
  320.                         player(me).size = 15
  321.                     CASE id_NEWCOLOR 'server color changes must always be applied
  322.                         player(me).color = CVI(value$)
  323.                     CASE id_NEWNAME 'server name changes must always be applied
  324.                         player(me).name = value$
  325.                     CASE id_COLOR
  326.                         player(CVI(LEFT$(value$, 2))).color = CVI(RIGHT$(value$, 2))
  327.                     CASE id_SIZE
  328.                         player(CVI(LEFT$(value$, 2))).size = CVI(RIGHT$(value$, 2))
  329.                     CASE id_POS
  330.                         'playerStream(CVI(LEFT$(value$, 2))) = playerStream(CVI(LEFT$(value$, 2))) + MID$(value$, 3)
  331.                         player(CVI(LEFT$(value$, 2))).x = CVS(MID$(value$, LEN(value$) - 7, 4))
  332.                         player(CVI(LEFT$(value$, 2))).y = CVS(RIGHT$(value$, 4))
  333.                     CASE id_NAME
  334.                         player(CVI(LEFT$(value$, 2))).name = MID$(value$, 3)
  335.                     CASE id_CHAT
  336.                         addMessageToChat CVI(LEFT$(value$, 2)), MID$(value$, 3)
  337.                         hasUnreadMessages = True
  338.                     CASE id_SHOOT
  339.                         target = CVI(RIGHT$(value$, 2))
  340.                         IF target = me THEN score = score - 100
  341.                         addParticles player(target).x, player(target).y, 5, _RGB32(255)
  342.                         addParticles player(target).x, player(target).y, 100, colors(player(target).color)
  343.                         thickLine player(CVI(LEFT$(value$, 2))).x + camera.x, player(CVI(LEFT$(value$, 2))).y + camera.y, player(target).x + camera.x, player(target).y + camera.y, 8, _RGB32(227, 78, 6, 80)
  344.                     CASE id_PLAYERONLINE
  345.                         player(CVI(value$)).state = True
  346.                     CASE id_PLAYEROFFLINE
  347.                         IF player(CVI(value$)).state = True THEN
  348.                             player(CVI(value$)).state = False
  349.                             addWarning player(CVI(value$)).name + " left the game."
  350.                         END IF
  351.                     CASE id_PONG
  352.                         waitingForPong = False
  353.                     CASE id_KICK
  354.                         SCREEN 0
  355.                         _AUTODISPLAY
  356.                         COLOR 14: PRINT "/\ ";: COLOR 12
  357.                         PRINT "Kicked from server. Reason: "
  358.                         COLOR 14
  359.                         PRINT "   "; value$
  360.                         CLOSE server.handle
  361.                         GOTO start
  362.                 END SELECT
  363.             LOOP
  364.  
  365.             IF idSet THEN
  366.                 IF player(me).basicInfoSent = False THEN
  367.                     player(me).basicInfoSent = True
  368.                     sendData server, id_COLOR, MKI$(player(me).color)
  369.                     sendData server, id_NAME, player(me).name
  370.                     sendData server, id_SIZE, MKI$(player(me).size)
  371.                 END IF
  372.  
  373.                 IF player(me).x <> player(me).prevX OR player(me).y <> player(me).prevY THEN
  374.                     player(me).prevX = player(me).x
  375.                     player(me).prevY = player(me).y
  376.                     sendData server, id_POS, MKS$(player(me).x) + MKS$(player(me).y)
  377.                 END IF
  378.             END IF
  379.  
  380.             totalClients = 0
  381.             FOR i = 1 TO UBOUND(player)
  382.                 IF player(i).state = True THEN totalClients = totalClients + 1
  383.             NEXT
  384.     END SELECT
  385.  
  386.     IF playerSpeed < minSpeed THEN playerSpeed = minSpeed
  387.     IF playerSpeed > maxSpeed THEN playerSpeed = maxSpeed
  388.  
  389.     IF idSet THEN
  390.         IF chatOpen = False THEN
  391.             IF _KEYDOWN(keyUP) THEN player(me).y = player(me).y - playerSpeed
  392.             IF _KEYDOWN(keyDOWN) THEN player(me).y = player(me).y + playerSpeed
  393.             IF _KEYDOWN(keyLEFT) THEN player(me).x = player(me).x - playerSpeed
  394.             IF _KEYDOWN(keyRIGHT) THEN player(me).x = player(me).x + playerSpeed
  395.  
  396.             IF player(me).x < 0 THEN player(me).x = 0
  397.             IF player(me).y < 0 THEN player(me).y = 0
  398.             IF player(me).x > _WIDTH(mapImage) THEN player(me).x = _WIDTH(mapImage)
  399.             IF player(me).y > _HEIGHT(mapImage) THEN player(me).y = _HEIGHT(mapImage)
  400.         END IF
  401.         adjustCamera
  402.     END IF
  403.  
  404.     exitSign = _EXIT
  405.     IF exitSign THEN
  406.         IF mode = mode_onlineclient THEN sendData server, id_PLAYERQUIT, ""
  407.         EXIT DO
  408.     END IF
  409.  
  410.     IF (mode = mode_onlineclient) THEN
  411.         DIM k AS LONG
  412.         k = _KEYHIT
  413.  
  414.         IF k = 27 THEN
  415.             IF chatOpen THEN
  416.                 chatOpen = False
  417.             END IF
  418.         END IF
  419.  
  420.         COLOR _RGB32(255)
  421.  
  422.         DIM m$
  423.         currentPing = TIMER - serverPing
  424.         IF currentPing > timeout THEN
  425.             SCREEN 0
  426.             _AUTODISPLAY
  427.             COLOR 14: PRINT "/\ ";: COLOR 12
  428.             PRINT "Connection lost (timed out)"
  429.             CLOSE server.handle
  430.             GOTO start
  431.         END IF
  432.         m$ = LTRIM$(STR$(currentPing))
  433.         m$ = MID$(m$, INSTR(m$, ".") + 1)
  434.         m$ = LEFT$(STRING$(3 - LEN(m$), "0") + m$, 3) + "ms"
  435.         _PRINTSTRING (_WIDTH - 150 - _PRINTWIDTH(m$), 0), m$
  436.  
  437.         _FONT 16
  438.         m$ = LTRIM$(STR$(totalClients)) + "/" + LTRIM$(STR$(UBOUND(player)))
  439.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(m$)) / 2, _HEIGHT - _FONTHEIGHT), m$
  440.         _FONT 8
  441.     END IF
  442.  
  443.     DIM x AS SINGLE, y AS SINGLE
  444.     target = 0
  445.     FOR i = 1 TO UBOUND(player)
  446.         'proximity
  447.         IF i <> me AND player(i).state = True THEN
  448.             IF dist(player(me).x, player(me).y, player(i).x, player(i).y) < 150 THEN target = i
  449.         END IF
  450.     NEXT
  451.  
  452.     IF target THEN
  453.         DIM targetAnimation AS SINGLE
  454.         targetAnimation = targetAnimation - .1
  455.         IF targetAnimation < 0 THEN targetAnimation = 5
  456.  
  457.         x = player(target).x + camera.x + COS(shipFlotation) * shipFloatAmplitude
  458.         y = player(target).y + camera.y + SIN(shipFlotation) * shipFloatAmplitude
  459.         CircleFill x, y, player(target).size + 10 + targetAnimation, _RGB32(255, 0, 0, 100)
  460.     END IF
  461.  
  462.     FOR i = 1 TO UBOUND(player)
  463.         IF player(i).state = False OR player(i).color = 0 THEN _CONTINUE
  464.         'IF i <> me AND LEN(playerStream(i)) > 0 THEN
  465.         '    'process player stream of coordinates
  466.         '    player(i).x = CVS(MID$(playerStream(i), 1, 4))
  467.         '    player(i).y = CVS(MID$(playerStream(i), 5, 4))
  468.         '    playerStream(i) = MID$(playerStream(i), 9)
  469.         'END IF
  470.  
  471.         x = player(i).x + camera.x + COS(shipFlotation) * shipFloatAmplitude
  472.         y = player(i).y + camera.y + SIN(shipFlotation) * shipFloatAmplitude
  473.         CircleFill x, y + 6, player(i).size + 5, _RGB32(0, 50)
  474.         CircleFill x, y, player(i).size + 5, _RGB32(0)
  475.         CircleFill x, y, player(i).size, colors(player(i).color)
  476.         COLOR _RGB32(0)
  477.         _PRINTSTRING (1 + x - _PRINTWIDTH(player(i).name) / 2, 1 + y - 20), player(i).name
  478.         COLOR _RGB32(255)
  479.         _PRINTSTRING (x - _PRINTWIDTH(player(i).name) / 2, y - 20), player(i).name
  480.     NEXT
  481.  
  482.     IF _KEYDOWN(keySPACE) THEN
  483.         DIM lastShot AS SINGLE
  484.         IF target > 0 THEN
  485.             IF TIMER - lastShot > .5 THEN
  486.                 lastShot = TIMER
  487.                 score = score + 100
  488.                 sendData server, id_SHOOT, MKI$(target)
  489.                 addParticles player(target).x, player(target).y, 5, _RGB32(255)
  490.                 addParticles player(target).x, player(target).y, 100, colors(player(target).color)
  491.                 thickLine player(me).x + camera.x, player(me).y + camera.y, player(target).x + camera.x, player(target).y + camera.y, 8, _RGB32(227, 78, 6, 80)
  492.             END IF
  493.         END IF
  494.     END IF
  495.  
  496.     updateParticles
  497.  
  498.     'LINE (_WIDTH / 2 - cameraWindow, _HEIGHT / 2 - cameraWindow)-STEP(cameraWindow * 2, cameraWindow * 2), , B
  499.  
  500.     'display warnings
  501.     FOR i = 1 TO UBOUND(warning)
  502.         IF warning(i).state = True THEN
  503.             COLOR _RGB32(0)
  504.             _PRINTSTRING (11, 1 + _HEIGHT / 2 + _FONTHEIGHT * i), warning(i).name
  505.             COLOR _RGB32(238, 50, 22)
  506.             _PRINTSTRING (10, _HEIGHT / 2 + _FONTHEIGHT * i), warning(i).name
  507.             IF TIMER - warning(i).ping > 2.5 THEN warning(i).state = False
  508.         END IF
  509.     NEXT
  510.  
  511.     'display messagebox icon
  512.     IF mode = mode_onlineclient THEN
  513.         _PUTIMAGE (ui(1).x, ui(1).y), messageIcon
  514.         IF hasUnreadMessages THEN
  515.             CircleFill _WIDTH - 50, 10, 8, _RGB32(0)
  516.             CircleFill _WIDTH - 50, 10, 5, _RGB32(205, 6, 0)
  517.         END IF
  518.  
  519.         IF chatOpen THEN
  520.             hasUnreadMessages = False
  521.             LINE (50, 50)-(_WIDTH - 50, _HEIGHT - 50), _RGB32(0, 150), BF
  522.             LINE (50, 50)-(_WIDTH - 50, _HEIGHT - 50), _RGB32(0), B
  523.             _FONT 16
  524.             COLOR _RGB32(0)
  525.             FOR i = 1 TO UBOUND(chat)
  526.                 IF chat(i).state THEN
  527.                     y = 65 + _FONTHEIGHT * ((i - 1) * 2)
  528.                     LINE (55, y - 10)-(_WIDTH - 55, y + 18), _RGB32(255, 80), BF
  529.                     _FONT 8
  530.                     x = 60
  531.                     IF chat(i).id = me THEN x = _WIDTH - 60 - _PRINTWIDTH(chat(i).name)
  532.                     COLOR _RGB32(100)
  533.                     _PRINTSTRING (1 + x, 1 + y - 8), chat(i).name
  534.                     COLOR colors(chat(i).color)
  535.                     _PRINTSTRING (x, y - 8), chat(i).name
  536.                     _FONT 16
  537.                     x = 60
  538.                     IF chat(i).id = me THEN x = _WIDTH - 60 - _PRINTWIDTH(chat(i).text)
  539.                     COLOR _RGB32(100)
  540.                     _PRINTSTRING (1 + x, 1 + y), LEFT$(chat(i).text, (_WIDTH - 100) \ _FONTWIDTH)
  541.                     COLOR _RGB32(255)
  542.                     _PRINTSTRING (x, y), LEFT$(chat(i).text, (_WIDTH - 100) \ _FONTWIDTH)
  543.                 END IF
  544.             NEXT
  545.  
  546.             DIM myMessage$, char$, tooFast AS _BYTE
  547.             CONST messageSpeed = 1.5
  548.             char$ = INKEY$
  549.             SELECT CASE char$
  550.                 CASE CHR$(22) 'ctrl+v
  551.                     myMessage$ = myMessage$ + _CLIPBOARD$
  552.                 CASE " " TO "z"
  553.                     myMessage$ = myMessage$ + char$
  554.                 CASE CHR$(8)
  555.                     IF LEN(myMessage$) THEN
  556.                         myMessage$ = LEFT$(myMessage$, LEN(myMessage$) - 1)
  557.                     END IF
  558.                 CASE CHR$(13)
  559.                     DIM lastSentChat AS SINGLE
  560.                     IF myMessage$ = ">reset" THEN
  561.                         player(me).size = 15
  562.                         sendData server, id_SIZE, MKI$(player(me).size)
  563.                         myMessage$ = ""
  564.                         chatOpen = False
  565.                     ELSEIF myMessage$ = ">big" THEN
  566.                         player(me).size = 25
  567.                         sendData server, id_SIZE, MKI$(player(me).size)
  568.                         myMessage$ = ""
  569.                         chatOpen = False
  570.                     ELSEIF myMessage$ = ">updateserver" THEN
  571.                         'temporary solution for triggering auto-update checks
  572.                         sendData server, id_UPDATESERVER, ""
  573.                         myMessage$ = ""
  574.                         chatOpen = False
  575.                     ELSE
  576.                         IF LEN(myMessage$) > 0 AND TIMER - lastSentChat > messageSpeed THEN
  577.                             lastSentChat = TIMER
  578.                             addMessageToChat me, myMessage$
  579.                             sendData server, id_CHAT, myMessage$
  580.                             myMessage$ = ""
  581.                         ELSEIF LEN(myMessage$) > 0 AND TIMER - lastSentChat < messageSpeed THEN
  582.                             tooFast = True
  583.                         END IF
  584.                     END IF
  585.             END SELECT
  586.  
  587.             COLOR _RGB32(0)
  588.             _PRINTSTRING (61, 61 + _FONTHEIGHT * (i * 2) - 24), "> " + myMessage$ + "_"
  589.             COLOR _RGB32(255)
  590.             _PRINTSTRING (60, 60 + _FONTHEIGHT * (i * 2) - 24), "> " + myMessage$ + "_"
  591.             _FONT 8
  592.  
  593.             IF tooFast THEN
  594.                 DIM s AS INTEGER
  595.                 s = _CEIL(messageSpeed - (TIMER - lastSentChat))
  596.                 m$ = "(too fast - wait" + STR$(s) + " second" + LEFT$("s", ABS(s > 1)) + ")"
  597.                 y = _HEIGHT - 50 - _FONTHEIGHT
  598.                 COLOR _RGB32(0)
  599.                 _PRINTSTRING (61, 1 + y), m$
  600.                 COLOR _RGB32(200, 177, 44)
  601.                 _PRINTSTRING (60, y), m$
  602.                 IF TIMER - lastSentChat > messageSpeed THEN tooFast = False
  603.             END IF
  604.         ELSE
  605.             char$ = INKEY$
  606.             SELECT CASE char$
  607.                 CASE CHR$(13)
  608.                     chatOpen = True
  609.             END SELECT
  610.         END IF
  611.     END IF
  612.  
  613.     DIM mouseIsDown AS _BYTE, mouseDownOn AS INTEGER, mouseWheel AS INTEGER
  614.     DIM mb1 AS _BYTE, mb2 AS _BYTE, mx AS INTEGER, my AS INTEGER
  615.     mouseWheel = 0
  616.         mouseWheel = mouseWheel + _MOUSEWHEEL
  617.         IF _MOUSEBUTTON(1) = mb1 AND _MOUSEBUTTON(2) = mb2 THEN
  618.             DO WHILE _MOUSEINPUT
  619.                 mouseWheel = mouseWheel + _MOUSEWHEEL
  620.                 IF NOT (_MOUSEBUTTON(1) = mb1 AND _MOUSEBUTTON(2) = mb2) THEN EXIT DO
  621.             LOOP
  622.         END IF
  623.         mb1 = _MOUSEBUTTON(1)
  624.         mb2 = _MOUSEBUTTON(2)
  625.         mx = _MOUSEX
  626.         my = _MOUSEY
  627.     END IF
  628.  
  629.     focus = 0
  630.     FOR i = UBOUND(ui) TO 1 STEP -1
  631.         IF mx > ui(i).x AND mx < ui(i).x + ui(i).w AND my > ui(i).y AND my < ui(i).y + ui(i).h THEN
  632.             focus = i
  633.             EXIT FOR
  634.         END IF
  635.     NEXT
  636.  
  637.     IF mb1 THEN
  638.         mouseDownOn = focus
  639.         mouseIsDown = True
  640.     ELSE
  641.         IF mouseIsDown THEN
  642.             IF mouseDownOn THEN
  643.                 SELECT CASE ui(mouseDownOn).name
  644.                     CASE "messageicon"
  645.                         IF mode = mode_onlineclient THEN chatOpen = NOT chatOpen
  646.                 END SELECT
  647.             END IF
  648.         END IF
  649.         mouseIsDown = False
  650.     END IF
  651.  
  652.     IF mode = mode_onlineclient THEN
  653.         _FONT 16
  654.         COLOR _RGB32(0)
  655.         _PRINTSTRING (1, 1), "Score:" + STR$(score)
  656.         COLOR _RGB32(255)
  657.         _PRINTSTRING (0, 0), "Score:" + STR$(score)
  658.         _FONT 8
  659.     END IF
  660.  
  661.     _DISPLAY
  662.     _LIMIT 60
  663.  
  664. SUB addMessageToChat (id AS INTEGER, text$)
  665.     DIM i AS INTEGER
  666.     FOR i = 2 TO UBOUND(chat)
  667.         SWAP chat(i), chat(i - 1)
  668.     NEXT
  669.     chat(UBOUND(chat)).id = id
  670.     chat(UBOUND(chat)).state = True
  671.     IF id > 0 THEN
  672.         chat(UBOUND(chat)).name = player(id).name
  673.         chat(UBOUND(chat)).color = player(id).color
  674.     ELSE
  675.         chat(UBOUND(chat)).name = "SYSTEM:"
  676.         chat(UBOUND(chat)).color = 7
  677.         chatOpen = True
  678.     END IF
  679.     chat(UBOUND(chat)).text = text$
  680.  
  681. SUB addWarning (text$)
  682.     DIM i AS INTEGER
  683.     FOR i = 1 TO UBOUND(warning)
  684.         IF warning(i).state = False THEN
  685.             warning(i).state = True
  686.             warning(i).name = text$
  687.             warning(i).ping = TIMER
  688.             EXIT FOR
  689.         END IF
  690.     NEXT
  691.  
  692. SUB sendData (client AS object, id AS INTEGER, value$)
  693.     DIM packet$
  694.     packet$ = MKI$(id) + value$ + endSignal
  695.     IF client.handle THEN PUT #client.handle, , packet$
  696.  
  697. SUB getData (client AS object, buffer AS STRING)
  698.     DIM incoming$
  699.     GET #client.handle, , incoming$
  700.     buffer = buffer + incoming$
  701.  
  702. FUNCTION parse%% (buffer AS STRING, id AS INTEGER, value$)
  703.     DIM endMarker AS LONG
  704.     endMarker = INSTR(buffer, endSignal)
  705.     IF endMarker THEN
  706.         id = CVI(LEFT$(buffer, 2))
  707.         value$ = MID$(buffer, 3, endMarker - 3)
  708.         buffer = MID$(buffer, endMarker + LEN(endSignal))
  709.         parse%% = True
  710.     END IF
  711.  
  712. SUB adjustCamera
  713.     IF player(me).x + camera.x > _WIDTH / 2 + cameraWindow THEN
  714.         camera.x = _WIDTH / 2 - player(me).x + cameraWindow
  715.     ELSEIF player(me).x + camera.x < _WIDTH / 2 - cameraWindow THEN
  716.         camera.x = _WIDTH / 2 - player(me).x - cameraWindow
  717.     END IF
  718.     IF camera.x > 0 THEN camera.x = 0
  719.     IF camera.x < -(_WIDTH(mapImage) - _WIDTH) THEN camera.x = -(_WIDTH(mapImage) - _WIDTH)
  720.  
  721.     IF player(me).y + camera.y > _HEIGHT / 2 + cameraWindow THEN
  722.         camera.y = _HEIGHT / 2 - player(me).y + cameraWindow
  723.     ELSEIF player(me).y + camera.y < _HEIGHT / 2 - cameraWindow THEN
  724.         camera.y = _HEIGHT / 2 - player(me).y - cameraWindow
  725.     END IF
  726.     IF camera.y > 0 THEN camera.y = 0
  727.     IF camera.y < -(_HEIGHT(mapImage) - _HEIGHT) THEN camera.y = -(_HEIGHT(mapImage) - _HEIGHT)
  728.  
  729.  
  730. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  731.     ' CX = center x coordinate
  732.     ' CY = center y coordinate
  733.     '  R = radius
  734.     '  C = fill color
  735.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  736.     DIM X AS INTEGER, Y AS INTEGER
  737.     Radius = ABS(R)
  738.     RadiusError = -Radius
  739.     X = Radius
  740.     Y = 0
  741.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  742.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  743.     WHILE X > Y
  744.         RadiusError = RadiusError + Y * 2 + 1
  745.         IF RadiusError >= 0 THEN
  746.             IF X <> Y + 1 THEN
  747.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  748.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  749.             END IF
  750.             X = X - 1
  751.             RadiusError = RadiusError - X * 2
  752.         END IF
  753.         Y = Y + 1
  754.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  755.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  756.     WEND
  757.  
  758. SUB db (text$)
  759.     $IF DEBUGGING = TRUE THEN
  760.         _ECHO text$
  761.     $ELSE
  762.         DIM dummy$
  763.         dummy$ = text$
  764.     $END IF
  765.  
  766. FUNCTION dist! (x1!, y1!, x2!, y2!)
  767.     dist! = _HYPOT((x2! - x1!), (y2! - y1!))
  768.  
  769. SUB thickLine (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE, lineWeight%, c~&)
  770.     DIM a AS SINGLE, x0 AS SINGLE, y0 AS SINGLE
  771.     DIM prevDest AS LONG
  772.     DIM colorSample AS LONG
  773.  
  774.     colorSample = _NEWIMAGE(1, 1, 32)
  775.  
  776.     prevDest = _DEST
  777.     _DEST colorSample
  778.     PSET (0, 0), c~&
  779.     _DEST prevDest
  780.  
  781.     a = _ATAN2(y2 - y1, x2 - x1)
  782.     a = a + _PI / 2
  783.     x0 = 0.5 * lineWeight% * COS(a)
  784.     y0 = 0.5 * lineWeight% * SIN(a)
  785.  
  786.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), colorSample TO(x1 - x0, y1 - y0)-(x1 + x0, y1 + y0)-(x2 + x0, y2 + y0), , _SMOOTH
  787.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), colorSample TO(x1 - x0, y1 - y0)-(x2 + x0, y2 + y0)-(x2 - x0, y2 - y0), , _SMOOTH
  788.  
  789.     _FREEIMAGE colorSample
  790.  
  791. SUB addParticles (x AS SINGLE, y AS SINGLE, total AS INTEGER, c AS _UNSIGNED LONG)
  792.     DIM addedP AS INTEGER, p AS INTEGER
  793.     DIM a AS SINGLE
  794.  
  795.     addedP = 0: p = 0
  796.     DO
  797.         p = p + 1
  798.         IF p > UBOUND(particle) THEN EXIT DO
  799.         IF particle(p).state = True THEN _CONTINUE
  800.         addedP = addedP + 1
  801.         particle(p).state = True
  802.         particle(p).x = x
  803.         particle(p).y = y
  804.         a = RND * _PI(2)
  805.         particle(p).xv = COS(a) * (RND * 10)
  806.         particle(p).yv = SIN(a) * (RND * 10)
  807.         particle(p).r = _RED32(c)
  808.         particle(p).g = _GREEN32(c)
  809.         particle(p).b = _BLUE32(c)
  810.         particle(p).size = _CEIL(RND * 3)
  811.         particle(p).start = TIMER
  812.         particle(p).duration = RND
  813.     LOOP UNTIL addedP >= total
  814.  
  815. SUB updateParticles
  816.     DIM i AS INTEGER
  817.  
  818.     FOR i = 1 TO UBOUND(particle)
  819.         CONST gravity = .1
  820.         IF particle(i).state THEN
  821.             particle(i).xv = particle(i).xv + particle(i).xa
  822.             particle(i).x = particle(i).x + particle(i).xv
  823.             particle(i).yv = particle(i).yv + particle(i).ya + gravity
  824.             particle(i).y = particle(i).y + particle(i).yv
  825.  
  826.             IF particle(i).x > _WIDTH(mapImage) OR particle(i).x < 0 OR particle(i).y > _HEIGHT(mapImage) OR particle(i).y < 0 THEN
  827.                 particle(i).state = False
  828.             ELSE
  829.                 CircleFill particle(i).x + camera.x, particle(i).y + camera.y, particle(i).size, _RGB32(particle(i).r, particle(i).g, particle(i).b, map(TIMER - particle(i).start, 0, particle(i).duration, 255, 0))
  830.             END IF
  831.         END IF
  832.     NEXT
  833.  
  834. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  835.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  836.  
Title: Re: Pretentious not-yet-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 26, 2020, 01:08:41 am
Version 3 of the client attached to this post. Notice that previous versions won't be able to connect to the servers now.

 
Title: Re: Pretentious not-yet-a-clone clone of Among Us in QB64
Post by: SMcNeill on October 26, 2020, 04:52:25 am
Question:  Can you have the game simply try to share itself across all three servers, much like IRC and freenode does?  QB64 has a limited user base, and having to divide your chances into thirds to find someone else playing, seems like it'd just make it harder to find others to join with. 
Title: Re: Pretentious not-yet-a-clone clone of Among Us in QB64
Post by: qbkiller101 on October 26, 2020, 06:02:27 am
Hey, @FellippeHeitor can you add an option on the main screen to choose controls? WASD, arrow keys, or mouse, cuz I can't figure out graphics, I have written the code for movement of each option though.
Title: Re: Pretentious not-yet-a-clone clone of Among Us in QB64
Post by: FellippeHeitor on October 26, 2020, 12:32:30 pm
@SMcNeill We're still researching a way to keep it in sync across clients in the same server, that might at some point be considered. When you're at Discord let me know and I'll tell you in which server I currently am logged in.

@qbkiller101 I'll check it out, thanks!