您可以做的是定义一个列表,turned 来存储翻过来的卡片。
这是Card 类的示例:
class Card(turtle.Turtle):
def __init__(self, number):
super(Card, self).__init__()
self.number = number
def click(self, x, y):
if self in turned:
self.clear()
turned.remove(self)
else:
self.sety(self.ycor() - self.shapesize()[1] * 7)
self.write(self.number, align='center', font=('Arial', 20, 'bold'))
self.sety(self.ycor() + self.shapesize()[1] * 7)
turned.append(self)
super(Card, self).__init__() 将赋予Card 类turtle.Turtle 类具有的所有属性。使用self.number = number 将类变量添加到Card 类。
在click 函数中:
if self in turned:
self.clear()
turned.remove(self)
这将允许用户通过将其从turned 列表中删除并清除文本来取消选择已选择的卡,然后
else:
self.sety(self.ycor() - self.shapesize()[1] * 7)
self.write(self.number, align='center', font=('Arial', 20, 'bold'))
self.sety(self.ycor() + self.shapesize()[1] * 7)
turned.append(self)
将写入文本并将卡片附加到turned 列表中。
我还定义了一个Deck 类,它将使用Card 类来创建一个完整的卡片网格:
class Deck:
def __init__(self, rows, cols, width, height, x, y):
self.cards = []
for i in range(cols):
for j in range(rows):
card = Card(randint(2, 10))
card.shape("square")
card.color('black', 'white')
card.shapesize(height / 20, width / 20)
card.goto(i * width + x, j * height + y)
card.onclick(card.click)
self.cards.append(card)
例子:
import turtle
from random import randint
wn = turtle.Screen()
wn.tracer(0)
turned = []
class Card(turtle.Turtle):
def __init__(self, number):
super(Card, self).__init__()
self.number = number
def click(self, x, y):
if self in turned:
self.clear()
turned.remove(self)
else:
self.sety(self.ycor() - self.shapesize()[1] * 7)
self.write(self.number, align='center', font=('Arial', 20, 'bold'))
self.sety(self.ycor() + self.shapesize()[1] * 7)
turned.append(self)
print([card.number for card in turned]) # print to display the clicked cards
class Deck:
def __init__(self, rows, cols, width, height, x, y):
self.cards = []
for i in range(cols):
for j in range(rows):
card = Card(randint(2, 10))
card.shape("square")
card.color('black', 'white')
card.shapesize(height / 20, width / 20)
card.goto(i * width + x, j * height + y)
card.onclick(card.click)
self.cards.append(card)
deck = Deck(8, 8, 45, 62.5, -165, -210)
wn.update()
wn.mainloop()
输出:
上面的代码可能看起来更简单,但它使用了一个全局变量turned,并且在tracer 保持打开状态下,数字只会显示半秒钟。并且直接点击显示的数字不会改变卡片的状态。
以下代码纠正了这些缺陷:
您可以做的是为每张卡片定义一个类,并将一个类定义为一副卡片。在deck类中,定义一个类变量列表turned来存放翻过来的卡片。
这是Card 类的示例:
class Card(turtle.Turtle):
def __init__(self, number):
super(Card, self).__init__()
self.number = number
self.penup()
def write_number(self, pen):
pen.goto(self.xcor(), self.ycor() - self.shapesize()[1] * 7)
pen.write(self.number, align='center', font=('Arial', 20, 'bold'))
def clicked(self, x, y):
h, w = self.shapesize()[:-1]
half_width = w * 10
half_height = h * 10
return self.xcor() + half_width > x > self.xcor() - half_width and \
self.ycor() + half_height > y > self.ycor() - half_height
super(Card, self).__init__() 将赋予Card 类turtle.Turtle 类具有的所有属性。使用self.number = number 将类变量添加到Card 类。
write_number 函数将使用单独的海龟对象在当前海龟对象上显示一个数字,以便数字显示在卡片的中心。
clicked函数基本上会取两个坐标,检测坐标是否在当前的turtle对象上。我定义一个clicked 函数而不是使用内置的turtle.onclick 方法的原因是因为我希望它返回一个布尔值而不是执行一个函数。
Deck 类将使用 Card 类创建整个卡片网格。:
class Deck:
def __init__(self, rows, cols, width, height, x, y):
self.pen = turtle.Turtle(visible=False)
self.pen.penup()
self.pen.speed(0)
self.cards = []
self.numbers = []
self.turned = []
for i in range(cols):
for j in range(rows):
card = Card(randint(2, 10))
card.shape("square")
card.color('black', 'white')
card.shapesize(height / 20, width / 20)
card.goto(i * width + x, -j * height - y)
self.cards.append(card)
def click(self, x, y):
for card in self.cards:
if card.clicked(x, y):
if card in self.turned:
card.clear()
self.turned.remove(card)
else:
self.turned.append(card)
self.draw()
print([card.number for card in self.turned])
def draw(self):
for card in self.turned:
card.write_number(self.pen)
self.cards 列表存储所有Card 对象,self.turned 存储翻转的卡片。
click 函数将使用来自Card 类的clicked 函数来检测对Deck 类变量cards 内的所有Card 对象的点击。
最后,draw 函数将使用Deck 中定义的self.pen 显示turned 列表中所有卡片上的数字。
完整的工作代码:
import turtle
from random import randint
wn = turtle.Screen()
class Card(turtle.Turtle):
def __init__(self, number):
super(Card, self).__init__()
self.number = number
self.penup()
def write_number(self, pen):
pen.goto(self.xcor(), self.ycor() - self.shapesize()[1] * 7)
pen.write(self.number, align='center', font=('Arial', 20, 'bold'))
def clicked(self, x, y):
h, w = self.shapesize()[:-1]
half_width = w * 10
half_height = h * 10
return self.xcor() + half_width > x > self.xcor() - half_width and \
self.ycor() + half_height > y > self.ycor() - half_height
class Deck:
def __init__(self, rows, cols, width, height, x, y):
self.pen = turtle.Turtle(visible=False)
self.pen.penup()
self.pen.speed(0)
self.cards = []
self.numbers = []
self.turned = []
for i in range(cols):
for j in range(rows):
card = Card(randint(2, 10))
card.shape("square")
card.color('black', 'white')
card.shapesize(height / 20, width / 20)
card.goto(i * width + x, -j * height - y)
self.cards.append(card)
def click(self, x, y):
for card in self.cards:
if card.clicked(x, y):
if card in self.turned:
card.clear()
self.turned.remove(card)
else:
self.turned.append(card)
self.draw()
print([card.number for card in self.turned])
def draw(self):
for card in self.turned:
card.write_number(self.pen)
deck = Deck(8, 8, 45, 62.5, -165, -210)
wn.onscreenclick(deck.click)
wn.mainloop()