Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 24, 2023 09:00:34

m1r42
Зарегистрирован: 2022-07-26
Сообщения: 133
Репутация: +  7  -
Профиль   Отправить e-mail  

Игра в текстовом поле tkinter

Собственно это даже не вопрос. Выкладываю скрипт примитивной игрушки которую сделал в выходные от безделья. Думаю это поможет тем кто хочет чутка разобраться в потоках и понять зачем они нужны. Также реализован механизм защиты для 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)

Офлайн

#2 Янв. 24, 2023 20:45:47

Genabox
Зарегистрирован: 2022-12-24
Сообщения: 198
Репутация: +  1  -
Профиль   Отправить e-mail  

Игра в текстовом поле tkinter

игра запускается, фулскрина не хватает _)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version