Advertisement
cookertron

Chuckie Egg (Python Pygame v1.7.2)

Mar 4th, 2020
761
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 34.29 KB | None | 0 0
  1. """Version 1.7.2
  2.  
  3. Chuckie Egg clone, as see on a ZX Spectrum
  4. Coded by Anthony Cook and posted to fb.com/groups/pygame
  5.  
  6. NOTES:
  7. The variable SCALE must be an integer (a whole number)!
  8.  
  9. Added chickens! They can go up and down ladders and across platforms.
  10. Their decision making totally random but I may switch that to a random
  11. seed to keep it consistent like in the original
  12. """
  13.  
  14. import pygame
  15. import pygame.gfxdraw
  16. import base64, lzma
  17. import collections
  18. import math, time, random
  19.  
  20. # game time
  21. class gTime:
  22.     def __init__(s, fps): # input = frames per second
  23.         s.fps = fps
  24.         s.tpf = 1 / fps * 1000000000
  25.         s.time = 0
  26.         s.timeStamp = time.time_ns()
  27.  
  28.     def tick(s):
  29.         while time.time_ns() - s.timeStamp < s.tpf:
  30.             pass
  31.         s.timeStamp = time.time_ns()
  32.         s.time += 1
  33.  
  34. class spritesSheet:
  35.     def b(s, a):
  36.         return a[1 :], int.from_bytes(a[: 1], "big")
  37.  
  38.     def w(s, a):
  39.         return a[2 :], int.from_bytes(a[: 2], "big")
  40.  
  41.     def d(s, a):
  42.         return a[4 :], int.from_bytes(a[: 4], "big")
  43.  
  44.     def rgb(s, a):
  45.         return a[3 :], int.from_bytes(a[: 3], "big")
  46.  
  47.     def name(s, a):
  48.         sl = int.from_bytes(a[: 1], "big")
  49.         return a[1 + sl :], a[1 : sl + 1].decode("utf-8")
  50.  
  51.     def cr(s, index):
  52.         return [index % s.c * s.cw, int(index / s.c) * s.ch, s.cw, s.ch]
  53.  
  54.     def __init__(s, lz64_data):
  55.         # decompress data
  56.         data = lzma.decompress(base64.b64decode(lz64_data))
  57.  
  58.         # get image dimensions
  59.         data, s.c = s.b(data) # cols
  60.         data, s.r = s.b(data) # rows
  61.         data, s.cw = s.b(data) # cell width
  62.         data, s.ch = s.b(data) # cell height
  63.         s.iw = s.c * s.cw # image width
  64.         s.ih = s.r * s.ch # image height
  65.  
  66.         # get palette length
  67.         data, s.pl = s.b(data) # palette length
  68.  
  69.         # get palette
  70.         s.palette = []
  71.         for index in range(s.pl):
  72.             data, irgb = s.rgb(data)
  73.             s.palette.append(irgb)
  74.  
  75.         # create pygame surface to place spritesheet
  76.         s.surface = pygame.Surface((s.iw, s.ih))
  77.         pa = pygame.PixelArray(s.surface)
  78.  
  79.         # get image data length in bytes
  80.         idl = s.iw * s.ih
  81.  
  82.         # extract image data
  83.         for index in range(idl):
  84.             data, pi = s.b(data) # palette index
  85.             pa[index % s.iw][int(index / s.iw)] = s.palette[pi]
  86.         pa.close()
  87.         del pa
  88.  
  89.         # make the sprites using the assembly data
  90.         s.sprites = {}
  91.         cell = pygame.Surface((s.cw, s.ch)) # to temp store cell
  92.  
  93.         while data:
  94.             data, sn = s.name(data) # sprite name
  95.             data, sw = s.w(data) # sprite width, if width is zero then it's a copy instruction
  96.  
  97.             if sw == 0: # copy instruction?
  98.                 data, snc = s.name(data) #sprite name to copy
  99.                 data, at = s.b(data) # assembly attribute
  100.  
  101.                 # apply attribute 0 = none, 1 = h flip, 2 = v flip, 3 = rot 90, 4 = rot 180, 5 = rot 270
  102.                 if at == 0:
  103.                     s.sprites[sn] = s.sprites[snc].copy()
  104.                 elif at == 1:
  105.                     s.sprites[sn] = pygame.transform.flip(s.sprites[snc], True, False)
  106.                 elif at == 2:
  107.                     s.sprites[sn] = pygame.transform.flip(s.sprites[snc], False, True)
  108.                 elif at == 3:
  109.                     s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -90)
  110.                 elif at == 4:
  111.                     s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -180)                      
  112.                 elif at == 5:
  113.                     s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -270)  
  114.                 continue
  115.  
  116.             data, sh = s.w(data) # sprite height
  117.  
  118.             sc = math.ceil(sw / s.cw) # sprite columns
  119.             sr = math.ceil(sh / s.ch) # sprite rows
  120.             scc = sc * sr # sprite cell count
  121.             scc_index = 0
  122.  
  123.             # create a surface for the sprite
  124.             s.sprites[sn] = pygame.Surface((sw, sh))
  125.  
  126.             # cycle through assembly instructions
  127.             while scc_index < scc:
  128.                 #print(scc_index, scc)
  129.                 data, ci = s.w(data) # cell index
  130.                 data, at = s.b(data) # assembly attribute
  131.  
  132.                 if at < 6: # single cell placement?
  133.                     # calc x, y coords of cell placement
  134.                     x = scc_index % sc * s.cw
  135.                     y = int(scc_index / sc) * s.ch
  136.  
  137.                     # get cell image
  138.                     cell.blit(s.surface, (0, 0), s.cr(ci))
  139.  
  140.                     # apply attribute 0 = none, 1 = h flip, 2 = v flip, 3 = rot 90, 4 = rot 180, 5 = rot 270
  141.                     if at == 0:
  142.                         s.sprites[sn].blit(cell, (x, y))
  143.                     elif at == 1:
  144.                         s.sprites[sn].blit(pygame.transform.flip(cell, True, False), (x, y))
  145.                     elif at == 2:
  146.                         s.sprites[sn].blit(pygame.transform.flip(cell, False, True), (x, y))
  147.                     elif at == 3:
  148.                         s.sprites[sn].blit(pygame.transform.rotate(cell, -90), (x, y))
  149.                     elif at == 4:
  150.                         s.sprites[sn].blit(pygame.transform.rotate(cell, -180), (x, y))                        
  151.                     elif at == 5:
  152.                         s.sprites[sn].blit(pygame.transform.rotate(cell, -270), (x, y))                        
  153.                     scc_index += 1
  154.                 else:
  155.                     data, r = s.w(data) # get range count
  156.  
  157.                     for index in range(r):
  158.                         # get x, y coords of cell placement
  159.                         x = (scc_index + index) % sc * s.cw
  160.                         y = int((scc_index + index) / sc) * s.ch
  161.                        
  162.                         # get cell image
  163.                         cell.blit(s.surface, (0, 0), s.cr(ci))
  164.                            
  165.                         # apply attribute 6 = none, 7 = h flip, 8 = v flip, 9 = rot 90, 10 = rot 180, 11 = rot 270
  166.                         if at == 6 or at == 12 or at == 18:
  167.                             s.sprites[sn].blit(cell, (x, y))
  168.                         elif at == 7 or at == 13 or at == 19:
  169.                             s.sprites[sn].blit(pygame.transform.flip(cell, True, False), (x, y))
  170.                         elif at == 8 or at == 14 or at == 20:
  171.                             s.sprites[sn].blit(pygame.transform.flip(cell, False, True), (x, y))
  172.                         elif at == 9 or at == 15 or at == 21:
  173.                             s.sprites[sn].blit(pygame.transform.rotate(cell, -90), (x, y))
  174.                         elif at == 10 or at == 16 or at == 22:
  175.                             s.sprites[sn].blit(pygame.transform.rotate(cell, -180), (x, y))                        
  176.                         elif at == 11 or at == 17 or at == 23:
  177.                             s.sprites[sn].blit(pygame.transform.rotate(cell, -270), (x, y))
  178.                        
  179.                         # increment/decrement the sprite sheet cell index
  180.                         if at > 11 and at < 18:
  181.                             ci += 1
  182.                         elif at > 17:
  183.                             ci -= 1
  184.  
  185.                     scc_index += r
  186.  
  187. class cycle:
  188.     def __init__(s, l, h, bounce = False):
  189.         s.index = l
  190.         s.l = l
  191.         s.h = h
  192.         s.d = 1
  193.         s.b = bounce
  194.  
  195.     def __call__(s):
  196.         s.index += s.d
  197.         if s.b:
  198.             if s.index == s.h or s.index == s.l: s.d = -s.d
  199.         else:
  200.             if s.index > s.h: s.index = s.l
  201.  
  202.     def reset(s):
  203.         s.index = s.l
  204.         s.d = 1
  205.         return s
  206.    
  207.     def set(s, index):
  208.         s.index = s.l + index
  209.         return s
  210.  
  211. class font:
  212.     def __init__(s, img, charMap, spacing):
  213.         s.surfaceWidth, s.surfaceHeight = img.get_size()
  214.  
  215.         s.fontSurface = img.copy()
  216.         s.monochromeFonts = {}
  217.  
  218.         s.cols = len(charMap)
  219.         s.charWidth = int(s.surfaceWidth / s.cols)
  220.  
  221.         s.spacing = spacing
  222.  
  223.         s.charMap = charMap
  224.  
  225.     def text(s, text, scale = None, colorName = None):
  226.         surfaceWidth = len(text) * s.charWidth + s.spacing * (len(text) - 1)
  227.         surface = pygame.Surface((surfaceWidth, s.surfaceHeight))
  228.        
  229.         charPosX = 0
  230.         for c in text:
  231.             charIndex = s.charMap.find(c)
  232.             if charIndex == -1:
  233.                 charPosX += s.charWidth + s.spacing
  234.                 continue
  235.            
  236.             charOffsetX = charIndex * s.charWidth
  237.  
  238.             if colorName:
  239.                 surface.blit(s.monochromeFonts[colorName], (charPosX, 0), (charOffsetX, 0, s.charWidth, s.surfaceHeight))
  240.             else:
  241.                 surface.blit(s.fontSurface, (charPosX, 0), (charOffsetX, 0, s.charWidth, s.surfaceHeight))
  242.             charPosX += s.charWidth + s.spacing
  243.  
  244.         if scale != None:
  245.             return pygame.transform.scale(surface, (surfaceWidth * scale, s.surfaceHeight * scale))
  246.        
  247.         return surface
  248.  
  249.     def newMonochromeFont(s, name, color):
  250.         global DS
  251.         monochromeSurface = s.fontSurface.copy()
  252.         monochromePA = pygame.PixelArray(monochromeSurface)
  253.         for x in range(s.surfaceWidth):
  254.             for y in range(s.surfaceHeight):
  255.                 if monochromePA[x][y] != 0: monochromePA[x][y] = DS.map_rgb(color)
  256.         monochromePA.close()
  257.         del monochromePA
  258.         s.monochromeFonts[name] = monochromeSurface
  259.  
  260.     def size(s, text, scale = 1):
  261.         w = len(text) * s.charWidth + s.spacing * (len(text) - 1)
  262.         h = s.surfaceHeight
  263.         return [w * scale, h * scale]
  264.  
  265. class rect:
  266.     def __init__(s, x, y, w, h):
  267.         s.x1, s.y1, s.w, s.h = x, y, w, h
  268.         s.x2, s.y2 = s.x1 + s.w, s.y1 + s.h
  269.    
  270.     def setX1(s, x):
  271.         s.x1 = x
  272.         s.x2 = x + s.w
  273.    
  274.     def setY1(s, y):
  275.         s.y1 = y
  276.         s.y2 = y + s.h
  277.  
  278.     def setXY(s, x, y):
  279.         s.x1, s.y1 = x, y
  280.         s.x2, s.y2 = x + s.w, y + s.h
  281.    
  282.     def setX2(s, x):
  283.         s.x2 = x
  284.         s.x1 = x - s.w
  285.    
  286.     def setY2(s, y):
  287.         s.y2 = y
  288.         s.y1 = y - s.h
  289.  
  290.     def setXY2(s, x, y):
  291.         s.x2, s.y2 = x, y
  292.         s.x1, s.y1 = x - s.w, y - s.h
  293.  
  294.     def offX1(s, x):
  295.         s.x1 += x
  296.         s.x2 = s.x1 + s.w
  297.    
  298.     def offY1(s, y):
  299.         s.y1 += y
  300.         s.y2 = s.y1 + s.h
  301.  
  302.     def pos(s, integer = False, offset = [0, 0]):
  303.         if integer: return [int(s.x1 + offset[0]), int(s.y1 + offset[1])]
  304.         return [s.x1 + offset[0], s.y1 + offset[1]]
  305.  
  306.     def rect(s, integer = False):
  307.         if integer: return [int(s.x1), int(s.y1), int(s.w), int(s.h)]
  308.         return [s.x1, s.y1, s.w, s.h]
  309.  
  310.     def box(s, integer = False):
  311.         if integer: return [int(s.x1), int(s.y1), int(s.x2), int(s.y2)]
  312.         return [s.x1, s.y1, s.x2, s.y2]
  313.  
  314.     def size(s, integer = False):
  315.         if integer: return [int(s.w), int(s.h)]
  316.         return [s.w, s.h]
  317.  
  318.     def scale(s, value):
  319.         s.x1 *= value
  320.         s.y1 *= value
  321.         s.w *= value
  322.         s.h *= value
  323.         s.x2 = s.x1 + s.w
  324.         s.y2 = s.y1 + s.h
  325.         return s
  326.    
  327.     def __str__(s):
  328.         return "x1={}, y1={}, w={}, h={} (x2={}, y2={})".format(s.x1, s.y1, s.w, s.h, s.x2, s.y2)
  329.  
  330. def maps(lz64_data):
  331.     global PLATFORM, LATFORM, RATFORM, LADDER, EGG, HAY, LIFT, CHICKEN, CHICKEN_RIGHT, CHICKEN_LEFT
  332.     def b(a):
  333.         return a[1 :], int.from_bytes(a[0 : 1], "big")
  334.  
  335.     maps = []
  336.  
  337.     data = lzma.decompress(base64.b64decode(lz64_data))
  338.     while data:
  339.         maps.append(collections.OrderedDict({1 : [], 2 : [], 3 : [], 4 : [], 5 : [], 6 : [], 8 : []}))
  340.         data, objectCount = b(data)
  341.         maps[-1]
  342.         for index in range(objectCount):
  343.             data, id = b(data)
  344.             data, x = b(data)
  345.             data, y = b(data)
  346.            
  347.             if id == PLATFORM:
  348.                 data, w = b(data)
  349.                 maps[-1][PLATFORM].append(platform(x, y, w))
  350.             elif id == LATFORM: maps[-1][LATFORM].append(latform(x, y))
  351.             elif id == RATFORM: maps[-1][RATFORM].append(ratform(x, y))
  352.             elif id == LADDER:
  353.                 data, h = b(data)
  354.                 maps[-1][LADDER].append(ladder(x, y, h))
  355.             elif id == EGG: maps[-1][EGG].append(egg(x, y))
  356.             elif id == HAY: maps[-1][HAY].append(hay(x, y))
  357.             elif id == LIFT: maps[-1][LIFT].append(lift(x, y))
  358.             elif id == CHICKEN_RIGHT: maps[-1][CHICKEN].append(chicken(x, y, 1))
  359.             elif id == CHICKEN_LEFT: maps[-1][CHICKEN].append(chicken(x, y, -1))
  360.  
  361.     return maps
  362.  
  363. class platform:
  364.     def __init__(s, x, y, w):
  365.         global TILE_SIZE
  366.         global SPRITES
  367.  
  368.         s.rect = rect(x, y, w, 1).scale(TILE_SIZE)
  369.         s.surface = pygame.Surface(s.rect.size(True))
  370.  
  371.         for index in range(w):
  372.             s.surface.blit(SPRITES.sprites['pf'], (index * TILE_SIZE, 0))
  373.  
  374. class latform:
  375.     def __init__(s, x, y):
  376.         global TILE_SIZE
  377.        
  378.         s.rect = rect(x, y, 2, 1).scale(TILE_SIZE)
  379.  
  380. class ratform:
  381.     def __init__(s, x, y):
  382.         global TILE_SIZE
  383.  
  384.         s.rect = rect(x, y, 2, 1).scale(TILE_SIZE)
  385.  
  386. class ladder:
  387.     def __init__(s, x, y, h):
  388.         global TILE_SIZE
  389.         global SPRITES
  390.  
  391.         s.rect = rect(x, y, 2, h).scale(TILE_SIZE)
  392.         s.surface = pygame.Surface(s.rect.size(True))
  393.  
  394.         for index in range(h):
  395.             s.surface.blit(SPRITES.sprites['ls'], (0, index * TILE_SIZE))
  396.  
  397. class egg:
  398.     def __init__(s, x, y):
  399.         global TILE_SIZE
  400.         global SPRITES
  401.  
  402.         s.rect = rect(x, y, 1, 1).scale(TILE_SIZE)
  403.         s.surface = SPRITES.sprites['eg']
  404.  
  405. class hay:
  406.     def __init__(s, x, y):
  407.         global TILE_SIZE
  408.         global SPRITES
  409.  
  410.         s.rect = rect(x, y, 1, 1).scale(TILE_SIZE)
  411.         s.surface = SPRITES.sprites['hy']
  412.  
  413. class lift:
  414.     def __init__(s, x, y):
  415.         global TILE_SIZE
  416.         global SPRITES
  417.  
  418.         s.moveToggle = 0
  419.         s.rect = rect(x, y, 2, 1).scale(TILE_SIZE)
  420.         s.surface = SPRITES.sprites['lt']
  421.  
  422.     def do(s):
  423.         global TILE_SIZE
  424.         global H
  425.  
  426.         if not s.moveToggle:
  427.             s.rect.offY1(-1)
  428.         s.moveToggle = 1 - s.moveToggle
  429.  
  430.         if s.rect.y1 <= TILE_SIZE * 3:
  431.             s.rect.setY1(H - TILE_SIZE)
  432.  
  433. CHICKEN_WALK_RIGHT = [0, 1]
  434. CHICKEN_WALK_LEFT = [2, 3]
  435. CHICKEN_CLIMB = [6, 7]
  436. CHICKEN_DELAY = 5
  437. CHICKEN_DIRECTIONS = [-1, 1]
  438.  
  439. class chicken:
  440.     def __init__(s, x, y, direction):
  441.         global TILE_SIZE
  442.         global CHICKEN_DELAY
  443.         global CHICKEN_WALK_RIGHT, CHICKEN_WALK_LEFT      
  444.  
  445.         s.rect = rect(x, y, 1, 2).scale(TILE_SIZE)
  446.  
  447.         s.currentObject = None
  448.  
  449.         s.state = s.walking
  450.  
  451.         s.moveToggle = CHICKEN_DELAY
  452.         s.dx = direction
  453.         s.dy = 0
  454.         if direction == 1:
  455.             s.anim = CHICKEN_WALK_RIGHT
  456.         else:
  457.             s.anim = CHICKEN_WALK_LEFT
  458.  
  459.         s.animIndex = 0
  460.  
  461.     def draw(s):
  462.         global CHICKEN_SPRITES
  463.         global ZX_SURFACE
  464.  
  465.         ZX_SURFACE.blit(CHICKEN_SPRITES[s.anim[s.animIndex]], s.rect.pos())
  466.  
  467.     def do(s):
  468.         global MAPS, MAP_INDEX, PLATFORM, CHICKEN
  469.         global CHICKEN_DELAY
  470.  
  471.         #if s != MAPS[MAP_INDEX][CHICKEN][0]: return # debug
  472.  
  473.         if not s.currentObject:
  474.             for p in MAPS[MAP_INDEX][PLATFORM]:
  475.                 if s.rect.y2 != p.rect.y1: continue
  476.                 if s.rect.x2 < p.rect.x1 or s.rect.x1 > p.rect.x2: continue
  477.                 s.currentObject = p
  478.                 break
  479.  
  480.         s.moveToggle -= 1
  481.         if s.moveToggle > 0: return
  482.         s.moveToggle = CHICKEN_DELAY
  483.         s.animIndex = 1 - s.animIndex
  484.  
  485.         s.state()
  486.  
  487.     def walking(s):
  488.         global MAPS, MAP_INDEX, PLATFORM, CHICKEN, LATFORM, RATFORM, LADDER
  489.         global CHICKEN_WALK_RIGHT, CHICKEN_WALK_LEFT, CHICKEN_CLIMB, CHICKEN_DIRECTIONS
  490.  
  491.         s.rect.offX1(s.dx)
  492.        
  493.         # check if chicken wants to climb a ladder
  494.         if (s.rect.x1 + 4) % 8 == 0:
  495.             for l in MAPS[MAP_INDEX][LADDER]:
  496.                 if l.rect.x1 == s.rect.x1 - 4:
  497.                     if s.rect.y1 >= l.rect.y1 and s.rect.y2 <= l.rect.y2:
  498.                         getOnLadder = random.randint(0, 1)
  499.                         if getOnLadder:
  500.                             if s.rect.y1 == l.rect.y1:
  501.                                 s.dy = 1
  502.                             elif s.rect.y2 == l.rect.y2:
  503.                                 s.dy = -1
  504.                             else:
  505.                                 s.dy = CHICKEN_DIRECTIONS[random.randint(0, 1)]
  506.                             s.currentObject = l
  507.                             s.animIndex = 0
  508.                             s.anim = CHICKEN_CLIMB
  509.                             s.state = s.climbing
  510.                             return
  511.                         break
  512.  
  513.         # walk along the platform
  514.         platformExtended = False
  515.         if s.dx == 1 and s.rect.x2 == s.currentObject.rect.x2:
  516.             for p in MAPS[MAP_INDEX][PLATFORM] + MAPS[MAP_INDEX][LATFORM]:
  517.                 if s.currentObject.rect.x2 == p.rect.x1 and s.currentObject.rect.y1 == p.rect.y1:
  518.                     s.currentObject = p
  519.                     platformExtended = True
  520.                     break    
  521.             if not platformExtended:
  522.                 s.dx = -1
  523.                 s.anim = CHICKEN_WALK_LEFT
  524.                 s.animIndex = 0
  525.         elif s.dx == -1 and s.rect.x1 == s.currentObject.rect.x1:
  526.             for p in MAPS[MAP_INDEX][PLATFORM] + MAPS[MAP_INDEX][RATFORM]:
  527.                 if s.currentObject.rect.x1 == p.rect.x2 and s.currentObject.rect.y1 == p.rect.y1:
  528.                     s.currentObject = p
  529.                     platformExtended = True
  530.                     break    
  531.             if not platformExtended:
  532.                 s.dx = 1
  533.                 s.anim = CHICKEN_WALK_RIGHT
  534.                 s.animIndex = 0
  535.  
  536.     def climbing(s):
  537.         global MAPS, MAP_INDEX, PLATFORM, RATFORM, LATFORM
  538.         global CHICKEN_WALK_RIGHT, CHICKEN_WALK_LEFT, CHICKEN_DIRECTIONS
  539.  
  540.         s.rect.offY1(s.dy)
  541.  
  542.         # does the chicken want to get off the ladder?
  543.         if s.rect.y2 % 8 == 0:
  544.             for p in MAPS[MAP_INDEX][PLATFORM] + MAPS[MAP_INDEX][RATFORM] + MAPS[MAP_INDEX][LATFORM]:
  545.                 if s.rect.y2 != p.rect.y1: continue
  546.                 if s.rect.x1 > p.rect.x2 or s.rect.x2 < p.rect.x1: continue
  547.                 getOffLadder = random.randint(0, 1)
  548.                 if getOffLadder:
  549.                     if type(p) == ratform:
  550.                         s.dx = 1
  551.                     elif type(p) == latform:
  552.                         s.dx = -1
  553.                     else:
  554.                         s.dx = CHICKEN_DIRECTIONS[random.randint(0, 1)]
  555.                     if s.dx == 1:
  556.                         s.anim = CHICKEN_WALK_RIGHT
  557.                     else:
  558.                         s.anim = CHICKEN_WALK_LEFT
  559.                     s.animIndex = 0
  560.                     s.currentObject = p
  561.                     s.state = s.walking
  562.                     return
  563.             if s.rect.y2 == s.currentObject.rect.y2 or s.rect.y1 == s.currentObject.rect.y1:
  564.                 s.dy = -s.dy
  565.  
  566.    
  567. HARRY_WALKING_RIGHT = cycle(0, 1)
  568. HARRY_WALKING_LEFT = cycle(2, 3)
  569. HARRY_CLIMBING_LADDER = cycle(4, 6, True)
  570.  
  571. # key binds
  572. UP = pygame.K_UP
  573. DOWN = pygame.K_DOWN
  574. LEFT = pygame.K_LEFT
  575. RIGHT = pygame.K_RIGHT
  576. SPACE = pygame.K_SPACE
  577.  
  578. class harry:
  579.     def __init__(s, x, y):
  580.         global SPEED
  581.         global TILE_SIZE
  582.         global HARRY_WALKING_RIGHT
  583.  
  584.         s.rect = rect(x, y, 1, 2).scale(TILE_SIZE)
  585.         s.xIndex = x * SPEED
  586.         s.xIndexDirection = 0
  587.         s.jumpHeight = 0
  588.  
  589.         s.state = s.falling
  590.  
  591.         s.currentObject = None
  592.  
  593.         s.anim = HARRY_WALKING_RIGHT.set(1)
  594.  
  595.     def draw(s):
  596.         global HARRY_SPRITES
  597.         global ZX_SURFACE
  598.  
  599.         ZX_SURFACE.blit(HARRY_SPRITES[s.anim.index], s.rect.pos(True, [-s.rect.w / 4, 0]))
  600.         #SPRITE_SETS['harry'].blit(s.anim.index, DS, s.rect.pos(True, [-s.rect.w / 4, 0]))
  601.         #pygame.draw.rect(DS, [255, 0, 0], s.rect.rect(True))
  602.  
  603.     def do(s):
  604.         s.keys = pygame.key.get_pressed()
  605.         s.state()
  606.         if type(s.currentObject) == lift:
  607.             s.rect.setY2(s.currentObject.rect.y1)
  608.         # check for collision with eggs, hay and birds
  609.        
  610.  
  611.     def falling(s):
  612.         global Y_VELOCITY
  613.  
  614.         if s.collidedWithPlatform(): return
  615.         s.rect.offY1(Y_VELOCITY)
  616.  
  617.     def stop(s):
  618.         global JUMP_HEIGHT
  619.         global HARRY_WALKING_LEFT, HARRY_WALKING_RIGHT
  620.         global LEFT, RIGHT, SPACE
  621.  
  622.         if s.hasClimbedLadder(): return
  623.  
  624.         if s.keys[LEFT]:
  625.             s.xIndexDirection = -1
  626.             s.anim = HARRY_WALKING_LEFT.reset()
  627.             s.state = s.walkLeft
  628.         elif s.keys[RIGHT]:
  629.             s.xIndexDirection = 1
  630.             s.anim = HARRY_WALKING_RIGHT.reset()
  631.             s.state = s.walkRight
  632.  
  633.         if s.keys[SPACE]:
  634.             s.jumpHeight = JUMP_HEIGHT
  635.             s.anim.set(1)
  636.             s.currentObject = None
  637.             s.state = s.jumpUp
  638.  
  639.     def walkRight(s):
  640.         global X_VELOCITY, JUMP_HEIGHT
  641.         global MAPS, MAP_INDEX, LATFORM, RATFORM
  642.         global RIGHT, SPACE
  643.         global W
  644.  
  645.         if s.hasClimbedLadder(): return
  646.  
  647.         if s.keys[SPACE]:
  648.             s.jumpHeight = JUMP_HEIGHT
  649.             s.anim.set(1)
  650.             s.currentObject = None
  651.             s.state = s.jumpUp
  652.             return
  653.  
  654.         if not s.keys[RIGHT]:
  655.             s.xIndexDirection = 0
  656.             s.anim.set(0)
  657.             s.state = s.stop
  658.             return
  659.  
  660.         if s.collidedWithLeftEdge():
  661.             s.anim.set(0)
  662.             return
  663.  
  664.         if s.xIndex == 186: return
  665.  
  666.         s.anim()
  667.         s.xIndex += s.xIndexDirection
  668.         s.rect.setX1(s.xIndex * X_VELOCITY)
  669.         if s.rect.x1 == s.currentObject.rect.x2:
  670.             if not s.collidedWithPlatform(MAPS[MAP_INDEX][LATFORM] + MAPS[MAP_INDEX][RATFORM]):
  671.                 s.xIndexDirection = 0
  672.                 s.currentObject = None
  673.                 s.anim.set(1)
  674.                 s.state = s.falling
  675.                 return
  676.  
  677.     def walkLeft(s):
  678.         global X_VELOCITY, JUMP_HEIGHT
  679.         global MAPS, MAP_INDEX, LATFORM, RATFORM
  680.         global LEFT, UP, DOWN, SPACE
  681.  
  682.  
  683.         if s.hasClimbedLadder(): return
  684.  
  685.         if s.keys[SPACE]:
  686.             s.jumpHeight = JUMP_HEIGHT
  687.             s.anim.set(1)
  688.             s.currentObject = None
  689.             s.state = s.jumpUp
  690.             return
  691.  
  692.         if not s.keys[LEFT]:
  693.             s.xIndexDirection = 0
  694.             s.anim.set(0)
  695.             s.state = s.stop
  696.             return
  697.  
  698.         if s.collidedWithRightEdge():
  699.             s.anim.set(0)
  700.             return
  701.  
  702.         if s.xIndex == 0: return
  703.  
  704.         s.anim()
  705.         s.xIndex += s.xIndexDirection
  706.         s.rect.setX1(s.xIndex * X_VELOCITY)
  707.  
  708.         if s.rect.x2 == s.currentObject.rect.x1:
  709.             if not s.collidedWithPlatform(MAPS[MAP_INDEX][LATFORM] + MAPS[MAP_INDEX][RATFORM]):            
  710.                 s.xIndexDirection = 0
  711.                 s.currentObject = None
  712.                 s.anim.set(1)
  713.                 s.state = s.falling
  714.                 return
  715.  
  716.     def jumpUp(s):
  717.         global X_VELOCITY, Y_VELOCITY
  718.  
  719.         if s.hasClimbedLadder(): return
  720.  
  721.         if s.xIndex == 0 or s.xIndex == 186:
  722.             s.xIndexDirection = -s.xIndexDirection
  723.  
  724.         s.xIndex += s.xIndexDirection
  725.         s.rect.setX1(s.xIndex * X_VELOCITY)
  726.         s.rect.offY1(-Y_VELOCITY)
  727.  
  728.         s.jumpHeight -= 1
  729.         if not s.jumpHeight:
  730.             s.state = s.jumpDown
  731.  
  732.     def jumpDown(s):
  733.         global X_VELOCITY, Y_VELOCITY
  734.         global MAPS, MAP_INDEX, LIFT
  735.  
  736.         if s.hasClimbedLadder(): return
  737.        
  738.         if s.xIndex == 0 or s.xIndex == 186:
  739.             s.xIndexDirection = -s.xIndexDirection
  740.        
  741.         if s.xIndexDirection > 0:
  742.             if s.collidedWithLeftEdge(): s.xIndexDirection = -s.xIndexDirection
  743.         elif s.xIndexDirection < 0:
  744.             if s.collidedWithRightEdge(): s.xIndexDirection = -s.xIndexDirection
  745.  
  746.         s.xIndex += s.xIndexDirection
  747.         s.rect.setX1(s.xIndex * X_VELOCITY)
  748.  
  749.         if LIFT in MAPS[MAP_INDEX]:
  750.             if s.collidedWithPlatform(MAPS[MAP_INDEX][LIFT]): return
  751.         else:
  752.             if s.collidedWithPlatform(): return
  753.  
  754.         s.rect.offY1(Y_VELOCITY)  
  755.  
  756.     def climbing(s):
  757.         global X_VELOCITY, Y_VELOCITY, JUMP_HEIGHT
  758.         global HARRY_WALKING_LEFT, HARRY_WALKING_RIGHT
  759.         global MAPS, MAP_INDEX, PLATFORM, RATFORM, LATFORM
  760.         global UP, DOWN, LEFT, RIGHT, SPACE
  761.  
  762.         if s.keys[UP]:
  763.             if s.rect.y1 > s.currentObject.rect.y1:
  764.                 s.rect.offY1(-Y_VELOCITY)
  765.                 s.anim()
  766.         if s.keys[DOWN]:
  767.             if s.rect.y2 < s.currentObject.rect.y2:
  768.                 s.rect.offY1(Y_VELOCITY)
  769.                 s.anim()
  770.  
  771.         if s.keys[SPACE]:
  772.             s.jumpHeight = JUMP_HEIGHT
  773.             s.currentObject = None
  774.             s.state = s.jumpUp
  775.             if s.keys[LEFT]:
  776.                 s.xIndexDirection = -1
  777.                 s.anim = HARRY_WALKING_LEFT.set(1)
  778.             elif s.keys[RIGHT]:
  779.                 s.xIndexDirection = 1
  780.                 s.anim = HARRY_WALKING_RIGHT.set(1)
  781.             else:
  782.                 s.xIndexDirection = 0
  783.                 s.anim = HARRY_WALKING_RIGHT.set(1)
  784.             return
  785.            
  786.         #print(s.rect.y1, s.rect.y2, s.currentObject.rect.y1)
  787.  
  788.         if not (s.keys[LEFT] or s.keys[RIGHT]): return
  789.  
  790.         for platform in MAPS[MAP_INDEX][PLATFORM] + MAPS[MAP_INDEX][LATFORM] + MAPS[MAP_INDEX][RATFORM]:
  791.             if s.rect.y2 == platform.rect.y1 and s.rect.x1 > platform.rect.x1 and s.rect.x2 < platform.rect.x2:
  792.                 if s.keys[LEFT] and type(platform) != ratform:
  793.                     s.currentObject = platform
  794.                     s.xIndexDirection = -1
  795.                     s.anim = HARRY_WALKING_LEFT.reset()
  796.                     s.state = s.walkLeft
  797.                 elif s.keys[RIGHT] and type(platform) != latform:
  798.                     s.currentObject = platform
  799.                     s.xIndexDirection = 1
  800.                     s.anim = HARRY_WALKING_RIGHT.reset()
  801.                     s.state = s.walkRight
  802.                 s.xIndex += s.xIndexDirection
  803.                 s.rect.setX1(s.xIndex * X_VELOCITY)
  804.                 break
  805.  
  806.  
  807.     def collidedWithLeftEdge(s):
  808.         global TILE_SIZE
  809.         global MAPS, MAP_INDEX, PLATFORM
  810.  
  811.         for platform in MAPS[MAP_INDEX][PLATFORM]:
  812.             if s.rect.x2 != platform.rect.x1: continue
  813.             if s.rect.y1 + TILE_SIZE > platform.rect.y2 or s.rect.y2 < platform.rect.y1 + 1: continue
  814.             return True
  815.         return False
  816.  
  817.     def collidedWithRightEdge(s):
  818.         global TILE_SIZE
  819.         global MAPS, MAP_INDEX, PLATFORM
  820.  
  821.         for platform in MAPS[MAP_INDEX][PLATFORM]:
  822.             if s.rect.x1 != platform.rect.x2: continue
  823.             if s.rect.y1 + TILE_SIZE > platform.rect.y2 or s.rect.y2 < platform.rect.y1 + 1: continue
  824.             return True
  825.         return False
  826.  
  827.     def collidedWithPlatform(s, additionalObjects = []): # worded as a question
  828.         global Y_VELOCITY
  829.         global MAPS, MAP_INDEX, PLATFORM
  830.        
  831.         for platform in MAPS[MAP_INDEX][PLATFORM] + additionalObjects:
  832.             if not (s.rect.x1 >= platform.rect.x2 or s.rect.x2 <= platform.rect.x1):
  833.                 if (s.rect.y2 < platform.rect.y1 and s.rect.y2 + Y_VELOCITY >= platform.rect.y1) or s.rect.y2 == platform.rect.y1:
  834.                     s.rect.setY2(platform.rect.y1)
  835.                     s.xIndexDirection = 0
  836.                     s.currentObject = platform
  837.                     s.anim.set(0)
  838.                     s.state = s.stop
  839.                     return True
  840.  
  841.         return False
  842.  
  843.     def hasClimbedLadder(s):
  844.         global HARRY_CLIMBING_LADDER
  845.         global MAPS, MAP_INDEX, LADDER
  846.         global UP, DOWN
  847.  
  848.         if not (s.keys[UP] or s.keys[DOWN]): return
  849.  
  850.         for ladder in MAPS[MAP_INDEX][LADDER]:
  851.             if s.rect.x1 == ladder.rect.x1 + 4:
  852.                 if (s.keys[UP] and s.rect.y1 > ladder.rect.y1 and s.rect.y2 <= ladder.rect.y2) or (s.keys[DOWN] and s.rect.y2 < ladder.rect.y2 and s.rect.y1 >= ladder.rect.y1):
  853.                     s.xIndexDirection = 0
  854.                     s.currentObject = ladder
  855.                     s.anim = HARRY_CLIMBING_LADDER.reset()
  856.                     s.state = s.climbing
  857.                     return
  858. #print("can climb, {} {} {} {}".format(ladder.rect.x1, ladder.rect.y1, ladder.rect.x2, ladder.rect.y2))
  859.  
  860. # set up scale and pygame variables
  861. SCALE = 5
  862. ZX_TILE_SIZE = 8
  863. TILE_SIZE = ZX_TILE_SIZE
  864. WIDTH_IN_TILES = 32
  865. HEIGHT_IN_TILES = 24
  866.  
  867. FPS = 60
  868. W, H = int(WIDTH_IN_TILES * TILE_SIZE), int(HEIGHT_IN_TILES * TILE_SIZE)
  869. HW, HH = int(W / 2), int(H / 2)
  870.  
  871. pygame.init()
  872. DS = pygame.display.set_mode((W * SCALE, H * SCALE))
  873. ZX_SURFACE = pygame.Surface((W, H))
  874. TIME = gTime(FPS)
  875.  
  876. # a tonne of data
  877. CHUCKIE_SPRITES = b'/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4B9PBF5dAASDqq1TN1vaXm7k3zboYptpmiLlGK/nz2hNtPva\
  878. h/InbMa+8OnbcQatGrITZdE2gey/xwuWnBbd8OAhoIoG5RzLaOwVg150Qt6+wy5vOOIfE1iY7X/nsvkzPdJiz6vpX5rR045sHHe6\
  879. G2Qv9iQxcWiUaFwDtBGQWBug27uyQ1GMiaj88WZz4f0S2iojyiXgYJ/gvIHTDIjRShb2krisOlGLHoPY3otfA4nzX3ekFjwLdDmc\
  880. oJuyILAgHh1B0xy7urQeMvMfsiA76Z/phxvRcBPuVbHeo+h4qeYSa7A6XYBuFfNZFCGVwghbVaVxAp5pOTXkLftWwuBRGIZGE+41\
  881. lBgNhbp8OAofi8PRNmh9MySaHF+DG+76rlMjqUBCyIIfzMACbfXlbzHUhOpk9D1KoCIqa/a/escN2d5SUnr9FP/3xMZF2kZm2V+A\
  882. uXhnIluc1JQSoWf73+kQj78Pf9FxwbMCr44W9w3l7Ghzbck6OWHczvHVh0jLjOC+QI+58qn5HwOW6xQsFay88bCb01rIMNCJ06J1\
  883. 3BuLiceX2AyzclGXNIiGLaoNbG0iDD4YKFkX5DM63AwipfndzO7fj4TM0/DHrTRzdaMEMKUivnOTOMk560IH42siCZQz1rNYEQ8J\
  884. XLG3lO031I+8ly591BG2KneUx7dZeEf2xy0JeagmGA2n/t9xxDo3HNO5sq7q4lboNDRMKwI+TTBmuCyUz8rG0JH3iXcDM0o3FuOU\
  885. ajOEt8W+zUZKoR2hsAoooQSwnnfuH1qNacfcjczWnS/FouhwNKqFGowOBZvrbsiSDMPXRQV73pUWXjgGo9Z1aW+kO8IEZI+rKc+9\
  886. vBiDQLv0ixStHYaArO1lKVOG61Bc7tULQgOItoxyONQrrJOmMmO06t3QsZW2IRUAAMpYgf97loTBinYsHsywYrvPWj0SjIXsERjJ\
  887. 73DmNSWv9AFWmwkJBFpCsAV24BNUVu4QaY2zn+a0Plm4tvB5l66b/OTBde7bE1fn1JCB2B8bbNMSr/MjwvrqfXH2gJ7d8ECUAjzv\
  888. J21SaPn6jqTT12K3m3ix6c64Q7YP1eKq6hcUNsVfdX4rRe/apAUIZnt2WGzSXhBkP8BiHx+nnZ1shrWCwrKfnQbpIfZXM+8TBBHY\
  889. /AOQevvxYWehily9YoHAeIF3M89eSWv8UC9VV2KwQ3MX6xPTwilfK4/nNOXn7TS3tDVcwtwvNS4cbvxaJQVlXZRFK1auLC0/+cUc\
  890. KDPoWCqBlt4vyWYFrh/jogJI4G5IkmrygsmTH+CLuP+4+bWbItpjzFlLpJMcikQAt7LsH0vdpRECQn4pKM12o5ROvqI38yQuyyBx\
  891. LcXavSIjk6Hd91ZadeBwkohc/Sb6+aR8pN5OdMjDo34vZRC46m+ForbpXJxCYQMEYfsCwc0b3sCuH235H+3znQyYSRbwSoqpXH3E\
  892. sRHT/Hr3SzLhKY+nCaqVYsT63iGzoBTQaNUQiFvUdbwImMLb8isAAAAA/kdTHBIIrMkAAfoI0D4AAGDUjU+xxGf7AgAAAAAEWVo='
  893.  
  894. MAPS = b'/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AEpANddABUA/UoJu3jJ4BZISBX4qyJ8e1ZMTy4yPPcARMkYyurpSEqERo+\
  895. eSQHx9tycAFXNjYV8YxSm2C+7r/hqKP3A5GjVAlU7k0grSFH3PCfvGZhmde7sKSe8JEsRrckwaYzlJ/257PTpQWXn3Q5zFkIjJ+O\
  896. 8PnB9KJAkaqONh5IZPNcULqvmAaLMi8DRavSpc5hLP+RppKs5BB8iXHDuBzFTA0GM1zNPwU0PYYmTPM6SKs8ZECKYjfMv4qw8DHq\
  897. 7ENgFIQk0wIQVz19gNKM/2MPQa2o81eh0F2IAAAAS/m2jGnQr0QAB8wGqAgAA1bthTLHEZ/sCAAAAAARZWg=='
  898.  
  899. # make sprites
  900. SPRITES = spritesSheet(CHUCKIE_SPRITES)
  901. FONT = font(SPRITES.sprites['fnt'], "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.!?:,'", 0)
  902.  
  903. HARRY_SPRITES = [SPRITES.sprites['hsr'], SPRITES.sprites['hwr'], SPRITES.sprites['hsl'], SPRITES.sprites['hwl'], SPRITES.sprites['hc1'], SPRITES.sprites['hc2'], SPRITES.sprites['hc3']]
  904. [HARRY_SPRITES[index].set_colorkey([0, 0, 0]) for index in range(len(HARRY_SPRITES))]
  905.  
  906. CHICKEN_SPRITES = [SPRITES.sprites['csr'], SPRITES.sprites['cwr'], SPRITES.sprites['csl'], SPRITES.sprites['cwl'], SPRITES.sprites['cpr'], SPRITES.sprites['cpl'], SPRITES.sprites['cc1'], SPRITES.sprites['cc2']]
  907. [CHICKEN_SPRITES[index].set_colorkey([0, 0, 0]) for index in range(len(CHICKEN_SPRITES))]
  908.  
  909. # map tile IDs
  910. PLATFORM = 1
  911. LATFORM = 2
  912. RATFORM = 3
  913. LADDER = 4
  914. EGG = 5
  915. HAY = 6
  916. LIFT = 7
  917. CHICKEN = 8
  918. CHICKEN_RIGHT = 24
  919. CHICKEN_LEFT = 27
  920.  
  921. # generate maps
  922. MAPS = maps(MAPS)
  923. MAP_INDEX = 1
  924.  
  925. # player stuff
  926. SPEED = 6
  927. X_VELOCITY = TILE_SIZE / SPEED
  928. Y_VELOCITY = 1
  929. JUMP_HEIGHT = 12
  930. PLAYER = harry(12, 21)
  931.  
  932. # screens
  933. # title screen
  934. TITLE_SCREEN = pygame.Surface((W, H))
  935. TITLE_SCREEN.blit(SPRITES.sprites['be1'], (7 * TILE_SIZE, 8 * TILE_SIZE))
  936. TITLE_SCREEN.blit(SPRITES.sprites['be2'], (9 * TILE_SIZE, 8 * TILE_SIZE))
  937. TITLE_SCREEN.blit(SPRITES.sprites['tle'], (6 * TILE_SIZE, 10 * TILE_SIZE))
  938. TITLE_SCREEN.blit(FONT.text("S...START  ESC...EXIT"), (6 * TILE_SIZE, 13 * TILE_SIZE))
  939.  
  940. TITLE_SCREEN = pygame.transform.scale(TITLE_SCREEN, (W * SCALE, H * SCALE))
  941.  
  942. DEBUG = False
  943. while True:
  944.     if not DEBUG:
  945.         exitGame = False
  946.         while True:
  947.             e = pygame.event.get()
  948.             if pygame.key.get_pressed()[pygame.K_s]: break
  949.             if pygame.key.get_pressed()[pygame.K_ESCAPE]:
  950.                 exitGame = True
  951.                 break
  952.  
  953.             DS.blit(TITLE_SCREEN, (0, 0))
  954.             pygame.display.update()
  955.             TIME.tick()        
  956.  
  957.         if exitGame: break
  958.  
  959.     while True:
  960.         e = pygame.event.get()
  961.         if pygame.key.get_pressed()[pygame.K_ESCAPE]: break
  962.  
  963.         ZX_SURFACE.fill([0, 0, 0])
  964.        
  965.         for l, objs in MAPS[MAP_INDEX].items():
  966.             for obj in objs:
  967.                 if hasattr(obj, "surface"):
  968.                     ZX_SURFACE.blit(obj.surface, obj.rect.pos(True))
  969.                     #pygame.draw.rect(DS, (255, 255, 255), obj.rect.rect())
  970.                 if hasattr(obj, "draw"):
  971.                     obj.draw()
  972.                 if hasattr(obj, "do"):
  973.                     obj.do()
  974.         ZX_SURFACE.blit(SPRITES.sprites['cg'], (0, 3 * TILE_SIZE))
  975.         PLAYER.draw()
  976.         PLAYER.do()
  977.  
  978.         if DEBUG:
  979.             ZX_SURFACE.blit(FONT.text("PLAY X1:{} Y1:{} X2:{} Y2:{}".format(round(PLAYER.rect.x1, 1), PLAYER.rect.y1, round(PLAYER.rect.x2, 1), PLAYER.rect.y2)), (0, 0))
  980.             ZX_SURFACE.blit(FONT.text("XI:{}".format(PLAYER.xIndex)), (0, 8))
  981.             if PLAYER.currentObject:
  982.                 ZX_SURFACE.blit(FONT.text("OBJ X1:{} Y1:{} X2:{} Y2:{}".format(PLAYER.currentObject.rect.x1, PLAYER.currentObject.rect.y1, PLAYER.currentObject.rect.x2, PLAYER.currentObject.rect.y2)), (0, 16))
  983.  
  984.         DS.blit(pygame.transform.scale(ZX_SURFACE, (W * SCALE, H * SCALE)), (0, 0))
  985.         pygame.display.update()
  986.         TIME.tick()
  987.    
  988.     if DEBUG: break
  989.     while True:
  990.         e = pygame.event.get()
  991.         if not pygame.key.get_pressed()[pygame.K_ESCAPE]: break
  992.  
  993. pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement