Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ASCII AQUERIUM
#1
This one is for all the people who wanted to have an aquarium as a child but couldn't Wink

[Image: zylwm-msk-2025-11-25-214307.png]

Code: (Select All)
' QUARIUM - ASCII Aquarium for QB64PE
' Ported and enhanced from FreeBASIC version
' by ron77 2025
' Configuration constants
CONST SCREEN_WIDTH = 800
CONST SCREEN_HEIGHT = 600
CONST MAX_FISH = 20
CONST MAX_BUBBLES = 30
CONST MAX_SEAWEED = 8
' Fish structure using parallel arrays (QB64PE style)
DIM SHARED fishX(MAX_FISH) AS SINGLE
DIM SHARED fishY(MAX_FISH) AS SINGLE
DIM SHARED fishDX(MAX_FISH) AS SINGLE        ' horizontal speed
DIM SHARED fishDY(MAX_FISH) AS SINGLE        ' vertical speed
DIM SHARED fishShape(MAX_FISH) AS INTEGER    ' which shape to use
DIM SHARED fishColorIndex(MAX_FISH) AS INTEGER   ' color index
' Bubble structure
DIM SHARED bubbleX(MAX_BUBBLES) AS SINGLE
DIM SHARED bubbleY(MAX_BUBBLES) AS SINGLE
DIM SHARED bubbleSpeed(MAX_BUBBLES) AS SINGLE
' Seaweed positions
DIM SHARED seaweedX(MAX_SEAWEED) AS INTEGER
DIM SHARED seaweedHeight(MAX_SEAWEED) AS INTEGER
DIM SHARED seaweedColorIndex(MAX_SEAWEED) AS INTEGER
' Fish ASCII shapes (left-facing and right-facing)
DIM SHARED fishShapeRight(5) AS STRING
DIM SHARED fishShapeLeft(5) AS STRING
' Initialize fish shapes
fishShapeRight(0) = "><(((('>"
fishShapeRight(1) = "><>"
fishShapeRight(2) = "><)))*>"
fishShapeRight(3) = ">==|||>>"
fishShapeRight(4) = "><(((^>"
fishShapeLeft(0) = "<'))))><"
fishShapeLeft(1) = "<><"
fishShapeLeft(2) = "<*(((<>"
fishShapeLeft(3) = "<<|||==<"
fishShapeLeft(4) = "<^)))><"
' Screen setup - 32-bit graphics mode
DIM SHARED mainScreen AS LONG
mainScreen = _NEWIMAGE(SCREEN_WIDTH, SCREEN_HEIGHT, 32)
SCREEN mainScreen
_TITLE "QUARIUM - ASCII Aquarium (Press ESC to exit)"
' Calculate screen dimensions in characters (8x16 font)
DIM SHARED screenCols AS INTEGER, screenRows AS INTEGER
screenCols = SCREEN_WIDTH \ 8
screenRows = SCREEN_HEIGHT \ 16
' Color definitions using _RGB32
DIM SHARED colWater AS _UNSIGNED LONG
DIM SHARED colSurface AS _UNSIGNED LONG
DIM SHARED colSand AS _UNSIGNED LONG
DIM SHARED colBubble AS _UNSIGNED LONG
DIM SHARED colTitle AS _UNSIGNED LONG
DIM SHARED colSeaweedDark AS _UNSIGNED LONG
DIM SHARED colSeaweedLight AS _UNSIGNED LONG
colWater = _RGB32(0, 40, 80)           ' Dark blue water background
colSurface = _RGB32(100, 200, 255)     ' Light blue surface
colSand = _RGB32(194, 178, 128)        ' Sandy tan
colBubble = _RGB32(200, 230, 255)      ' Light bubble color
colTitle = _RGB32(255, 255, 0)         ' Yellow title
colSeaweedDark = _RGB32(0, 100, 0)     ' Dark green
colSeaweedLight = _RGB32(0, 180, 0)    ' Light green
' Fish colors array
DIM SHARED fishColors(10) AS _UNSIGNED LONG
fishColors(0) = _RGB32(255, 100, 100)   ' Light Red
fishColors(1) = _RGB32(255, 200, 0)     ' Orange/Gold
fishColors(2) = _RGB32(255, 255, 0)     ' Yellow
fishColors(3) = _RGB32(100, 255, 100)   ' Light Green
fishColors(4) = _RGB32(0, 255, 255)     ' Cyan
fishColors(5) = _RGB32(100, 150, 255)   ' Light Blue
fishColors(6) = _RGB32(255, 100, 255)   ' Magenta/Pink
fishColors(7) = _RGB32(255, 255, 255)   ' White
fishColors(8) = _RGB32(255, 150, 50)    ' Orange
fishColors(9) = _RGB32(150, 255, 200)   ' Aqua/Mint
' Seaweed colors
DIM SHARED seaweedColors(2) AS _UNSIGNED LONG
seaweedColors(0) = _RGB32(0, 120, 0)
seaweedColors(1) = _RGB32(0, 180, 50)
' Initialize random seed
RANDOMIZE TIMER
' Main program
CALL InitializeFish
CALL InitializeBubbles
CALL InitializeSeaweed
DIM k AS STRING
' Main loop
DO
    k = INKEY$
   
    ' Clear screen with blue water background
    CLS , colWater
   
    ' Draw everything
    CALL DrawTankDecorations
    CALL DrawBubbles
    CALL DrawFish
    CALL DrawTitle
   
    ' Update positions
    CALL UpdateFish
    CALL UpdateBubbles
   
    ' Display and limit frame rate
    _DISPLAY
    _LIMIT 30  ' 30 FPS
   
