Author Topic: Gapper, Give it a try! (updated[11/19/21])  (Read 2578 times)

0 Members and 1 Guest are viewing this topic.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Gapper, Give it a try! (updated[11/19/21])
« on: November 18, 2021, 01:36:35 pm »
So I present Gapper. Surf the grid changing its color to rack up points. But beware the Seeker who is out to get you!

Being absurdly busy of late this has taken far longer than it should of, but its coming along.

There is a few things to iron out yet; Bonus squares, the ability to "Gap", the 5000 point bonus life, and the high score list.
But based on my trial runs everything seems to be working as close to original as possible. Granted my own tests hardly find anything that might be hidden or obscure. So I could use some other players to make sure they can not find anything!

The seeker has a very subtle speed curve and wont reach full speed till closer to Level 8 now.

need to find a way to add the intro screens as data without it taking 2.4mb of space(original BMP was only 900k)

Controls: Arrow Keys
                Space Bar- place a temporary gap in the line.
(introduced a bug, you only get an extra life if you have exact multiples of 5000! fixing this soon) Fixed(again)
Code: QB64: [Select]
  1. 'Gapper(1986) Clone
  2. '10\25\2019 Cobalt
  3. 'ÃInital Start; Layout, Gapper, Seeker, L1 Grid finished [13:55EDT]
  4. 'ÀCorreted 'Catcher' to 'Seeker' as per original game
  5. '10\31\2021
  6. 'ÃFixed Seeker movement issue with help from Bplus and Keybone, used ABS as per Bplus
  7. 'Àadded startup screen, player initials input,game options
  8. '11\1\2021
  9. 'ÃAdded the instructions screens
  10. 'Àenabled collision of Seeker and Gapper
  11. '11\11\2021
  12. 'ÃFinished all 8 boards
  13. '11\13\2021
  14. 'ÃInserted Bplus's code for detecting completed boxes.
  15. '11\14\2021
  16. 'ÃIntegrated Bplus's code for detecting completed boxes and filling them.
  17. 'ÃAdded score amount to filled boxes
  18. 'ÃLevels now end when boxes are full
  19. 'ÀScore is now kept
  20. '11\15\2021
  21. 'ÃFixed a few minor bugs with help from Bplus
  22. 'ÃReplaced each level creation sub with a master so now all levels created with in a single sub, saved ~210 lines
  23. 'ÀChanged Seeker speed to use reducing timer to move faster as levels progress.
  24. '11\18\2021
  25. 'ÃAdded extra life at 5000 point intervals
  26. 'ÀAdded ability to create "Gaps" on board
  27.  
  28. TYPE GameData
  29.  Player AS STRING * 4
  30.  Score AS LONG
  31.  Lives AS _BYTE
  32.  Level AS _BYTE
  33.  GX AS INTEGER 'Gapper X location
  34.  GY AS INTEGER 'Gapper Y location
  35.  GD AS _BYTE 'Gapper direction
  36.  SX AS INTEGER
  37.  SY AS INTEGER
  38.  SS AS _BYTE 'Seeker speed
  39.  SD AS _BYTE 'Seeker direction
  40.  Start AS _BYTE 'is level started or not(nothing happens until started)
  41.  FPS AS INTEGER
  42.  Quit AS _BYTE
  43.  Caught AS _BYTE 'has the seeker caught the gapper?
  44.  Gapped AS _BYTE 'has the player used the gap feature?
  45.  Gap_time AS SINGLE 'the time the gap was placed. Gaps last less time at higher levels
  46.  'board info
  47.  CellHeight AS _BYTE
  48.  CellWidth AS _BYTE
  49.  Rows AS _BYTE
  50.  Columns AS _BYTE
  51.  Offx AS _BYTE
  52.  Offy AS _BYTE
  53.  Needed AS _BYTE 'number of cells needing finished to win level
  54.  Finished AS _BYTE 'number of cells currently boxed in
  55.  
  56. TYPE High_Scores
  57.  Nam AS STRING * 4
  58.  Score AS LONG
  59.  Level AS INTEGER
  60.  
  61. CONST TRUE = -1, FALSE = NOT TRUE, Gapper = 1, Seeker = 2
  62. CONST UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4
  63. CONST Key_Right = 19712, Key_Left = 19200, Key_Up = 18432, Key_Down = 20480
  64. CONST Key_Space = 32, Key_Enter = 13
  65. CONST Cyan = &HFF10E0E0~& '_RGB32(0, 170, 170)
  66. CONST Magenta = &HFFC040C0~&
  67. CONST OffWhite = &HFFC0C0C0~&
  68. CONST Brown = &HFFB06000~&
  69. CONST Yellow = &HFFFFFF00~&
  70. CONST Black = &HFF000000~&
  71. CONST DB_Blue = &HFF0000FF~&
  72.  
  73. Level_data:
  74. DATA 104,60,3,3,4,10,9,0,14,626,374
  75. DATA 76,44,4,4,8,12,16,8,18,616,370
  76. DATA 60,36,5,5,10,10,25,12,14,612,374
  77. DATA 48,24,7,6,16,16,42,24,26,600,362
  78. DATA 36,24,7,8,16,16,44,24,26,458,362
  79. DATA 36,24,7,8,16,16,40,168,26,458,362
  80. DATA 36,24,7,8,16,16,44,168,26,600,362
  81. DATA 36,24,7,8,16,16,56,24,26,600,362
  82.  
  83. SCREEN _NEWIMAGE(640, 440, 32)
  84. DIM SHARED Layer(11) AS LONG, G AS GameData, Frames%
  85. DIM SHARED Scores(10) AS High_Scores
  86. DIM SHARED FinishedBox(72) AS _BYTE, T1 AS LONG, T2 AS LONG
  87.  
  88. Layer(0) = _DISPLAY
  89. Layer(1) = _NEWIMAGE(640, 440, 32) 'mix layer
  90. Layer(2) = _NEWIMAGE(320, 220, 32) 'Grid Layer
  91. Layer(3) = _NEWIMAGE(640, 440, 32) 'Sprite layer
  92. Layer(4) = _NEWIMAGE(320, 220, 32) 'Info layer
  93. Layer(5) = _NEWIMAGE(640, 440, 32) 'Collision 'Gapper\Catcher' layer
  94. Layer(6) = _NEWIMAGE(640, 440, 32) 'Collision 'Grid' layer
  95. Layer(7) = _NEWIMAGE(640, 440, 32) 'debug layer
  96. Layer(8) = _NEWIMAGE(320, 220, 32) 'Menu layer
  97. Layer(9) = _NEWIMAGE(320, 240, 32) 'instructions layer
  98. Layer(10) = _NEWIMAGE(320, 8, 32) 'title bar layer
  99. Layer(11) = _NEWIMAGE(320, 220, 32) 'point test location layer
  100.  
  101. _FONT 8, Layer(4)
  102. _FONT 8, Layer(8)
  103. _FONT 8, Layer(9)
  104. _FONT 8, Layer(10)
  105. _FONT 8, Layer(2)
  106. _CLEARCOLOR _RGB32(0, 0, 0), Layer(3)
  107. _CLEARCOLOR _RGB32(0, 0, 0), Layer(7)
  108.  
  109. _SOURCE Layer(6)
  110. ON TIMER(T1, 1) FPS
  111. ON TIMER(T2, .05) Move_Seeker
  112.  
  113. Game_INIT
  114. Title_Startup
  115.  
  116.  
  117. SUB Play_game
  118.  DO
  119.   IF _KEYDOWN(27) THEN ExitFlag%% = TRUE: G.Quit = TRUE
  120.   IF _KEYDOWN(Key_Up) THEN
  121.    G.Start = TRUE
  122.    IF NOT Collision_Grid(Gapper, UP) THEN G.GD = UP
  123.   END IF
  124.   IF _KEYDOWN(Key_Down) THEN
  125.    G.Start = TRUE
  126.    IF NOT Collision_Grid(Gapper, DOWN) THEN G.GD = DOWN
  127.   END IF
  128.   IF _KEYDOWN(Key_Left) THEN
  129.    G.Start = TRUE
  130.    IF NOT Collision_Grid(Gapper, LEFT) THEN G.GD = LEFT
  131.   END IF
  132.   IF _KEYDOWN(Key_Right) THEN
  133.    G.Start = TRUE
  134.    IF NOT Collision_Grid(Gapper, RIGHT) THEN G.GD = RIGHT
  135.   END IF
  136.   IF _KEYDOWN(32) AND G.Gapped = FALSE AND G.Start THEN
  137.    G.Gapped = TRUE
  138.    G.Score = G.Score - 5
  139.    Create_Gap
  140.   END IF
  141.   IF G.Start THEN Move_Gapper ':Move_Seeker
  142.   IF G.Gapped THEN Time_Gap 'if there is a gap then check how long its been there
  143.  
  144.   FOR i%% = 1 TO G.Columns * G.Rows
  145.    IF BoxSurrounded(i%%) THEN FinishedBox(i%%) = TRUE
  146.    IF FinishedBox(i%%) THEN FillBox i%%
  147.   NEXT i%%
  148.  
  149.   Game_Data_Update
  150.   _PUTIMAGE (0, 0)-STEP(639, 15), Layer(10), Layer(1) 'title bar
  151.   _PUTIMAGE , Layer(4), Layer(1) 'information bar
  152.   _PUTIMAGE , Layer(2), Layer(1) 'game board
  153.   Place_Gapper
  154.   Place_Seeker
  155.   IF G.Caught THEN 'seeker caught 'em
  156.    ClearLayer Layer(5)
  157.    Reset_Pos
  158.    DrawBoard
  159.    G.Lives = G.Lives - 1
  160.    IF G.Lives = -1 THEN ExitFlag%% = TRUE
  161.   END IF
  162.   ' _PRINTSTRING (600, 0), STR$(G.FPS), Layer(7)
  163.   _PUTIMAGE , Layer(7), Layer(1) 'debug layer
  164.   _PUTIMAGE , Layer(1), Layer(0)
  165.   _LIMIT 60
  166.   ClearLayer Layer(1)
  167.   Frames% = Frames% + 1
  168.   IF G.Finished = G.Needed THEN _DELAY .5: Change_Level
  169.  LOOP UNTIL ExitFlag%%
  170.  
  171. SUB Place_Gapper
  172.  old& = _DEST
  173.  _DEST Layer(5)
  174.  LINE (G.GX - 2, G.GY - 2)-STEP(20, 18), Black, BF
  175.  'place gapper-----
  176.  _PUTIMAGE (G.GX, G.GY), Layer(3), Layer(1), (318, 218)-STEP(15, 13)
  177.  'place Gapper shadow
  178.  _PUTIMAGE (G.GX, G.GY), Layer(3), Layer(5), (318, 218)-STEP(15, 13)
  179.  ' _DEST old&
  180.  
  181. SUB Place_Seeker
  182.  'place Seeker----
  183.  _PUTIMAGE (G.SX, G.SY), Layer(3), Layer(1), (341, 218)-STEP(14, 11)
  184.  '-----------------
  185.  
  186.  
  187. SUB Game_INIT
  188.  _DEST Layer(3)
  189.  'Player----
  190.  DRAW "c" + STR$(Cyan) + "drurd8l2dr3u9d2rd5ru5rd5ru5ru2d9r3ul2u8r2dlbl3c" + STR$(Magenta) + "u3ld3lu3ld3"
  191.  DRAW "bd7d3ru3rd3ru3bu3br3r4ul4bl9l4dr4"
  192.  '----------
  193.  DRAW "br20bu7"
  194.  'Seeker----
  195.  DRAW "c" + STR$(Cyan) + "r3dl3bd10r3ul3br10r3dl3bu10r3ul3c" + STR$(Magenta) + "bd2brl3dr3bd5l3dr3bl6l3ur3"
  196.  DRAW "bu5l3ur3d2lr5dl5dr5dl5"
  197.  '------------
  198.  Title_Header
  199.  _DEST Layer(5)
  200.  LINE (0, 0)-STEP(639, 439), Black, BF
  201.  _DEST Layer(0)
  202.  G.Score = 0
  203.  G.Lives = 2
  204.  G.Level = 1
  205.  
  206. SUB Title_Header
  207.  'Header
  208.  _DEST Layer(10)
  209.  LINE (84, 0)-STEP(151, 8), Magenta, BF
  210.  LINE (132, 0)-STEP(52, 8), Cyan, BF
  211.  COLOR Magenta
  212.  _PRINTSTRING (135, 1), "GAPPER"
  213.  COLOR OffWhite
  214.  
  215. SUB Game_Data_Update
  216.  'Info area updating ---------------
  217.  _PRINTSTRING (7, 192), "Score[      ]    Lives[ ]    Level[  ]", Layer(4)
  218.  _PRINTSTRING (95 - ((LEN(LTRIM$(STR$(G.Score))) - 1) * 8), 192), LTRIM$(STR$(G.Score)), Layer(4)
  219.  _PRINTSTRING (191, 192), LTRIM$(STR$(G.Lives)), Layer(4)
  220.  _PRINTSTRING (295 - ((LEN(LTRIM$(STR$(G.Level))) - 1) * 8), 192), LTRIM$(STR$(G.Level)), Layer(4)
  221.  '-----------------------------------
  222.  
  223. SUB DrawBoard
  224.  _DEST Layer(2)
  225.  SELECT CASE G.Level
  226.   CASE 1 TO 8 'draw level 1 grid
  227.    Master_Level G.Level
  228.   CASE ELSE 'after level 8 board is random between 5 and 8
  229.    Master_Level INT(RND * 4) + 5
  230.  _DEST Layer(0)
  231.  ClearLayer Layer(6)
  232.  _PUTIMAGE , Layer(2), Layer(6) 'make a copy for the collision layer
  233.  
  234. SUB ClearLayer (L&)
  235.  _DEST L&
  236.  CLS
  237.  
  238. SUB ClearLayerTrans (L&)
  239.  _DEST L&
  240.  CLS , 0
  241.  
  242. FUNCTION Collision_Seeker%%
  243.  Result%% = FALSE
  244.  _SOURCE Layer(5)
  245.  IF POINT(G.SX, G.SY) <> Black THEN Result%% = TRUE
  246.  IF POINT(G.SX + 8, G.SY) <> Black THEN Result%% = TRUE
  247.  IF POINT(G.SX, G.SY + 8) <> Black THEN Result%% = TRUE
  248.  IF POINT(G.SX + 8, G.SY + 8) <> Black THEN Result%% = TRUE
  249.  Collision_Seeker = Result%%
  250.  _SOURCE Layer(6)
  251.  
  252. FUNCTION Collision_Grid%% (who%%, Direction%%)
  253.  Result%% = TRUE 'always assume collision
  254.  SELECT CASE who%% 'who are we checking collision for?
  255.   CASE Gapper
  256.    SELECT CASE Direction%%
  257.     CASE UP 'see if there is grid up from Gappers position
  258.      Check~& = POINT(G.GX + 8, G.GY + 5)
  259.     CASE DOWN 'see if there is Grid below Gapper
  260.      Check~& = POINT(G.GX + 8, G.GY + 9)
  261.     CASE LEFT 'check for grid to the left of Gapper
  262.      Check~& = POINT(G.GX + 6, G.GY + 7)
  263.     CASE RIGHT 'Check for grid to the Right of Gapper
  264.      Check~& = POINT(G.GX + 10, G.GY + 7)
  265.    END SELECT
  266.   CASE Seeker
  267.    SELECT CASE Direction%%
  268.     CASE UP 'see if there is grid up from Gappers position
  269.      Check~& = POINT(G.SX + 8, G.SY + 5)
  270.     CASE DOWN 'see if there is Grid below Gapper
  271.      Check~& = POINT(G.SX + 8, G.SY + 9)
  272.     CASE LEFT 'check for grid to the left of Gapper
  273.      Check~& = POINT(G.SX + 6, G.SY + 7)
  274.     CASE RIGHT 'Check for grid to the Right of Gapper
  275.      Check~& = POINT(G.SX + 10, G.SY + 7)
  276.    END SELECT
  277.  Blue~%% = _BLUE32(Check~&) 'check for Blue, grid is Cyan in color
  278.  IF Blue~%% THEN Result%% = FALSE 'there is grid to move onto, no collision with edge of grid
  279.  Collision_Grid = Result%%
  280.  '_SOURCE Layer(0)
  281.  
  282. SUB Move_Seeker
  283.  IF G.Start THEN
  284.   Seeker_Logic
  285.   SELECT CASE G.SD
  286.    CASE UP
  287.     IF NOT Collision_Grid(Seeker, UP) THEN G.SY = G.SY - 2
  288.    CASE DOWN
  289.     IF NOT Collision_Grid(Seeker, DOWN) THEN G.SY = G.SY + 2
  290.    CASE LEFT
  291.     IF NOT Collision_Grid(Seeker, LEFT) THEN G.SX = G.SX - 2
  292.    CASE RIGHT
  293.     IF NOT Collision_Grid(Seeker, RIGHT) THEN G.SX = G.SX + 2
  294.  IF Collision_Seeker THEN G.Caught = TRUE
  295.  
  296. SUB Move_Gapper
  297.  SELECT CASE G.GD
  298.   CASE UP
  299.    IF NOT Collision_Grid(Gapper, UP) THEN G.GY = G.GY - 2
  300.   CASE DOWN
  301.    IF NOT Collision_Grid(Gapper, DOWN) THEN G.GY = G.GY + 2
  302.   CASE LEFT
  303.    IF NOT Collision_Grid(Gapper, LEFT) THEN G.GX = G.GX - 2
  304.   CASE RIGHT
  305.    IF NOT Collision_Grid(Gapper, RIGHT) THEN G.GX = G.GX + 2
  306.  Color_Line
  307.  
  308. SUB Seeker_Logic
  309.  DistX% = (G.SX - G.GX) 'find X distance between seeker and gapper
  310.  DistY% = (G.SY - G.GY) 'find Y distance between Seeker and Gapper
  311.  IF ABS(DistX%) > ABS(DistY%) THEN 'if player is farther on the X then
  312.   IF DistX% < 0 THEN
  313.    Turn_Seeker RIGHT 'try going right to get closer
  314.   ELSE
  315.    Turn_Seeker LEFT 'try going left to get closer
  316.   END IF
  317.  ELSE 'player is farther on the Y then
  318.   IF DistY% < 0 THEN
  319.    Turn_Seeker DOWN 'try going down to get closer
  320.   ELSE
  321.    Turn_Seeker UP 'try going up to get closer
  322.   END IF
  323.  
  324. SUB Turn_Seeker (Direction%%)
  325.  SELECT CASE Direction%%
  326.   CASE UP
  327.    IF NOT Collision_Grid(Seeker, UP) THEN G.SD = UP
  328.   CASE DOWN
  329.    IF NOT Collision_Grid(Seeker, DOWN) THEN G.SD = DOWN
  330.   CASE LEFT
  331.    IF NOT Collision_Grid(Seeker, LEFT) THEN G.SD = LEFT
  332.   CASE RIGHT
  333.    IF NOT Collision_Grid(Seeker, RIGHT) THEN G.SD = RIGHT
  334.  
  335. SUB Color_Line
  336.  _DEST Layer(2)
  337.  LINE (4 + G.GX \ 2, 3 + G.GY \ 2)-STEP(0, 0), Magenta, BF
  338.  _DEST Layer(0)
  339.  
  340. SUB FPS
  341.  G.FPS = Frames%
  342.  Frames% = 0
  343.  
  344. SUB Title_Startup
  345.  Load_Scores
  346.  _DEST Layer(8)
  347.  LINE (84, 0)-STEP(151, 8), Brown, BF
  348.  LINE (132, 0)-STEP(52, 8), Cyan, BF
  349.  COLOR Brown
  350.  _PRINTSTRING (135, 1), "GAPPER"
  351.  LINE (0, 140)-STEP(639, 8), Brown, BF
  352.  COLOR Black
  353.  _PRINTSTRING (0, 141), "Score:"
  354.  _PRINTSTRING (220, 141), "Level:"
  355.  _PRINTSTRING (100 - (LEN(LTRIM$(STR$(G.Score))) * 8), 141), STR$(G.Score) + "."
  356.  _PRINTSTRING (284 - (LEN(LTRIM$(STR$(G.Level))) * 8), 141), STR$(G.Level)
  357.  
  358.  COLOR Yellow
  359.  _PRINTSTRING (100, 160), "P: Play a game."
  360.  _PRINTSTRING (100, 170), "Q: Quit"
  361.  _PRINTSTRING (100, 180), "N: New Player"
  362.  _PRINTSTRING (100, 190), "I: Instuctions"
  363.  
  364.  Get_Player
  365.  IF Search_For_Player THEN AddPlayer 'first time this player has played!
  366.  Display_HighScores
  367.  Get_Menu_Selection
  368.  
  369. SUB Get_Player
  370.  Blink%% = TRUE: I$ = ""
  371.  _DEST Layer(8)
  372.  COLOR Magenta
  373.  LINE (0, 210)-STEP(219, 9), Black, BF
  374.  _PRINTSTRING (0, 210), "Enter your initials:"
  375.  COLOR OffWhite
  376.  DO 'Initials input Loop
  377.   KBD& = _KEYHIT
  378.   SELECT CASE KBD&
  379.    CASE 8 'delete
  380.     IF LEN(I$) THEN I$ = LEFT$(I$, LEN(I$) - 1)
  381.     LINE (168, 210)-(248, 219), Black, BF
  382.    CASE 32 TO 122 'characters
  383.     IF LEN(I$) < 3 THEN I$ = I$ + CHR$(KBD&)
  384.     LINE (168, 210)-(248, 219), Black, BF
  385.    CASE 13 'accept input(if any)
  386.     IF RTRIM$(I$) <> "" THEN ExitFlag%% = TRUE ELSE BEEP
  387.    CASE 27
  388.     ExitFlag%% = TRUE
  389.     G.Quit = TRUE
  390.   COLOR OffWhite
  391.   _PRINTSTRING (168, 210), I$
  392.   IF Blink%% THEN COLOR Black ELSE COLOR OffWhite
  393.   _PRINTSTRING (168 + LEN(I$) * 8, 210), "_"
  394.   _PUTIMAGE , Layer(8), _DISPLAY
  395.   _LIMIT 30
  396.   t%% = t%% + 1
  397.   IF t%% = 4 THEN Blink%% = NOT Blink%%: t%% = 0
  398.  LOOP UNTIL ExitFlag%%
  399.  G.Player = I$
  400.  
  401. SUB Get_Menu_Selection
  402.  LINE (0, 210)-STEP(200, 9), Black, BF
  403.  _PRINTSTRING (0, 210), "Please enter selection:  "
  404.  DO
  405.   KBD& = _KEYHIT
  406.   SELECT CASE KBD&
  407.    CASE ASC("p") OR ASC("P")
  408.     New_Game
  409.     DrawBoard
  410.     TIMER(T1&) ON
  411.     TIMER(T2&) ON
  412.     Play_game
  413.     TIMER(T1&) OFF
  414.     TIMER(T2&) OFF
  415.  
  416.     CLS
  417.     _KEYCLEAR
  418.    CASE ASC("q") OR ASC("Q")
  419.     ExitFlag%% = TRUE
  420.     G.Quit = TRUE
  421.    CASE ASC("n") OR ASC("N")
  422.     Get_Player
  423.     LINE (0, 210)-STEP(200, 9), Black, BF
  424.     _PRINTSTRING (0, 210), "Please enter selection:  "
  425.    CASE ASC("i") OR ASC("I")
  426.     Instructions
  427.    CASE 27
  428.     'ExitFlag%% = TRUE
  429.     'G.Quit = TRUE
  430.   _PUTIMAGE , Layer(8), _DISPLAY
  431.  LOOP UNTIL ExitFlag%%
  432.  
  433. SUB Display_HighScores
  434.  _DEST Layer(8)
  435.  IF LTRIM$(RTRIM$(Scores(1).Nam)) <> "" THEN
  436.   COLOR Magenta
  437.   _PRINTSTRING (0, 24), "High scores:"
  438.   FOR i%% = 1 TO 10
  439.    IF G.Player = Scores(i%%).Nam THEN
  440.     COLOR Yellow 'player shows up Yellow
  441.    ELSEIF i%% = 1 THEN
  442.     COLOR Magenta 'High score if not player shows magenta
  443.    ELSE
  444.     COLOR OffWhite 'everybody else is off white
  445.    END IF
  446.   NEXT i%%
  447.  
  448. SUB Instructions
  449.  ClearLayer Layer(0)
  450.  _DEST Layer(9)
  451.  LINE (84, 0)-STEP(151, 8), Brown, BF
  452.  LINE (132, 0)-STEP(52, 8), Cyan, BF
  453.  COLOR Brown
  454.  _PRINTSTRING (135, 1), "GAPPER"
  455.  COLOR OffWhite
  456.  _PRINTSTRING (84, 10), "OBJECT"
  457.  _PRINTSTRING (1, 20), "To color all the blue lines"
  458.  _PRINTSTRING (1, 30), "red by moving your man GAPPER"
  459.  _PRINTSTRING (1, 40), "with the arrow keys.  At the"
  460.  _PRINTSTRING (1, 50), "same time, you myst avoid"
  461.  _PRINTSTRING (1, 60), "the SEEKER."
  462.  
  463.  _PRINTSTRING (84, 80), "POINTS"
  464.  _PRINTSTRING (1, 90), "Fifty points are awarded for"
  465.  _PRINTSTRING (1, 100), "each square that you surround"
  466.  _PRINTSTRING (1, 110), "in red.  100 points are given"
  467.  _PRINTSTRING (1, 120), "when you encircle the extra"
  468.  _PRINTSTRING (1, 130), "point box while it is on. Each"
  469.  _PRINTSTRING (1, 140), "gap costs 5 points."
  470.  
  471.  _PRINTSTRING (84, 150), "GAPPING"
  472.  _PRINTSTRING (1, 160), "You can create a temporary"
  473.  _PRINTSTRING (1, 170), "gap in the lines by pressing"
  474.  _PRINTSTRING (1, 180), "the SPACE bar or RETURN.  The"
  475.  _PRINTSTRING (1, 190), "word ON appears as long as the"
  476.  _PRINTSTRING (1, 200), "gap is active.  Neither you nor"
  477.  _PRINTSTRING (1, 210), "the seeker can cross the gap."
  478.  
  479.  _PRINTSTRING (0, 230), "Press a key..."
  480.  _PUTIMAGE , Layer(9), _DISPLAY
  481.  _DELAY .5
  482.  'end of page 1
  483.  DO: _LIMIT 24: LOOP WHILE INKEY$ = ""
  484.  CLS
  485.  LINE (84, 0)-STEP(151, 8), Brown, BF
  486.  LINE (132, 0)-STEP(52, 8), Cyan, BF
  487.  COLOR Brown
  488.  _PRINTSTRING (135, 1), "GAPPER"
  489.  COLOR OffWhite
  490.  _PRINTSTRING (84, 10), "LEVELS"
  491.  _PRINTSTRING (1, 20), "The level increases each time"
  492.  _PRINTSTRING (1, 30), "you complete a screen.  The"
  493.  _PRINTSTRING (1, 40), "seeker gets faster, the gap"
  494.  _PRINTSTRING (1, 50), "time shorter and there will"
  495.  _PRINTSTRING (1, 60), "be more boxes."
  496.  
  497.  _PRINTSTRING (84, 80), "LIVES"
  498.  _PRINTSTRING (1, 90), "You start out with 2 extra"
  499.  _PRINTSTRING (1, 100), "men.  One more will be given"
  500.  _PRINTSTRING (1, 110), "for each 5000 points."
  501.  
  502.  _PRINTSTRING (84, 130), "START"
  503.  _PRINTSTRING (1, 140), "When the grid appears, you"
  504.  _PRINTSTRING (1, 150), "Will be in the top left and"
  505.  _PRINTSTRING (1, 160), "the seeker at the low right."
  506.  _PRINTSTRING (1, 170), "Press a key to begin each new"
  507.  _PRINTSTRING (1, 180), "screen."
  508.  
  509.  _PRINTSTRING (0, 230), "Press a key..."
  510.  'end of page 2
  511.  _PUTIMAGE , Layer(9), _DISPLAY
  512.  _DELAY .5
  513.  DO: _LIMIT 24: LOOP WHILE INKEY$ = ""
  514.  ClearLayer Layer(0)
  515.  
  516. SUB Load_Scores
  517.  OPEN "Gapper.HSL" FOR BINARY AS #1
  518.  GET #1, , Count%%
  519.  FOR i%% = 1 TO Count%%
  520.   GET #1, , Scores(i%%).Nam
  521.   GET #1, , Scores(i%%)
  522.   GET #1, , Scores(i%%)
  523.  NEXT i%%
  524.  CLOSE #1
  525.  
  526. FUNCTION Search_For_Player
  527.  FOR i%% = 1 TO 10
  528.   IF G.Player = Scores(i%%).Nam THEN Result%% = TRUE: i%% = 11 ELSE Result%% = FALSE
  529.  NEXT i%%
  530.  Search_For_Player = Result%%
  531.  
  532. SUB AddPlayer
  533.  OPEN "Gapper.HSL" FOR BINARY AS #1
  534.  GET #1, , Count%%
  535.  IF Count%% < 10 THEN Count%% = Count%% + 1
  536.  PUT #1, 1, Count%%
  537.  PUT #1, 1 + 10 * Count%%, G.Player
  538.  PUT #1, , NULL& 'filler for score
  539.  PUT #1, , NULL% 'filler for level
  540.  CLOSE #1
  541.  Load_Scores 'reload score list
  542.  
  543. SUB Reset_Pos
  544.  PLAY "o1l32aacceegg"
  545.  _DELAY .25
  546.  G.Start = FALSE
  547.  G.Caught = FALSE
  548.  G.Finished = 0
  549.  ClearLayerTrans Layer(2)
  550.  FOR i%% = 0 TO 72
  551.   FinishedBox(i%%) = FALSE
  552.  NEXT i%%
  553.  
  554.  
  555.  
  556. FUNCTION BoxSurrounded%% (boxNumber AS INTEGER) 'save already tested boxes in shared array BoxesSurrounded()
  557.  'Bplus contributed code. 11\12\2021
  558.  'some variables changed to use existing, `**` comments are added
  559.  _SOURCE Layer(2)
  560.  IF FinishedBox(boxNumber) = 0 THEN '**Is the box completed already?
  561.   row = INT((boxNumber - 1) / G.Columns) '[cellsPerCpl)] '**which row
  562.   col = (boxNumber - 1) MOD G.Columns + 1 '[cellsAcross + 1] '**which column
  563.  
  564.   Good%% = TRUE
  565.   FOR I% = row * G.CellHeight TO (row + 1) * G.CellHeight STEP 4 '**No need to check every pixel
  566.    IF POINT(G.Offx + (col - 1) * G.CellWidth, G.Offy + I%) <> Magenta THEN I% = 9999: Good%% = FALSE ' False Baox not surrounded
  567.    IF POINT(G.Offx + col * G.CellWidth, G.Offy + I%) <> Magenta THEN I% = 9999: Good%% = FALSE
  568.   NEXT I%
  569.  
  570.   IF Good%% THEN '**only check other lines if it hasn't failed yet
  571.    FOR I% = (col - 1) * G.CellWidth TO col * G.CellWidth STEP 4 '**No need to check every pixel
  572.     IF POINT(G.Offx + I%, G.Offy + row * G.CellHeight) <> Magenta THEN I% = 9999: Good%% = FALSE ' False Baox not surrounded
  573.     IF POINT(G.Offx + I%, G.Offy + (row + 1) * G.CellHeight) <> Magenta THEN I% = 9999: Good%% = FALSE
  574.    NEXT I%
  575.   END IF
  576.   IF Good%% THEN BoxSurrounded = -1: G.Finished = G.Finished + 1: G.Score = G.Score + 50: PLAY "o3l54eeggee": Check_Score 'all OK
  577.   BoxSurrounded = -1
  578.  _SOURCE Layer(6)
  579.  
  580. SUB FillBox (boxNumber)
  581.  ' _DELAY .25
  582.  _DEST Layer(2)
  583.  row = INT((boxNumber - 1) / G.Columns)
  584.  col = (boxNumber - 1) MOD G.Columns + 1
  585.  LINE (G.Offx + (col - 1) * G.CellWidth + 3, G.Offy + row * G.CellHeight + 3)-STEP(G.CellWidth - 6, G.CellHeight - 6), OffWhite, BF
  586.  COLOR Black
  587.  _PRINTSTRING (G.Offx + (col - 1) * G.CellWidth + 3 + (INT(G.CellWidth \ 2) - 8), G.Offy + row * G.CellHeight + 3 + (INT(G.CellHeight \ 2) - 8)), "50", Layer(2)
  588.  COLOR OffWhite
  589.  _DEST Layer(0)
  590.  
  591. SUB Change_Level
  592.  G.Level = G.Level + 1
  593.  speed! = (.05 - (G.Level / 1000) * 5)
  594.  IF speed! <= .015 THEN speed! = .015
  595.  ON TIMER(T2, speed!) Move_Seeker
  596.  ClearLayerTrans Layer(2)
  597.  ClearLayer Layer(5)
  598.  ClearLayer Layer(6)
  599.  DrawBoard
  600.  G.Finished = 0
  601.  FOR i%% = 0 TO 72
  602.   FinishedBox(i%%) = FALSE
  603.  NEXT i%%
  604.  
  605. SUB Master_Level (Level)
  606.  G.Start = FALSE
  607.  RESTORE Level_data
  608.  FOR i%% = 1 TO Level 'load level data
  609.   READ G.CellWidth, G.CellHeight, G.Rows, G.Columns, G.Offx, G.Offy, G.Needed, G.GX, G.GY, G.SX, G.SY
  610.  NEXT i%%
  611.  SELECT CASE Level 'create levels
  612.   CASE 1 TO 4, 8
  613.    FOR i%% = 0 TO G.Rows
  614.     LINE (G.Offx, G.Offy + i%% * G.CellHeight)-STEP(G.CellWidth * G.Columns, 0), Cyan 'horizontal lines
  615.    NEXT i%%
  616.    FOR i%% = 0 TO G.Columns
  617.     LINE (G.Offx + i%% * G.CellWidth, G.Offy)-STEP(0, G.CellHeight * G.Rows), Cyan 'vertical lines
  618.    NEXT i%%
  619.   CASE 5 ' "Â" shaped level
  620.    FOR i%% = 0 TO 4
  621.     LINE (16, 16 + i%% * 24)-STEP(288, 0), Cyan 'horizontal lines
  622.     LINE (88 + i%% * 36, 16)-STEP(0, 168), Cyan 'vertical lines
  623.    NEXT i%%
  624.    FOR i%% = 0 TO 2
  625.     LINE (88, 136 + i%% * 24)-STEP(144, 0), Cyan 'horizontal lines
  626.     LINE (16 + i%% * 36, 16)-STEP(0, 96), Cyan 'vertical lines
  627.     LINE (268 + i%% * 36, 16)-STEP(0, 96), Cyan 'vertical lines
  628.    NEXT i%%
  629.   CASE 6 ' "Å" shaped level
  630.    FOR i%% = 0 TO 3
  631.     LINE (16, 64 + i%% * 24)-STEP(288, 0), Cyan 'horizontal lines
  632.     LINE (88 + i%% * 36, 16)-STEP(0, 168), Cyan 'vertical lines
  633.    NEXT i%%
  634.    LINE (88 + i%% * 36, 16)-STEP(0, 168), Cyan 'vertical lines
  635.  
  636.    FOR i%% = 0 TO 1
  637.     LINE (88, 16 + i%% * 24)-STEP(144, 0), Cyan 'horizontal lines
  638.     LINE (88, 160 + i%% * 24)-STEP(144, 0), Cyan 'horizontal lines
  639.     LINE (16 + i%% * 36, 64)-STEP(0, 72), Cyan 'vertical lines
  640.     LINE (268 + i%% * 36, 64)-STEP(0, 72), Cyan 'vertical lines
  641.    NEXT i%%
  642.   CASE 7 ' "Á" shaped level
  643.    FOR i%% = 0 TO 4
  644.     LINE (16, 88 + i%% * 24)-STEP(288, 0), Cyan 'horizontal lines
  645.     LINE (88 + i%% * 36, 16)-STEP(0, 168), Cyan 'vertical lines
  646.    NEXT i%%
  647.    FOR i%% = 0 TO 1
  648.     LINE (88, 16 + i%% * 24)-STEP(144, 0), Cyan 'horizontal lines
  649.     LINE (16 + i%% * 36, 88)-STEP(0, 96), Cyan 'vertical lines
  650.     LINE (268 + i%% * 36, 88)-STEP(0, 96), Cyan 'vertical lines
  651.    NEXT i%%
  652.    LINE (88, 16 + i%% * 24)-STEP(144, 0), Cyan 'horizontal lines
  653.  
  654. SUB Check_Score
  655.  STATIC Current_life AS _BYTE
  656.  IF G.Score = 0 THEN Current_life = 0 'reset on new game
  657.  IF INT(G.Score \ 5000) = Current_life + 1 THEN 'Bonus Life, only worry about the thousands place to
  658.   '                                                            avoid issues with non-5000 exact multiples
  659.   Current_life = Current_life + 1
  660.   G.Lives = G.Lives + 1
  661.   TIMER(T2) OFF
  662.   _DELAY .05
  663.   PLAY "o6l32GFED#"
  664.   TIMER(T2) ON
  665.  
  666. SUB Create_Gap
  667.  STATIC X%, Y%, D%
  668.  IF G.Gapped THEN 'when a new gap is made get the pos. this sub is called to erase too
  669.   X% = G.GX + 8 'Xpos of gapper center
  670.   Y% = G.GY + 7 'Ypos of gapper center
  671.   D% = G.GD 'direction of gap(up\down or left\right)
  672.   G.Gap_time = TIMER
  673.   CASE UP, DOWN
  674.    _DEST Layer(6) 'draw the gap to the detection layer
  675.    IF G.Gapped THEN LINE (X%, Y% - 1)-STEP(0, 2), Black ELSE LINE (X%, Y% - 1)-STEP(0, 2), Cyan 'erase or restore
  676.    _DEST Layer(2) 'also display gap on visual layer (can only gap where you've been so restore to Magenta)
  677.    'layer 2 is 320x220 so we must half the x,y points
  678.    IF G.Gapped THEN LINE (.5 * X%, .5 * Y% - 3)-STEP(0, 5), Black ELSE LINE (.5 * X%, .5 * Y% - 3)-STEP(0, 5), Magenta 'erase or restore
  679.   CASE LEFT, RIGHT
  680.    _DEST Layer(6) 'draw the gap to the detection layer
  681.    IF G.Gapped THEN LINE (X% - 1, Y% - 1)-STEP(2, 1), Black, BF ELSE LINE (X% - 1, Y% - 1)-STEP(2, 1), Cyan, BF 'erase or restore
  682.    _DEST Layer(2) 'also display gap on visual layer (can only gap where you've been so restore to Magenta)
  683.    'layer 2 is 320x220 so we must half the x,y points
  684.    IF G.Gapped THEN LINE (.5 * X% - 3, .5 * Y% - 1)-STEP(5, 1), Black, BF ELSE LINE (.5 * X% - 3, .5 * Y% - 1)-STEP(5, 1), Magenta, BF 'erase or restore
  685.  ' _DEST Layer(0)
  686.  ' CLS
  687.  ' _PUTIMAGE , Layer(2), Layer(0)
  688.  ' G.GY = G.GY + 16
  689.  ' _PUTIMAGE (G.GX, G.GY), Layer(3), Layer(0), (318, 218)-STEP(15, 13)
  690.  ' END
  691.  
  692. SUB Time_Gap
  693.  IF G.Level <= 20 THEN Max_Time! = 500 - (G.Level * 20) ELSE Max_Time! = 100
  694.  Max_Time! = Max_Time! / 100 'convert to seconds (5 sec to 1 sec)
  695.  
  696.  IF G.Gap_time + Max_Time! <= TIMER THEN 'gap time up
  697.   G.Gapped = FALSE
  698.   Create_Gap 'call the SUB again to fill in gap
  699.  
  700. SUB New_Game
  701.  G.Score = 0
  702.  G.Lives = 2
  703.  FOR i%% = 0 TO 72
  704.   FinishedBox(i%%) = FALSE
  705.  NEXT i%%
  706.  ClearLayerTrans Layer(2)
  707.  Check_Score 'reset extra lives counter
  708.  
