[Game]Top Fish

topfish

There are a lot of fish in this pond, and you’re the tiniest. Avoid the bigger fish and eat smaller or same-sized fish to get bigger, so you can become the Top Fish!

You might recognize this game from a lot of places, I’m pretty sure there are tons of clones of this type of game. I wanted to add a few more things, like sound effects, but ran out of time.

Download:
topfish.bin (148.0 KB)
topfish.zip (11.5 KB) (source)

Or check out the source here:

main.py
# Top Fish by wuuff
# Code and Graphics License: CC0

import upygame as pygame

import umachine as pok

import urandom as random

pygame.display.init()
screen = pygame.display.set_mode() # full screen
screenRect = screen.get_rect()
screenW = screenRect.width
screenH = screenRect.height

level = 0
state_game = 0
state_dead = 1
state_win = 2
state = state_game
state_timer = 0

pygame.display.set_palette_16bit([
0x0536, 0x0126, 0x03b9, 0xd7bf, 0xf701, 0xdea9, 0xf360, 0xdb81, 0xc800, 0x8806, 0x032a, 0x4448, 0x7015, 0x7296, 0x8e2e, 0xd636
])

tinyFishPixels = b'\
\x40\x40\
\x04\x14\
\x40\x40\
'

tinyFishPixelsL = b'\
\x04\x04\
\x41\x40\
\x04\x04\
'

teenyFishPixels = b'\
\x60\x60\
\x66\x16\
\x06\x66\
\x60\x60\
'

teenyFishPixelsL = b'\
\x06\x06\
\x61\x66\
\x66\x60\
\x06\x06\
'
smallFishPixels = b'\
\x89\x99\x80\
\x08\x88\x18\
\x08\x88\x88\
\x88\x99\x80\
'

smallFishPixelsL = b'\
\x08\x99\x98\
\x81\x88\x80\
\x88\x88\x80\
\x08\x99\x88\
'

medFishPixels = b'\
\xab\xaa\xbb\xa0\
\x0b\xbb\xba\x1a\
\x0b\xbb\xba\xaa\
\xab\xba\xab\xa0\
'

medFishPixelsL = b'\
\x0a\xbb\xaa\xba\
\xa1\xab\xbb\xb0\
\xaa\xbb\xbb\xb0\
\x0a\xba\xab\xba\
'

largeFishPixels = b'\
\xdd\xd0\xdc\xcd\xd0\
\x00\xdd\xcc\xcc\x1c\
\x0d\xdc\xcc\xdc\x1c\
\xdd\x0c\xdd\xdc\xcc\
'

largeFishPixelsL = b'\
\x0d\xdc\xcd\x0d\xdd\
\xc1\xcc\xcc\xdd\x00\
\xc1\xcd\xcc\xcd\xd0\
\xcc\xcd\xdd\xc0\xdd\
'

hugeFishPixels = b'\
\xc2\x20\xc2\x2c\x22\x20\
\x0c\x22\x2c\x22\x11\x12\
\x00\xcc\x2c\x22\xc1\x22\
\x0c\x22\x2c\x22\xc2\x22\
\xc2\x20\xc2\x2c\x22\x20\
'

hugeFishPixelsL = b'\
\x02\x22\xc2\x2c\x02\x2c\
\x21\x11\x22\xc2\x22\xc0\
\x22\x1c\x22\xc2\xcc\x00\
\x22\x2c\x22\xc2\x22\xc0\
\x02\x22\xc2\x2c\x02\x2c\
'

gargantuanFishPixels = b'\
\xcc\x0c\xcc\xcc\xdd\xdd\xd0\
\x0c\xc0\xdd\xdd\xdd\x11\xdd\
\x05\x55\x55\x55\x55\x11\x55\
\x09\x99\x99\x99\x99\x11\x99\
\x0c\xc0\xdd\xdd\xdd\xdd\xdd\
\xcc\x0c\xcc\xcd\xdd\xdd\xd0\
'

