Started working on the same game using COBOL...
Sun Mar 14, 2021 3:32am

Being that COBOL is more my programming language of interest outside of work lately, I decided I'd try to make the QB game in GnuCOBOL instead. So far, I don't have the area scrolling like I do in the QB version. It's just a full map view for now. (I'll be working on that next).

This is definitely not what COBOL is made for and I'm surprised it's even possible with how limited the visual options are with the language. (There's only 8 colors total to choose from and resizing the terminal can cause the input and drawing to mess up if it's too small!)

Anyway, here's a quick idea of what I have going so far:

Screen shot in case you don't want to watch the video:

Here's the current code if you're interested in it's nastiness. :P
Check out how nasty it is to declare a 2d array in COBOL. (ws-tile-map area) It worked, but it's definitely not pretty.
       identification division.
       program-id. tile-game-test.

       environment division.

       input-output section.

           select optional fd-tile-data assign to "world.dat"
               organization is record sequential.

       data division.

       file section.

           fd fd-tile-data.
           01  f-tile-data-record.
               05  f-tile-fg               pic 9.   
               05  f-tile-bg               pic 9.
               05  f-tile-char             pic x.
               05  f-tile-is-blocking      pic a.

       working-storage section.

           01  ws-temp-time                pic 9(9).

      *> Color constants:    
           01 black   constant as 0.
           01 blue    constant as 1.
           01 green   constant as 2.
           01 cyan    constant as 3.
           01 red     constant as 4.
           01 magenta constant as 5.
           01 yellow  constant as 6.  *> or Brown
           01 white   constant as 7.

           78  ws-max-screen-height         value 25.
           78  ws-max-screen-width          value 80.

           01  ws-player.
               05  ws-player-pos            pic 9999.
               05  ws-player-pos-delta      pic S9(4).               
               78  ws-player-char           value "@".

           01  ws-kb-input                  pic x.

           01  ws-is-quit                   pic a value 'N'.
               88  ws-quit                  value 'Y'.
               88  ws-not-quit              value 'N'.

           01  ws-tile-map            occurs ws-max-screen-height times.
               05  ws-tile-map-data   occurs ws-max-screen-width times.
                   10  ws-tile-fg               pic 9.   
                   10  ws-tile-bg               pic 9.
                   10  ws-tile-char             pic x.
                   10  ws-tile-is-blocking      pic a value 'N'.
                       88  ws-tile-blocking     value 'Y'.
                       88  ws-tile-not-blocking value 'N'.         

           01  ws-scr-refresh-req           pic a value 'Y'.
               88  ws-scr-refresh           value 'Y'.
               88  ws-scr-no-refresh        value 'N'.

           01  ws-counter-1                 pic 99.
           01  ws-counter-2                 pic 99.
           01  ws-temp-color                pic 9.
           01  ws-temp-scr-pos              pic 9999.
           01  ws-temp-x-idx                pic 99.
           01  ws-temp-y-idx                pic 99.

           01  ws-filler                    pic 9(9).

           01  ws-eof                       pic a value 'N'.
               88 ws-is-eof                 value 'Y'.
               88 ws-not-eof                value 'N'.

       procedure division.

           move 0510 to ws-player-pos           
           display space blank screen 

           accept ws-temp-time from time 
           move function random(ws-temp-time) to ws-filler.

      *     perform generate-fake-world-data.

           open input fd-tile-data

           perform varying ws-counter-1 
           from 1 by 1 until ws-counter-1 > ws-max-screen-height
               perform varying ws-counter-2 
               from 1 by 1 until ws-counter-2 > ws-max-screen-width

                   read fd-tile-data 
                       into ws-tile-map-data(ws-counter-1, ws-counter-2)


           close fd-tile-data.       


           perform until ws-quit         
               perform draw-playfield               
               perform get-input
               perform move-player




      *> only redraw if needed.
           if ws-scr-no-refresh then 
               exit paragraph 

           move zeros to ws-temp-scr-pos

           perform varying ws-counter-1 
           from 1 by 1 until ws-counter-1 > ws-max-screen-height
               perform varying ws-counter-2 
               from 1 by 1 until ws-counter-2 > ws-max-screen-width

                   move ws-counter-1 to ws-temp-scr-pos(1:2)
                   move ws-counter-2 to ws-temp-scr-pos(3:2)

      *> draw player
                   if ws-temp-scr-pos = ws-player-pos then

                       display ws-player-char 
                           at ws-player-pos 
                           ws-tile-bg(ws-counter-1, ws-counter-2) 
                           foreground-color yellow highlight
      *>  draw world tile:
                       display ws-tile-char(ws-counter-1, ws-counter-2) 
                           at ws-temp-scr-pos 
                               ws-tile-bg(ws-counter-1, ws-counter-2) 
                               ws-tile-fg(ws-counter-1, ws-counter-2) 


           set ws-scr-no-refresh to true

           exit paragraph.

           accept ws-kb-input at 2601 with auto-skip no-echo

           evaluate true

               when ws-kb-input = 'q'
                   display "QUITING" 
                   set ws-quit to true 

               when ws-kb-input = 's' 
                   add 100 to ws-player-pos-delta

               when ws-kb-input = 'w' 
                   subtract 100 from ws-player-pos-delta

               when ws-kb-input = 'd'
                   add 1 to ws-player-pos-delta

               when ws-kb-input = 'a'
                   subtract 1 from ws-player-pos-delta

      *>         when other   
      *>             display "KB INPUT: " at 0101 ws-kb-input at 0110


           exit paragraph.

           if ws-player-pos-delta <> 0 then 

      *> only move player if tile is not blocking and inside map.
               move ws-player-pos to ws-temp-scr-pos
               add ws-player-pos-delta to ws-temp-scr-pos
               move zeros to ws-player-pos-delta

               move ws-temp-scr-pos(1:2) to ws-temp-y-idx
               move ws-temp-scr-pos(3:2) to ws-temp-x-idx
               if ws-temp-y-idx > ws-max-screen-height 
                  or ws-temp-x-idx > ws-max-screen-width
                  or ws-temp-y-idx < 0 or ws-temp-x-idx < 0 
                   exit paragraph

               if ws-tile-not-blocking(ws-temp-y-idx, ws-temp-x-idx) 
                   move ws-temp-scr-pos to ws-player-pos
                   set ws-scr-refresh to true 

           exit paragraph.

      *> generate temp world tile data.

           open output fd-tile-data

           perform varying ws-counter-1 
           from 1 by 1 until ws-counter-1 > ws-max-screen-height
               perform varying ws-counter-2 
               from 1 by 1 until ws-counter-2 > ws-max-screen-width

                  compute ws-temp-color = function random * 7
                   move ws-temp-color to f-tile-fg 
                   compute ws-temp-color = function random * 7
                   move ws-temp-color to f-tile-bg                       

                   compute ws-filler = function random * 10 + 1
                   if ws-filler > 8 then  
                       move 'Y' to f-tile-is-blocking                       
                       move "B" to f-tile-char
                       move zero to f-tile-fg
                       move 'N' to f-tile-is-blocking
                       move space to f-tile-char

                   write f-tile-data-record                                                                      


           close fd-tile-data
           exit paragraph.       

       end program tile-game-test.

    • Kind of got something working... - Retna, Sun Mar 07 2021 10:12pm
      Still need to figure out how to move the viewport based on the characters position. And also how to stitch the two areas together. Should be able to copy and paste this into your browser console on newer browsers. document.write(` <html> <head> <style> body { overflow:hid... more
      • Started working on the same game using COBOL...- Erik_, Sun Mar 14 2021 3:32am
        • Got the scrolling working now. - Erik_, Wed Mar 17 2021 5:28pm
          Looping gif example:
          • Sweet! - Retna, Wed Mar 17 2021 9:43pm
            Do you scroll the viewport and the player position at the same time when they press the direction? I might try doing that too...
            • This is the second time of me writing this after clearing... I guess that's definitely a sign it needs to be rewritten. :) * Player position holds x/y coordinates on the tile map. * Screen is drawn based on player xy as the starting point and drawn until it reaches the defined screen width and ... more
              • I removed the "if player's position in the x/y is less than so and so" and just made the player's screen position constant. I was having a weird issue where as you approached 1,1 on the map, you would move 2 tiles instead of one. The new way fixes this. To get the player's map position, I just ne... more
      • Nice! That worked in Firefox. - Erik_, Mon Mar 08 2021 6:29pm
        That's really cool! I never would have thought to make a ASCII style game like this in Javascript. I would totally play a full fledged game that was done like that. Your screen drawing is similar to how I'm doing it. My 2d array just is a TILE type instead of straight integers so it can ho... more
        • Having a tile type could be a good way to define define more things the player can interact with. Like a chest or a door that can be open or closed.
          • and then having some TileHandler or something that defines the action based performed based on the tile type. I guess you would also need some sort of id or something to specify that it was, for example, a specific treasure chest on this specific map? Currently, the only different tile type I hav... more
  • Click here to receive daily updates
    "Forces act when not restrained" - Puckdropper