« Last Edit: November 19, 2021, 02:05:33 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Gapper, Give it a try!
« Reply #1 on: November 18, 2021, 03:45:41 pm »
Hi Cobalt,

When I was playing first game, the chaser got stuck @ top line near right corner when that box lit up from being enclosed (or just before that). It remained stuck until next level started. Maybe a fluke?

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Gapper, Give it a try!
« Reply #2 on: November 18, 2021, 06:48:37 pm »
Hi Cobalt,

When I was playing first game, the chaser got stuck @ top line near right corner when that box lit up from being enclosed (or just before that). It remained stuck until next level started. Maybe a fluke?

Yeah its done that a few times since I switched over to using a TIMER to control the seeker speed. not sure if its a nuance of the timers and I'm doing something wrong or if Timers have an unknown issue? I cant use _DELAY anywhere without turning the timer off and back on. as I did try to add a little delay for the box enclosed sound, to mimic the original game better. (the sound pauses game play momentarily, pretty sure it was originally coded in some form of basic). Not sure how to diagnose this further to confirm one way or another as to why the timer seems to stop working. The FPS timer doesn't seem to have this issue though.
Granted after becoming radioactive I only have a half-life!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Gapper, Give it a try!
« Reply #3 on: November 18, 2021, 07:43:30 pm »
8000 1st guy level 6 :-)
fun game - reminds me of an old arcade game.. just can't remember.
here is a suggestion for harder, can't go backward.
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Gapper, Give it a try!
« Reply #4 on: November 18, 2021, 09:36:58 pm »
8000 1st guy level 6 :-)
fun game - reminds me of an old arcade game.. just can't remember.
here is a suggestion for harder, can't go backward.


People claim the original game was a take on something called "Amidar".

Harder huh? Apparently you haven't made it to the level where the seeker becomes faster than the gapper! (not sure if I will leave it that way as it becomes a kill level) the player moves at a rate of 1px every .0167 sec(roughly 60x second). At max speed the seeker moves at 1px every .015 sec. and the gap lasts shorter and shorter period of time too.
Here.jpg
* Here.jpg (Filesize: 163.16 KB, Dimensions: 1005x552, Views: 30)
« Last Edit: November 30, 2021, 10:46:46 am by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Gapper, Give it a try! (updated)
« Reply #5 on: November 19, 2021, 04:23:37 am »
Never played Amidar
I was thinking of QIX
=67

I used to play that a lot.

Yours has a nice addictive nature to it. The "ok-one-more-level" type LOL!!





I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!