Skip to content

Instantly share code, notes, and snippets.

@horstjens
Last active June 27, 2022 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save horstjens/225f33fc6cace75c097ff9cd0d2f373a to your computer and use it in GitHub Desktop.
Save horstjens/225f33fc6cace75c097ff9cd0d2f373a to your computer and use it in GitHub Desktop.
catch_me
import PySimpleGUI as sg
import random
import time
RESOLUTIONS = ["100x100", "200x200", "320x200", "400x400", "600x600", "640x400","800x600","1024x800", "1024x960","1280x1024"]
WIDTH, HEIGHT = 400,400
MIN_TILES = 10
MAX_TILES = 50
TX = 40
TY = 40
HELPTEXT = """You are a green square.
Catch the red cat(s).
Use the cursor keys.
"""
# -------- first gui: theme cooser --------------------------
sg.theme(random.choice(sg.theme_list()))
# ---------------------- theme selector layout -------------
layout1 = [
[
sg.Text("Select theme:"),
sg.Combo(
values=sg.theme_list(),
default_value=sg.theme(),
enable_events=True,
key="selector",
),
],
[sg.Text("# x-tiles:"),sg.Slider(range=(MIN_TILES,MAX_TILES), default_value=10,orientation="h", key="x_slider", enable_events=True,)],
[sg.Text("# y-tiles:"),sg.Slider(range=(MIN_TILES,MAX_TILES), default_value=10,orientation="h", key="y_slider", enable_events=True)],
[sg.Text("10 x 10 = 100 tiles", key="tiles")],
[sg.Text("canvas resolution in Pixel:"),
sg.Combo(values=RESOLUTIONS, key="resolution", default_value="400x400", enable_events=True)],
#[sg.Text("Pause in [ms]:"),sg.Slider(range=(0,1000), default_value=500,orientation="h", key="pause_slider")],
[sg.Text("tile size in pixel:"), sg.Text("40 x 40",key="tile_size")],
[sg.Button("play the game")],
]
window1 = sg.Window("theme selector", layout1)
# ---------------- main loop for first layout ---------------
while True:
event1, values1 = window1.read()
if event1 == "play the game" or event1 == sg.WIN_CLOSED:
# sg.theme("DarkBlue3")
break
if event1 == "selector":
old = sg.theme()
sg.theme(values1["selector"])
if sg.PopupYesNo("do you like this Theme?") == "Yes":
break
else:
sg.theme(old)
if event1 in ("x_slider", "y_slider"):
window1["tiles"].update(f'{int(values1["x_slider"])} x {int(values1["y_slider"])} = {int(values1["x_slider"])*int(values1["y_slider"])} tiles')
if event1 in ("x_slider", "y_slider", "resolution"):
WIDTH, HEIGHT = [int(v) for v in values1["resolution"].split("x")]
TX = WIDTH / int(values1["x_slider"])
TY = HEIGHT / int(values1["y_slider"])
tile_size_string = ""
if TX == int(TX):
tile_size_string += f"{TX:.0f} x "
else:
tile_size_string += f"{TX:.1f} x "
if TY == int(TY):
tile_size_string += f"{TY:.0f}"
else:
tile_size_string += f"{TY:.1f}"
window1["tile_size"].update(tile_size_string)
WIDTH, HEIGHT = [int(v) for v in values1["resolution"].split("x")]
X_TILES = int(values1["x_slider"])
Y_TILES = int(values1["y_slider"])
window1.close()
# -----------------end of theme chooser -------------------
# --------------- start of labyrinth game ------------------
class Game:
number = 0
figures = []
lines = []
def is_free(x,y):
"""check if there is a 0 in Game.lines[y][x]"""
print("is free ",x,y)
if x < 0 or y < 0:
return False
try:
result = Game.lines[y][x]
except IndexError:
return False
if Game.lines[y][x] == 0:
return True
else:
return False
def create_blocks(min_number=0, max_number=7, ):
"""create random numbers in array Game.lines[]"""
for y, line in enumerate(Game.lines):
for x, number in enumerate(line):
new_value=random.choice((0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7))
Game.lines[y][x]= new_value
def delete_old_figures():
"""delete all figures from canvas (except player and cursor)"""
for f in Game.figures:
c.delete_figure(f)
Game.figures = []
def delete_old_blocks():
"""delete all old blocks"""
Game.lines = [[0 for x in range(X_TILES)] for y in range(Y_TILES)]
#for f in Game.figures:
# c.delete_figure(f)
#Game.figures = []
def paint_blocks():
"""create colorful blocks, depending on the value in lines
adds the Tkinter figure into the list figures"""
#print(lines)
colordict = {
0: "#000000", # black,
1: "#FF0000", # red
2: "#00FF00", # green
3: "#0000FF", # blue
4: "#FFFF00", # yellow
5: "#FF00FF", # violet
6: "#00FFFF", # cyan
7: "#FFFFFF", # white
}
for y, line in enumerate(Game.lines):
for x, number in enumerate(line):
color = colordict[number]
# do not paint black, just leave it
if color == 0:
continue
Game.figures.append(c.draw_rectangle(top_left=(x,y),
bottom_right=(x+1,y+1),
fill_color = color))
layout2 = [
#[sg.Text("Playce your ships:", font=["System",32]),
# sg.Text("Battleship", key="head1", font=["System",32]),
[sg.Text("Time left:"),sg.Text("10", key="time_left", font=("Arial", 20, "bold")),],
[sg.Graph((WIDTH,30), graph_bottom_left=(0,30), graph_top_right=(WIDTH,0),
key="bar", background_color=sg.theme_background_color())],
[ #sg.Text("Cursor:"),
#sg.Text("mouse xy",key="mousepos"),
sg.Text("Player:"),
sg.Text("player xy", key="playerpos"),
],
[ sg.Button("Help"), sg.Button("Exit"), ],
[sg.Graph(canvas_size=(WIDTH,HEIGHT),
key="canvas", graph_bottom_left=(0, Y_TILES),
graph_top_right=(X_TILES,0 ),
background_color="#333333",
enable_events=True, drag_submits=True, motion_events=True)],
]
window2 = sg.Window("enjoy the game", layout2, return_keyboard_events=True)
window2.finalize() # necessary to be able to draw on canvas
c = window2["canvas"]
# ----- create labyrinth -----
# fill labyrinth with zeros
Game.lines = [[0 for x in range(X_TILES)] for y in range(Y_TILES)]
Game.figures = [] # for Tkinter
#delete_old_blocks()
create_blocks()
paint_blocks()
# ------------- main loop -----------
duration = 60
player_pos_x = 0
player_pos_y = 0
cat_pos_x = X_TILES // 2
cat_pos_y = Y_TILES // 2
#figures.append(make_trail())
player = c.draw_rectangle(top_left=(0,0), bottom_right=(1,1), fill_color="#55FF55")
cat = c.draw_rectangle(top_left=(cat_pos_x,cat_pos_y),
bottom_right=(cat_pos_x+1,cat_pos_y+1), line_width=5, fill_color="#FF0000")
#goal = c.draw_rectangle(top_left=(X_TILES-1,Y_TILES-1), bottom_right=(X_TILES, Y_TILES), fill_color="yellow")
end_time = time.time() + duration
barfig = window2["bar"].draw_rectangle(top_left=(0,30),
bottom_right=(WIDTH,0),
fill_color="#77FF77")
while True:
event2, values2 = window2.read(timeout=100)
#print(event2, values2)
moved = False
if event2 in ("Exit", sg.WINDOW_CLOSED ):
break
if event2 == "Help":
reading_start = time.time()
sg.PopupScrolled(HELPTEXT)
reading_end = time.time()
end_time += (reading_end - reading_start )
if event2 == sg.TIMEOUT_EVENT:
# ----- time bar -----
time_left = end_time - time.time()
if time_left < 0:
# ---- play again? ---
answer = sg.PopupYesNo("You run out of time.\nPlay again?")
# answer can be "Yes", "No" or None
if answer != "Yes":
break
# --- play again --
end_time = time.time() + duration
player_pos_x = 0
player_pos_y = 0
cat_pos_x = X_TILES // 2
cat_pos_y = Y_TILES // 2
c.relocate_figure(player, player_pos_x, player_pos_y )
c.relocate_figure(cat, cat_pos_x, cat_pos_y)
c.bring_figure_to_front(player)
c.bring_figure_to_front(cat)
delete_old_blocks()
delete_old_figures()
create_blocks()
paint_blocks()
c.bring_figure_to_front(player)
c.bring_figure_to_front(cat)
continue
#---- end of play again ----
#------------------
window2["time_left"].update(f"{time_left:.1f}")
# --- update barfig ----
percent = time_left / duration
window2["bar"].delete_figure(barfig)
barfig = window2["bar"].draw_rectangle(top_left=(0,30),
bottom_right=(WIDTH*percent,0),
fill_color="#77FF77")
# ----- move cat -----
possible_directions = []
for (dx,dy) in [(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1)]:
if is_free(cat_pos_x+dx, cat_pos_y+dy):
# do not run towards player
if (cat_pos_x+dx, cat_pos_y+dy) != (player_pos_x, player_pos_y):
possible_directions.append((dx,dy))
#if len(possible_directions) == 0:
# print("cat catched")
# break
dx, dy = 0, 0
if len(possible_directions) > 0:
dx, dy = random.choice(possible_directions)
cat_pos_x += dx
cat_pos_y += dy
c.move_figure(cat, dx, dy )
# mouse movement event
#if event2.endswith("+MOVE"):
# pass
# mousepos = values2["canvas"]
# window2["mousepos"].update(mousepos)
# cursor_pos_x, cursor_pos_y = mousepos
# c.relocate_figure(cursor, cursor_pos_x, cursor_pos_y)
# c.bring_figure_to_front(cursor)
# mouse click down event
#if event2 == "canvas":
# mousepos = values2["canvas"]
# print("mouseclick down at: ", mousepos)
# mouse click up event
#if event2 == "canvas+UP":
# mousepos = values2["canvas"]
# print("mouseclick up at: ", mousepos)
# --------------- keyboard handler -----------
moved = False
#if event2 == "Up:111":
if event2.startswith("Up:"):
if is_free(x=player_pos_x, y=player_pos_y-1):
player_pos_y -= 1
#figures.append(make_trail())
moved = True
#if event2 == "Left:113":
if event2.startswith("Left:"):
if is_free(x=player_pos_x-1, y=player_pos_y):
player_pos_x -= 1
#figures.append(make_trail())
moved = True
#if event2 == "Down:116":
if event2.startswith("Down:"):
if is_free(x=player_pos_x, y=player_pos_y+1):
player_pos_y += 1
#figures.append(make_trail())
moved = True
#if event2 == "Right:114":
if event2.startswith("Right"):
if is_free(x=player_pos_x+1, y=player_pos_y):
player_pos_x += 1
#figures.append(make_trail())
moved = True
# ------ always ----
if moved:
#print("moving player")
# --------- move player ----
c.relocate_figure(player, player_pos_x, player_pos_y)
c.bring_figure_to_front(player)
window2["playerpos"].update(f"{player_pos_x},{player_pos_y}")
if (player_pos_x == cat_pos_x) and (player_pos_y == cat_pos_y):
# ---- play again? ---
answer = sg.PopupYesNo("you caught the cat.\nPlay again?")
# answer can be "Yes", "No" or None
if answer != "Yes":
break
end_time = time.time() + duration
player_pos_x = 0
player_pos_y = 0
cat_pos_x = X_TILES // 2
cat_pos_y = Y_TILES // 2
c.relocate_figure(player, player_pos_x, player_pos_y )
c.relocate_figure(cat, cat_pos_x, cat_pos_y)
c.bring_figure_to_front(player)
c.bring_figure_to_front(cat)
delete_old_blocks()
delete_old_figures()
create_blocks()
paint_blocks()
c.bring_figure_to_front(player)
c.bring_figure_to_front(cat)
continue
#---- end of play again ----
window2.close()
print("bye")
# todo: use class cat, several cats
import PySimpleGUI as sg
import random
import time
RESOLUTIONS = ["100x100", "200x200", "320x200", "400x400", "600x600", "640x400","800x600","1024x800", "1024x960","1280x1024"]
WIDTH, HEIGHT = 400,400
MIN_TILES = 10
MAX_TILES = 50
TX = 40
TY = 40
HELPTEXT = """You are a green square.
Catch the red cat(s).
Use the cursor keys.
"""
# -------- first gui: theme cooser --------------------------
sg.theme(random.choice(sg.theme_list()))
# ---------------------- theme selector layout -------------
layout1 = [
[
sg.Text("Select theme:"),
sg.Combo(
values=sg.theme_list(),
default_value=sg.theme(),
enable_events=True,
key="selector",
),
],
[sg.Text("# x-tiles:"),sg.Slider(range=(MIN_TILES,MAX_TILES), default_value=10,orientation="h", key="x_slider", enable_events=True,)],
[sg.Text("# y-tiles:"),sg.Slider(range=(MIN_TILES,MAX_TILES), default_value=10,orientation="h", key="y_slider", enable_events=True)],
[sg.Text("10 x 10 = 100 tiles", key="tiles")],
[sg.Text("canvas resolution in Pixel:"),
sg.Combo(values=RESOLUTIONS, key="resolution", default_value="400x400", enable_events=True)],
#[sg.Text("Pause in [ms]:"),sg.Slider(range=(0,1000), default_value=500,orientation="h", key="pause_slider")],
[sg.Text("tile size in pixel:"), sg.Text("40 x 40",key="tile_size")],
[sg.Button("play the game")],
]
window1 = sg.Window("theme selector", layout1)
# ---------------- main loop for first layout ---------------
while True:
event1, values1 = window1.read()
if event1 == "play the game" or event1 == sg.WIN_CLOSED:
# sg.theme("DarkBlue3")
break
if event1 == "selector":
old = sg.theme()
sg.theme(values1["selector"])
if sg.PopupYesNo("do you like this Theme?") == "Yes":
break
else:
sg.theme(old)
if event1 in ("x_slider", "y_slider"):
window1["tiles"].update(f'{int(values1["x_slider"])} x {int(values1["y_slider"])} = {int(values1["x_slider"])*int(values1["y_slider"])} tiles')
if event1 in ("x_slider", "y_slider", "resolution"):
WIDTH, HEIGHT = [int(v) for v in values1["resolution"].split("x")]
TX = WIDTH / int(values1["x_slider"])
TY = HEIGHT / int(values1["y_slider"])
tile_size_string = ""
if TX == int(TX):
tile_size_string += f"{TX:.0f} x "
else:
tile_size_string += f"{TX:.1f} x "
if TY == int(TY):
tile_size_string += f"{TY:.0f}"
else:
tile_size_string += f"{TY:.1f}"
window1["tile_size"].update(tile_size_string)
WIDTH, HEIGHT = [int(v) for v in values1["resolution"].split("x")]
X_TILES = int(values1["x_slider"])
Y_TILES = int(values1["y_slider"])
window1.close()
# -----------------end of theme chooser -------------------
# --------------- start of labyrinth game ------------------
class Game:
number = 0
figures = []
lines = []
cats = []
cat_start_pos = {
0: (0, 0), # north-west
1: (X_TILES-1,0), # north-east
2: (X_TILES-1, Y_TILES-1), # south-east
3: (0, Y_TILES-1), # south-west
}
cat_colors = {
0: "#335577",
1: "#CCDDCC",
2: "#889977",
3: "#99AA88",
}
class Cat:
def __init__(self):
"""cats position themself in the four corners"""
self.number = Game.number
Game.number += 1
Game.cats.append(self)
self.x, self.y = Game.cat_start_pos[self.number]
self.active = True
self.figure = c.draw_circle(
center_location = (self.x + 0.5, self.y + 0.5),
radius = 0.4,
line_width=5, fill_color=Game.cat_colors[self.number])
def is_free(x,y):
"""check if there is a 0 in Game.lines[y][x]"""
print("is free ",x,y)
if x < 0 or y < 0:
return False
try:
result = Game.lines[y][x]
except IndexError:
return False
if Game.lines[y][x] == 0:
return True
else:
return False
def create_blocks(min_number=0, max_number=7, ):
"""create random numbers in array Game.lines[]"""
for y, line in enumerate(Game.lines):
for x, number in enumerate(line):
new_value=random.choice((0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7))
Game.lines[y][x]= new_value
def delete_old_figures():
"""delete all figures from canvas (except player and cursor)"""
for f in Game.figures:
c.delete_figure(f)
Game.figures = []
def delete_old_blocks():
"""delete all old blocks"""
Game.lines = [[0 for x in range(X_TILES)] for y in range(Y_TILES)]
#for f in Game.figures:
# c.delete_figure(f)
#Game.figures = []
def paint_blocks():
"""create colorful blocks, depending on the value in lines
adds the Tkinter figure into the list figures"""
#print(lines)
colordict = {
0: "#000000", # black,
1: "#FF0000", # red
2: "#00FF00", # green
3: "#0000FF", # blue
4: "#FFFF00", # yellow
5: "#FF00FF", # violet
6: "#00FFFF", # cyan
7: "#FFFFFF", # white
}
for y, line in enumerate(Game.lines):
for x, number in enumerate(line):
color = colordict[number]
# do not paint black, just leave it
if color == 0:
continue
Game.figures.append(c.draw_rectangle(top_left=(x,y),
bottom_right=(x+1,y+1),
fill_color = color))
layout2 = [
#[sg.Text("Playce your ships:", font=["System",32]),
# sg.Text("Battleship", key="head1", font=["System",32]),
[sg.Text("Cats active: 4", key="cats"), sg.Text("Time left:"),sg.Text("10", key="time_left", font=("Arial", 20, "bold")),],
[sg.Graph((WIDTH,30), graph_bottom_left=(0,30), graph_top_right=(WIDTH,0),
key="bar", background_color=sg.theme_background_color())],
[ #sg.Text("Cursor:"),
#sg.Text("mouse xy",key="mousepos"),
sg.Text("Player:"),
sg.Text("player xy", key="playerpos"),
],
[ sg.Button("Help"), sg.Button("Exit"), ],
[sg.Graph(canvas_size=(WIDTH,HEIGHT),
key="canvas", graph_bottom_left=(0, Y_TILES),
graph_top_right=(X_TILES,0 ),
background_color="#333333",
enable_events=True, drag_submits=True, motion_events=True)],
]
window2 = sg.Window("enjoy the game", layout2, return_keyboard_events=True)
window2.finalize() # necessary to be able to draw on canvas
c = window2["canvas"]
# ----- create labyrinth -----
# fill labyrinth with zeros
Game.lines = [[0 for x in range(X_TILES)] for y in range(Y_TILES)]
Game.figures = [] # for Tkinter
#delete_old_blocks()
create_blocks()
paint_blocks()
# ------------- main loop -----------
duration = 60
player_pos_x = X_TILES //2
player_pos_y = Y_TILES //2
Game.cats = [Cat(), Cat(), Cat(), Cat()]
#figures.append(make_trail())
player = c.draw_rectangle(top_left=(player_pos_x,player_pos_y), bottom_right=(player_pos_x+0.5,player_pos_y+0.5), fill_color="#55FF55")
#cat = c.draw_rectangle(top_left=(cat_pos_x,cat_pos_y),
# bottom_right=(cat_pos_x+1,cat_pos_y+1), line_width=5, fill_color="#FF0000")
#goal = c.draw_rectangle(top_left=(X_TILES-1,Y_TILES-1), bottom_right=(X_TILES, Y_TILES), fill_color="yellow")
end_time = time.time() + duration
barfig = window2["bar"].draw_rectangle(top_left=(0,30),
bottom_right=(WIDTH,0),
fill_color="#77FF77")
while True:
event2, values2 = window2.read(timeout=100)
#print(event2, values2)
moved = False
if event2 in ("Exit", sg.WINDOW_CLOSED ):
break
if event2 == "Help":
reading_start = time.time()
sg.PopupScrolled(HELPTEXT)
reading_end = time.time()
end_time += (reading_end - reading_start )
if event2 == sg.TIMEOUT_EVENT:
# ----- time bar -----
time_left = end_time - time.time()
if time_left < 0:
# ---- play again? ---
sg.PopupOK("time is up. Game over")
break
#------------------
window2["time_left"].update(f"{time_left:.1f}")
# --- update barfig ----
percent = time_left / duration
window2["bar"].delete_figure(barfig)
barfig = window2["bar"].draw_rectangle(top_left=(0,30),
bottom_right=(WIDTH*percent,0),
fill_color="#77FF77")
# ----- move cats -----
for cat in Game.cats:
possible_directions = []
for (dx,dy) in [(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1)]:
if is_free(cat.x+dx, cat.y+dy):
# do not run towards player
if (cat.x+dx, cat.y+dy) != (player_pos_x, player_pos_y):
possible_directions.append((dx,dy))
dx, dy = 0, 0
if len(possible_directions) > 0:
dx, dy = random.choice(possible_directions)
cat.x += dx
cat.y += dy
c.move_figure(cat.figure, dx, dy )
# mouse movement event
#if event2.endswith("+MOVE"):
# pass
# mousepos = values2["canvas"]
# window2["mousepos"].update(mousepos)
# cursor_pos_x, cursor_pos_y = mousepos
# c.relocate_figure(cursor, cursor_pos_x, cursor_pos_y)
# c.bring_figure_to_front(cursor)
# mouse click down event
#if event2 == "canvas":
# mousepos = values2["canvas"]
# print("mouseclick down at: ", mousepos)
# mouse click up event
#if event2 == "canvas+UP":
# mousepos = values2["canvas"]
# print("mouseclick up at: ", mousepos)
# --------------- keyboard handler -----------
moved = False
#if event2 == "Up:111":
if event2.startswith("Up:"):
if is_free(x=player_pos_x, y=player_pos_y-1):
player_pos_y -= 1
#figures.append(make_trail())
moved = True
#if event2 == "Left:113":
if event2.startswith("Left:"):
if is_free(x=player_pos_x-1, y=player_pos_y):
player_pos_x -= 1
#figures.append(make_trail())
moved = True
#if event2 == "Down:116":
if event2.startswith("Down:"):
if is_free(x=player_pos_x, y=player_pos_y+1):
player_pos_y += 1
#figures.append(make_trail())
moved = True
#if event2 == "Right:114":
if event2.startswith("Right"):
if is_free(x=player_pos_x+1, y=player_pos_y):
player_pos_x += 1
#figures.append(make_trail())
moved = True
# ------ always ----
if moved:
#print("moving player")
# --------- move player ----
c.relocate_figure(player, player_pos_x, player_pos_y)
c.bring_figure_to_front(player)
window2["playerpos"].update(f"{player_pos_x},{player_pos_y}")
# catch ONE CAT
for cat in Game.cats:
if (player_pos_x == cat.x) and (player_pos_y == cat.y):
print("catchted cat #", cat.number)
# --- remove cat ---
c.delete_figure(cat.figure)
cat.active = False
Game.cats = [cat for cat in Game.cats if cat.active == True]
window2["cats"].update(f"Cats active: {len(Game.cats)}")
if len(Game.cats) == 0:
# ---- play again? ---
answer = sg.PopupYesNo("you caught the cat.\nPlay again?")
# answer can be "Yes", "No" or None
if answer != "Yes":
break
end_time = time.time() + duration
delete_old_blocks()
delete_old_figures()
create_blocks()
paint_blocks()
player_pos_x = 0
player_pos_y = 0
Game.number = 0
Game.cats = [Cat(), Cat(), Cat(), Cat()]
player_pos_x = X_TILES // 2
player_pos_y = Y_TILES // 2
c.relocate_figure(player, player_pos_x, player_pos_y )
continue
#---- end of play again ----
window2.close()
print("bye")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment