在tkinter游戏中初始化椭圆形位置

时间:2017-11-30 02:24:07

标签: python tkinter init

我需要帮助。我在使用Python中的tkinter的类似pong的游戏中遇到了一个小问题。游戏按预期工作,但我试图让椭圆形或球形开始在“自我”高度范围内的随机y位置。变量。 我对Python很新,所以我想知道是否有人可以帮助我。

init ()方法中说#NEED HELP是我试图让球从一个随机高度而不是在中间开始的地方。

提前谢谢。

import random
import tkinter
from tkinter import messagebox
import sys

def some_randomness():
    """ ~ returns random value from -0.5 to 0.5 """
    return random.random() - 0.5

class PaddleBall:
    def __init__(self):
        # window
        root = tkinter.Tk()
        root.geometry("400x200+100+100")
        root.title("Paddle Ball!")

        # used in move_paddle() method
        self.paddle_dy = 10

        # canvas
        self.width = 400
        self.height = 200
        self.my_canvas = tkinter.Canvas(root, bg="white", \
                                    width=self.width, height=self.height)
        self.my_canvas.pack()

        # frame
        self.frm_control = tkinter.Frame(root)
        self.frm_control.pack()

        # oval
        self.radius = 10
        self.x = 375
        self.y = int(self.height / 2) # NEED HELP
        self.my_canvas.create_oval(self.x - self.radius, \
                               self.height / 2 + self.radius, \
                               self.x + self.radius, \
                               self.height / 2 - self.radius,
                               fill="red", tags="disk")

        # paddle
        self.paddle_top = 75
        self.paddle_bot = 125
        self.paddle_x = 15
        # line
        self.my_canvas.create_line(self.paddle_x, self.paddle_top, \
                               self.paddle_x, self.paddle_bot, \
                               width=3, fill="blue", tags="paddle")

        # slot
        self.slot_width = 15
        self.slot_height = 20
        self.slot_top = int(self.height / 2 - self.slot_height)
        self.slot_bot = int(self.height / 2 + self.slot_height)

        # top line - slot
        self.my_canvas.create_line(self.width - self.slot_width / 2, 0, \
                               self.width - self.slot_width / 2, \
                               self.slot_top, width=self.slot_width, \
                               fill="blue", tags="slot")

        # bottom line - slot
        self.my_canvas.create_line(self.width - self.slot_width / 2, \
                               self.slot_bot, \
                               self.width - self.slot_width / 2, \
                               self.height, width=self.slot_width, \
                               fill="blue", tags="slot")

        # bind
        self.my_canvas.bind("<KeyPress-Up>", self.move_paddle_up)
        self.my_canvas.bind("<KeyPress-Down>", self.move_paddle_down)

        self.sleep_time = 30
        self.my_canvas.focus_set()
        self.animate()

    # paddle method(s)
    def move_paddle_up(self, _):
        self.paddle_dy = -abs(self.paddle_dy)
        self.move_paddle()

    def move_paddle_down(self, _):
        self.paddle_dy = abs(self.paddle_dy)
        self.move_paddle()

    def move_paddle(self):
        if self.is_paddle_on_screen():
            self.paddle_top += self.paddle_dy
            self.paddle_bot += self.paddle_dy

            self.my_canvas.move("paddle", 0, self.paddle_dy)

    def animate(self):
        dx = -3
        dy = random.randint(-3, 3)

        while True:
            self.my_canvas.move("disk", dx, dy)
            self.x += dx
            self.y += dy

            self.my_canvas.after(self.sleep_time)
            self.my_canvas.update()

            # when disk is in the slot, it'll move to the end of the canvas
            # and not bounce from the slot walls
            if self.is_in_slot():
                d_width = 0
            else:
                d_width = self.slot_width

            if self.x <= self.radius or \
            self.x + self.radius >= self.width - d_width:
                dx = -dx + some_randomness()
            if self.y <= self.radius or self.y + self.radius >= self.height:
                dy = -dy + some_randomness()

            if self.is_in_slot() and self.x >= self.width - self.radius:
                messagebox.showinfo("Victory", "You win!!")
                sys.exit(0)

            if self.is_touching_paddle():
                dx = -dx + some_randomness()
                dy += some_randomness()

    # boundary methods
    def is_touching_paddle(self):
        """ ~ checks if the oval is touching the paddle:
         1. if the left point of the oval (x - radius) is touching the paddle
         2. and if the y position is in the paddle's vertical boundaries """
        return self.x - self.radius <= self.paddle_x and \
               (self.paddle_top <= self.y <= self.paddle_bot)

    def is_in_slot(self):
        """ ~ checks if the oval's in the slot:
         1. if the right part of the oval (x + radius) has crossed slot
        entrance (width - slot_width)
         2. if the top oval point (y - radius) is bigger than slot_top position
            and if bottom oval point (y + radius) is smaller than slot_bottom
            position. also, it allows small clipping (2 pixels) to avoid 
            strange bounces on the boundaries of the slot """
        return self.x + self.radius >= self.width - self.slot_width and \
            self.slot_top + self.radius - 2 <= self.y <= \
            self.slot_bot - self.radius + 2

    def is_paddle_on_screen(self):
        """ ~ checks if the paddle is in the screen's boundaries """
        return (self.paddle_dy > 0 or self.paddle_top >= \
                abs(self.paddle_dy)) and self.paddle_bot < \
                self.height - self.paddle_dy

PaddleBall() # anonymous instance

2 个答案:

答案 0 :(得分:1)

这可以帮到你

from random import randrange

self.y = randrange(0, self.height - radius/2)

randrange采用上限和下限并返回一个int。

答案 1 :(得分:0)

你可以去:

self.y = random.randint(self.radius, self.height - self.radius)

但您还需要更改:

self.my_canvas.create_oval(self.x - self.radius, \
                       self.height / 2 + self.radius, \
                       self.x + self.radius, \
                       self.height / 2 - self.radius,
                       fill="red", tags="disk")

为:

self.my_canvas.create_oval(self.x - self.radius, \
                               self.y + self.radius, \
                               self.x + self.radius, \
                               self.y - self.radius,
                               fill="red", tags="disk")

如果没有进行更改,它无论如何都不会使用self.y属性。