我正在为一个项目在pygame上编写一个非常基本的游戏,该游戏的主要功能是根据用户选择玩哪个游戏的运营商和级别来询问20个问题。
我真的在两件事上挣扎:首先是我编写的代码确实会以正确的操作员和难度级别产生20个问题,但是我不知道每次用户回答最后一个问题时如何一次将这些问题显示在屏幕上。当前,该代码仅在屏幕上显示最后一个问题。
我遇到的第二个问题是为每个问题选择多项。我的游戏中有一个“按钮”类,与您在代码中可以看到的“文本”类相同,但是它也跟踪单击按钮的时间。对于每个问题,我需要在屏幕上有4个按钮类的实例,其中一个是每个问题的正确答案,另外三个是随机数,并且我需要代码来随机化哪个按钮是每个问题的答案,因此答案并不总是相同的。
我在游戏中也有秒表,但这些都不会干扰它。
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
gameBG=pygame.image.load('gameBG.bmp').convert()
screen.blit(gameBG,(0,0))
questiontxt= Text((325,45),(question), (white), 80)
questiontxt.draw(screen)
ticks=pygame.time.get_ticks()
if timing == False:
timing=True
seconds=0
seconds=int((ticks/1000%60))
minutes=int((ticks/60000%24))
out='{minutes:02d}:{seconds:02d}'.format(minutes=minutes, seconds=seconds)
timefont.render_to(screen,(855,50),out, green)
pygame.display.update()
clock.tick(60)
while j < 38:
qnum1=int(numlist[j])
qnum2=int(numlist[j+1])
if section == 'mixed':
mixedno=random.randrange(0,4)
operators=['addition','subtraction','division','multiplication']
qsection=operators[mixedno]
else:
qsection=section
if qsection == 'addition':
question=str(qnum1)+ '+'+ str(qnum2)+' = ?'
answer= qnum1+qnum2
elif qsection == 'subtraction':
question=str(qnum1)+ '-'+ str(qnum2)+' = ?'
answer= qnum1-qnum2
elif qsection == 'multiplication':
question=str(qnum1)+ 'x'+ str(qnum2)+' = ?'
answer= qnum1*qnum2
else:
question=str(qnum1)+'÷'+str(qnum2)+' = ?'
answer= qnum1/qnum2
print(question)
questiontxt= Text((325,45),(question), (white), 80)
questiontxt.draw(screen)
j=j+2
让我们从一个新的基本pygame程序开始。我通常是这样开始的:
import pygame
def main():
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
screen.fill(pygame.Color('lightgrey'))
pygame.display.flip()
dt = clock.tick(60)
if __name__ == '__main__':
main()
这里没什么可看的。我们创建一个窗口,将其涂成灰色,处理事件并跟踪增量时间(每帧花费的时间)。
让我们思考一下游戏应该如何运作。首先,我们有一个标题屏幕,然后选择一个难度,然后显示一些问题,最后,我们显示结果。我们将每个部分称为scene,然后从一个跳到另一个。
这是我们可以实现这些的方法:
import pygame
import pygame.freetype
class SimpleScene:
FONT = None
def __init__(self, text, next_scene):
self.background = pygame.Surface((640, 480))
self.background.fill(pygame.Color('lightgrey'))
if text:
if SimpleScene.FONT == None:
SimpleScene.FONT = pygame.freetype.SysFont(None, 32)
SimpleScene.FONT.render_to(self.background, (120, 180), text, pygame.Color('black'))
SimpleScene.FONT.render_to(self.background, (119, 179), text, pygame.Color('white'))
self.next_scene = next_scene
def start(self):
pass
def draw(self, screen):
screen.blit(self.background, (0, 0))
def update(self, events, dt):
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
return self.next_scene
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
dt = 0
scenes = {
'TITLE': SimpleScene('PRESS SPACE TO START', 'GAME'),
'GAME': SimpleScene('Can you press [SPACE]', 'RESULT'),
'RESULT': SimpleScene('You win! 100 points!', 'TITLE'),
}
scene = scenes['TITLE']
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
next_scene = scene.update(events, dt)
if next_scene:
scene = scenes[next_scene]
scene.start()
scene.draw(screen)
pygame.display.flip()
dt = clock.tick(60)
if __name__ == '__main__':
main()
我们现在可以通过按空格在场景之间切换。如您所见,每个场景本身就像一个微型游戏。当然,我们只有SimpleScene
除了绘制简单的文字外什么也不做,因此让我们对其进行更改并实现真实的游戏。我们也有一个游戏状态,因此我们也需要跟踪它。
这里是它的样子:
import pygame
import pygame.freetype
import random
class SimpleScene:
FONT = None
def __init__(self, next_scene, *text):
self.background = pygame.Surface((640, 480))
self.background.fill(pygame.Color('lightgrey'))
y = 80
if text:
if SimpleScene.FONT == None:
SimpleScene.FONT = pygame.freetype.SysFont(None, 32)
for line in text:
SimpleScene.FONT.render_to(self.background, (120, y), line, pygame.Color('black'))
SimpleScene.FONT.render_to(self.background, (119, y-1), line, pygame.Color('white'))
y += 50
self.next_scene = next_scene
self.additional_text = None
def start(self, text):
self.additional_text = text
def draw(self, screen):
screen.blit(self.background, (0, 0))
if self.additional_text:
y = 180
for line in self.additional_text:
SimpleScene.FONT.render_to(screen, (120, y), line, pygame.Color('black'))
SimpleScene.FONT.render_to(screen, (119, y-1), line, pygame.Color('white'))
y += 50
def update(self, events, dt):
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
return (self.next_scene, None)
class GameState:
def __init__(self, difficulty):
self.difficulty = difficulty
self.questions = [
('How many legs has a cow?', 4),
('How many legs has a bird?', 2),
('What is 1 x 1 ?', 1)
]
self.current_question = None
self.right = 0
self.wrong = 0
def pop_question(self):
q = random.choice(self.questions)
self.questions.remove(q)
self.current_question = q
return q
def answer(self, answer):
if answer == self.current_question[1]:
self.right += 1
else:
self.wrong += 1
def get_result(self):
return f'{self.right} answers correct', f'{self.wrong} answers wrong', '', 'Good!' if self.right > self.wrong else 'You can do better!'
class SettingScene:
def __init__(self):
self.background = pygame.Surface((640, 480))
self.background.fill(pygame.Color('lightgrey'))
if SimpleScene.FONT == None:
SimpleScene.FONT = pygame.freetype.SysFont(None, 32)
SimpleScene.FONT.render_to(self.background, (120, 50), 'Select your difficulty level', pygame.Color('black'))
SimpleScene.FONT.render_to(self.background, (119, 49), 'Select your difficulty level', pygame.Color('white'))
self.rects = []
x = 120
y = 120
for n in range(4):
rect = pygame.Rect(x, y, 80, 80)
self.rects.append(rect)
x += 100
def start(self, *args):
pass
def draw(self, screen):
screen.blit(self.background, (0, 0))
n = 1
for rect in self.rects:
if rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect)
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect, 5)
SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+30), str(n), pygame.Color('black'))
SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+29), str(n), pygame.Color('white'))
n+=1
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
n = 1
for rect in self.rects:
if rect.collidepoint(event.pos):
return ('GAME', GameState(n))
n += 1
class GameScene:
def __init__(self):
if SimpleScene.FONT == None:
SimpleScene.FONT = pygame.freetype.SysFont(None, 32)
self.rects = []
x = 120
y = 120
for n in range(4):
rect = pygame.Rect(x, y, 80, 80)
self.rects.append(rect)
x += 100
def start(self, gamestate):
self.background = pygame.Surface((640, 480))
self.background.fill(pygame.Color('lightgrey'))
self.gamestate = gamestate
question, answer = gamestate.pop_question()
SimpleScene.FONT.render_to(self.background, (120, 50), question, pygame.Color('black'))
SimpleScene.FONT.render_to(self.background, (119, 49), question, pygame.Color('white'))
def draw(self, screen):
screen.blit(self.background, (0, 0))
n = 1
for rect in self.rects:
if rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect)
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect, 5)
SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+30), str(n), pygame.Color('black'))
SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+29), str(n), pygame.Color('white'))
n+=1
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
n = 1
for rect in self.rects:
if rect.collidepoint(event.pos):
self.gamestate.answer(n)
if self.gamestate.questions:
return ('GAME', self.gamestate)
else:
return ('RESULT', self.gamestate.get_result())
n += 1
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
dt = 0
scenes = {
'TITLE': SimpleScene('SETTING', 'Welcome to the quiz', '', '', '', 'press [SPACE] to start'),
'SETTING': SettingScene(),
'GAME': GameScene(),
'RESULT': SimpleScene('TITLE', 'Here is your result:'),
}
scene = scenes['TITLE']
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
result = scene.update(events, dt)
if result:
next_scene, state = result
if next_scene:
scene = scenes[next_scene]
scene.start(state)
scene.draw(screen)
pygame.display.flip()
dt = clock.tick(60)
if __name__ == '__main__':
main()
当然还不是100%完成,但是应该可以让您了解如何构建游戏来获得所需的内容。