用python写贪吃蛇,不来看看这个吗?

当你学会python,兴趣正浓的时候,是不是迫不及待的想实现些什么,实现什么好呢,好难受,快让我实现些什么。实现个贪吃蛇吧,反正也没啥技术含量(狗头)
实现贪吃蛇的博客真的好多啊,一开始我想复制一个下来,然后看一看,改一改,我就想找一个直接全部复制到pycharm,然后运行就可以的,哎,怎么找了几个都不行…后来去pygame官网看看,随手找到一个贪吃蛇实现,github把代码复制下来,哎,好像就是我想要的东西了。原版的是这个样子的
在这里插入图片描述
我们可以修改成这个样子,看起来会不会好一点
在这里插入图片描述
是的上面的其实就是改颜色,不过还添加一个有趣地方,当蛇靠近边缘时,会开启“慢动作”比如下面这个
在这里插入图片描述

来一起看看是如何实现的,然后我们再给他修改修改,嘿嘿嘿
先来了解下思路,整个游戏过程中,我们应该是不停的在循环检查,每次循环检查蛇是否碰到墙壁,是否碰到自己,是否吃到食物,然后每个结果都执行对应操作,最后更新一下画面,继续循环。蛇如何存呢,程序采用一个列表来存,把蛇的每一节都存在这个列表里,然后蛇的移动,我们只需要把最后一节蛇删除,然后计算出新的蛇头位置,把蛇头更新,说起来可能不太好理解,一看代码就明白了,下面分步来看看(原始的版本),说明全部在代码注释中啦

1、初始化
def __init__(self, windowSizeX=500, windowSizeY=500):
        #窗口大小
        self.windowSizeX = windowSizeX
        self.windowSizeY = windowSizeY
        #食物和蛇的单位大小
        self.gameUnitSize = 16
        #让屏幕和单位大小适配
        if (self.windowSizeX % self.gameUnitSize != 0):
            self.windowSizeX += self.gameUnitSize - self.windowSizeX % self.gameUnitSize
        if (self.windowSizeY % self.gameUnitSize != 0):
            self.windowSizeY += self.gameUnitSize - self.windowSizeY % self.gameUnitSize
        self.window = pygame.display.set_mode(
            [self.windowSizeX, self.windowSizeY])

		#标题
        pygame.display.set_caption("Snake!")
        #填充色
        self.window.fill((255, 255, 255))
        #初始化字体
        pygame.font.init()
        #设置字体
        self.font = pygame.font.SysFont("bahnschrift", 20)
		
		#设置画面显示的内容
        self.text = self.font.render(
            "Press Direction key to begin", True, (0, 0, 0))
        self.startTextRect = self.text.get_rect(
            center=(windowSizeX/2, windowSizeY/2))

		#这个就是我们的蛇了
        self.snake = [self.startSnake()]
        #这是我们的食物
        self.food = self.createFood()
        #速度
        self.speed = self.gameUnitSize
        #得分
        self.score = 0
        #得分显示
        self.scoreText = self.font.render(
            f"Score: {self.score}", True, (0, 0, 0), None)
        #蛇的方向控制
        self.snakeDirections = {
            'left': (-1, 0), 'right': (1, 0), 'up': (0, -1), 'down': (0, 1)}
		#上一次的执行动作,初始化随便给一个
        self.previousDirection = self.snakeDirections.get('left')
	
		#循环内容
        self.readyScreen()
        self.gameLoop()
2、循环部分
#检测键盘事件,当有键盘按键按下时,pygame可以帮我们检测到是什么按键被按下了
    def readyScreen(self):
        while True:
            self.window.blit(self.text, self.startTextRect)
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        exit()
            keys = pygame.key.get_pressed()
            if (keys[K_LEFT]):
                self.previousDirection = self.snakeDirections.get('left')
                break
            if (keys[K_RIGHT]):
                self.previousDirection = self.snakeDirections.get('right')
                break
            if (keys[K_UP]):
                self.previousDirection = self.snakeDirections.get('up')
                break
            if (keys[K_DOWN]):
                self.previousDirection = self.snakeDirections.get('down')
                break
            pygame.display.update()
#循环开始     
    def gameLoop(self):
        while True:
            pygame.time.delay(100)
            self._input()
            self._update()
            
