检测是否单击Python Zelle图形中的框

时间:2018-12-20 05:54:32

标签: python zelle-graphics

我创建了一个骰子下注游戏。当我的代码运行时,有一个“单击滚动”按钮。当前,如果您单击屏幕上的任意位置,骰子就会滚动。如果您单击框外的任何地方,并且仅当您在框内单击时,骰子滚动,该如何关闭程序?

import graphics
from graphics import *
from random import randrange
max_x = 500
max_y = 300
win = GraphWin("Dice Rolls", max_x,max_y)
#drives the program
def main():
   class dots():
       #Drawn dots
     def __init__(self,p_x=0,p_y=0,p_s=50):
       self.m_x  = p_x
       self.m_y  = p_y
       self.m_dice_size = p_s
       self.m_items = []
       dot_size = 4
       x = self.m_x
       y = self.m_y
       s = self.m_dice_size
       d = s/4
       self.m_items.append(Circle(Point(x+2*d, y+2*d), dot_size))
       self.m_items.append(Circle(Point(x+1*d, y+1*d), dot_size))
       self.m_items.append(Circle(Point(x+1*d, y+2*d), dot_size))
       self.m_items.append(Circle(Point(x+1*d, y+3*d), dot_size))
       self.m_items.append(Circle(Point(x+3*d, y+1*d), dot_size))
       self.m_items.append(Circle(Point(x+3*d, y+2*d), dot_size))
       self.m_items.append(Circle(Point(x+3*d, y+3*d), dot_size))
       for dot in self.m_items:
         dot.setFill('black')
        #Displays three dice images based on the random value
     def display_dice(self):
       return (self.m_x,self.m_y,self.m_s)
     def undraw(self):
       for dot in self.m_items:
         dot.undraw()
               #Drawn Dice
     def draw(self, p_win, p_num):
       for dot in self.m_items:
         dot.undraw()
       if (p_num==1):
         self.m_items[0].draw(p_win)
       elif (p_num==2):
         self.m_items[3].draw(p_win)
         self.m_items[4].draw(p_win)
       elif (p_num==3):
         self.m_items[0].draw(p_win)
         self.m_items[3].draw(p_win)
         self.m_items[4].draw(p_win)
       elif (p_num==4):
         self.m_items[1].draw(p_win)
         self.m_items[3].draw(p_win)
         self.m_items[4].draw(p_win)
         self.m_items[6].draw(p_win)
       elif (p_num==5):
         self.m_items[0].draw(p_win)
         self.m_items[1].draw(p_win)
         self.m_items[3].draw(p_win)
         self.m_items[4].draw(p_win)
         self.m_items[6].draw(p_win)
       elif (p_num==6):
         self.m_items[1].draw(p_win)
         self.m_items[2].draw(p_win)
         self.m_items[3].draw(p_win)
         self.m_items[4].draw(p_win)
         self.m_items[5].draw(p_win)
         self.m_items[6].draw(p_win)

   #Prepares for next roll
   class dice_t:
     def __init__(self,x=0,y=0):
       self.m_x = x
       self.m_y = y
       self.m_s = 50
       self.m_item = Rectangle(Point(self.m_x,self.m_y),Point(self.m_x+self.m_s,self.m_y+self.m_s))
       self.m_item.setFill('white')
       self.m_dots = dots(self.m_x,self.m_y,self.m_s)
     def display_dice(self):
       return (self.m_x,self.m_y,self.m_s)
     def draw_die(self, p_win):
       self.m_item.undraw()
       self.m_item.draw(p_win)
     def draw(self, p_win, p_num):
       self.draw_die(p_win)
       self.m_dots.draw(p_win,p_num)
     def undraw(self):
       self.m_item.undraw()
       self.m_dots.undraw()
   #Winnings and losing calculation
   def check_winner(p_rolls=[]):
      last = None
      total = 0
      triple = True
      for r in p_rolls:
        if (last!=None) and (last!=r):
          triple = False
        last = r
        total += r
      if (total==3) or (total==18):
        return 10
      elif (total==4) or (total==17):
        return 5
      elif (triple ==True):
        return 2
      return -1
   #Text and instructions/rules
   def get_bet(p_win,p_balance,p_def_bet):
      inst = []
      inst.append(Text(Point(max_x/2,20), "MAKE YOUR BET: "))
      inst.append(Text(Point(max_x/2,40), "BALANCE:"+str(p_balance)))
      inst.append(Text(Point(max_x/2,70), "Rules: "))
      inst.append(Text(Point(max_x/2,90), "If you roll a 3 or 18 in total your bet winnings will be 10x your bet."))
      inst.append(Text(Point(max_x/2,110), "If you roll a 4 or 17 in total your bet winnings will be 5x your bet."))
      inst.append(Text(Point(max_x/2,130), "If you roll triples besides a 3 and 18 your bet winnings will be 2x your bet."))
      inst.append(Text(Point(max_x/2,150), 'If you roll anything else, you lose your bet.'))
      inst.append(Rectangle(Point(max_x/2-59,190), Point(max_x/2+59, 210)))
      inst.append(Text(Point(max_x/2, 200), 'CLICK TO ROLL'))
      for item in inst:
        item.draw(p_win)

      bet_text = str(p_def_bet)
      bet_input = Entry(Point (max_x/2+100, 20),5)
      bet_input.setText(bet_text)
      bet_input.draw(p_win)
      p_win.getMouse()
      bet_text = bet_input.getText()
      bet = int(bet_text)
      bet_input.undraw()
      for item in inst:
        item.undraw()
      return bet
   #Shows winnings, checks for winner, updates total, and returns the updated total
   def show_winnings(p_win, p_winnings):
      inst = []
      inst.append(Text(Point(max_x/2,90), "Your WINNINGS:"+str(winnings)))
      inst.append(Rectangle(Point(max_x/2-50,190), Point(max_x/2+50, 210)))
      inst.append(Text(Point(max_x/2, 200), 'PLAY AGAIN'))
      for item in inst:
        item.draw(p_win)
      p_win.getMouse()
      for item in inst:
        item.undraw()
   #Shows bet
   def show_bet_invalid(p_win):
      inst = []
      inst.append(Text(Point(max_x/2,90), "YOUR BET WAS INVALID"))
      inst.append(Rectangle(Point(max_x/2-50,190), Point(max_x/2+50, 210)))
      inst.append(Text(Point(max_x/2, 200), 'TRY AGAIN'))
      for item in inst:
        item.draw(p_win)
      p_win.getMouse()
      for item in inst:
        item.undraw()
   #Shows game over
   def show_game_over(p_win):
      inst = []
      inst.append(Text(Point(max_x/2,90), "YOU ARE OUT OF MONEY"))
      inst.append(Rectangle(Point(max_x/2-50,190), Point(max_x/2+50, 210)))
      inst.append(Text(Point(max_x/2, 200), 'QUIT'))
      for item in inst:
        item.draw(p_win)
      p_win.getMouse()
      for item in inst:
        item.undraw()


   # M A I N and balances along with random outputs
   #################################################

   dice = []
   for d in range(0,3):
     dice.append(dice_t(max_x/2-90+d*60,5))

   balance = 100
   def_bet = 10
   while ( balance > 0 ):
     bet_invalid = True
     while (bet_invalid):
       bet = get_bet(win,balance,def_bet)
       if (bet>=1) and (bet<=balance):
         bet_invalid = False
       else:
         show_bet_invalid(win)
     def_bet = bet
     rolls = []
     for r in range(0,3):
       roll = randrange(1, 7)
       dice[r].draw(win,roll)
       rolls.append(roll)
     winnings = check_winner(rolls) * bet
     balance += winnings
     show_winnings(win, winnings)
     for r in range(0,3):
       dice[r].undraw()
   show_game_over(win)

