added a vipe coded tetris gui
This commit is contained in:
Executable
+182
@@ -0,0 +1,182 @@
|
||||
#!/home/honney/Projects/tetris_gui/.venv/bin/python3
|
||||
import sys, json, select, os
|
||||
import pygame
|
||||
|
||||
WIDTH, HEIGHT = 1280, 720
|
||||
CELL = 32
|
||||
BOARD_H, BOARD_W = 20, 10
|
||||
NEXT_H, NEXT_W = 4, 4
|
||||
|
||||
B1 = (304, 40, 320, 640)
|
||||
B2 = (656, 40, 320, 640)
|
||||
N1 = (88, 96, 128, 128)
|
||||
N2 = (1064, 96, 128, 128)
|
||||
S1 = (84, 454, 136, 32)
|
||||
S2 = (1060, 454, 136, 32)
|
||||
|
||||
SCORE_FONT = [
|
||||
[ # S
|
||||
[0,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,0,0],
|
||||
[0,1,1,1,0,0],[0,0,1,1,1,0],[0,0,0,0,1,1],
|
||||
[1,1,0,0,1,1],[0,1,1,1,1,0],
|
||||
],
|
||||
[ # C
|
||||
[0,1,1,1,1,0],[1,1,1,0,1,1],[1,1,0,0,0,0],
|
||||
[1,1,0,0,0,0],[1,1,0,0,0,0],[1,1,0,0,0,0],
|
||||
[1,1,1,0,1,1],[0,1,1,1,1,0],
|
||||
],
|
||||
[ # O
|
||||
[0,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,1,1],
|
||||
[1,1,0,0,1,1],[1,1,0,0,1,1],[1,1,0,0,1,1],
|
||||
[1,1,0,0,1,1],[0,1,1,1,1,0],
|
||||
],
|
||||
[ # R
|
||||
[1,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,1,1],
|
||||
[1,1,1,1,1,0],[1,1,0,1,1,1],[1,1,0,0,1,1],
|
||||
[1,1,0,0,1,1],[1,1,0,0,1,1],
|
||||
],
|
||||
[ # E
|
||||
[1,1,1,1,1,1],[1,1,0,0,0,0],[1,1,0,0,0,0],
|
||||
[1,1,1,1,1,1],[1,1,0,0,0,0],[1,1,0,0,0,0],
|
||||
[1,1,0,0,0,0],[1,1,1,1,1,1],
|
||||
],
|
||||
]
|
||||
|
||||
PALETTE = [
|
||||
(0,0,0),(0,255,255),(0,0,255),(255,128,0),
|
||||
(255,242,0),(0,255,0),(159,0,255),(255,0,0),
|
||||
]
|
||||
PALETTE_ALT = [
|
||||
(0,0,0),(0,134,243),(61,79,220),(253,171,1),
|
||||
(171,203,4),(2,189,205),(210,15,99),(254,75,15),
|
||||
]
|
||||
|
||||
def bevel_color(r, g, b, x, y, style):
|
||||
if style == 0:
|
||||
if 8 <= x < 24 and 8 <= y < 24:
|
||||
return (r, g, b)
|
||||
if 6 <= x < 26 and 6 <= y < 26:
|
||||
return (r & 0xB0, g & 0xB0, b & 0xB0)
|
||||
if x + y < 31:
|
||||
return (r, g, b) if x > y else (r & 0xEF, g & 0xEF, b & 0xEF)
|
||||
return (r & 0xD7, g & 0xD7, b & 0xD7) if x > y else (r & 0xC0, g & 0xC0, b & 0xC0)
|
||||
if x == 31 or y == 31:
|
||||
return (r >> 1, g >> 1, b >> 1) if (x == 0 or y == 0) else (r >> 2, g >> 2, b >> 2)
|
||||
if x == 0 or y == 0:
|
||||
return (r, g, b)
|
||||
return (r & 0xC0, g & 0xC0, b & 0xC0)
|
||||
|
||||
def build_blocks(palette, style):
|
||||
tex = []
|
||||
for clr in palette:
|
||||
surf = pygame.Surface((CELL, CELL))
|
||||
for y in range(CELL):
|
||||
for x in range(CELL):
|
||||
surf.set_at((x, y), bevel_color(*clr, x, y, style))
|
||||
tex.append(surf)
|
||||
return tex
|
||||
|
||||
def build_background():
|
||||
surf = pygame.Surface((WIDTH, HEIGHT))
|
||||
for y in range(HEIGHT):
|
||||
for x in range(WIDTH):
|
||||
if (x + y) & 1:
|
||||
surf.set_at((x, y), (0, 0, 255))
|
||||
else:
|
||||
v = (x + y) >> 3
|
||||
surf.set_at((x, y), (v, 250 - v, 0))
|
||||
return surf
|
||||
|
||||
def build_score():
|
||||
surf = pygame.Surface((136, 32))
|
||||
surf.fill((0, 0, 0))
|
||||
x_off = 0
|
||||
for glyph in SCORE_FONT:
|
||||
for fy, row in enumerate(glyph):
|
||||
for fx, px in enumerate(row):
|
||||
if px:
|
||||
pygame.draw.rect(surf, (255, 255, 255), (x_off + fx * 4, fy * 4, 4, 4))
|
||||
x_off += 28
|
||||
return surf
|
||||
|
||||
class Display:
|
||||
def __init__(self):
|
||||
pygame.init()
|
||||
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Tetris")
|
||||
self.bg = build_background()
|
||||
self.score = build_score()
|
||||
self.b1_tex = build_blocks(PALETTE, 0)
|
||||
self.b2_tex = build_blocks(PALETTE_ALT, 0)
|
||||
self.n1_tex = build_blocks(PALETTE, 1)
|
||||
self.n2_tex = build_blocks(PALETTE_ALT, 1)
|
||||
self.board1 = [[0] * BOARD_W for _ in range(BOARD_H)]
|
||||
self.board2 = [[0] * BOARD_W for _ in range(BOARD_H)]
|
||||
self.next1 = [[0] * NEXT_W for _ in range(NEXT_H)]
|
||||
self.next2 = [[0] * NEXT_W for _ in range(NEXT_H)]
|
||||
|
||||
def draw_grid(self, board, rect, textures):
|
||||
x, y, w, h = rect
|
||||
for row in range(h // CELL):
|
||||
for col in range(w // CELL):
|
||||
v = board[row][col]
|
||||
self.screen.blit(textures[v if 0 <= v <= 7 else 0], (x + col * CELL, y + row * CELL))
|
||||
|
||||
def render(self):
|
||||
self.screen.blit(self.bg, (0, 0))
|
||||
self.draw_grid(self.board1, B1, self.b1_tex)
|
||||
self.draw_grid(self.board2, B2, self.b2_tex)
|
||||
self.draw_grid(self.next1, N1, self.n1_tex)
|
||||
self.draw_grid(self.next2, N2, self.n2_tex)
|
||||
self.screen.blit(self.score, (S1[0], S1[1]))
|
||||
self.screen.blit(self.score, (S2[0], S2[1]))
|
||||
pygame.display.flip()
|
||||
|
||||
def close(self):
|
||||
pygame.quit()
|
||||
|
||||
def main():
|
||||
disp = Display()
|
||||
buf = ""
|
||||
clock = pygame.time.Clock()
|
||||
running = True
|
||||
|
||||
while running:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
|
||||
if not sys.stdin.isatty():
|
||||
r, _, _ = select.select([sys.stdin], [], [], 0)
|
||||
if r:
|
||||
chunk = os.read(sys.stdin.fileno(), 65536)
|
||||
if not chunk:
|
||||
running = False
|
||||
else:
|
||||
buf += chunk.decode("utf-8")
|
||||
while "\n" in buf:
|
||||
line, buf = buf.split("\n", 1)
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
data = json.loads(line)
|
||||
if "b1" in data:
|
||||
disp.board1 = data["b1"]
|
||||
if "b2" in data:
|
||||
disp.board2 = data["b2"]
|
||||
if "n1" in data:
|
||||
disp.next1 = data["n1"]
|
||||
if "n2" in data:
|
||||
disp.next2 = data["n2"]
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
disp.render()
|
||||
clock.tick(60)
|
||||
|
||||
disp.close()
|
||||
sys.exit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user