Skip to content

Instantly share code, notes, and snippets.

@horstjens
Last active Jun 21, 2022
Embed
What would you like to do?
pysimplegui paint
import PySimpleGUI as sg
import random
import time
#from matplotlib.colors import hex2color
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
CHANCE_FOR_NONE = 0.25
HELPTEXT = """Write here instructions for your game.
You can use several lines.
"""
#COLORS = []
#for r in range(16,200,8):
# for g in range(16,200,8):
# for b in range(16,200,8):
# COLORS.append("#{}{}{}".format(str(hex(r).replace("0x","")),
# str(hex(g).replace("0x","")),
# str(hex(b).replace("0x","")),
# ))
#print(COLORS)
#random.shuffle(COLORS)
# -------- 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 main program ------------------
class Game:
number = 0
figures = []
lines = []
bgcolor = "#646464"
fgcolor = "#FF00FF"
def is_free(x,y):
"""check if there is a None in Game.lines[y][x]"""
if x < 0 or y < 0:
return False
try:
result = Game.lines[y][x]
except IndexError:
return False
if Game.lines[y][x] is None:
return True
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):
if random.random() < CHANCE_FOR_NONE:
new_value = None
continue
else:
red = random.randint(0,255)
green = random.randint(0,255)
blue = random.randint(0,255)
new_value = f"#{red:02X}{green:02X}{blue:02X}"
#print(x,y,"old value:", lines[y][x], "new value:", new_value)
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, fill Game.lines with [None, None,...] """
Game.lines = [[None 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)
for y, line in enumerate(Game.lines):
for x, number in enumerate(line):
if number is None:
#color = Game.bgcolor
continue
# do not paint black, just leave it
color = Game.lines[y][x]
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("Cursor:"),
sg.Text("mouse xy",key="mousepos"),
sg.Text("Color:"),
sg.Text("#??????", key="mousecolor"),
],
[#sg.Text("show:"),
#sg.Radio("instructions", group_id="showgroup", default=True, enable_events=True, key="instructions"),
#sg.Radio("lines", group_id="showgroup", default=False,enable_events=True, key="lines"),
#sg.Radio("figures", group_id="showgroup", default=False, enable_events=True, key="figures"),
sg.Radio("paint", group_id="modus", default=True, key="paint"),
sg.Button("fg color:", key="button_fg", button_color="#FF00FF"),
sg.Text("#FF00FF", key="fg_color", size=(8,1)),
sg.Radio("erase", group_id="modus", default=False,key="erase"),
sg.Button("bg color:", key="button_bg", button_color="#646464"),
sg.Input("#646464", key="bg_color", size=(8,1), ),
],
# sg.Checkbox("show grid", default=False, change_submits=True, key="show_grid")],
[sg.Multiline(default_text=HELPTEXT, size=(90,6), disabled=True, key="multi"),],
[sg.Button("new blocks"),sg.Button("delete all"), 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 = [[None 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
cursor_pos_x = 0
cursor_pos_y = 0
#figures.append(make_trail())
#player = c.draw_rectangle(top_left=(0,0), bottom_right=(1,1), fill_color="#CCCCCC")
cursor = c.draw_rectangle(top_left=(0,0), bottom_right=(1,1), line_width=5, line_color="#D1D1D1", fill_color=None)
#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
while True:
event2, values2 = window2.read()
#print(event2, values2)
# print all values except the multiline field
#print("Event:",event2, "Values:", {k:v for k,v in values2.items() if k != "multi"})
#moved = False
if event2 in ("Exit", sg.WINDOW_CLOSED ):
break
#if event2 == sg.TIMEOUT_EVENT:
# pass
#----- color choosen ----
if event2 == "button_fg":
# askcolor gives back a tuple like: ((140, 0, 255), '#8c00ff')
new_color = sg.askcolor(Game.fgcolor)[1]
if new_color is None:
continue
new_color = new_color.upper()
#print("new color=", new_color)
window2["button_fg"].update(button_color=new_color)
window2["fg_color"].update(new_color)
Game.fgcolor = new_color
if event2 == "button_bg":
new_color = sg.askcolor(Game.fgcolor)[1]
if new_color is None:
continue
new_color = new_color.upper()
#print("new color=", new_color)
window2["button_bg"].update(button_color=new_color)
window2["bg_color"].update(new_color)
Game.bgcolor = new_color
window2["canvas"].update(background_color=new_color)
if event2 == "new blocks":
#delete_old_blocks()
delete_old_blocks()
delete_old_figures()
create_blocks()
paint_blocks()
#c.bring_figure_to_front(player)
if event2 == "delete all":
delete_old_blocks()
delete_old_figures()
#if event2 == "delete figures":
# mouse movement event
if event2.endswith("+MOVE"):
mousepos = values2["canvas"]
window2["mousepos"].update(mousepos)
#print("mousepos:", mousepos)
cursor_pos_x, cursor_pos_y = mousepos
window2["mousecolor"].update(str(Game.lines[cursor_pos_y][cursor_pos_x]))
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"]
window2["mousepos"].update(mousepos)
#print("mousepos:", mousepos)
cursor_pos_x, cursor_pos_y = mousepos
if not ( 0 <= cursor_pos_x < X_TILES):
continue
if not ( 0 <= cursor_pos_y < Y_TILES):
continue
print("cursor:", cursor_pos_x, cursor_pos_y, X_TILES, Y_TILES)
window2["mousecolor"].update(str(Game.lines[cursor_pos_y][cursor_pos_x]))
c.relocate_figure(cursor, cursor_pos_x, cursor_pos_y)
c.bring_figure_to_front(cursor)
print("mouseclick down at: ", mousepos)
actual_color = Game.lines[cursor_pos_y][cursor_pos_x]
#print("paint, erase", values2["paint"], values2["erase"])
if values2["paint"]:
if actual_color != Game.fgcolor:
Game.lines[cursor_pos_y][cursor_pos_x] = Game.fgcolor
#delete_old_blocks()
delete_old_figures()
paint_blocks()
if values2["erase"]:
if actual_color is not None:
Game.lines[cursor_pos_y][cursor_pos_x] = None
delete_old_figures()
paint_blocks()
# mouse click up event
if event2 == "canvas+UP":
mousepos = values2["canvas"]
print("mouseclick up at: ", mousepos)
##if event2.endswith('+RIGHT+'): # Righ click
## print("mouseclick right at ", values2["canvas"])
window2.close()
print("bye")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment