floppy_v35.py

Created by polettielio

Created on October 15, 2022

8.21 KB


# A flappybird-ish small game
# import then execute `flop()`

# imported fun. names are shortened
from ion import keydown as kd
from kandinsky import get_pixel as gp, fill_rect as fr, draw_string as ds
from time import *
from random import randint, choice

# flop game function - everything is in there
# optional args: logmode, godmode, player_color
def flop(clr=(0,0,255),log=False,god=False):
  vers="35"
  const = (
    ( # difficulty level
      # hole_height, (hole_y...), menu_desc
      (120,(10,51,92), "Baby mode"),
      (90, (25,66,107), "Very simple"),
      (68, (20,58,96,134), "it's ok"),
      (58, (12,57,82,127,152),"normy"),
      (52, (15,50,85,120,155), "Hard"),
      (45, (16,52,88,124,160), "Hell hard"),
    ),
    # wall_density
    # new_wall_x_min, new_wall_x_max
    (
      (500,520),
      (480,500),
      (450,470),
      (420,460),
      (390,450),
      (350,410),
      (320,370),
    ),
    # scrool speed x_diff...
    (8,10,13,15,18),
    # ingame frame speed
    (0.042,),
    # player movements
    # (up), (cooldown), (down)
    ((-1,-3,-7,-9,-13), (-5,-2,0), (1,2,3,5,6,8,10,13)),
  )
  config = [
    [ # player settings
      # diff, wall_density, scroll_speed, frame_speed
      1,1,1,0
    ],
    god, # godmode
    4, # jump key (4, 52)
  ]

  def sc(c): # fill screen with c
    fr(0,0,320,222,c)