#方向键被按下时,修改组成蛇的列表            
    def _input(self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    exit()
        keys = pygame.key.get_pressed()
        if (keys[K_LEFT] and self.previousDirection != self.snakeDirections.get('right')):
            self.moveSnake(self.snakeDirections.get('left'))
        elif (keys[K_RIGHT] and self.previousDirection != self.snakeDirections.get('left')):
            self.moveSnake(self.snakeDirections.get('right'))
        elif (keys[K_UP] and self.previousDirection != self.snakeDirections.get('down')):
            self.moveSnake(self.snakeDirections.get('up'))
        elif (keys[K_DOWN] and self.previousDirection != self.snakeDirections.get('up')):
            self.moveSnake(self.snakeDirections.get('down'))
        else:
            self.moveSnake(self.previousDirection)
            
#更新画面的地方                       
    def _update(self):

        self.window.fill((0,0,0))

        if (self.intersect() == True):
            self.appendSnake()
            self.moveFood()
            self.score += 1

        elif (self.snakeCollidingWithWall() == True or self.snakeCollidingWithSelf() == True):
            return self.killSnake()

        for link in self.snake:
            pygame.draw.rect(self.window, (255,255,255), link)
        pygame.draw.rect(self.window, (102, 255, 51), self.food)

        self.scoreText = self.font.render(
            f"Score: {self.score}", True, (255, 255, 255))
        self.scoreTextRect = self.scoreText.get_rect(center=(40, 10))
        self.window.blit(self.scoreText, self.scoreTextRect)
		#不要忘了这个updata
        pygame.display.update()

源码代码汇总如下:

class Game_snake_ex:
    def __init__(self, windowsize_x=500, windowsize_y=500):
        self.windowsize_x = windowsize_x
        self.windowsize_y = windowsize_y
        self.gameUnitsize = 16
        if (self.windowsize_x % self.gameUnitsize != 0):
            self.windowsize_x += self.gameUnitsize - self.windowsize_x % self.gameUnitsize
        if (self.windowsize_y % self.gameUnitsize != 0):
            self.windowsize_y += self.gameUnitsize - self.windowsize_y % self.gameUnitsize
        self.window = pygame.display.set_mode(
            [self.windowsize_x, self.windowsize_y])

        pygame.display.set_caption("Snake!")
        self.window.fill((0, 0, 0))
        pygame.font.init()
        self.font = pygame.font.SysFont("bahnschrift", 20)

        self.text = self.font.render(
            "Press Direction key to begin", True, (255, 255, 255))
        self.startTextRect = self.text.get_rect(
            center=(windowsize_x/2, windowsize_y/2))
        self.snake = [self.startSnake()]
        self.food = self.createFood()
        self.speed = self.gameUnitsize
        self.score = 0
        self.scoreText = self.font.render(
            f"Score: {self.score}", True, (255, 255, 255), None)
        self.snakeDirections = {
            'left': (-1, 0), 'right': (1, 0), 'up': (0, -1), 'down': (0, 1)}

        self.previousDirection = self.snakeDirections.get('left')
        self.readyScreen()
        self.gameLoop()

    def startSnake(self):
        snakeNodeX = self.window.get_width() / 2 - self.gameUnitsize
        if (snakeNodeX % self.gameUnitsize != 0):
            snakeNodeX -= snakeNodeX % self.gameUnitsize
        snakeNodeY = self.window.get_height() / 2 - self.gameUnitsize
        if (snakeNodeY % self.gameUnitsize != 0):
            snakeNodeY -= snakeNodeY % self.gameUnitsize

        snakeNodeRectangle = Rect(
            (snakeNodeX, snakeNodeY), (self.gameUnitsize, self.gameUnitsize))
        return snakeNodeRectangle

    def createFood(self):
        foodX = randint(0, self.window.get_width() - self.gameUnitsize)
        if (foodX % self.gameUnitsize != 0):
            foodX -= foodX % self.gameUnitsize
        foodY = randint(0, self.window.get_height() - self.gameUnitsize)
        if (foodY % self.gameUnitsize != 0):
            foodY -= foodY % self.gameUnitsize
        foodRectangle = Rect(
            (foodX, foodY), (self.gameUnitsize, self.gameUnitsize))
        return foodRectangle

    def moveFood(self):
        self.food.x = randint(0, self.window.get_width() - self.gameUnitsize)
        if (self.food.x % self.gameUnitsize != 0):
            self.food.x -= self.food.x % self.gameUnitsize
        self.food.y = randint(0, self.window.get_height() - self.gameUnitsize)
        if (self.food.y % self.gameUnitsize != 0):
            self.food.y -= self.food.y % self.gameUnitsize

    def createSnake(self):
        snakeNodeX = randint(0, self.window.get_width())
        if (snakeNodeX % self.gameUnitsize != 0):
            snakeNodeX -= snakeNodeX % self.gameUnitsize
        snakeNodeY = randint(0, self.window.get_height())
        if (snakeNodeY % self.gameUnitsize != 0):
            snakeNodeY -= snakeNodeY % self.gameUnitsize
        snakeNodeRectangle = Rect(
            (snakeNodeX, snakeNodeY), (self.gameUnitsize, self.gameUnitsize))
        return snakeNodeRectangle

    def appendSnake(self):
        # add node to tail
        newSnakeLink = Rect((self.snake[len(self.snake) - 1].x, self.snake[len(
            self.snake) - 1].y), (self.gameUnitsize, self.gameUnitsize))
        self.snake.append(newSnakeLink)

    def moveSnake(self, direction):
    	#蛇尾删掉,更新蛇头,其他不变
        x = 0
        y = 1
        self.snake[len(self.snake) - 1].x = self.snake[0].x + \
            direction[x] * self.speed
        self.snake[len(self.snake) - 1].y = self.snake[0].y + \
            direction[y] * self.speed
        self.snake.insert(0, self.snake.pop())
        self.previousDirection = direction


    def intersect(self):
        if self.snake[0].x == self.food.x and self.snake[0].y == self.food.y:
            return True
        return False

    def snakeCollidingWithWall(self):
        if self.snake[0].x >= self.windowsize_x or self.snake[0].x < 0 or self.snake[0].y >= self.windowsize_y or self.snake[0].y < 0:
            return True
        return False


    def snakeCollidingWithSelf(self):
        for link in self.snake:
            if (self.snake[0] is not link):
                if self.snake[0].x == link.x and self.snake[0].y == link.y:
                    return True
        return False

    def killSnake(self):
        return self._gameOverScreen()

    def _update(self):

        self.window.fill((0,0,0))

        if (self.intersect() == True):
            self.appendSnake()
            self.moveFood()
            self.score += 1

        elif (self.snakeCollidingWithWall() == True or self.snakeCollidingWithSelf() == True):
            return self.killSnake()

        for link in self.snake:
            pygame.draw.rect(self.window, (255,255,255), link)
        pygame.draw.rect(self.window, (102, 255, 51), self.food)

        self.scoreText = self.font.render(
            f"Score: {self.score}", True, (255, 255, 255))
        self.scoreTextRect = self.scoreText.get_rect(center=(40, 10))
        self.window.blit(self.scoreText, self.scoreTextRect)

        pygame.display.update()

    def _input(self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    exit()
        keys = pygame.key.get_pressed()
        if (keys[K_LEFT] and self.previousDirection != self.snakeDirections.get('right')):
            self.moveSnake(self.snakeDirections.get('left'))
        elif (keys[K_RIGHT] and self.previousDirection != self.snakeDirections.get('left')):
            self.moveSnake(self.snakeDirections.get('right'))
        elif (keys[K_UP] and self.previousDirection != self.snakeDirections.get('down')):
            self.moveSnake(self.snakeDirections.get('up'))
        elif (keys[K_DOWN] and self.previousDirection != self.snakeDirections.get('up')):
            self.moveSnake(self.snakeDirections.get('down'))
        else:
            self.moveSnake(self.previousDirection)

    def readyScreen(self):
        while True:
            self.window.blit(self.text, self.startTextRect)
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        exit()
            keys = pygame.key.get_pressed()
            if (keys[K_LEFT]):
                self.previousDirection = self.snakeDirections.get('left')
                break
            if (keys[K_RIGHT]):
                self.previousDirection = self.snakeDirections.get('right')
                break
            if (keys[K_UP]):
                self.previousDirection = self.snakeDirections.get('up')
                break
            if (keys[K_DOWN]):
                self.previousDirection = self.snakeDirections.get('down')
                break
            pygame.display.update()

    def _gameOverScreen(self):
        while True:
            self.window.fill((0, 0, 0))
            self.text = self.font.render(
                f"Game Over, Score: {self.score}", True, (255, 255, 255))
            self.startTextRect = self.text.get_rect(
                center=(self.windowsize_x/2, self.windowsize_y/2))
            self.window.blit(self.text, self.startTextRect)

            keys = pygame.key.get_pressed()
            if (keys[K_r]):
                break
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                     exit()
            pygame.display.update()
        return 1

    def gameLoop(self):
        while True:
            pygame.time.delay(100)
            self._input()
            self._update()

上面那个是原版,实现方法明白了以后,就可以自己动手来修改修改啦
这个是我添加 颜色变化 和“慢动作” 的版本
下载地址gitbub

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值