Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- import lzma, base64
- import time, math, random
- ENEMYFLEET_SPRITES = b'/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AT+AhldAAOAjkKY23w2zlqFsNf/5cxaAOxdN8As5Ysmb\
- TRMHQV5Jg6V0NsrLpAPkQElcEzcyxXgwm3JefykstBV+7adR72+xmk+qanXZKa77X1N9C9792CSEFTR9TGpbkAnUvQcwjFR0Z6mu\
- JrywnJ8lSsKlVr2scXmlMB6uQo5/huPxUgl8fDAszSdIzy7NLvowIyqlXTc6K1ULqk9uy4BHHjz4F+CGC42+laUvelshNK7ZNJmt\
- laQLzDpcRqh/U1vx3hG5ct490FcdQEmPp911reyvKW1sWEJp8PVXW0+um6HyOQbTRIeHl32IvPfQHyhXgyLyqkfrv6VjdDZaGHm3\
- Lr8GPGSG67UY2YRyoqTRT73mTbxYLOQcdjkVvuWa30Z3D+Fxiltvlx2tA7rFRmjct0OnNb11x681SZr6NbyrLJQwaYPFRDBVUFgU\
- lFezZ5utnrWnVPCH0Ih5dVcKoo6IcnTasppSfv7FssFaJFckQeHA57zlmkGMZZA+BIpfKSU2cr7COjLh4RTbGg4zBu8iLAtxdKzQ\
- 6HWVqSENuvAFvkGY7ZrQdAtCaAlH0xgJzfodRWfx8SX3AvshlPkCn/mr1LIO9KFaVuNjtuyxziQpWJE9tsXSyCx6JvGYNBBTJKDD\
- 92Zyki9YXQCtjxoyEKIhEr2qo7zdzjMKQiHcSkGEirM+tLBdoNryTrJKAWyZxmUuDUHO5TgAf3RK1T2AAAAAABpay/xVB7KHQABt\
- QT/CQAApc0GrbHEZ/sCAAAAAARZWg=='
- class spritesSheet:
- def b(s, a):
- return a[1 :], int.from_bytes(a[: 1], "big")
- def w(s, a):
- return a[2 :], int.from_bytes(a[: 2], "big")
- def d(s, a):
- return a[4 :], int.from_bytes(a[: 4], "big")
- def rgb(s, a):
- return a[3 :], int.from_bytes(a[: 3], "big")
- def name(s, a):
- sl = int.from_bytes(a[: 1], "big")
- return a[1 + sl :], a[1 : sl + 1].decode("utf-8")
- def cr(s, index):
- return [index % s.c * s.cw, int(index / s.c) * s.ch, s.cw, s.ch]
- def __init__(s, lz64_data):
- # decompress data
- data = lzma.decompress(base64.b64decode(lz64_data))
- # get image dimensions
- data, s.c = s.b(data) # cols
- data, s.r = s.b(data) # rows
- data, s.cw = s.b(data) # cell width
- data, s.ch = s.b(data) # cell height
- s.iw = s.c * s.cw # image width
- s.ih = s.r * s.ch # image height
- # get palette length
- data, s.pl = s.b(data) # palette length
- # get palette
- s.palette = []
- for index in range(s.pl):
- data, irgb = s.rgb(data)
- s.palette.append(irgb)
- # create pygame surface to place spritesheet
- s.surface = pygame.Surface((s.iw, s.ih))
- pa = pygame.PixelArray(s.surface)
- # get image data length in bytes
- idl = s.iw * s.ih
- # extract image data
- for index in range(idl):
- data, pi = s.b(data) # palette index
- pa[index % s.iw][int(index / s.iw)] = s.palette[pi]
- pa.close()
- del pa
- # make the sprites using the assembly data
- s.sprites = {}
- cell = pygame.Surface((s.cw, s.ch)) # to temp store cell
- while data:
- data, sn = s.name(data) # sprite name
- data, sw = s.w(data) # sprite width, if width is zero then it's a copy instruction
- if sw == 0: # copy instruction?
- data, snc = s.name(data) #sprite name to copy
- data, at = s.b(data) # assembly attribute
- # apply attribute 0 = none, 1 = h flip, 2 = v flip, 3 = rot 90, 4 = rot 180, 5 = rot 270
- if at == 0:
- s.sprites[sn] = s.sprites[snc].copy()
- elif at == 1:
- s.sprites[sn] = pygame.transform.flip(s.sprites[snc], True, False)
- elif at == 2:
- s.sprites[sn] = pygame.transform.flip(s.sprites[snc], False, True)
- elif at == 3:
- s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -90)
- elif at == 4:
- s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -180)
- elif at == 5:
- s.sprites[sn] = pygame.transform.rotate(s.sprites[snc], -270)
- continue
- data, sh = s.w(data) # sprite height
- sc = math.ceil(sw / s.cw) # sprite columns
- sr = math.ceil(sh / s.ch) # sprite rows
- scc = sc * sr # sprite cell count
- scc_index = 0
- # create a surface for the sprite
- s.sprites[sn] = pygame.Surface((sw, sh))
- # cycle through assembly instructions
- while scc_index < scc:
- #print(scc_index, scc)
- data, ci = s.w(data) # cell index
- data, at = s.b(data) # assembly attribute
- if at < 6: # single cell placement?
- # calc x, y coords of cell placement
- x = scc_index % sc * s.cw
- y = int(scc_index / sc) * s.ch
- # get cell image
- cell.blit(s.surface, (0, 0), s.cr(ci))
- # apply attribute 0 = none, 1 = h flip, 2 = v flip, 3 = rot 90, 4 = rot 180, 5 = rot 270
- if at == 0:
- s.sprites[sn].blit(cell, (x, y))
- elif at == 1:
- s.sprites[sn].blit(pygame.transform.flip(cell, True, False), (x, y))
- elif at == 2:
- s.sprites[sn].blit(pygame.transform.flip(cell, False, True), (x, y))
- elif at == 3:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -90), (x, y))
- elif at == 4:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -180), (x, y))
- elif at == 5:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -270), (x, y))
- scc_index += 1
- else:
- data, r = s.w(data) # get range count
- for index in range(r):
- # get x, y coords of cell placement
- x = (scc_index + index) % sc * s.cw
- y = int((scc_index + index) / sc) * s.ch
- # get cell image
- cell.blit(s.surface, (0, 0), s.cr(ci))
- # apply attribute 6 = none, 7 = h flip, 8 = v flip, 9 = rot 90, 10 = rot 180, 11 = rot 270
- if at == 6 or at == 12 or at == 18:
- s.sprites[sn].blit(cell, (x, y))
- elif at == 7 or at == 13 or at == 19:
- s.sprites[sn].blit(pygame.transform.flip(cell, True, False), (x, y))
- elif at == 8 or at == 14 or at == 20:
- s.sprites[sn].blit(pygame.transform.flip(cell, False, True), (x, y))
- elif at == 9 or at == 15 or at == 21:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -90), (x, y))
- elif at == 10 or at == 16 or at == 22:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -180), (x, y))
- elif at == 11 or at == 17 or at == 23:
- s.sprites[sn].blit(pygame.transform.rotate(cell, -270), (x, y))
- # increment/decrement the sprite sheet cell index
- if at > 11 and at < 18:
- ci += 1
- elif at > 17:
- ci -= 1
- scc_index += r
- def colorKey(s, color):
- for key, sprite in s.sprites.items():
- sprite.set_colorkey(color)
- class bullets:
- class bullet:
- def __init__(s):
- global shipX, shipY
- global ZX_TILE_SIZE
- s.x = shipX + ZX_TILE_SIZE
- s.y = shipY + ZX_TILE_SIZE - 4
- def __init__(s):
- s.bullets = []
- def draw(s):
- global ZX_SURFACE, SPRITES
- for b in s.bullets:
- ZX_SURFACE.blit(SPRITES.sprites['bullet'], (int(b.x), int(b.y)))
- def move(s):
- global BULLET_SPEED
- global W
- deadBullets = []
- for b in s.bullets:
- b.x += BULLET_SPEED
- if b.x >= W: deadBullets += [b]
- for db in deadBullets:
- s.bullets.remove(db)
- def add(s):
- s.bullets += [s.bullet()]
- class UFOs:
- class bullet:
- def __init__(s, x, y):
- global shipX, shipY
- global ZX_TILE_SIZE
- s.x = x
- s.y = y + int(ZX_TILE_SIZE / 2)
- x = s.x - shipX
- y = s.y - shipY
- d = math.hypot(s.x - shipX, s.y - shipY)
- s.vx = (x / d) * UFO_BULLET_SPEED
- s.vy = (y / d) * UFO_BULLET_SPEED
- class UFO:
- def __init__(s):
- global UFO_BULLET_SPEED, UFO_BULLET_DELAY
- global ZX_TILE_SIZE
- global W
- s.x = W
- s.y = random.randint(ZX_TILE_SIZE, H - ZX_TILE_SIZE * 2)
- s.bulletTime = int(UFO_BULLET_DELAY / 2)
- s.dead = False
- def __init__(s):
- s.ufos = []
- s.bullets = []
- def draw(s):
- global ZX_SURFACE, SPRITES
- for u in s.ufos:
- ZX_SURFACE.blit(SPRITES.sprites['ufo'], (int(u.x), int(u.y)))
- for b in s.bullets:
- ZX_SURFACE.blit(SPRITES.sprites['ufo_bullet'], (int(b.x), int(b.y)))
- def move(s):
- global UFO_SPEED, UFO_BULLET_SPEED, UFO_BULLET_DELAY
- global EXPLOSIONS
- global ZX_TILE_SIZE
- deadUFOs = []
- for u in s.ufos:
- if u.dead:
- EXPLOSIONS.add(u.x + ZX_TILE_SIZE, u.y + ZX_TILE_SIZE / 2)
- deadUFOs += [u]
- continue
- u.x += UFO_SPEED
- if u.x < -ZX_TILE_SIZE * 2:
- deadUFOs += [u]
- if u.bulletTime:
- u.bulletTime -= 1
- if not u.bulletTime:
- s.bullets += [s.bullet(u.x, u.y)]
- u.bulletTime = UFO_BULLET_DELAY
- for du in deadUFOs:
- s.ufos.remove(du)
- deadBullets = []
- for b in s.bullets:
- b.x += b.vx
- b.y += b.vy
- if b.x < ZX_TILE_SIZE:
- deadBullets += [b]
- for db in deadBullets:
- s.bullets.remove(db)
- def add(s):
- s.ufos += [s.UFO()]
- class explosions:
- class explosion:
- def __init__(s, x, y, delay):
- global EXPLOSION_RADIUS
- s.x = x + random.uniform(-1, 1) * EXPLOSION_RADIUS
- s.y = y + random.uniform(-1, 1) * EXPLOSION_RADIUS
- s.frame = 1
- s.delay = delay
- def __init__(s):
- s.explosions = []
- def add(s, x, y):
- global EXPLOSION_COUNT, EXPLOSION_DELAY
- for index in range(EXPLOSION_COUNT):
- s.explosions += [s.explosion(x, y, index * EXPLOSION_DELAY)]
- def draw(s):
- global ZX_SURFACE, SPRITES
- global ZX_TILE_SIZE
- for e in s.explosions:
- if e.delay: continue
- ZX_SURFACE.blit(SPRITES.sprites['exp' + str(e.frame)], (int(e.x - ZX_TILE_SIZE / 2), int(e.y - ZX_TILE_SIZE / 2)))
- def move(s):
- global EXPLOSION_FRAMES
- deadExplosions = []
- for e in s.explosions:
- if e.delay:
- e.delay -= 1
- else:
- e.frame += 1
- if e.frame == EXPLOSION_FRAMES + 1:
- deadExplosions += [e]
- for de in deadExplosions:
- s.explosions.remove(de)
- SCALE = 3
- ZX_TILE_SIZE = 8
- ZX_WIDTH = 32
- ZX_HEIGHT = 24
- W, H = ZX_WIDTH * ZX_TILE_SIZE, ZX_HEIGHT * ZX_TILE_SIZE
- HW, HH = int(W / 2), int(H / 2)
- FPS = 60
- pygame.init()
- DS = pygame.display.set_mode((W * SCALE, H * SCALE))
- ZX_SURFACE = pygame.Surface((W, H))
- CLOCK = pygame.time.Clock()
- SPRITES = spritesSheet(ENEMYFLEET_SPRITES)
- SPRITES.colorKey([0, 0, 0])
- THRUST = 0.2
- MAX_THRUST = 2
- shipX = 10
- shipY = HH
- shipVX = 0
- shipVY = 0
- shipDead = False
- BULLETS = bullets()
- BULLET_DELAY = int(FPS / 6)
- BULLET_SPEED = 10
- bulletTime = 0
- UFOS = UFOs()
- UFO_SPEED = -1
- UFO_BULLET_SPEED = -1.5
- UFO_BULLET_DELAY = int(FPS) * 2
- UFO_STARTING_FREQUENCY = int(2 * FPS)
- UFO_FREQUENCY_REDUCTION_COUNT = 10
- UFO_FREQUENCY_REDUCTION = 5
- ufoDelay = UFO_STARTING_FREQUENCY
- ufoFrequency = UFO_STARTING_FREQUENCY
- ufoCount = 0
- EXPLOSIONS = explosions()
- EXPLOSION_FRAMES = 6
- EXPLOSION_COUNT = 20
- EXPLOSION_DELAY = 1
- EXPLOSION_RADIUS = 8
- while True:
- e = pygame.event.get()
- k = pygame.key.get_pressed()
- # exit game
- if k[pygame.K_ESCAPE]: break
- # keyboard controls
- # vertical movement
- if not shipDead:
- if k[pygame.K_UP]:
- if shipVY > -MAX_THRUST:
- shipVY -= THRUST
- elif k[pygame.K_DOWN]:
- if shipVY < MAX_THRUST:
- shipVY += THRUST
- else:
- shipVY /= 1.1
- # horizontal movement
- blitThruster = False
- if k[pygame.K_RIGHT]:
- if shipVX < MAX_THRUST:
- shipVX += THRUST
- blitThruster = True
- elif k[pygame.K_LEFT]:
- if shipVX > -MAX_THRUST:
- shipVX -= THRUST
- else:
- shipVX /= 1.1
- # fire!
- if k[pygame.K_SPACE] and bulletTime == 0:
- BULLETS.add()
- bulletTime = BULLET_DELAY
- # decrement the bullet delay
- if bulletTime:
- bulletTime -= 1
- # apply motion to the ship
- shipX += shipVX
- shipY += shipVY
- # move ship bullets
- BULLETS.move()
- # apply motion to UFOs
- UFOS.move()
- # animate explosions
- EXPLOSIONS.move()
- # time to add a UFO?
- if ufoDelay:
- ufoDelay -= 1
- if not ufoDelay:
- UFOS.add()
- ufoCount += 1
- if ufoCount == UFO_FREQUENCY_REDUCTION_COUNT:
- ufoFrequency -= UFO_FREQUENCY_REDUCTION
- if ufoFrequency < 10:
- ufoFrequency = 10
- ufoDelay = ufoFrequency
- # check for collision between ship bullets and ufos
- for b in BULLETS.bullets:
- for u in UFOS.ufos:
- if not (b.x > u.x + ZX_TILE_SIZE or b.x + 7 < u.x or b.y + 3 < u.y or b.y > u.y + ZX_TILE_SIZE):
- u.dead = True
- # check for collision between ufo bullets and ship
- if not shipDead:
- for b in UFOS.bullets:
- if not (b.x > shipX + ZX_TILE_SIZE or b.x + 4 < shipX or b.y > shipY + ZX_TILE_SIZE or b.y + 4 < shipY):
- shipDead = True
- EXPLOSIONS.add(shipX, shipY)
- break
- """ drawing/blitting bit """
- # clear display
- ZX_SURFACE.fill([0, 0, 0])
- if not shipDead:
- # blit space ship
- ZX_SURFACE.blit(SPRITES.sprites['ship'], (int(shipX), int(shipY)))
- # blit thrusters but only if ship moving to the right
- if blitThruster:
- ZX_SURFACE.blit(SPRITES.sprites['thruster'], (int(shipX - ZX_TILE_SIZE), int(shipY)))
- # blit bullets
- BULLETS.draw()
- # blit UFOS and UFO Bullets
- UFOS.draw()
- # blit explosion frames
- EXPLOSIONS.draw()
- # scale surface to fit primary display
- DS.blit(pygame.transform.scale(ZX_SURFACE, (W * SCALE, H * SCALE)), (0, 0))
- pygame.display.update()
- CLOCK.tick(FPS)
- pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement