首页 > 解决方案 > SQLite 数据不会在游戏第二次运行时检索,而只会在重新启动时检索

问题描述

我在 Alien Invasion 上实现了一个 SQLite 数据库(Python Crash Course,第 2 版,由Eric Matthes 编写)来存储高分。如您所见,有一个开始运行的“播放”按钮,屏幕顶部显示当前分数和最高分。

https://imgur.com/a/XW8yNpJ

首次启动游戏时,存储在数据库中的最高分数被正确检索,当运行完成时,如果您获得最高分数,它也被正确存储。

问题:如果我做的最高分,然后我去玩第二轮,它仍然显示之前的高分。尽管已正确存储,但我的高分仅在重新启动应用程序时显示。

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

感谢您查看它:

(已编辑)

外星人入侵.py

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


完整项目: https ://github.com/rpiflv/Alien-Invasion

标签: pythonsqlite

解决方案


我已经能够通过如下更新self.stats.high_score来修复它:def _ship_hit(self)

外星人入侵.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)

推荐阅读