Python SQLite数据不会在游戏的第二次运行时检索,而只会在重新启动时检索

Python SQLite数据不会在游戏的第二次运行时检索,而只会在重新启动时检索,python,sqlite,Python,Sqlite,我实现了一个由Eric Matthes编写的关于外星人入侵Python速成课程(第二版)的SQLite db来存储高分。如您所见,有一个播放按钮用于开始跑步,并在屏幕顶部显示当前分数和最高分 当第一次启动游戏时,数据库中存储的最高分数会被正确地检索,当一次跑步结束时,如果您获得了最高分数,它也会被正确地存储 问题:如果我得到了最高的分数,然后我又打了第二轮,它仍然显示了之前的最高分数。我的高分仅在重新启动应用程序时显示,尽管存储正确 我知道这里还有很多需要改进的地方,所以所有建设性的建议都将受到

我实现了一个由Eric Matthes编写的关于外星人入侵Python速成课程(第二版)的SQLite db来存储高分。如您所见,有一个播放按钮用于开始跑步,并在屏幕顶部显示当前分数和最高分

当第一次启动游戏时,数据库中存储的最高分数会被正确地检索,当一次跑步结束时,如果您获得了最高分数,它也会被正确地存储

问题:如果我得到了最高的分数,然后我又打了第二轮,它仍然显示了之前的最高分数。我的高分仅在重新启动应用程序时显示,尽管存储正确

我知道这里还有很多需要改进的地方,所以所有建设性的建议都将受到热烈欢迎

感谢您查看:

编辑

外星人入侵

class AlienInvasion:
    """Overall class to manage the app"""

    def __init__(self):

        pygame.init()
        ...

        self.stats = GameStats(self)
        self.play_button = Button(self, "Play")
        self.scoreboard = Scoreboard(self)
        
    def _create_fleet(self):
        ...

    def _create_alien(self, alien_number, row_number):
        ...

    def _check_keydown(self, event):
        ...

    def _check_keyup(self, event):
        ...

    def check_events(self):
        ...
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            self.settings.dynamic_settings()
            self.stats.reset_stats()
            self.stats.game_active = True
            self._provide_highscore()
            self.scoreboard._prep_score()
            self.scoreboard._prep_high_score()
            pygame.mouse.set_visible(False)

            self.aliens.empty()
            self.bullets.empty()

            self._create_fleet()
            self.ship.center_ship()

            self.scoreboard.show()

    def _update_bullets(self):
        ...

    def _check_fleet_edges(self):
        ...

    def _update_aliens(self):
        ...

    def _change_fleet_direction(self):
        ...

    def _fire_bullet(self):
        ...

    def update_screen(self):
        ...

    def _ship_hit(self):
        # To keep playing in case you still have ships, or new run.
        # In case of high score, store it.
        if self.stats.ships_left > 1:
            self.stats.ships_left -= 1
            self.aliens.empty()
            self.bullets.empty()

            self._create_fleet()
            self.ship.center_ship()

            sleep(1.5)
        else:
            self.add_high_score()
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _provide_highscore(self):
# Open DB and provide the (name, score) tuple for the high score
        db = sqlite3.connect("highscores.sqlite")
        cursor = db.cursor()

        cursor.execute("CREATE TABLE IF NOT EXISTS highscores (name TEXT, score INTEGER)")

        for name, score in cursor.execute("SELECT name, MAX(score)  FROM highscores").fetchall():
            return name, score

        cursor.close()
        db.commit()
        db.close()

    def add_high_score(self):
    # Storing high score
        if self.stats.score > self.stats.high_score[1]:
            db = sqlite3.connect("highscores.sqlite")
            # self.name = input("Please enter your name: ")
            self.new_high = self.stats.score
            self.scoreboard._prep_high_score()
            # name_input = InputBox # todo need to fix this name value
            self.name = self.input_name()
            add_sql = 'INSERT INTO highscores VALUES (?, ?)'
            db.execute(add_sql, (self.name, self.new_high))
            db.commit()

            db.close()
            # return self.new_high

    def input_name(self):
        .....

    def _check_alien_bottom(self):
        .....
                

    def run_game(self):
        """Start the MAIN LOOP"""
        while True:
            self.check_events()
            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
            self.update_screen()


if __name__ == "__main__":
    ai = AlienInvasion()
    ai.run_game()

game_stats.py

class GameStats:
    def __init__(self, ai_game):
          ...
          self.high_score = ai_game._provide_highscore()
记分牌.py

import pygame.font

class Scoreboard:
    def __init__(self, ai_game):
        ....
        self._prep_high_score()

    def _prep_score(self):
        .....

    def show(self):
        ....

    def _prep_high_score(self):
        high_score = round(self.stats.high_score[1], -1)
        # high_score = round(self.stats.scoreboard.highest_score)
        high_score_str = str("{:,}".format(high_score))
        high_scorer = self.stats.high_score[0]

        self.high_score_img = self.font.render(high_score_str, True, self.text_color, self.settings.bg_color)
        self.high_scorer_img = self.font.render(high_scorer, True, self.text_color, self.settings.bg_color)

        self.high_score_rect = self.high_score_img.get_rect()
        self.high_scorer_rect = self.high_scorer_img.get_rect()

        self.high_score_rect.centerx = self.screen_rect.centerx
        self.high_score_rect.top = self.score_rect.top

        self.high_scorer_rect.right = self.high_score_rect.left - 15
        self.high_scorer_rect.top = self.high_score_rect.top


完整项目:

以下是您的“提供高分”方法:

def_提供高分自我: db=sqlite3.connecthighscores.sqlite cursor=db.cursor cursor.executeCREATE表如果不存在highscores名称文本,则为分数整数 db.execute'INSERT INTO highscores VALUES FLA,1000000' db.执行“插入高分值ANG,1500000” db.执行“插入高分值KAL,500000” 对于名称,在cursor.executeSELECT name中打分,从highscores.fetchall中选择MAXscore: 返回名称、分数 光标。关闭 db.commit db.close 函数一碰到返回语句就停止执行。看起来这里有一个循环只执行一次,在循环的第一次迭代中,它将返回一个包含名称和分数的元组。最后三条线从未运行过。我根本没有太多使用SQLite,所以我不确定这是否是问题所在,但这是我将开始研究的一个地方


此外,当有一个新的高分时,您显然是在将其写入数据库。但是您是否曾经更新过self.stats.high_分数?

我已经能够通过更新def\u ship\u hitself中的self.stats.high_分数来修复它,如下所示:

alien_.py:

def _ship_hit(self):
    # To keep playing in case you still have ships, or new run.
    # In case of high score, store it, *and update the high score*
    if self.stats.ships_left > 1:
        ...
    else:
        if self.stats.score > self.stats.high_score[1]:
            self.add_high_score()
            self.stats.high_score = self.name, self.new_high
        self.stats.game_active = False
        pygame.mouse.set_visible(True)

很抱歉发布完整的项目。问题已编辑谢谢japhyr的提示,我已经解决了。我将发布一个答案来说明解决方案。附言:你的书很棒!