期望的结果是有一个可以被玩家点击的框,然后慢慢填满。我在测试后尝试使用while和for循环,如果用户单击按钮,但不是缓慢增加,而是仅增加整个框的一小部分。整个游戏代码如下,但我的问题似乎是70-80行。
import pygame, sys, time, threading, tqdm
pygame.init()
#Setting up background colors, etc
WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
YELLOW =(255,255,0)
#Setting up window and caption
DISPLAYSURF_x = 460
DISPLAYSURF_y = 720
DISPLAYSURF = pygame.display.set_mode((DISPLAYSURF_x,DISPLAYSURF_y))
pygame.display.set_caption('Adventure Capitalist')
logo = pygame.image.load('Logo.png')
menu = pygame.image.load('menu.png')
DISPLAYSURF.fill(WHITE)
cash = 30
amount = 0
barlength = 102
storeBoard = pygame.image.load('storeBoard.png')
def buyDraw(amount, minxbuy, minybuy):
Font1 = pygame.font.SysFont('monaco', 24)
buySurface = Font1.render('{0}'.format(amount), True, BLACK)
buyRect = buySurface.get_rect()
buyRect.midtop = (75, minybuy)
DISPLAYSURF.blit(buySurface,buyRect)
def cashDraw(cash):
Font2 = pygame.font.SysFont('monaco', 40)
cashSurface = Font2.render(' ${0}'.format(cash), True, GREEN)
cashRect = cashSurface.get_rect()
cashRect.midtop = (420, 10)
DISPLAYSURF.blit(cashSurface,cashRect)
# amount of item, cost to buy, time taken to complete action, money per run
def capitalist(amount, cost, timez, gain, minxbuy, maxxbuy, minybuy, maxybuy, minxgain, maxxgain, minygain, maxygain, cash):
print ("ran")
# Buy button
DISPLAYSURF.fill(WHITE)
DISPLAYSURF.blit(storeBoard, (0, 0))
buyDraw(amount, minxbuy, minybuy)
cashDraw(cash)
pygame.display.flip()
button_rect = pygame.Rect(minxgain, minygain, maxxgain, maxygain)
# Coefficient to calculate the width of the rect for a given time.
coefficient = maxxgain / timez
time = 0
clock = pygame.time.Clock()
dt = 0
done = False
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
(x, y) = pygame.mouse.get_pos()
if x < maxxbuy and x > minxbuy and y < maxybuy and y > minybuy and cash >= cost:
DISPLAYSURF.fill(WHITE, (minxbuy+25, minybuy, maxxbuy+30, maxybuy))
amount += 1
buyDraw(amount, minxbuy, minybuy)
print (cash)
DISPLAYSURF.fill(WHITE, (375, 0 , 460, 51))
cash -= cost
cashDraw(cash)
pygame.display.flip()
if x < maxxgain and x > minxgain and y < maxygain and y > minygain and amount > 0:
# If mouse is over the button, increase the timer.
if time < timez: # Stop increasing if max_time is reached.
time += dt
if time >= timez:
time = timez
inc = time * coefficient
pygame.draw.rect(DISPLAYSURF, BLACK, (minxgain, minygain, inc/2, maxygain/2))
pygame.display.flip()
dt = clock.tick(60) / 100
def opening():
DISPLAYSURF.blit(logo, (155, 50))
DISPLAYSURF.blit(menu, (0 , 125))
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
(x, y) = pygame.mouse.get_pos()
if x < 375 and x > 80 and y < 545 and y > 395:
# 1 2 3 4 5 6 7 8 9 10 11 12 13
#amount, cost, time, gain, minxbuy, maxxbuy, minybuy, maxybuy, minxgain, maxxgain, minygain, maxygain, cash
# capitalist(0, 5, 1, 1, 21, 41, 21, 41, 120, 204, 20, 41, cash)
capitalist(1, 10, 3, 5, 21, 41, 21, 41, 120, 204, 20, 41, cash)
pygame.display.flip()
opening()
答案 0 :(得分:1)
没有2个主循环。无论是嵌套还是线程。应该只有一个循环检查事件队列。如果需要线程,则应在主循环中创建自己的事件分发或手动管理事件队列。获取并删除main-main循环中的所有事件,除了另一个中需要的事件。另一个循环应该只删除它自己的事件。
不要直接绘制到显示表面。最好有一个你修改过的表面,然后将它完全blit或将它的一部分blit到屏幕上并翻转()/ update()它。有时将显示器表面处理成任何其他问题。
也许您应该使用子表面来简化填充矩形的任务。
当您稍微整理一下代码时,问题应该消失或者更明显。
答案 1 :(得分:0)
我不确定按钮的确切行为,但我可以告诉您如何修复capitalist
功能中的事件处理和逻辑。您的主要问题是您使用事件循环来增加数量,而您希望在这种情况下使用pygame.mouse.get_pressed
循环中的while
来查看当前按下的鼠标按钮。然后检查mouse_pos
是否与其中一个预定义按钮(pygame.Rect
s)发生冲突并运行所需的代码。
绘图代码也应该与事件处理和游戏逻辑分开。我在这里有一个完整的,有效的示例,附带一些附注(正如我所说,我不确定按钮应该如何表现,所以你必须根据需要调整它们):
import pygame, sys
pygame.init()
WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = pygame.Color('green')
DISPLAYSURF = pygame.display.set_mode((460, 720))
clock = pygame.time.Clock()
cash = 30
amount = 0
barlength = 102
storeBoard = pygame.Surface((102, 40))
storeBoard.fill((100, 100, 250))
# Side note: Define the fonts once here.
Font1 = pygame.font.SysFont('monaco', 24)
Font2 = pygame.font.SysFont('monaco', 40)
def buyDraw(amount, minxbuy, minybuy):
buySurface = Font1.render('{0}'.format(amount), True, BLACK)
buyRect = buySurface.get_rect()
buyRect.midtop = (75, minybuy)
DISPLAYSURF.blit(buySurface, buyRect)
def cashDraw(cash):
cashSurface = Font2.render(' ${0}'.format(cash), True, GREEN)
cashRect = cashSurface.get_rect()
cashRect.midtop = (420, 10)
DISPLAYSURF.blit(cashSurface, cashRect)
# amount of item, cost to buy, time taken to complete action, money per run
def capitalist(amount, cost, timez, gain, minxbuy, maxxbuy, minybuy, maxybuy, minxgain, maxxgain, minygain, maxygain, cash):
pygame.display.set_caption('capitalist loop')
# Define the buttons here.
buy_button = pygame.Rect(minxbuy, minybuy, maxxbuy, maxybuy)
gain_button = pygame.Rect(minxgain, minygain, maxxgain, maxygain)
# Coefficient to calculate the width of the rect for a given time.
coefficient = maxxgain / timez
time = 0
dt = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# pygame.mouse.get_pressed() returns a tuple of zeros and ones that
# show you which mouse buttons are currently being held down.
mouse_pressed = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
# Use the collidepoint method of the rects to see if they collide with the mouse.
# `mouse_pressed[0]` is the left mouse button.
if buy_button.collidepoint(mouse_pos) and mouse_pressed[0] and cash >= cost:
amount += 1
print(cash)
cash -= cost
if gain_button.collidepoint(mouse_pos) and mouse_pressed[0] and amount > 0:
# If the mouse is over the button, increase the timer.
if time < timez: # Stop increasing if max_time is reached.
time += dt
if time >= timez:
time = timez
inc = time * coefficient
# Draw everything and then flip the display.
DISPLAYSURF.fill(WHITE)
pygame.draw.rect(DISPLAYSURF, BLACK, (minxgain, minygain, inc/2, maxygain/2))
pygame.draw.rect(DISPLAYSURF, BLACK, buy_button, 2)
pygame.draw.rect(DISPLAYSURF, BLACK, gain_button, 2)
buyDraw(amount, minxbuy, minybuy)
cashDraw(cash)
pygame.display.flip()
dt = clock.tick(60) / 1000 # dt is the passed time in seconds.
def opening():
pygame.display.set_caption('opening loop')
rect = pygame.Rect(20, 20, 100, 70)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
# Collidepoint with the event.pos to see if the mouse
# collides with the button.
if rect.collidepoint(event.pos):
# Named arguments make the code more readable. Passing
# so many arguments can be a code smell and indicates
# that the code could probably be refactored.
capitalist(
amount=1, cost=10, timez=3, gain=5, minxbuy=21,
maxxbuy=41, minybuy=21, maxybuy=41, minxgain=120,
maxxgain=204, minygain=20, maxygain=41, cash=cash)
DISPLAYSURF.fill(WHITE)
# Draw the orange start button.
pygame.draw.rect(DISPLAYSURF, (200, 100, 10), rect)
pygame.display.flip()
clock.tick(60) # Call clock.tick here as well.
opening()