main()

2 个答案:

答案 0 :(得分:1)

我建议使用像tkinter这样的gui框架

import tkinter 

root = tkinter.tk()
def on_click():
     print('clicked')


btn = tkinter.Button(root, command=on_click)
root.mainloop()

答案 1 :(得分:0)

  

我如何做到这一点,如果您单击外部的任何地方,程序都将关闭   盒子

根据您设计界面的方式,这很容易做到。我们可以更改此代码:

inst.append(Rectangle(Point(max_x/2-59,190), Point(max_x/2+59, 210)))

...

p_win.getMouse()

改为:

rectangle = Rectangle(Point(max_x/2 - 59, 190), Point(max_x/2 + 59, 210))
inst.append(rectangle)

...

point = p_win.getMouse()
if not inside(point, rectangle):
    p_win.close()
    exit()

inside()的定义为:

def inside(point, rectangle):
    p1 = rectangle.getP1()
    p2 = rectangle.getP2()

    return  p1.getX() <= point.getX() <= p2.getX() and p1.getY() <= point.getY() <= p2.getY()

我们可以对'PLAY AGAIN'做同样的事情。

但是,由于代码密集且嵌入在main()中,因此很难遵循。我对下面的代码进行了重新整理,以从main()中提取代码,进行上述更改,然后使用以下样式:

from random import randrange
from graphics import *

MAX_X, MAX_Y = 500, 300

PIP_SIZE = 4
DICE_SIZE = 50

class Pips():
    """ Draw pips """

    def __init__(self, x, y, dice_size):
        self.m_x = x
        self.m_y = y

        d = dice_size / 4

        self.m_items = []

        self.m_items.append(Circle(Point(x + 2 * d, y + 2 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 1 * d, y + 1 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 1 * d, y + 2 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 1 * d, y + 3 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 3 * d, y + 1 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 3 * d, y + 2 * d), PIP_SIZE))
        self.m_items.append(Circle(Point(x + 3 * d, y + 3 * d), PIP_SIZE))

        for pip in self.m_items:
            pip.setFill('black')

    def undraw(self):
        for pip in self.m_items:
            pip.undraw()

    def draw(self, p_win, p_num):
        """ Draw Dice """

        self.undraw()

        if p_num == 1:
            self.m_items[0].draw(p_win)
        elif p_num == 2:
            self.m_items[3].draw(p_win)
            self.m_items[4].draw(p_win)
        elif p_num == 3:
            self.m_items[0].draw(p_win)
            self.m_items[3].draw(p_win)
            self.m_items[4].draw(p_win)
        elif p_num == 4:
            self.m_items[1].draw(p_win)
            self.m_items[3].draw(p_win)
            self.m_items[4].draw(p_win)
            self.m_items[6].draw(p_win)
        elif p_num == 5:
            self.m_items[0].draw(p_win)
            self.m_items[1].draw(p_win)
            self.m_items[3].draw(p_win)
            self.m_items[4].draw(p_win)
            self.m_items[6].draw(p_win)
        elif p_num == 6:
            self.m_items[1].draw(p_win)
            self.m_items[2].draw(p_win)
            self.m_items[3].draw(p_win)
            self.m_items[4].draw(p_win)
            self.m_items[5].draw(p_win)
            self.m_items[6].draw(p_win)

class Dice_t:
    """ Prepares for next roll """

    def __init__(self, x, y):
        self.m_x = x
        self.m_y = y
        self.m_s = DICE_SIZE

        self.m_item = Rectangle(Point(x, y), Point(x + self.m_s, y + self.m_s))
        self.m_item.setFill('white')
        self.m_pips = Pips(x, y, self.m_s)

    def draw_die(self, p_win):
        self.m_item.undraw()
        self.m_item.draw(p_win)

    def draw(self, p_win, p_num):
        self.draw_die(p_win)
        self.m_pips.draw(p_win, p_num)

    def undraw(self):
        self.m_item.undraw()
        self.m_pips.undraw()

def inside(point, rectangle):
    p1 = rectangle.getP1()
    p2 = rectangle.getP2()

    return  p1.getX() <= point.getX() <= p2.getX() and p1.getY() <= point.getY() <= p2.getY()

def get_bet(p_win, p_balance, p_def_bet):
    """ Text and instructions/rules"""

    inst = []
    inst.append(Text(Point(MAX_X/2, 20), "MAKE YOUR BET:"))
    inst.append(Text(Point(MAX_X/2, 40), "BALANCE: " + str(p_balance)))
    inst.append(Text(Point(MAX_X/2, 70), "Rules:"))
    inst.append(Text(Point(MAX_X/2, 90), "If you roll a 3 or 18 in total your bet winnings will be 10x your bet."))
    inst.append(Text(Point(MAX_X/2, 110), "If you roll a 4 or 17 in total your bet winnings will be 5x your bet."))
    inst.append(Text(Point(MAX_X/2, 130), "If you roll triples besides a 3 and 18 your bet winnings will be 2x your bet."))
    inst.append(Text(Point(MAX_X/2, 150), "If you roll anything else, you lose your bet."))
    rectangle = Rectangle(Point(MAX_X/2 - 59, 190), Point(MAX_X/2 + 59, 210))
    inst.append(rectangle)
    inst.append(Text(Point(MAX_X/2, 200), 'CLICK TO ROLL'))

    for item in inst:
        item.draw(p_win)

    bet_input = Entry(Point(MAX_X/2 + 100, 20), 5)
    bet_input.setText(str(p_def_bet))
    bet_input.draw(p_win)

    point = p_win.getMouse()
    if not inside(point, rectangle):
        p_win.close()
        exit()

    bet = int(bet_input.getText())
    bet_input.undraw()

    for item in inst:
        item.undraw()

    return bet

def show_winnings(p_win, p_winnings):
    """ Shows winnings, checks for winner, updates total, and returns the updated total """

    inst = []
    inst.append(Text(Point(MAX_X/2, 90), "Your WINNINGS: " + str(p_winnings)))
    rectangle = Rectangle(Point(MAX_X/2 - 50, 190), Point(MAX_X/2 + 50, 210))
    inst.append(rectangle)
    inst.append(Text(Point(MAX_X/2, 200), 'PLAY AGAIN'))

    for item in inst:
        item.draw(p_win)

    point = p_win.getMouse()
    if not inside(point, rectangle):
        p_win.close()
        exit()

    for item in inst:
        item.undraw()

def check_winner(p_rolls):
    """ Winnings and losing calculation """

    last = None
    total = 0
    triple = True

    for r in p_rolls:
        if last is not None and last != r:
            triple = False
        last = r
        total += r

    if total == 3 or total == 18:
        return 10
    if total == 4 or total == 17:
        return 5
    if triple:
        return 2

    return -1

def show_bet_invalid(p_win):
    """ Shows invalid bet """

    inst = []
    inst.append(Text(Point(MAX_X/2, 90), "YOUR BET WAS INVALID"))
    inst.append(Rectangle(Point(MAX_X/2 -50, 190), Point(MAX_X/2 + 50, 210)))
    inst.append(Text(Point(MAX_X/2, 200), 'TRY AGAIN'))

    for item in inst:
        item.draw(p_win)

    p_win.getMouse()

    for item in inst:
        item.undraw()

def show_game_over(p_win):
    """ Shows game over """

    inst = []
    inst.append(Text(Point(MAX_X/2, 90), "YOU ARE OUT OF MONEY"))
    inst.append(Rectangle(Point(MAX_X/2 - 50, 190), Point(MAX_X/2 + 50, 210)))
    inst.append(Text(Point(MAX_X/2, 200), 'QUIT'))

    for item in inst:
        item.draw(p_win)

    p_win.getMouse()

    for item in inst:
        item.undraw()

def main():
    """ Drives the program """

    # M A I N and balances along with random outputs
    #################################################

    win = GraphWin("Dice Rolls", MAX_X, MAX_Y)

    dice = [Dice_t(MAX_X/2 - 90 + d * 60, 5) for d in range(3)]

    balance = 100
    def_bet = 10

    while balance > 0:
        bet_invalid = True

        while bet_invalid:
            bet = get_bet(win, balance, def_bet)
            if 1 <= bet <= balance:
                bet_invalid = False
            else:
                show_bet_invalid(win)
        def_bet = bet
        rolls = []

        for r in range(3):
            roll = randrange(1, 7)
            dice[r].draw(win, roll)
            rolls.append(roll)

        winnings = check_winner(rolls) * bet
        balance += winnings
        show_winnings(win, winnings)

        for r in range(3):
            dice[r].undraw()

    show_game_over(win)

main()

它们被称为 pips ,而不是 dots