python贪吃蛇小游戏,面向对象设计模式,附带源码以及所需素材

在python中通过面向对象设计模式来实现一个贪吃蛇小游戏

源码在最下方,上传的资源包内也包括代码源文件以及所需素材等,源文件在game文件夹内,exe文件可直接运行,pygame模块需要自行下载

先来看运行效果图:

开始界面,点击按钮开始游戏

python贪吃蛇小游戏,面向对象设计模式,附带源码以及所需素材_第1张图片

游戏内界面,吃掉食物增加长度,蛇头出界或撞到身体部分则游戏失败 

python贪吃蛇小游戏,面向对象设计模式,附带源码以及所需素材_第2张图片

结算界面,显示当前成绩和历史最高分,点击按钮重来

python贪吃蛇小游戏,面向对象设计模式,附带源码以及所需素材_第3张图片

 测试功能:游戏内按下空格键强制死亡

然后说我的设计思路,主要依靠的是pygame的精灵以及精灵组碰撞,我这里总共创建了十个类

  • BaseSprite类  基本精灵类,用作玩家类,食物类等的父类

  • Food  食物类

  • FoodManage  食物管理类,用于管理食物类

  • PlayerSprite  玩家类

  • PlayerManage  玩家管理类,分为蛇身和蛇头,实现移动,吃食物等方法

  • UISprite  UI类

  • UIMange  UI管理类,有三个UI界面,开始前,游戏中,结束

  • AudioManage  声音管理类,按钮点击,背景音乐,死亡音效,吃掉食物音效

  • Util  鼠标点击检测,用于检测用户是否点击了开始或重来按钮

  • GameManage  总管理类

下面是源代码部分

import random
import time
import pygame
import sys


class Util:
    """
    鼠标点击碰撞检测
    """

    @staticmethod
    def click_check(sprite):
        if pygame.mouse.get_pressed()[0]:
            if sprite.rect.collidepoint(pygame.mouse.get_pos()):
                return True
        return False


class AudioManage:
    """
    声音管理类
    """

    @staticmethod
    def play_bg_music():
        """
        背景音乐
        """
        pygame.mixer.music.load("../sound/bgm.wav")
        pygame.mixer.music.play(True)

    @staticmethod
    def play_sound(name):
        sound = pygame.mixer.Sound(name)
        sound.play()


class BaseSprite(pygame.sprite.Sprite):
    """
    基本精灵类, 有name属性, 就是精灵的图片路径
    """

    def __init__(self, name):
        super().__init__()
        self.image = pygame.image.load(name)
        self.rect = self.image.get_rect()


class Food(BaseSprite):
    """
    食物类
    """

    def __init__(self, name, center):
        super().__init__(name)
        self.rect.center = center


class PlayerSprite(Food):
    """
    玩家类(蛇头, 蛇身)
    """

    def __init__(self, name, center):
        super().__init__(name, center)


class UISprite(Food):
    """
    ui类
    """

    def __init__(self, name, center):
        super().__init__(name, center)


class FoodManage:
    """
    食物管理类
    """

    def __init__(self, gm):
        self.gm = gm
        self.food_groups = pygame.sprite.Group()

    def update(self):
        self.food_groups.update()
        self.food_groups.draw(self.gm.screen)

    def clear(self):
        self.food_groups.empty()

    def add_food(self):
        self.food = Food("../image/food.png", (random.randrange(25, 575, 25), random.randrange(25, 575, 25)))
        self.food.add(self.food_groups)


class PlayerManage:
    """
    玩家管理类
    """

    def __init__(self, gm):
        self.gm = gm
        self.player_groups = pygame.sprite.Group()
        self.body_groups = pygame.sprite.Group()
        AudioManage.play_bg_music()

    def born(self):
        self.mk_dir = "left"
        self.player = PlayerSprite("../image/left.png", (500, 500))
        self.player.add(self.player_groups)

        for i in range(3):
            self.body = PlayerSprite("../image/body.png", (500 + 25 * (i + 1), 500))
            self.body.add(self.body_groups)

        for i in range(3):
            self.food = Food("../image/food.png", (random.randrange(25, 575, 25), random.randrange(25, 575, 25)))
            self.food.add(self.gm.food_manage.food_groups)

        pygame.time.set_timer(6666, 100)

    def update(self):
        self.player_groups.update()
        self.body_groups.update()
        self.player_groups.draw(self.gm.screen)
        self.body_groups.draw(self.gm.screen)

    def clear(self):
        self.player_groups.empty()
        self.body_groups.empty()

    def move(self, dir):
        first = self.player.rect.center
        last = self.body.rect.center
        for i in range(len(self.body_groups.sprites()) - 1, 0, -1):
            self.body_groups.sprites()[i].rect.center = self.body_groups.sprites()[i - 1].rect.center
        self.body_groups.sprites()[0].rect.center = first

        self.mk_dir = dir
        if self.mk_dir == "up":
            self.player.image = pygame.image.load("../image/up.png")
            self.player.rect.centery -= 25
        elif self.mk_dir == "down":
            self.player.image = pygame.image.load("../image/down.png")
            self.player.rect.centery += 25
        elif self.mk_dir == "left":
            self.player.image = pygame.image.load("../image/left.png")
            self.player.rect.centerx -= 25
        elif self.mk_dir == "right":
            self.player.image = pygame.image.load("../image/right.png")
            self.player.rect.centerx += 25

        if pygame.sprite.spritecollide(self.player, self.gm.food_manage.food_groups, True):
            AudioManage.play_sound("../sound/eat.mp3")
            self.eat(last)
            self.gm.food_manage.add_food()
        if pygame.sprite.spritecollide(self.player, self.body_groups, False):
            AudioManage.play_sound("../sound/die.wav")
            self.gm.state = "end"
            pygame.time.set_timer(6666, 0)

        if self.player.rect.left < 0 or self.player.rect.right > 600 or self.player.rect.top < 0 or self.player.rect.bottom > 600:
            AudioManage.play_sound("../sound/die.wav")
            self.gm.state = "end"
            pygame.time.set_timer(6666, 0)

    def eat(self, center):
        self.body = PlayerSprite("../image/body.png", center)
        self.body.add(self.body_groups)
        self.gm.ui_manage.score += 5
        if self.gm.ui_manage.score > self.gm.ui_manage.max_score:
            self.gm.ui_manage.max_score = self.gm.ui_manage.score
        self.gm.ui_manage.gaming_surface = self.gm.ui_manage.font.render(f"得分:{self.gm.ui_manage.score}", True,
                                                                         (0, 0, 0))


