Как в python tkinter в игре сделать реакцию на столкновения?

как в это игре добавить реакцию на столкновения?:
код

from tkinter import *
import random
import time
import sys

class Ball:
    def __init__(self, canvas, paddle, score, color):
        self.canvas = canvas
        self.paddle = paddle
        self.score = score
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3,]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_heidnt = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        self.hit_bottom = False

    def hit_paddl(self, pos):
        paddl_pos = self.canvas.coords(self.paddle.id)
        if pos[2] >= paddl_pos[0] and pos[0] <= paddl_pos[2]:
            if pos[3] >= paddl_pos[1] and \
               pos[3] <= paddl_pos[3]:
                self.x += self.paddle.x
                self.score.hit()
                return True
        return False

    def hit_приград(self, pos):
        приград_pos = self.canvas.coords(Приграда.id)
        pos = self.canvas.coords(self.id)
        if ????:
            print("ви достигли висоти макс. уровня")
            return True
        return False
    
    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 3
        if pos[3] >= self.canvas_heidnt:
            self.hit_bottom = True
        if self.hit_paddl(pos) ==  True:
            self.y = -3
        if pos[0] <= 0:
            self.x = 3
        if pos[2] >= self.canvas_width:
            self.x = -3
        #приграда-винищування

    def rte(self, evt):
        print(pos[3])
            
class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, \
                    fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.started = False
            
    def draw(self):   
        self.canvas.move(self.id, self.x, 0)
        pos = self.canvas.coords(self.id)
        if pos[0] <= 0: 
            self.x = 0
        elif pos[2] >= self.canvas_width:
            self.x = 0
               
    def turn_left(self, evt):
        self.x = -3
          
    def turn_rre(self, evt):
        self.x = 3

    def start_game(self, evt):
        self.started = True

class Score:
    def __init__(self, canvas, color):
        self.score = 0
        self.canvas = canvas
        self.id = canvas.create_text(450, 10, text=("score:" , self.score), \
                                     fill=color)

    def hit(self):
        self.score += 1
        self.canvas.itemconfig(self.id, text=("score:" , self.score))

class приграда:
    def __init__(self, x, y, список1, список2):
        self.id = canvas.create_rectangle(x, y, x + 40, y + 40, fill="#450a0a")
        if список1 == 1:
            pass
        elif список1 == 2:
            pass
        elif список1 == 3:
            pass
    
tk = Tk()
tk.title("гра")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, \
        highlightthickness=0)
canvas.pack()
tk.update()

score = Score(canvas, 'green')
paddle = Paddle(canvas, 'blue')
ball = Ball(canvas, paddle, score, 'red')
Приграда = приграда(70, 10, 1, 1)
game_over_text = canvas.create_text(250, 200, text='КІНЕЦЬ ГРИ', state='hidden', font=50, fill="red")
pos = ball.canvas.coords(ball.id)
pos = paddle.canvas.coords(paddle.id)
paddle.canvas.bind_all('<KeyPress-Left>', paddle.turn_left)
paddle.canvas.bind_all('<KeyPress-Right>', paddle.turn_rre)
ball.canvas.bind_all('<KeyPress-a>', ball.rte)
paddle.canvas.bind_all('<Button-1>', paddle.start_game)
ballpos = ball.canvas.coords(ball.id)
print(ballpos)

while 1:
    ball.hit_приград(pos)
    if ball.hit_bottom == False and paddle.started == True:
        paddle.draw()
        ball.draw()
    if ball.hit_bottom == True:
        time.sleep(1)
        canvas.itemconfig(game_over_text, state='normal')
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)


да, тут переменные названы как попало.
как фунцию hit_приград(self, pos) сделать функцией для того чтобы узнавать висоту?
пробивал:
код

def hit_приград(self, pos):
        програда_pos = self.canvas.coords(self.paddle.id)
        if pos[2] >= приграда_pos[0] and pos[0] <= приграда_pos[2]:
            if pos[3] >= приграда_pos[1] and \
               pos[3] <= приграда_pos[3]:
                print("ви достигли камня")
                sys.exit()
                return True
        return False


но работает только над камнем и все.
(отвечайте кодом)
  • Вопрос задан
  • 575 просмотров
Пригласить эксперта
Ответы на вопрос 1
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
В общем, если уж используешь классы, то почему бы не сделать атрибуты у того же камня типа верх, низ, лево, право:
stone.top, stone.bottom, stone.left, stone.right


также и у других объектов, например у шарика, у paddl-а... и сравнивать не невнятные "pos[3]", а типа:

def hit_stone(ball, stone):
    return (stone.left <= ball.x_coord <= stone.right) and (stone.top <= ball.y_coord <= stone.bottom)


Кстати, в принципе можно еще проще: если есть центр камня и центр шарика, то можно делать что-то вроде:
def hit_stone(ball, stone):
    return (abs(stone.x_coord - ball.x_coord) < (stone.size//2 + ball.radius)) and (abs(stone.y_coord - ball.y_coord) < (stone.size//2 + ball.radius))
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы