如何在python上制作选择题游戏

如何在python上制作选择题游戏,python,pygame,Python,Pygame,我正在做一个包含多项选择题的游戏。它将包括用户选择三个选项中的一个来回答问题。 每个新问题的选项都会改变 由于我是python新手,我对如何开始感到困惑和不确定。我无法创建可单击的文本框。我在pygame上制作这个游戏 在一个预先回答的问题中:我想要一些关于如何创建这样的东西的建议。这方面的代码在链接中 下面是@sloth成功创建的图像 所以对于我的问题,我的游戏将有不同的答案,而不是数字作为选项,每个新问题的答案都会改变 如果您有任何建议或可以告诉我如何开始,将不胜感激。谢谢。您可以使用各种

我正在做一个包含多项选择题的游戏。它将包括用户选择三个选项中的一个来回答问题。 每个新问题的选项都会改变

由于我是python新手,我对如何开始感到困惑和不确定。我无法创建可单击的文本框。我在pygame上制作这个游戏

在一个预先回答的问题中:我想要一些关于如何创建这样的东西的建议。这方面的代码在链接中

下面是@sloth成功创建的图像

所以对于我的问题,我的游戏将有不同的答案,而不是数字作为选项,每个新问题的答案都会改变


如果您有任何建议或可以告诉我如何开始,将不胜感激。谢谢。

您可以使用各种GUI(图形用户界面),如Tkinter、pyautogui等

以下是您需要的所有文档:

pyautogui:

特金特:

其他图形用户界面:


希望这对您有所帮助,您可以在这里随时在线提问:)

您可以使用各种GUI(图形用户界面),如Tkinter、pyautogui等

以下是您需要的所有文档:

pyautogui:

特金特:

其他图形用户界面:


希望这对你有所帮助,并且可以在这里随时在线提问:)

在游戏场景类中,你可以添加一些类似选项的内容

 self.choices = ['x', '-', '*', '+'] 
我以前从未使用过
pygame.freetype
,但似乎渲染文本是使用

SimpleScene.FONT.render_to
因此,您可以迭代选择并绘制它们

SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+29), str(self.choices[n]), 
pygame.Color('white'))

要为不同的问题提供不同的选项,您可以将
self.choices
列表扩展为二维列表。然后遍历该列表并根据当前问题呈现它们。另外,看起来sloths原始代码没有调整大小,因此无法渲染单词。因此,我稍微修改了框的呈现方式,以适合文字。此外,我还添加了一条名为
#CHANGE
的注释,以显示对前一条所做的更改

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

        #CHANGE
        self.questions = [
            (" 4 _ 6 = 10 ?", 4),
            ("Which one is a fruit?", 2)
        ]
        self.current_question = None

        #CHANGE
        self.question_index = 0
        
        self.right = 0
        self.wrong = 0


    def pop_question(self):
        q = random.choice(self.questions)
        self.questions.remove(q)
        self.current_question = q

        #CHANGE
        self.question_index += 1
        
        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 = []

        #CHANGE
        for n in range(4):
            rect = pygame.Rect(50, (n * 70) + 100, 500, 50)
            self.rects.append(rect)


    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)

            #CHANGE
            SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+15), str(n), pygame.Color('black'))
            SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+14), 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 = []
        
        for n in range(4):
            rect = pygame.Rect(50, (n * 70) + 100, 500, 50)
            self.rects.append(rect)

        #CHANGE
        self.choices = [['x', '-', '*', '+'], ["whatever", "apple", "whatever", "whatever"]] 

    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 = 0
        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)

            #CHANGE
            for i in range(len(self.choices)):
                if self.gamestate.question_index ==  i + 1:
                    SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+20), str(self.choices[i][n]), pygame.Color('black'))
                    SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+19), str(self.choices[i][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()

问题在于这些问题是随机挑选的,所以索引没有对齐。由于原始代码不是为有不同的选择而设计的,因此处理答案的类无法访问控制选择哪个问题的随机变量。因此,在不牺牲封装的情况下,没有任何方法可以产生随机问题。所以我建议去掉随机性,直接提出问题

替换

q = random.choice(self.questions)


它在
pop_questions
方法中的
GameState
类中。

在游戏场景类中,您可以添加类似选项的内容

 self.choices = ['x', '-', '*', '+'] 
我以前从未使用过
pygame.freetype
,但似乎渲染文本是使用

SimpleScene.FONT.render_to
因此,您可以迭代选择并绘制它们

SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+29), str(self.choices[n]), 
pygame.Color('white'))

要为不同的问题提供不同的选项,您可以将
self.choices
列表扩展为二维列表。然后遍历该列表并根据当前问题呈现它们。另外,看起来sloths原始代码没有调整大小,因此无法渲染单词。因此,我稍微修改了框的呈现方式,以适合文字。此外,我还添加了一条名为
#CHANGE
的注释,以显示对前一条所做的更改

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

        #CHANGE
        self.questions = [
            (" 4 _ 6 = 10 ?", 4),
            ("Which one is a fruit?", 2)
        ]
        self.current_question = None

        #CHANGE
        self.question_index = 0
        
        self.right = 0
        self.wrong = 0


    def pop_question(self):
        q = random.choice(self.questions)
        self.questions.remove(q)
        self.current_question = q

        #CHANGE
        self.question_index += 1
        
        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 = []

        #CHANGE
        for n in range(4):
            rect = pygame.Rect(50, (n * 70) + 100, 500, 50)
            self.rects.append(rect)


    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)

            #CHANGE
            SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+15), str(n), pygame.Color('black'))
            SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+14), 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 = []
        
        for n in range(4):
            rect = pygame.Rect(50, (n * 70) + 100, 500, 50)
            self.rects.append(rect)

        #CHANGE
        self.choices = [['x', '-', '*', '+'], ["whatever", "apple", "whatever", "whatever"]] 

    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 = 0
        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)

            #CHANGE
            for i in range(len(self.choices)):
                if self.gamestate.question_index ==  i + 1:
                    SimpleScene.FONT.render_to(screen, (rect.x+30, rect.y+20), str(self.choices[i][n]), pygame.Color('black'))
                    SimpleScene.FONT.render_to(screen, (rect.x+29, rect.y+19), str(self.choices[i][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()

问题在于这些问题是随机挑选的,所以索引没有对齐。由于原始代码不是为有不同的选择而设计的,因此处理答案的类无法访问控制选择哪个问题的随机变量。因此,在不牺牲封装的情况下,没有任何方法可以产生随机问题。所以我建议去掉随机性,直接提出问题

替换

q = random.choice(self.questions)


它在
GameState
类的
pop_-questions
方法中。

您需要使用GUI。试试像tkinter或PyQT5这样的应用程序,你可以找到一个例子@Pilot Dude-如果可能的话,我会尽量远离像tkinter这样的应用程序。主要是因为我的游戏的其余部分使用pygame,因为我可以从那里制作一个空白屏幕。@Hippozipos&sloth-我查看了一下,并尝试使用代码来摆脱第一个场景,即开始的空格键。我不知道如何摆脱它。如果我能把它去掉,它会对我有更多的帮助。但屏幕上的答案框是固定的,但我的答案框会因每个问题而改变,而这正是我感到困难的地方。@Davina你的答案框改变是什么意思?如果您展示了处理它的方法,这会有所帮助。您需要使用GUI。试试像tkinter或PyQT5这样的应用程序,你可以找到一个例子@Pilot Dude-如果可能的话,我会尽量远离像tkinter这样的应用程序。主要是因为我的游戏的其余部分使用pygame,因为我可以从那里制作一个空白屏幕。@Hippozipos&sloth-我查看了一下,并尝试使用代码来摆脱第一个场景,即开始的空格键。我不知道如何摆脱它。如果我能把它去掉,它会对我有更多的帮助。但屏幕上的答案框是固定的,但我的答案框会因每个问题而改变,而这正是我感到困难的地方。@Davina你的答案框改变是什么意思?如果你能给我展示一下它的处理能力,那会有帮助的。谢谢你@hippozipos!如果选择与前一个问题不同,我将如何添加另一个问题?您是否需要再次重复代码,因为我不知道如何执行。为什么不说将选项保留为1、2、3、4,然后在下面呈现一些文本,说明每个选项的含义。类似于
1.+,,2. -,  3. *, @hippozhopos对于我的A级,我们必须创建一个具有足够范围的程序。我分为四类。每个类别有三个选择题,因此问题必须不同。信息技术