class UIMange:
    """
    ui管理类
    """

    def __init__(self, gm):
        self.gm = gm
        self.max_score = 0
        self.score = 0
        self.font = pygame.font.Font(r"../font/simkai.ttf", 32)
        # 开始前
        self.start_groups = pygame.sprite.Group()
        self.start_btn = UISprite("../image/begin_btn.png", (300, 300))
        self.start_btn.add(self.start_groups)

        # 游戏中
        self.gaming_surface = self.font.render(f"得分:{self.score}", True, (0, 0, 0))

        # 结束
        self.end_groups = pygame.sprite.Group()
        self.end_btn = UISprite("../image/replay_btn.png", (300, 300))
        self.end_btn.add(self.end_groups)

    def update(self):
        if self.gm.state == "ready":
            self.start_groups.draw(self.gm.screen)
            if Util.click_check(self.start_btn):
                AudioManage.play_sound("../sound/click.mp3")
                self.gm.state = "gaming"
                self.gm.player_manage.born()
        if self.gm.state == "gaming":
            self.gm.screen.blit(self.gaming_surface, (400, 20))
        if self.gm.state == "end":
            self.final_score = self.font.render(f"最终得分:{self.score}", True, (0, 0, 0))
            self.final_max_score = self.font.render(f"最高分:{self.max_score}", True, (0, 0, 0))
            self.gm.screen.blit(self.final_score, (200, 150))
            self.gm.screen.blit(self.final_max_score, (200, 100))
            self.gm.player_manage.clear()
            self.gm.food_manage.clear()
            self.end_groups.draw(self.gm.screen)
            if Util.click_check(self.end_btn):
                self.gm.dir = "left"
                AudioManage.play_sound("../sound/click.mp3")
                self.gm.player_manage.born()
                self.gm.state = "gaming"
                self.score = 0
                self.gaming_surface = self.font.render(f"得分:{self.score}", True, (0, 0, 0))


class GameManage:
    """
    游戏管理类(总管理类)
    """

    def __init__(self, name):
        pygame.init()
        self.screen = pygame.display.set_mode((600, 600))
        self.clock = pygame.time.Clock()
        self.state = "ready"
        self.ui_manage = UIMange(self)
        self.player_manage = PlayerManage(self)
        self.food_manage = FoodManage(self)
        self.dir = "left"
        pygame.display.set_caption(name)

    def check_move(self):
        if self.player_manage.mk_dir == "left" and self.dir == "right" or self.player_manage.mk_dir == "right" and self.dir == "left" or self.player_manage.mk_dir == "up" and self.dir == "down" or self.player_manage.mk_dir == "down" and self.dir == "up":
            return False
        else:
            return True

    def check_event(self):
        for event in pygame.event.get():
            if event.type == 256:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_SPACE:
                    self.state = "end"

            # 键盘控制移动
            if self.state == "gaming":
                if event.type == 6666:
                    if self.check_move():
                        self.player_manage.move(self.dir)
                    else:
                        self.player_manage.move(self.player_manage.mk_dir)
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP and self.dir != "up":
                        self.dir = "up"
                    elif event.key == pygame.K_DOWN and self.dir != "down":
                        self.dir = "down"
                    elif event.key == pygame.K_LEFT and self.dir != "left":
                        self.dir = "left"
                    elif event.key == pygame.K_RIGHT and self.dir != "right":
                        self.dir = "right"
                    time.sleep(0.05)

    def run(self):
        while True:
            if pygame.mixer.music.get_busy() == False:
                AudioManage.play_bg_music()
            self.clock.tick(50)
            self.check_event()
            self.screen.fill("#FFFACD")
            self.ui_manage.update()
            self.player_manage.update()
            self.food_manage.update()

            pygame.display.flip()


gm = GameManage("贪吃蛇大作战")

if __name__ == '__main__':
    gm.run()

你可能感兴趣的:(python,pygame)