python - 有没有办法返回被点击的海龟对象?
问题描述
我正在制作一个配对游戏,其中有几张纸牌倒置,用户必须匹配正确的配对。倒置的牌都是海龟对象。
例如。如果有 8 张面朝下的牌,则有 8 个海龟对象。
我在弄清楚如何选择卡片时遇到了一些麻烦,因为我不知道哪个海龟与用户选择的特定卡片相关联。我确实有一个包含所有海龟的嵌套列表,并且具有相似图像的那些被组合在一起。有没有办法返回用户选择的海龟对象?
解决方案
你可以做的是定义一个列表,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
left on。并且直接点击显示的数字不会改变卡片的状态。
下面的代码纠正了这些缺陷:
您可以做的是将一个类定义为每张卡片,并将一个类定义为一副卡片。在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
函数基本上会取两个坐标,并检测坐标是否在当前海龟对象上。我定义一个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
函数将使用该类中的clicked
函数Card
来检测对类变量Card
内所有对象的点击。Deck
cards
最后,该draw
函数将显示turned
列表中所有卡片的编号,self.pen
使用Deck
.
完整的工作代码:
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()
推荐阅读
- sql-server - 如何在一个更新语句中填写 ParentID 列?
- java - 我想使用 Java 将链接 ID 分配给具有特定站点 ID 的公交车站
- swift - Swift:如何在导航控制器之后访问第二个视图?
- sql - 在oracle中的表中插入数据时如何避免空格
- c++ - 双向数组作为函数返回
- mysql - 查询以获取与特定用户的每个联系人的最后一次对话
- php - laravel 模型修改器不访问定义的字段
- android - 华为 P40 Pro (ELS-NX9) 上的 INSTALL_FAILED_ABORTED 错误
- javascript - 如何在 JavaScript 中制作修改后的计数器动画?
- github-actions - Actions 选项卡仅显示在主分支的 /.github/workflows/ 中创建的工作流