gargantuanFishPixelsL = b'\
\x0d\xdd\xdd\xcc\xcc\xc0\xcc\
\xdd\x11\xdd\xdd\xdd\x0c\xc0\
\x55\x11\x55\x55\x55\x55\x50\
\x99\x11\x99\x99\x99\x99\x90\
\xdd\xdd\xdd\xdd\xdd\x0c\xc0\
\x0d\xdd\xdd\xdc\xcc\xc0\xcc\
'

wowFishPixels = b'\
\x66\x60\x66\x66\x76\x66\x77\x00\
\x06\x66\x07\x77\x77\x79\x97\x70\
\x00\x67\x67\x66\x67\x77\x19\x77\
\x00\x06\x76\x66\x67\x77\x17\x77\
\x00\x67\x67\x66\x67\x77\x77\x77\
\x06\x66\x07\x77\x77\x77\x77\x70\
\x66\x60\x66\x67\x77\x66\x67\x00\
'

wowFishPixelsL = b'\
\x00\x77\x66\x67\x66\x66\x06\x66\
\x07\x79\x97\x77\x77\x70\x66\x60\
\x77\x91\x77\x76\x66\x76\x76\x00\
\x77\x71\x77\x76\x66\x67\x60\x00\
\x77\x77\x77\x76\x66\x76\x76\x00\
\x07\x77\x77\x77\x77\x70\x66\x60\
\x00\x76\x66\x77\x76\x66\x06\x66\
'

seaweedPixels = b'\
\x00\x00\xe0\x00\
\x00\x0e\x00\x00\
\x00\x00\xe0\x00\
\x00\x0e\x00\x00\
\x00\x00\xe0\x00\
\x00\x0e\xe0\x00\
\x0f\xff\xff\xf0\
\xff\xff\xff\xff\
'

seaweedPixels2 = b'\
\x00\x0e\x00\x00\
\x00\x00\xe0\x00\
\x00\x0e\x00\x00\
\x00\x00\xe0\x00\
\x00\x0e\x00\x00\
\x00\x0e\xe0\x00\
\x0f\xff\xff\xf0\
\xff\xff\xff\xff\
'

sandPixels = b'\
\x00\x00\x00\x00\
\x00\x00\x00\x00\
\x00\x00\x00\x00\
\x00\x00\x00\x00\
\x00\x00\x00\x00\
\x00\x00\x00\x00\
\x00\xff\xff\x00\
\xff\xff\xff\xff\
'

tinyFishSurf = pygame.surface.Surface(4,3,tinyFishPixels)
tinyFishSurfL = pygame.surface.Surface(4,3,tinyFishPixelsL)
teenyFishSurf = pygame.surface.Surface(4,4,teenyFishPixels)
teenyFishSurfL = pygame.surface.Surface(4,4,teenyFishPixelsL)
smallFishSurf = pygame.surface.Surface(6,4,smallFishPixels)
smallFishSurfL = pygame.surface.Surface(6,4,smallFishPixelsL)
medFishSurf = pygame.surface.Surface(8,4,medFishPixels)
medFishSurfL = pygame.surface.Surface(8,4,medFishPixelsL)
largeFishSurf = pygame.surface.Surface(10,4,largeFishPixels)
largeFishSurfL = pygame.surface.Surface(10,4,largeFishPixelsL)
hugeFishSurf = pygame.surface.Surface(12,5,hugeFishPixels)
hugeFishSurfL = pygame.surface.Surface(12,5,hugeFishPixelsL)
gargantuanFishSurf = pygame.surface.Surface(14,6,gargantuanFishPixels)
gargantuanFishSurfL = pygame.surface.Surface(14,6,gargantuanFishPixelsL)
wowFishSurf = pygame.surface.Surface(16,7,wowFishPixels)
wowFishSurfL = pygame.surface.Surface(16,7,wowFishPixelsL)