LOOP UNTIL k = CHR$(27)
' Cleanup
CLS , _RGB32(0, 0, 0)
COLOR _RGB32(255, 255, 255), _RGB32(0, 0, 0)
_PRINTSTRING (300, 280), "Thanks for watching the fish!"
_DISPLAY
_DELAY 2
SYSTEM
' Initialize all fish
SUB InitializeFish
    DIM i AS INTEGER
    FOR i = 0 TO MAX_FISH - 1
        fishX(i) = RND * (screenCols - 12) + 2
        fishY(i) = RND * (screenRows - 6) + 3
        fishDX(i) = (RND * 0.8 + 0.2) * (SGN(RND - 0.5) + (SGN(RND - 0.5) = 0) * 1)
        fishDY(i) = (RND * 0.3 - 0.15)
        fishShape(i) = INT(RND * 5)
        fishColorIndex(i) = INT(RND * 10)
    NEXT i
END SUB
' Initialize bubbles
SUB InitializeBubbles
    DIM i AS INTEGER
    FOR i = 0 TO MAX_BUBBLES - 1
        bubbleX(i) = RND * (screenCols - 2) + 1
        bubbleY(i) = RND * (screenRows - 4) + 2
        bubbleSpeed(i) = RND * 0.3 + 0.1
    NEXT i
END SUB
' Initialize seaweed
SUB InitializeSeaweed
    DIM i AS INTEGER
    FOR i = 0 TO MAX_SEAWEED - 1
        seaweedX(i) = INT(RND * (screenCols - 4)) + 2
        seaweedHeight(i) = INT(RND * 8) + 4
        seaweedColorIndex(i) = INT(RND * 2)
    NEXT i
END SUB
' Draw text at pixel position (helper)
SUB DrawText (row AS INTEGER, col AS INTEGER, txt AS STRING, fg AS _UNSIGNED LONG)
    DIM px AS INTEGER, py AS INTEGER
    px = (col - 1) * 8
    py = (row - 1) * 16
    COLOR fg, _RGBA32(0, 0, 0, 0)  ' Transparent background
    _PRINTSTRING (px, py), txt
END SUB
' Draw the tank decorations (sand, frame)
SUB DrawTankDecorations
    DIM i AS INTEGER
   
    ' Draw water surface wave
    FOR i = 1 TO screenCols
        DrawText 1, i, "~", colSurface
    NEXT i
   
    ' Draw sandy bottom
    FOR i = 1 TO screenCols
        DrawText screenRows, i, CHR$(176), colSand
    NEXT i
   
    ' Draw seaweed
    DIM j AS INTEGER, waveOffset AS INTEGER
    waveOffset = INT(TIMER * 2) MOD 2
   
    FOR i = 0 TO MAX_SEAWEED - 1
        DIM swCol AS _UNSIGNED LONG
        swCol = seaweedColors(seaweedColorIndex(i))
       
        FOR j = 0 TO seaweedHeight(i) - 1
            DIM seaweedChar AS STRING
            IF (j + waveOffset) MOD 2 = 0 THEN
                seaweedChar = "("
            ELSE
                seaweedChar = ")"
            END IF
            DIM swRow AS INTEGER
            swRow = screenRows - j - 1
            IF swRow > 1 AND seaweedX(i) >= 1 AND seaweedX(i) <= screenCols THEN
                DrawText swRow, seaweedX(i), seaweedChar, swCol
            END IF
        NEXT j
    NEXT i
END SUB
' Draw bubbles
SUB DrawBubbles
    DIM i AS INTEGER
   
    FOR i = 0 TO MAX_BUBBLES - 1
        DIM bx AS INTEGER, by AS INTEGER
        bx = INT(bubbleX(i))
        by = INT(bubbleY(i))
        IF by >= 2 AND by < screenRows AND bx >= 1 AND bx <= screenCols THEN
            DIM bubbleChar AS STRING
            IF RND > 0.5 THEN
                bubbleChar = "o"
            ELSE
                bubbleChar = "O"
            END IF
            DrawText by, bx, bubbleChar, colBubble
        END IF
    NEXT i
END SUB
' Update bubble positions
SUB UpdateBubbles
    DIM i AS INTEGER
    FOR i = 0 TO MAX_BUBBLES - 1
        bubbleY(i) = bubbleY(i) - bubbleSpeed(i)
        bubbleX(i) = bubbleX(i) + (RND * 0.4 - 0.2)  ' Slight wobble
       
        ' Reset bubble if it reaches the top
        IF bubbleY(i) < 2 THEN
            bubbleY(i) = screenRows - 1
            bubbleX(i) = RND * (screenCols - 2) + 1
            bubbleSpeed(i) = RND * 0.3 + 0.1
        END IF
       
        ' Keep X in bounds
        IF bubbleX(i) < 1 THEN bubbleX(i) = 1
        IF bubbleX(i) > screenCols THEN bubbleX(i) = screenCols
    NEXT i
END SUB
' Draw all fish
SUB DrawFish
    DIM i AS INTEGER
   
    FOR i = 0 TO MAX_FISH - 1
        DIM fx AS INTEGER, fy AS INTEGER
        fx = INT(fishX(i))
        fy = INT(fishY(i))
       
        ' Bounds check
        IF fy >= 2 AND fy < screenRows AND fx >= 1 AND fx <= screenCols - 8 THEN
            DIM fishStr AS STRING
            DIM fCol AS _UNSIGNED LONG
            fCol = fishColors(fishColorIndex(i))
           
            ' Choose direction based on movement
            IF fishDX(i) > 0 THEN
                fishStr = fishShapeRight(fishShape(i))
            ELSE
                fishStr = fishShapeLeft(fishShape(i))
            END IF
           
            DrawText fy, fx, fishStr, fCol
        END IF
    NEXT i
END SUB
' Update fish positions
SUB UpdateFish
    DIM i AS INTEGER
   
    FOR i = 0 TO MAX_FISH - 1
        ' Update position
        fishX(i) = fishX(i) + fishDX(i)
        fishY(i) = fishY(i) + fishDY(i)
       
        ' Occasionally change vertical direction slightly
        IF RND < 0.02 THEN
            fishDY(i) = (RND * 0.4 - 0.2)
        END IF
       
        ' Occasionally change speed slightly
        IF RND < 0.01 THEN
            DIM newSpeed AS SINGLE
            newSpeed = RND * 0.6 + 0.2
            fishDX(i) = newSpeed * SGN(fishDX(i))
        END IF
       
        ' Horizontal bounds - turn around at edges
        IF fishX(i) > screenCols - 9 THEN
            fishDX(i) = -ABS(fishDX(i))  ' Turn left
            fishX(i) = screenCols - 9
        ELSEIF fishX(i) < 1 THEN
            fishDX(i) = ABS(fishDX(i))   ' Turn right
            fishX(i) = 1
        END IF
       
        ' Vertical bounds
        IF fishY(i) > screenRows - 2 THEN
            fishDY(i) = -ABS(fishDY(i))
            fishY(i) = screenRows - 2
        ELSEIF fishY(i) < 2 THEN
            fishDY(i) = ABS(fishDY(i))
            fishY(i) = 2
        END IF
    NEXT i
END SUB
' Draw the title
SUB DrawTitle
    DIM titleText AS STRING
    titleText = " QUARIUM - Press ESC to exit "
    DIM titleX AS INTEGER
    titleX = (screenCols - LEN(titleText)) \ 2
    DrawText 1, titleX, titleText, colTitle
END SUB

My mom still has to this day, a full aquarium in her home... goldfish and all.

Cheers.

solo88 (ron77)
aka ron77
Reply
#2
I had aquariums as a kid, but I grew up... which ended up in me having a 30 x 45 foot ham shaped koi pond. That was a real pain in the ASCII.

+2.  It reminded me of Mark's (bplus) post here: https://qb64phoenix.com/forum/showthread...61#pid1461

Pete
Reply
#3
Hahaha. Nice. Love aquariums. We should have a dedicated thread for aquarium demos.

Here are some more that I saw in the past:

https://github.com/a740g/QB64-PE-Museum/...shTank.bas

https://github.com/a740g/QB64-PE-Museum/...s/kelp.bas
Reply
#4
Count me out on this one, Sam. I made an amazing 3-D life like virtual aquarium back in the day, but I lost all my work when I tried to fill it up with water. Oh well, at least having water handy was invaluable for putting out the computer fire, and it wasn't a complete loss. Oh sure, the computer was burned beyond recognition, but on the bright side it was running Windows Vista.

Pete Big Grin
Reply
#5
@solo88
it is funny!
On my machine Acer a laptop with 4GB ram, 500GB HDD and Kubuntu 24.04 it works fine.
I must decrease the _LIMIT  value from 30 to 10 in the main loop!
Reply
#6
One glimpse and i KNEW pete would LOVE it! He is the ASCII king!
Reply
#7
Yes, and I had a bunch of aquariums as a kid, but the dogs kept jumping out. One day, someone said I should get fish. So I did, but they kept slipping out of the leashes.

Pete Big Grin
Reply
#8
Nice one, @solo88.  Runs fine on my laptop.  Fish aquarium demos are neat. 

- Dav

Find my programs here in Dav's QB64 Corner
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Exploding Ascii Diamonds bplus 5 525 11-16-2025, 05:06 PM
Last Post: Dav
  Tiny Maze Maker - ASCII SierraKen 19 1,676 08-09-2025, 11:39 PM
Last Post: SierraKen
  ASCII cube DANILIN 6 1,691 11-07-2023, 01:06 AM
Last Post: bplus
  ASCII Animations SpriggsySpriggs 6 6,065 10-27-2023, 10:55 PM
Last Post: madscijr
  Little ASCII Race Car Game TerryRitchie 0 706 10-27-2023, 06:21 PM
Last Post: TerryRitchie

Forum Jump:


Users browsing this thread: