Форум сайта python.su
Собственно это даже не вопрос. Выкладываю скрипт примитивной игрушки которую сделал в выходные от безделья. Думаю это поможет тем кто хочет чутка разобраться в потоках и понять зачем они нужны. Также реализован механизм защиты для tkinter, так как tkinter является непотокобезопасным. Есть в скрипте и недочеты, например не правильно работает clear_display(), так как несколько потоков одновременно захватывают текст из поля и выводят его после обработки обратно. Если есть желание у кого разобраться как обойти этот момент, то добро пожаловать в тему.
import tkinter as tk from tkinter import ttk from tkinter import * import time from threading import Thread from random import randint x = 14 y = 1 bullet = False alien = 'Ж' alienX = 0 alienY = 0 score = 0 HP = 3 stop = False speed = 0.4 exit_game = False def clear_display(): text.delete(1.0, END) def update_display(*arg): """создает один кадр изображения""" display_1 = text.get(1.0, 1.28) display_2 = text.get(2.0, 2.28) display_3 = text.get(3.0, 3.28) display_4 = text.get(4.0, 4.28) display_5 = text.get(5.0, 5.28) display_6 = text.get(6.0, 6.28) display_7 = text.get(7.0, 7.28) display_8 = text.get(8.0, 8.28) display_9 = text.get(9.0, 9.28) display_10 = text.get(10.0, 10.28) display_11 = text.get(11.0, 11.28) display_12 = text.get(12.0, 12.28) display_13 = text.get(13.0, 13.28) s, x, y = arg display_1 = ' ' * 28 display_1 = display_1[:2] + 'Score: ' + str(score) + ' '*12 display_1 = display_1[:18] + 'HP: ' + str(HP) if y == 2: display_2 = ' ' * 28 display_2 = display_2[:x-1] + s + display_2[x+len(s):] elif y == 3: display_3 = ' ' * 28 display_3 = display_3[:x-1] + s + display_3[x+len(s):] elif y == 4: display_4 = ' ' * 28 display_4 = display_4[:x-1] + s + display_4[x+len(s):] elif y == 5: display_5 = ' ' * 28 display_5 = display_5[:x-1] + s + display_5[x+len(s):] elif y == 6: display_6 = ' ' * 28 display_6 = display_6[:x-1] + s + display_6[x+len(s):] elif y == 7: display_7 = ' ' * 28 display_7 = display_7[:x-1] + s + display_7[x+len(s):] elif y == 8: display_8 = ' ' * 28 display_8 = display_8[:x-1] + s + display_8[x+len(s):] elif y == 9: display_9 = ' ' * 28 display_9 = display_9[:x-1] + s + display_9[x+len(s):] elif y == 10: display_10 = ' ' * 28 display_10 = display_10[:x-1] + s + display_10[x+len(s):] elif y == 11: display_11 = ' ' * 28 display_11 = display_11[:x-1] + s + display_11[x+len(s):] elif y == 12: display_12 = ' ' * 28 display_12 = display_12[:x-1] + s + display_12[x+len(s):] elif y == 13: display_13 = ' ' * 28 display_13 = display_13[:x-2] + s + display_13[x+1:] display = display_1 + '\n' +\ display_2 + '\n' +\ display_3 + '\n' +\ display_4 + '\n' +\ display_5 + '\n' +\ display_6 + '\n' +\ display_7 + '\n' +\ display_8 + '\n' +\ display_9 + '\n' +\ display_10 + '\n' +\ display_11 + '\n' +\ display_12 + '\n' +\ display_13 return display def alien_ship(): global alien, alienX, alienY, HP, stop, speed, exit_game, root alienX = randint(2, 27) clear_display() draw_display(('<0>',x, 13)) for i in range(2, 12): if i < 11 and not stop: alienY = i + 1 draw_display((alien, alienX, alienY),(' ', alienX, i)) #draw_display((alien, alienX, alienY)) time.sleep(speed) if i == 11 and alien == 'Ж' and not stop: alienY = i + 1 HP -= 1 draw_display(('@', alienX, alienY),(' ', alienX, i)) #draw_display(('@', alienX, alienY)) if HP == 0: stop = True if alien == '~' and not stop: clear_display() draw_display(('<0>',x, 13)) break if not stop: if speed > 0.002: speed -= 0.002 else: speed = 0.4 alien = 'Ж' th = Thread(target=alien_ship) th.start() if stop and not exit_game: clear_display() draw_display(('GAME OVER', 10, 6)) if stop and exit_game: root.destroy() def move_left(event): global x if x != 2: x -= 1 draw_display(('<0>', x, 13)) def move_right(event): global x if x != 27: x += 1 draw_display(('<0>', x, 13)) def draw_display(*args): for i in args: obj, x , y = i display = update_display(obj, x, y) text.config(state='normal') text.delete(0.0, END) text.insert(0.0, display) text.config(state='disabled') def bullet_go(): global x, bullet, alien, alienX, alienY, score, stop, HP, speed bullet = True bullet_x = x for i in range(1, 14): if i == 1: draw_display(('X', bullet_x, 12)) elif i > 1 and i < 12: draw_display((' ', bullet_x, 14-i),('|', bullet_x, 13-i)) if alienX == bullet_x and alien == 'Ж' and (alienY == 13-i\ or alienY == 12-i): alien = '~' score += 1 elif i == 13: draw_display(('*', bullet_x, 2)) time.sleep(0.02) draw_display((' ', bullet_x, 2)) if stop: stop = False score = 0 HP = 3 speed = 0.4 th = Thread(target=alien_ship) th.start() time.sleep(0.02) bullet = False def bullet_run(event): global bullet if not bullet: th = Thread(target=bullet_go) th.start() def on_closing(): global stop, exit_game if stop: root.destroy() stop = True exit_game = True root = tk.Tk() root.geometry("250x250+200+200") text_frame = ttk.Frame(root, width=200, height=200) text_frame.pack(anchor="nw") text = tk.Text(text_frame, width=28, height=13) text.pack(anchor="nw") text.focus_set() text.bind('<KeyPress-Left>', move_left) text.bind('<KeyPress-Right>', move_right) text.bind('<Escape>', bullet_run) if __name__ == '__main__': th = Thread(target=alien_ship) th.start() root.protocol("WM_DELETE_WINDOW", on_closing) root.mainloop()
Отредактировано m1r42 (Янв. 24, 2023 09:03:57)
Офлайн
игра запускается, фулскрина не хватает _)
Офлайн