sandSurf = pygame.surface.Surface(8,8,sandPixels)
weedSurf = pygame.surface.Surface(8,8,seaweedPixels)
weedSurf2 = pygame.surface.Surface(8,8,seaweedPixels2)

class Fish:
    def __init__(self, drawable, drawableL, width, height, rank):
        self.drawable = drawable
        self.drawableL = drawableL
        self.width = width
        self.height = height
        self.rank = rank

fishes = [Fish(tinyFishSurf,tinyFishSurfL,4,3,0),Fish(teenyFishSurf,teenyFishSurfL,4,4,1),Fish(smallFishSurf,smallFishSurfL,6,4,2),Fish(medFishSurf,medFishSurfL,8,4,3),
          Fish(largeFishSurf,largeFishSurfL,10,4,4),Fish(hugeFishSurf,hugeFishSurfL,12,5,5),Fish(gargantuanFishSurf,gargantuanFishSurfL,14,6,6),Fish(wowFishSurf,wowFishSurfL,16,7,7)]

vmax = 64

class Entity:
    def step(self):
        if self.vx > vmax:
            self.vx = vmax
        if self.vx < -vmax:
            self.vx = -vmax
        if self.vy > vmax:
            self.vy = vmax
        if self.vy < -vmax:
            self.vy = -vmax
        
        self.x += self.vx
        self.y += self.vy
        self.rect.x = self.x
        self.rect.y = self.y
    def draw(self):
        if self.dir == 0:
            screen.blit( self.fish.drawable, self.x//8, self.y//8, 0 )
        else:
            screen.blit( self.fish.drawableL, self.x//8, self.y//8, 0 )
    def __init__(self, x, y, fish):
        self.x = x
        self.y = y
        self.vx = 0
        self.vy = 0
        self.dir = 0
        self.fish = fish
        self.rect = pygame.Rect(x,y,fish.width*8,fish.height*8)

class Player(Entity):
    def die(self):
        global state
        global state_timer
        global level
        state = state_dead
        state_timer = 0
        level = 0
        if self.score > self.hiscore:
            self.hiscore = self.score
        self.fish = fishes[0]
        self.rect.width = self.fish.width*8
        self.rect.height = self.fish.height*8
        self.x = screenW//2*8
        self.y = screenH//2*8
        self.vx = 0
        self.vy = 0
        self.rscore = 0
        self.score = 0
    def win(self):
        global state
        global state_timer
        global level
        state = state_win
        state_timer = 0
        level += 1
        self.fish = fishes[0]
        self.rect.width = self.fish.width*8
        self.rect.height = self.fish.height*8
        self.x = screenW//2*8
        self.y = screenH//2*8
        self.vx = 0
        self.vy = 0
        self.rscore = 0
    def step(self):
        if self.vx > 0:
            self.dir = 0
        elif self.vx < 0:
            self.dir = 1
        if keys[pygame.K_LEFT]:
            if self.vx > 0:
                self.vx -= 4
            else:
                self.vx -= 2
        if keys[pygame.K_RIGHT]:
            if self.vx < 0:
                self.vx += 4
            else:
                self.vx += 2
        if keys[pygame.K_UP]:
            if self.vy > 0:
                self.vy -= 4
            else:
                self.vy -= 2
        if keys[pygame.K_DOWN]:
            if self.vy < 0:
                self.vy += 4
            else:
                self.vy += 2
        super().step()
        for entity in entities:
            if isinstance(entity, Enemy):
                if self.rect.colliderect(entity.rect):
                    if self.fish.rank >= entity.fish.rank:
                        self.rscore += entity.fish.rank+1
                        self.score += entity.fish.rank+1
                        if self.rscore > (self.fish.rank+1)*2:
                            # Rank up or win
                            if self.fish.rank < len(fishes)-1:
                                self.fish = fishes[self.fish.rank+1]
                                self.rect.width = self.fish.width*8
                                self.rect.height = self.fish.height*8
                                self.rscore = 0
                            else:
                                self.win()
                        entity.spawn()
                    else:
                        self.die()
                    pok.draw_text(0,0,"HIT", 1)
                
        # Friction
        if self.vx > 0:
            self.vx -= 1
            self.dir = 0
        if self.vx < 0:
            self.vx += 1
            self.dir = 1
        if self.vy > 0:
            self.vy -= 1
        if self.vy < 0:
            self.vy += 1
        # Borders
        if self.x > screenW*8-self.fish.width*8:
            self.x = screenW*8-self.fish.width*8
        if self.x < 0:
            self.x = 0
        if self.y > screenH*8-self.fish.width*8:
            self.y = screenH*8-self.fish.width*8
        if self.y < 0:
            self.y = 0
    def draw(self):
        super().draw()
        pok.draw_text(0,0,'%d'%self.score,1)
        pok.draw_text(screenW-4*5,0,'%-4d'%self.hiscore,1)
    def __init__(self,x,y,fish):
        super().__init__(x,y,fish)
        self.score = 0
        self.rscore = 0
        self.hiscore = 0
            
class Enemy(Entity):
    def step(self):
        super().step()
        if self.x < -8*8 or self.x > (screenW+8)*8:
            self.spawn()
    def spawn(self):
        self.fish = fishes[random.getrandbits(3)]
        self.x = -self.fish.width*8
        self.dir = 0
        self.rect.width = self.fish.width*8
        self.rect.height = self.fish.height*8
        #self.y = (10*random.getrandbits(3))*8
        self.vx = 1+level*4+random.getrandbits(3)
        if random.getrandbits(1) == 0:
            self.dir = 1
            self.vx *= -1
            self.x = (screenW+8)*8
    def __init__(self, x, y):
        super().__init__(x, y, fishes[0])
        self.spawn()
        

entities = []
entities.append(Player(screenW//2*8,screenH//2*8,fishes[0]))
entities.append(Enemy(0,10*8))
entities.append(Enemy(0,20*8))
entities.append(Enemy(0,30*8))
entities.append(Enemy(0,40*8))
entities.append(Enemy(0,50*8))
entities.append(Enemy(0,60*8))
entities.append(Enemy(0,70*8))
entities.append(Enemy(0,80*8))

keys = {pygame.K_UP:False,pygame.K_DOWN:False,pygame.K_LEFT:False,pygame.K_RIGHT:False}

timer = 0
frame = False

while True:
    timer += 1
    if timer%32 == 0:
        frame = not frame
    e = pygame.event.poll()
    if e != pygame.NOEVENT:
        if e.type == pygame.KEYDOWN:
            keys[e.key] = True
        if e.type == pygame.KEYUP:
            keys[e.key] = False
    
    if state == state_game:
        for entity in entities:
            entity.step()
            entity.draw()
    elif state == state_dead or state == state_win:
        for entity in entities:
            if isinstance(entity,Enemy):
                entity.draw()
        if state == state_dead:
            pok.draw_text(screenW//4,screenH//2,'GAME OVER',1)
        else:
            pok.draw_text(screenW//4,screenH//2,'TOP FISH!',1)
        state_timer += 1
        if state_timer > 40:
            state = state_game
            for entity in entities:
                if isinstance(entity,Enemy):
                    entity.spawn()
    for i in range(14):
        if i%2 == 0:
            if frame:
                screen.blit( weedSurf, i*8, screenH-8, 0 )
            else:
                screen.blit( weedSurf2, i*8, screenH-8, 0 )
        else:
            screen.blit( sandSurf, i*8, screenH-8, 0 )
    pygame.display.flip()
9 Likes

I have this game on my decade-old Motorola phone.

2 Likes

I have this game on my decade-old Mattel Intellivision.

3 Likes