main.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. import tkinter as tk
  2. from random import shuffle, randint, choice
  3. from PIL import Image, ImageTk
  4. # Window
  5. root = tk.Tk()
  6. root.title("Elite Four")
  7. root.resizable(False, False)
  8. root.geometry("1280x720")
  9. # Canvas
  10. cv = tk.Canvas(root, width=1280, height=720)
  11. cv.place(x=0, y=0)
  12. # Game variables
  13. game_number = 4
  14. games_list = ["E"] # To finish
  15. # Creation of the start menu
  16. start_button: tk.Button
  17. def menu():
  18. global start_button
  19. cv.delete("all")
  20. bg_rect = cv.create_rectangle(0, 0, 1280, 720, fill="#7993a3", outline="#7993a3")
  21. title = cv.create_text(640, 360, text="Elite Four", font=("Helvetica", 48, "bold"), fill="aliceblue")
  22. start_button = tk.Button(bg="#7993a3", fg="aliceblue", activebackground="aliceblue", activeforeground="#7993a3", text="START", font=("Helvetica", 24, "bold"), cursor="hand2", borderwidth=0, highlightthickness=0, command=start)
  23. start_button.place(x=576, y=600)
  24. def start():
  25. # To finish
  26. global game_number, games_list
  27. shuffle(games_list)
  28. game_number = 0
  29. start_button.destroy()
  30. next_game()
  31. def next_game():
  32. cv.delete("all")
  33. if game_number < len(games_list):
  34. if games_list[game_number] == "N":
  35. miss_n_init()
  36. elif games_list[game_number] == "C":
  37. mister_c_init()
  38. elif games_list[game_number] == "E":
  39. mister_e_init()
  40. else:
  41. print("THE END") # TODO the end
  42. def reset():
  43. # To finish
  44. global game_number, miss_n_state, flour_qtt, flour_qtt_inc, sugar_qtt, sugar_qtt_inc, eggs_qtt, eggs_qtt_inc, milk_qtt, milk_qtt_inc, ingredients_height, mister_c_state,\
  45. mister_c_dialog, mister_c_result, skyline_image, ptimage, mister_c_input, mister_c_score, mister_e_state, mister_e_time, mister_e_time_count, mister_e_timer, mask_images,\
  46. masks_list, happy_mask, mister_e_dialog
  47. game_number = 4
  48. # Miss N
  49. miss_n_state = 0
  50. flour_qtt = 0
  51. flour_qtt_inc = True
  52. sugar_qtt = 0
  53. sugar_qtt_inc = True
  54. eggs_qtt = 0
  55. eggs_qtt_inc = True
  56. milk_qtt = 0
  57. milk_qtt_inc = True
  58. ingredients_height = 359
  59. # Mister C
  60. mister_c_state = 0
  61. mister_c_dialog = 0
  62. skyline_image = 0
  63. ptimage = None
  64. mister_c_input = tk.Entry(root)
  65. mister_c_input.bind("<Return>", enter)
  66. mister_c_score = 0
  67. # Mister E
  68. mister_e_state = 0
  69. mister_e_time = 0
  70. mister_e_time_count = 0
  71. mister_e_timer = 0
  72. mask_images = []
  73. masks_list = []
  74. happy_mask = {}
  75. mister_e_dialog = 0
  76. menu()
  77. # General GUI functions
  78. def draw_dialog_area():
  79. dialog_rect = cv.create_rectangle(8, 500, 1272, 712, fill="#ffffff", outline="#ffffff")
  80. dialog_name_rect = cv.create_rectangle(580, 484, 700, 500, fill="#ffffff", outline="#ffffff")
  81. # Miss N game
  82. miss_n_state = 0
  83. flour_qtt = 0
  84. flour_qtt_inc = True
  85. sugar_qtt = 0
  86. sugar_qtt_inc = True
  87. eggs_qtt = 0
  88. eggs_qtt_inc = True
  89. milk_qtt = 0
  90. milk_qtt_inc = True
  91. miss_n_dialog: int
  92. flour_qtt_text: int
  93. sugar_qtt_text: int
  94. eggs_qtt_text: int
  95. milk_qtt_text: int
  96. ingredients_height = 359
  97. def miss_n_init():
  98. bg_rect = cv.create_rectangle(0, 0, 1280, 720, fill="#6abd9c", outline="#6abd9c")
  99. draw_dialog_area()
  100. dialog_name = cv.create_text(640, 500, text="Miss N", font=("Helvetica", 16, "bold"), fill="#163226")
  101. container_rect = cv.create_rectangle(1140, 80, 1240, 360, fill="#c9c9c9", outline="#c9c9c9")
  102. flour_rect = cv.create_rectangle(40, 100, 180, 280, fill="#fff4de", outline="#fff4de")
  103. flour_text = cv.create_text(110, 88, text="FLOUR", font=("Helvetica", 16), fill="#163226")
  104. sugar_rect = cv.create_rectangle(220, 160, 360, 280, fill="#ffb34f", outline="#ffb34f")
  105. sugar_top = cv.create_polygon(220, 160, 360, 160, 290, 100, fill="#ffb34f", outline="#ffb34f")
  106. sugar_text = cv.create_text(290, 88, text="SUGAR", font=("Helvetica", 16), fill="#163226")
  107. eggs_oval = cv.create_oval(400, 100, 540, 280, fill="#e6c493", outline="#e6c493")
  108. eggs_text = cv.create_text(470, 88, text="EGGS", font=("Helvetica", 16), fill="#163226")
  109. milk_rect = cv.create_rectangle(580, 160, 720, 280, fill="#ffffff", outline="#ffffff")
  110. milk_top = cv.create_rectangle(580, 100, 720, 160, fill="#0000cc", outline="#0000cc")
  111. milk_text = cv.create_text(650, 88, text="MILK", font=("Helvetica", 16), fill="#163226")
  112. miss_n_game()
  113. def miss_n_game():
  114. global miss_n_dialog, flour_qtt, flour_qtt_inc, flour_qtt_text, sugar_qtt, sugar_qtt_inc, sugar_qtt_text, eggs_qtt, eggs_qtt_inc, eggs_qtt_text, milk_qtt, milk_qtt_inc, milk_qtt_text
  115. if miss_n_state == 0:
  116. miss_n_dialog = cv.create_text(640, 606, text="Hiiiiii! I'm Miss N and in my game, you'll have to make a crêpe!\n\
  117. The rules are easy, just press SPACE when you think that a quantity is good.\n\
  118. If you follow the recipe, you win. If you don't, you lose.\n\
  119. Here is the recipe:\n\
  120. - 170g of flour\n\
  121. - 40g of sugar\n\
  122. - 3 eggs\n\
  123. - 600mL of milk\n\n\
  124. Press SPACE to start, good luck <3", font=("Helvetica", 12), fill="#163226")
  125. flour_qtt_text = cv.create_text(110, 308, text="", font=("Helvetica", 16), fill="#163226")
  126. sugar_qtt_text = cv.create_text(290, 308, text="", font=("Helvetica", 16), fill="#163226")
  127. eggs_qtt_text = cv.create_text(470, 308, text="", font=("Helvetica", 16), fill="#163226")
  128. milk_qtt_text = cv.create_text(650, 308, text="", font=("Helvetica", 16), fill="#163226")
  129. elif miss_n_state == 1:
  130. if flour_qtt_inc:
  131. flour_qtt += 1
  132. if flour_qtt == 400:
  133. flour_qtt_inc = False
  134. else:
  135. flour_qtt -= 1
  136. if flour_qtt == 0:
  137. flour_qtt_inc = True
  138. cv.itemconfig(flour_qtt_text, text=str(flour_qtt))
  139. root.after(8, miss_n_game)
  140. elif miss_n_state == 2:
  141. if sugar_qtt_inc:
  142. sugar_qtt += 1
  143. if sugar_qtt == 100:
  144. sugar_qtt_inc = False
  145. else:
  146. sugar_qtt -= 1
  147. if sugar_qtt == 0:
  148. sugar_qtt_inc = True
  149. cv.itemconfig(sugar_qtt_text, text=str(sugar_qtt))
  150. root.after(10, miss_n_game)
  151. elif miss_n_state == 3:
  152. if eggs_qtt_inc:
  153. eggs_qtt += 1
  154. if eggs_qtt == 5:
  155. eggs_qtt_inc = False
  156. else:
  157. eggs_qtt -= 1
  158. if eggs_qtt == 0:
  159. eggs_qtt_inc = True
  160. cv.itemconfig(eggs_qtt_text, text=str(eggs_qtt))
  161. root.after(140, miss_n_game)
  162. elif miss_n_state == 4:
  163. if milk_qtt_inc:
  164. milk_qtt += 1
  165. if milk_qtt == 1000:
  166. milk_qtt_inc = False
  167. else:
  168. milk_qtt -= 1
  169. if milk_qtt == 0:
  170. milk_qtt_inc = True
  171. cv.itemconfig(milk_qtt_text, text=str(milk_qtt))
  172. root.after(4, miss_n_game)
  173. def miss_n_end():
  174. global miss_n_state
  175. score = abs(flour_qtt - 170) * 3 + abs(sugar_qtt - 40) * 15 + abs(eggs_qtt - 3) * 200 + abs(milk_qtt - 600)
  176. if score < 300:
  177. cv.itemconfig(miss_n_dialog, text="Those crepes look delicious, great job!\nPress SPACE to continue <3")
  178. miss_n_state = 6
  179. else:
  180. cv.itemconfig(miss_n_dialog, text="It seems absolutely uneatable, I hope you'll do better next time.")
  181. root.after(5000, reset)
  182. # Mister C game
  183. mister_c_state = 0
  184. images_list = ["images/bucharest.png", "images/dallas.png", "images/dublin.png", "images/kualalumpur.png", "images/lagos.png", "images/lyon.png", "images/warsaw.png"]
  185. mister_c_answers = {"images/bucharest.png": ["bucharest", "Bucharest", "BUCHAREST"], "images/dallas.png": ["dallas", "Dallas", "DALLAS"], "images/dublin.png": ["dublin", "Dublin", "DUBLIN"], "images/kualalumpur.png": ["kuala lumpur", "Kuala lumpur", "Kuala Lumpur", "KUALA LUMPUR"], "images/lagos.png": ["lagos", "Lagos", "LAGOS"], "images/lyon.png": ["lyon", "Lyon", "LYON"], "images/warsaw.png": ["warsaw", "Warsaw", "WARSAW"]}
  186. mister_c_dialog: int
  187. mister_c_result: int
  188. skyline_image: int
  189. ptimage = None
  190. mister_c_input = tk.Entry(root)
  191. mister_c_score = 0
  192. def mister_c_init():
  193. shuffle(images_list)
  194. bg_rect = cv.create_rectangle(0, 0, 1280, 720, fill="#7cf27c", outline="#7cf27c")
  195. draw_dialog_area()
  196. dialog_name = cv.create_text(640, 500, text="Mister C", font=("Helvetica", 16, "bold"), fill="#0b6b0b")
  197. mister_c_game()
  198. def mister_c_game():
  199. global mister_c_dialog, skyline_image, ptimage
  200. if mister_c_state == 0:
  201. mister_c_dialog = cv.create_text(640, 606, text="Halloooo, my name is Mister C !\n\
  202. In my game, you'll have to recognize a city from his skyline, and the colors on the flag of its country.\n\
  203. You will see 3 images, and you'll have to make 2 correct guesses if you want to continue.\n\
  204. You only have one chance per image, good luck !\n\
  205. Press SPACE to start", font=("Helvetica", 12), fill="#0b6b0b")
  206. if mister_c_state == 1:
  207. cv.itemconfig(mister_c_dialog, text="Which city do you think it is ?")
  208. ptimage = ImageTk.PhotoImage(file=images_list[0])
  209. skyline_image = cv.create_image(640, 242, image=ptimage, anchor=tk.CENTER)
  210. mister_c_input.place(x=640, y=632, anchor=tk.CENTER)
  211. elif mister_c_state == 2:
  212. cv.itemconfig(mister_c_dialog, text="Which city do you think it is ?")
  213. ptimage = ImageTk.PhotoImage(file=images_list[1])
  214. cv.itemconfigure(skyline_image, image=ptimage)
  215. elif mister_c_state == 3:
  216. cv.itemconfig(mister_c_dialog, text="Which city do you think it is ?")
  217. ptimage = ImageTk.PhotoImage(file=images_list[2])
  218. cv.itemconfigure(skyline_image, image=ptimage)
  219. elif mister_c_state == 4:
  220. cv.itemconfig(mister_c_dialog, text="Well played!\nPress SPACE to continue.")
  221. elif mister_c_state == 5:
  222. cv.itemconfig(mister_c_dialog, text="You have to work a little more, see you later !")
  223. root.after(5000, reset)
  224. def mister_c_verif():
  225. global mister_c_score, mister_c_result
  226. if mister_c_input.get() in mister_c_answers[images_list[mister_c_state - 1]]:
  227. mister_c_score += 1
  228. if mister_c_state == 1:
  229. mister_c_result = cv.create_text(640, 680, text="Correct!", font=("Helvetica", 12), fill="#0b6b0b")
  230. else:
  231. cv.itemconfig(mister_c_result, text="Correct!")
  232. return True
  233. else:
  234. if mister_c_state == 1:
  235. mister_c_result = cv.create_text(640, 680, text="Wrong!", font=("Helvetica", 12), fill="#0b6b0b")
  236. else:
  237. cv.itemconfig(mister_c_result, text="Wrong!")
  238. return False
  239. # Mister E game
  240. mister_e_state = 0
  241. mister_e_time = 0
  242. mister_e_time_count = 0
  243. mister_e_timer: int
  244. mask_images = []
  245. masks_list = []
  246. happy_mask = {}
  247. mister_e_dialog: int
  248. def mister_e_init():
  249. bg_rect = cv.create_rectangle(0, 0, 1280, 720, fill="#fda3ff", outline="#fda3ff")
  250. draw_dialog_area()
  251. dialog_name = cv.create_text(640, 500, text="Mister E", font=("Helvetica", 16, "bold"), fill="#730075")
  252. mister_e_game()
  253. def mister_e_game():
  254. global mister_e_dialog, mister_e_state, mister_e_time, mister_e_time_count, mister_e_timer
  255. if mister_e_state == 0:
  256. mister_e_dialog = cv.create_text(640, 606, text="Hello! I'm Mister E, nice to meet you!\n\
  257. In my game, you'll see some comedy masks, and you'll just have to find the happy one.\n\
  258. Good luck!\n\
  259. Press SPACE to start.", font=("Helvetica", 12), fill="#730075")
  260. elif mister_e_state == 1:
  261. spawn_masks()
  262. mister_e_state = 2
  263. mister_e_time = 15
  264. mister_e_timer = cv.create_text(1260, 700, text="15", font=("Helvetica", 16, "bold"), fill="#730075")
  265. mister_e_game()
  266. elif mister_e_state == 2:
  267. move_masks()
  268. mister_e_countdown()
  269. root.after(100, mister_e_game)
  270. elif mister_e_state == 3:
  271. mister_e_clear()
  272. cv.itemconfig(mister_e_dialog, text="Well done! But it was the easy level,\nPress SPACE to continue.")
  273. elif mister_e_state == 4:
  274. spawn_masks()
  275. mister_e_time = 20
  276. cv.itemconfig(mister_e_timer, text="20")
  277. mister_e_time_count = 0
  278. mister_e_state = 5
  279. mister_e_game()
  280. elif mister_e_state == 5:
  281. move_masks()
  282. mister_e_countdown()
  283. root.after(100, mister_e_game)
  284. elif mister_e_state == 6:
  285. mister_e_clear()
  286. cv.itemconfig(mister_e_dialog, text="Good job! You're ready to the next step,\nPress SPACE to continue.")
  287. elif mister_e_state == 7:
  288. spawn_masks()
  289. mister_e_time = 25
  290. cv.itemconfig(mister_e_timer, text="25")
  291. mister_e_time_count = 0
  292. mister_e_state = 8
  293. mister_e_game()
  294. elif mister_e_state == 8:
  295. move_masks()
  296. mister_e_countdown()
  297. root.after(100, mister_e_game)
  298. elif mister_e_state == 9:
  299. mister_e_clear()
  300. cv.itemconfig(mister_e_dialog, text="Well played! The next one is the last one, good luck!\nPress SPACE to continue.")
  301. elif mister_e_state == 10:
  302. spawn_masks()
  303. mister_e_time = 30
  304. cv.itemconfig(mister_e_timer, text="30")
  305. mister_e_time_count = 0
  306. mister_e_state = 11
  307. mister_e_game()
  308. elif mister_e_state == 11:
  309. move_masks()
  310. mister_e_countdown()
  311. root.after(100, mister_e_game)
  312. elif mister_e_state == 12:
  313. mister_e_clear()
  314. cv.itemconfig(mister_e_dialog, text="You did it!\nPress SPACE to continue.")
  315. elif mister_e_state == 13:
  316. mister_e_clear()
  317. cv.itemconfig(mister_e_dialog, text="Oh nooooo, the time is up!\nyou'll be luckier next time darling.")
  318. root.after(5000, reset)
  319. def spawn_masks():
  320. global masks_list, happy_mask, mask_images
  321. mask_images.append(ImageTk.PhotoImage(file="images/happy.png"))
  322. happy_mask = {"id": cv.create_image(randint(0, 1280), randint(0, 500), image=mask_images[0], anchor=tk.CENTER), "velx": mask_vel_gen(), "vely": mask_vel_gen()}
  323. cv.tag_bind(happy_mask["id"], "<Button-1>", button1)
  324. for i in range(40 * mister_e_state // 3 + 1):
  325. mask_images.append(ImageTk.PhotoImage(file=choice(["images/sad.png", "images/fastfood.png"])))
  326. masks_list.append({"id": cv.create_image(randint(0, 1280), randint(0, 500), image=mask_images[i + 1], anchor=tk.CENTER), "velx": mask_vel_gen(), "vely": mask_vel_gen()})
  327. def move_masks():
  328. global masks_list
  329. for mask in masks_list:
  330. cv.move(mask["id"], mask["velx"], mask["vely"])
  331. if cv.coords(mask["id"])[0] < 0 or 1280 < cv.coords(mask["id"])[0]:
  332. mask["velx"] = -mask["velx"]
  333. if cv.coords(mask["id"])[1] < 0 or 500 < cv.coords(mask["id"])[1]:
  334. mask["vely"] = -mask["vely"]
  335. cv.move(happy_mask["id"], happy_mask["velx"], happy_mask["vely"])
  336. if cv.coords(happy_mask["id"])[0] < 0 or 1280 < cv.coords(happy_mask["id"])[0]:
  337. happy_mask["velx"] = -happy_mask["velx"]
  338. if cv.coords(happy_mask["id"])[1] < 0 or 500 < cv.coords(happy_mask["id"])[1]:
  339. happy_mask["vely"] = -happy_mask["vely"]
  340. def mask_vel_gen():
  341. vel = randint(6, 12)
  342. sign = randint(0, 1)
  343. if sign == 1:
  344. vel = -vel
  345. return vel
  346. def mister_e_clear():
  347. global mask_images, masks_list, happy_mask
  348. for elt in masks_list:
  349. cv.delete(elt)
  350. mask_images = []
  351. masks_list = []
  352. happy_mask = {}
  353. def mister_e_countdown():
  354. global mister_e_time, mister_e_time_count, mister_e_timer, mister_e_state
  355. mister_e_time_count += 1
  356. if mister_e_time_count % 10 == 0:
  357. mister_e_time -= 1
  358. cv.itemconfig(mister_e_timer, text=str(mister_e_time))
  359. if mister_e_time == 0:
  360. mister_e_state = 13
  361. # Handle the pressed keys
  362. def space(_):
  363. global game_number, miss_n_state, ingredients_height, mister_c_state, mister_e_state
  364. if game_number < len(games_list):
  365. if games_list[game_number] == "N":
  366. if miss_n_state == 0:
  367. miss_n_state = 1
  368. miss_n_game()
  369. elif miss_n_state == 1:
  370. miss_n_state = 2
  371. ingredients_height -= round(flour_qtt / 3)
  372. cv.create_rectangle(1141, 359, 1239, ingredients_height, fill="#fff4de", outline="#fff4de")
  373. elif miss_n_state == 2:
  374. miss_n_state = 3
  375. cv.create_rectangle(1141, ingredients_height, 1239, ingredients_height - round(sugar_qtt / 3), fill="#ffb34f", outline="#ffb34f")
  376. ingredients_height -= round(sugar_qtt / 3)
  377. elif miss_n_state == 3:
  378. miss_n_state = 4
  379. cv.create_line(1141, ingredients_height, 1239, ingredients_height, fill="#ffffff")
  380. cv.create_line(1180, ingredients_height, 1200, ingredients_height, fill="#ffcc00")
  381. ingredients_height -= 1
  382. elif miss_n_state == 4:
  383. miss_n_state = 5
  384. cv.create_rectangle(1141, ingredients_height, 1239, ingredients_height - round(milk_qtt / 3), fill="#ffffff", outline="#ffffff")
  385. miss_n_end()
  386. elif miss_n_state == 6:
  387. game_number += 1
  388. next_game()
  389. elif games_list[game_number] == "C":
  390. if mister_c_state == 0:
  391. mister_c_state = 1
  392. mister_c_game()
  393. elif mister_c_state == 4:
  394. game_number += 1
  395. next_game()
  396. elif games_list[game_number] == "E":
  397. if mister_e_state in [0, 3, 6, 9]:
  398. mister_e_state += 1
  399. mister_e_game()
  400. elif mister_e_state == 12:
  401. game_number += 1
  402. next_game()
  403. elif game_number == 4:
  404. start()
  405. def enter(_):
  406. global mister_c_state, mister_c_score
  407. if game_number < len(games_list):
  408. if games_list[game_number] == "C":
  409. if mister_c_state == 1:
  410. mister_c_verif()
  411. mister_c_input.delete(0, tk.END)
  412. mister_c_state = 2
  413. mister_c_game()
  414. elif mister_c_state == 2:
  415. mister_c_verif()
  416. mister_c_input.delete(0, tk.END)
  417. if mister_c_score == 2:
  418. mister_c_state = 4
  419. mister_c_input.destroy()
  420. else:
  421. mister_c_state = 3
  422. mister_c_game()
  423. elif mister_c_state == 3:
  424. if mister_c_verif():
  425. mister_c_state = 4
  426. mister_c_game()
  427. else:
  428. mister_c_state = 5
  429. mister_c_game()
  430. mister_c_input.destroy()
  431. def button1(_):
  432. global mister_e_state
  433. if game_number < len(games_list):
  434. if games_list[game_number] == "E":
  435. if mister_e_state in [2, 5, 8, 11]:
  436. mister_e_state += 1
  437. root.bind("<space>", space)
  438. mister_c_input.bind("<Return>", enter)
  439. menu()
  440. root.mainloop()