这是学习编码的第4天,我对一些基础知识仍然有些困惑。它具有pygame,pygame.text,所以本质上我的代码看起来像这样。
#Mouse click to get mouse Position
if event.type == pygame.MOUSEBUTTONDOWN:
if gamestage == 0 and gamestage <= 1:
gamestage += 1
mx, my =pygame.mouse.get_pos()
#Total rectangle dimentions mx>806 and mx<889 and my>890 and my<920
#Clickable squares for Shots and Team
#Use print function if bug arises
if mx>848 and mx<889 and my>890 and my<920:
#numberonscreen_x=859
#numberonscreen_y=905
n+=1
print(n)
n=str(n)
text_surface, rect = gamefont.render(n,(4, 8, 18))
n=int(n)
screen.blit(board,(0,0))
pygame.display.flip()
if mx>806 and mx<848 and my>890 and my<920:
print("Pass")
if mx>764 and mx<806 and my>890 and my<920:
print("Pass")
if mx>722 and mx<764 and my>890 and my<920:
print("Pass")
if mx>680 and mx<722 and my>890 and my<920:
print("Pass")
if mx>638 and mx<680 and my>890 and my<920:
print("Pass")
if mx>596 and mx<638 and my>890 and my<920:
print("Pass")
if mx>554 and mx<596 and my>890 and my<920:
print("Pass")
if mx>512 and mx<554 and my>890 and my<920:
print("Pass")
if mx>470 and mx<512 and my>890 and my<920:
print("Pass")
if mx>428 and mx<470 and my>890 and my<920:
print("Pass")
if mx>386 and mx<428 and my>890 and my<920:
print("Pass")
if mx>344 and mx<386 and my>890 and my<920:
print("Pass")
if mx>302 and mx<344 and my>890 and my<920:
print("Pass")
if mx>260 and mx<302 and my>890 and my<920:
print("Pass")
if mx>218 and mx<260 and my>890 and my<920:
print("Pass")
if mx>176 and mx<218 and my>890 and my<920:
print("Pass")
if mx>134 and mx<176 and my>890 and my<920:
print("Pass")
if event.type == pygame.MOUSEBUTTONUP:
if gamestage != 0:
gamestage = 0
#Press 0 set given on screen button to zero
if event.type == pygame.KEYDOWN and event.key == pygame.K_0:
mx, my =pygame.mouse.get_pos()
if mx>848 and mx<889 and my>905 and my<920:
n=0
print(n)
if mx>806 and mx<848 and my>905 and my<920:
print("Pass1")
if mx>764 and mx<806 and my>905 and my<920:
print("Pass1")
if mx>722 and mx<764 and my>905 and my<920:
print("Pass1")
if mx>680 and mx<722 and my>905 and my<920:
print("Pass1")
if mx>638 and mx<680 and my>905 and my<920:
print("Pass1")
if mx>596 and mx<638 and my>905 and my<920:
print("Pass1")
if mx>554 and mx<596 and my>905 and my<920:
print("Pass1")
if mx>512 and mx<554 and my>905 and my<920:
print("Pass1")
if mx>470 and mx<512 and my>905 and my<920:
print("Pass1")
if mx>428 and mx<470 and my>905 and my<920:
print("Pass1")
if mx>386 and mx<428 and my>905 and my<920:
print("Pass1")
if mx>344 and mx<386 and my>905 and my<920:
print("Pass1")
if mx>302 and mx<344 and my>905 and my<920:
print("Pass")
if mx>260 and mx<302 and my>905 and my<920:
print("Pass1")
if mx>218 and mx<260 and my>905 and my<920:
print("Pass1")
if mx>176 and mx<218 and my>905 and my<920:
print("Pass1")
if mx>134 and mx<176 and my>905 and my<920:
print("Pass1")
看起来真的很糟糕。我正在制作一个垄断游戏,并且为每个属性添加2个屏幕按钮。意味着将有100多种不同的(mx,my)集。仅基于查看其他人的代码,它看起来效率很低。由于董事会中会有许多不同的可点击部分,因此我需要找到一种方法来使它更加有效和易于阅读。
尽管有人“随便做”会很好,但我还是希望通过很多链接做出回应。使用这种方法,我还需要100个具有不同名称的text_surfaces,以及100个不同的变量n。我的思维过程是制作一些东西来存储所有n,text_surfaces并调用它。但是我真的不知道该怎么做,怎么称呼它以及它是否从“导入”中起作用。
答案 0 :(得分:2)
您可以初始化一个mx
范围的数组:
mx_ranges = [
(806,848),
(764,806),
(722,764),
(680,722),
(638,680),
(596,638),
(554,596),
(512,554),
(470,512),
(428,470),
(386,428),
(344,386),
(302,344),
(260,302),
(218,260),
(176,218),
(134,176),
]
然后使用此函数代替那些“ if
大块”中的每个块:
def check_mx_range(mx, min_my, max_my, result):
for mx_range in mx_ranges:
if mx_range[0] < mx < mx_range[1] and min_my < my < max_my:
print(result)
return True
return False
答案 1 :(得分:2)
您缺少abstraction的某些级别。
让我们从pygame游戏的基本框架开始:
import pygame
def main():
pygame.init()
screen = pygame.display.set_mode((500, 500))
screen_rect = screen.get_rect()
sprites = pygame.sprite.Group()
clock = pygame.time.Clock()
rects = []
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
sprites.update(dt, events)
screen.fill(pygame.Color('darkgrey'))
sprites.draw(screen)
pygame.display.update()
dt = clock.tick(60)
if __name__ == '__main__':
main()
我们要实现的是Separation of concerns,所以让我们的主循环保持简洁。我们处理事件(主循环关心的唯一事件是QUIT
),我们更新游戏状态(即名为sprites
的精灵的Group
),我们将内容绘制到屏幕上,我们将帧速率限制为Clock
因此,您说您有一个垄断委员会,那么让我们考虑一种表示这种情况的方法。让我们创建一个属性列表,每个属性都有一个颜色,一个名称和一个价格:
properties = (
('purple', 100, 'Oriental Avenue'),
('purple', 200, 'Vermont Avenue'),
('purple', 300, 'Connecticut Avenue'),
('white', 400, 'Atlantic Avenue'),
('white', 500, 'Ventnor Avenue'),
('white', 600, 'Marvin Gardens'),
('blue', 700, 'Park Place'),
('blue', 800, 'Boadwalk')
)
请注意,那只是一些数据的列表(实际上是元组的元组),因为我们想要Separation Of Data And Code。
属性是游戏状态的一部分。让我们创建一个包含所有游戏状态的类,并为我们创建一些sprites,用于将内容绘制到屏幕上。此类还将计算每个精灵的位置。
class Board:
def __init__(self, properties, font):
self.properties = properties
self.sprites = []
side = len(properties) / 4 + 1
size = (side * PROP_SIZE.width, side * PROP_SIZE.height)
x, y = 0, 0
flow = 'r'
for prop in properties:
if flow == 'r':
if x == side - 1:
flow = 'd'
else:
x += 1
if flow == 'd':
if y == side - 1:
flow = 'l'
else:
y += 1
if flow == 'l':
if x == 0:
flow = 'u'
else:
x -= 1
if flow == 'u':
y -= 1
self.sprites.append(Property(*prop, (x*PROP_SIZE.width, y*PROP_SIZE.height), font))
我们希望每个属性都有两个按钮,所以让我们创建一个精灵类Property
来处理事件检查是否使用:
class Property(pygame.sprite.Sprite):
def __init__(self, color, price, name, pos, font):
super().__init__()
self.image = pygame.Surface(PROP_SIZE.size)
self.rect = self.image.get_rect()
pygame.draw.rect(self.image, (0, 0, 0), self.rect)
pygame.draw.rect(self.image, pygame.Color(color), self.rect.inflate(-2, -2))
self.color = color
self.price = price
self.name = name
font.render_to(self.image, (11, 21), name, pygame.Color('black'))
font.render_to(self.image, (10, 20), name, pygame.Color('white'))
self.buttons = {
'A': pygame.Rect(10, 100, 100, 20),
'B': pygame.Rect(10, 125, 100, 20),
}
self.rect.topleft = pos
def update(self, dt, events):
pos = pygame.mouse.get_pos()
for button in self.buttons:
hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
pygame.draw.rect(self.image, pygame.Color('red' if hovered else 'darkgrey'), self.buttons[button])
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
for button in self.buttons:
hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
if hovered:
print(f'{self.name} says: You clicked {button}')
我们使用了一些不错的pygame之类的东西,例如Rect类,它是inflate,move和collidepoint方法,因此我们不必自己计算位置/冲突。
这是完整的运行代码。你会得到的想法:
import pygame
import pygame.freetype
PROP_SIZE = pygame.Rect(0, 0, 120, 180)
class Property(pygame.sprite.Sprite):
def __init__(self, color, price, name, pos, font):
super().__init__()
self.image = pygame.Surface(PROP_SIZE.size)
self.rect = self.image.get_rect()
pygame.draw.rect(self.image, (0, 0, 0), self.rect)
pygame.draw.rect(self.image, pygame.Color(color), self.rect.inflate(-2, -2))
self.color = color
self.price = price
self.name = name
font.render_to(self.image, (11, 21), name, pygame.Color('black'))
font.render_to(self.image, (10, 20), name, pygame.Color('white'))
self.buttons = {
'A': pygame.Rect(10, 100, 100, 20),
'B': pygame.Rect(10, 125, 100, 20),
}
self.rect.topleft = pos
def update(self, dt, events):
pos = pygame.mouse.get_pos()
for button in self.buttons:
hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
pygame.draw.rect(self.image, pygame.Color('red' if hovered else 'darkgrey'), self.buttons[button])
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
for button in self.buttons:
hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
if hovered:
print(f'{self.name} says: You clicked {button}')
class Board:
def __init__(self, properties, font):
self.properties = properties
self.sprites = []
side = len(properties) / 4 + 1
size = (side * PROP_SIZE.width, side * PROP_SIZE.height)
x, y = 0, 0
flow = 'r'
for prop in properties:
if flow == 'r':
if x == side - 1:
flow = 'd'
else:
x += 1
if flow == 'd':
if y == side - 1:
flow = 'l'
else:
y += 1
if flow == 'l':
if x == 0:
flow = 'u'
else:
x -= 1
if flow == 'u':
y -= 1
self.sprites.append(Property(*prop, (x*PROP_SIZE.width, y*PROP_SIZE.height), font))
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
screen_rect = screen.get_rect()
font = pygame.freetype.SysFont(None, 14)
font.origin = True
properties = (
('purple', 100, 'Oriental Avenue'),
('purple', 200, 'Vermont Avenue'),
('purple', 300, 'Connecticut Avenue'),
('white', 400, 'Atlantic Avenue'),
('white', 500, 'Ventnor Avenue'),
('white', 600, 'Marvin Gardens'),
('blue', 700, 'Park Place'),
('blue', 800, 'Boadwalk')
)
board = Board(properties, font)
sprites = pygame.sprite.Group(*board.sprites)
clock = pygame.time.Clock()
rects = []
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
sprites.update(dt, events)
screen.fill(pygame.Color('darkgrey'))
sprites.draw(screen)
pygame.display.update()
dt = clock.tick(60)
if __name__ == '__main__':
main()