### debug: draw each wall of each diff
#  def walld():
#    for j in range(len(const[0])):
#      sc((0,255,255))
#      ds(str(j),10,10)
#      sleep(1)
#      for i in range(len(const[0][j][1])):
#        fr(40+50*i,0,30,222,(0,255,0))
#        fr(40+50*i,const[0][j][1][i],30,const[0][j][0],(0,224,224))
#      while not kd(52):
#        sleep(0.1)
#      ds("end",10,10)
#  walld()
#  return

  def menu():
    def dm(p=0): # menu pattern
      if cache == gc():
        return

      sc((0,)*3)
      
      fr(92,14,136,34,(0,255,255))
      ds(" FLOPPY v"+vers,100,21,(0,)*3,(0,255,255))

      fr(0,62,320,34,(40,)*3)
      ds(" Menu - "+str(p+1)+" ",10,70,(255,)*3,(88,)*3)
      ds("(left/right paren)",20+10*len(" Menu - "+str(p+1)+" "),70,(255,)*3,(40,)*3)

      if p == 0:
        ds(" difficulty: ",10,110,(255,)*3,(88,)*3)
        ds("(up/down)",170,110,(255,)*3,(0,)*3)
        for i in range(len(const[0])):
          m=(len(const[0])+1)//2
          x=20+140*(i>2)
          y=140+(i>2)*(i-3)*20+(i<=2)*i*20
          ds(" " + const[0][i][2] + " ",x,y,(255,)*3,(44 + 44*(config[0][0]==i),)*3)
      elif p == 1:
        ds(" wall density: ",10,110,(255,)*3,(88,)*3)
        ds("(up/down)",170,110,(255,)*3,(0,)*3)
        for i in range(len(const[1])):
          ds(" " + str(i+1) + " ",30+i*30,130,(255,)*3,(44 + 44*(config[0][1]==i),)*3)
        ds(" scroll speed: ",10,160,(255,)*3,(88,)*3)
        ds("(left/right)",170,160,(255,)*3,(0,)*3)
        for i in range(len(const[2])):
          ds(" " + str(i+1) + " ",30+i*30,180,(255,)*3,(44 + 44*(config[0][2]==i),)*3)
      elif p == 2:
        ds(" god mode: ",10,110,(255,)*3,(88,)*3)
        ds(" No ",130,110,(255,)*3,(44+44*(not config[1]),)*3)
        if config[1]:
          c=((0,)*3,(255,255,0))
        else:
          c=((255,)*3,(44,)*3)
        ds(" Yes ",170,110,c[0],c[1])
        ds("(up)",230,110,(255,)*3,(0,)*3)
        ds(" frame speed: ",10,140,(255,)*3,(88,)*3)
        ds("(left/right)",170,140,(255,)*3,(0,)*3)
        for i in range(len(const[3])):
          ds(" " + str(i+1) + " ",30+i*30,160,(255,)*3,(44 + 44*(config[0][3]==i),)*3)
      elif p == 3:
        #ds(" About: ",10,110,(255,)*3,(88,)*3)
        #ds(" floppy ",20,140,(255,)*3,(40,)*3)
        #ds(" v"+vers+" ",100,140,(255,)*3,(88,)*3)
        ds(" About: floppy v"+vers+" ",10,110,(255,)*3,(88,)*3)
        # y=160
        ds(" A ",20,140,(255,)*3,(40,)*3)
        ds("flappybird",50,140,(0,255,255),(40,)*3)
        ds("-ish small game ",150,140,(255,)*3,(40,)*3)
        # y=180
        ds(" made by ",20,160,(255,)*3,(40,)*3)
        ds(" lapin",110,160,(255,255,0),(88,)*3)
        ds("genieur ",170,160,(146,110,226),(88,)*3)

    def gc(): # gen menu cache
      return (p,[i for i in config[0]],config[1])

    p=0 # menu pattern
    cache=()
    dm()
    sleep(0.2)
    while True:
      t=[0,0] # setting, value
      if kd(1): # UP
        if p == 0:
          t=[0,-1]
        elif p == 1:
          t=[1,1]
        elif p == 2:
          config[1]=not config[1]
          t[0]=1 # for delay
      elif kd(2): # DOWN
        if p == 0:
          t=[0,1]
        elif p == 1:
          t=[1,-1]
      elif kd(0): # LEFT
        if p == 1:
          t=[2,-1]
        elif p == 2:
          t=[3,-1]
      elif kd(3): # RIGHT
        if p == 1:
          t=[2,1]
        elif p == 2:
          t=[3,1]
      elif kd(34): # RIGHT_PAREN
        p+=1
        p%=4
        t[0]=1 # for delay
      elif kd(33): # LEFT_PAREN
        p-=1
        p%=4
        t[0]=1 # for delay
      elif kd(4): # OK
        config[2]=4
        break
      elif kd(52): # EXE
        config[2]=52
        break

      if t[1]!=0:
        config[0][t[0]]+=t[1]
        config[0][t[0]]%=len(const[t[0]])
        t[0]=1 # for delay

      dm(p)
      cache=gc()
      sleep(0.02+0.15*t[0])

  def main():
    def gw(x=0): # gen_wall
      t=const[1][config[0][1]]
      y=choice(const[0][config[0][0]][1])
      if x==0:
        x=randint(t[0],t[1])
        if len(walls)>1 and walls[-1][1] == y and walls[-2][1] == y:
          while y == walls[-1][1]:
            y=choice(const[0][config[0][0]][1])
      # [wall_x, hole_y, bool_val]
      return [x,y,True]

    def df(): # draw_frame
      sc((0,255,255))

      if walls[0][0] <= -26:
        walls.pop(0)
      for i in range(len(walls)):
        walls[i][0]-=const[2][config[0][2]]
        fr(walls[i][0],0,30,222,(0,255,0))
        fr(walls[i][0],walls[i][1],30,const[0][config[0][0]][0],(0,224,244))
        if walls[i][0] < 0 and not walls[i][2]:
          walls[i][2]=True
          cache[0]+=1
      if walls[-1][0] <= 220 and walls[i][2]:
        walls[i][2]=False
        walls.append(gw())

    # arg:
    # - n!=0: don't show score
    # - l: corner touched list
    def dp(n=0,l=[False,]*4): # draw_player
      if p[0] >= 0:
        fr(30,p[0],20,20,clr)
      else:
        fr(30,0,20,20+p[0],(0,0,255))
      if n==0:
        ds(" Score: "+str(cache[0])+" ",220-10*len(str(cache[0])),10,(0,)*3,(240,)*3)
        if config[1]:
          ds(" God: "+str(cache[2])+" ",240-10*len(str(cache[2])),30,(0,)*3,(240,)*3)
      for i in (30,p[0],0), (45,p[0],1), (45,p[0]+15,2), (30,p[0]+15,3):
        if l[i[2]]:
          fr(i[0],i[1],5,5,(255,0,0))

    walls=[gw(280)]
    cache=[0,0,0] # score, loop, godmode_score
    # y, jump, adv, cooldn, tmp
    p=[80,False,0,False,0]

    df()
    dp(1)
    for i in range(3):
      ds(str(3-i)+"...",135,86)
      sleep(0.8)
    ds("GO!!!",135,86)
    sleep(0.6)

    while cache[1]==0:
      if kd(config[2]):
        if not p[1] or p[3]:
          p[1]=True
          p[2]=0
          p[3]=False
        elif p[2] < len(const[-1][0])-1:
          p[2]+=1
        p[4]=const[-1][0][p[2]]
      else:
        if p[1]:
          if not p[3]:
            p[2]=0
            p[3]=True
          elif p[2] < len(const[-1][1])-1:
            p[2]+=1
          else:
            p[1]=False
            p[2]=0
          p[4]=const[-1][1][p[2]]
        if not p[1]:
          if p[2] < len(const[-1][2])-1:
            p[2]+=1
          p[4]=const[-1][2][p[2]]

      p[0]+=p[4]
      if p[0] < 0:
        if p[1] and not p[3]:
          p[0]=0
      elif p[0] > 222:
        p[0]=223
        cache[1]=1

      df()
      l=[False,]*4
      for i in (30,p[0],0), (50,p[0],1), (50,p[0]+20,2), (30,p[0]+20,3):
        c=gp(i[0],i[1])
        if c[0]<10 and c[1]>240 and c[2]<10:
          cache[1]=2
          l[i[2]]=True
      dp(0,l)

      if cache[1] != 0:
        if config[1]:
          cache[1]=0
          cache[2]+=1
      sleep(const[3][config[0][3]])

    if p[0]<110:
      y=124
    else:
      y=60
    sleep(0.2)
    ds(" Game over! ",100,y,(0,)*3,(220,105,0))
    m=(" You fell!"," You touched a wall!")[cache[1]-1]+" press ok "
    ds(m,160-(10*(len(m)//2)),y+18)
    sleep(0.3)
    while not kd(config[2]):
      sleep(0.02)

  while True:
    menu()
    main()

print("To launch floppy, execute this then press ok\n(arg clr=(R,G,B) to set color, from 0 to 255)")
print("flop()")