【学习记录】PYGAME实现贪吃蛇游戏

本文档介绍了如何使用Python、Pygame和Raspberry Pi开发一款蛇形游戏,涉及游戏逻辑、碰撞检测、动画升级以及随机元素。通过《Python, Pygame, and Raspberry Pi Game Development》一书为指导,玩家将学会如何创建和控制游戏角色,以及如何随着游戏进度提升难度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

资源下载:

python-pygame-raspberry-pi-game-dev-2e/projects/snake at master · Apress/python-pygame-raspberry-pi-game-dev-2e · GitHub

代码展示:

from http.client import FOUND
from importlib.resources import contents
from matplotlib.pyplot import text
from numpy import block
import pygame,os,sys
import random
from pygame.locals import *
from pyparsing import Opt
from scipy import rand


pygame.init()
fpsClock =  pygame.time.Clock()
surface = pygame.display.set_mode((640,480))
font = pygame.font.Font(None,32)


class Position:
    def __init__(self,x,y):
        self.x = x
        self.y = y

class GameDate:
    def __init__(self) :
        self.lives = 3
        self.isDead = False
        #The list of blocks that make up the tail of the snakes        
        self.blocks = []
        #The running total used to count down to the next animation frame. 
        # In milliseconds
        self.tick = 250
        self.speed = 250
        self.level = 1
        #The number of berries consumed by the snake in this level
        self.berrycount = 0
        #The number of segments added when a berry is consumed. 
        # This value changes each level.
        self.segments = 1
        #The current animation frame used to draw the 
        # snake’s head. The snake has two frames of animation, 
        # not unlike Pacman
        self.frame = 0

        bx = random.randint(1,38)
        by = random.randint(1,28)

        self.berry = Position(bx,by)
        self.blocks.append(Position(20,15))
        self.blocks.append(Position(19,15))
        self.direction = 0

def loseLife(gamedata):
    gamedata.lives -= 1
    gamedata.direction =0

    gamedata.blocks[:] = []
    gamedata.blocks.append(Position(20,15))
    gamedata.blocks.append(Position(19,15))

def positionBerry(gamedata):
    bx = random.randint(1,38)
    by = random.randint(1,28)
    found = True

    while (found):
        found = False
        for b in gamedata.blocks:
            if ( b.x == bx and b.y == by ):
                found =True

        if (found):
            bx = random.randint(1,38)
            by = random.randint(1,28)

    gamedata.berry = Position(bx,by)


def loadMapFile(fileName):
    f = open(fileName,'r')
    content = f.readlines()
    f.close()
    return content


def headHitBody(gamedata):
    head = gamedata.blocks[0]

    for b in gamedata.blocks:
        if (b != head):
            if (b.x == head.x and b.y == head.y):
                return True
    return False

def headHitWall(map,gamedata):
    row = 0

    for line in map:
        col = 0 
        for char in line:
            if (char =='1'):
                if (gamedata.blocks[0].x == col and gamedata.blocks[0].y == row):
                    return True
            col += 1
        row += 1
    return False


def drawData(surface, gamedata):
    text = 'Lives = {0},level ={1}'

    info = text.format(gamedata.lives,gamedata.level)

    text = font.render(info,0,(255,255,255))
    textpos= text.get_rect(centerx =surface.get_width()/2,top=32)
    surface.blit(text,textpos)




def drawGameOver(surface):

    text1 = font.render("Game over",1,(255,255,255))
    text2 = font.render('Space to play or close the window',1,(255,255,255))


    cx = surface.get_width() /2
    cy = surface.get_height()/2

    textpos1 = text1.get_rect(centerx =cx,top=cy -48)
    textpos2 = text2.get_rect(centerx = cx,top =cy)

    surface.blit(text1,textpos1)
    surface.blit(text2,textpos2)

def drawWalls(surface, img, map):
    row = 0
    for line in map:
        col = 0
        for char in line:
            if (char =='1'):
                imgRect = img.get_rect()
                imgRect.left = col *16
                imgRect.top = row *16
                surface.blit(img,imgRect)
            col += 1
        row += 1

def drawSnake(surface, img, gamedata):
    first = True

    for b in gamedata.blocks:
        dest =  (b.x *16,b.y *16,16,16)
        if first:
            first = True
            src = (((gamedata.direction *2) + gamedata.frame) *16 ,0,16,16)
        else:
            src = (8 *16,0,16,16)

        surface.blit(img,dest,src)

def updateGame(gamedata, gameTime):
    #  Update the snake’s head and tail
    gamedata.tick -= gameTime
    head = gamedata.blocks[0]

    if (gamedata.tick < 0):
        gamedata.tick += gamedata.speed
        gamedata.frame += 1
        gamedata.frame %= 2

        if (gamedata.direction == 0):
            move =(1,0)
        elif (gamedata.direction ==1):
            move = (-1,0)
        elif(gamedata.direction ==2):
            move =(0,-1)
        else:
            move = (0,1)

        newpos = Position(head.x +move[0],head.y + move[1])
        first = True
        for b in gamedata.blocks:
            temp = Position(b.x,b.y)
            b.x = newpos.x
            b.y = newpos.y
            newpos = Position(temp.x,temp.y)
    

    #snake movement
    keys = pygame.key.get_pressed()
    if (keys[K_RIGHT] and gamedata.direction != 1):
        gamedata.direction = 0
    elif (keys[K_LEFT] and gamedata.direction != 0):
        gamedata.direction = 1
    elif(keys[K_UP] and gamedata.direction != 3):
        gamedata.direction = 2 
    elif(keys[K_DOWN] and gamedata.direction != 2):
        gamedata.direction = 3
    
    
    
    #touching a berry
    if (head.x == gamedata.berry.x and head.y == gamedata.berry.y):
        lastIdx = len(gamedata.blocks) -1
        for i in range(gamedata.segments):
            blockX = gamedata.blocks[lastIdx].x
        blockY = gamedata.blocks[lastIdx].y
        gamedata.blocks.append(Position(blockX,blockY))

        bx = random.randint(1,38)
        by = random.randint(1,28)
        gamedata.berry = Position(bx,by)
        gamedata.berrycount += 1


        if (gamedata.berrycount==10):
            gamedata.berrycount =0
            gamedata.speed -= 25
            gamedata.level += 1
            gamedata.segments *= 2
            if (gamedata.segments >64):
                gamedata.segments = 64
            if (gamedata.speed < 100):
                gamedata.speed= 100



    
    
    
    #  Get input from the player
    #  Check to see if the snake’s head hit the berry


def loadImages():
    wall =pygame.image.load("wall.png")
    raspberry = pygame.image.load('berry.png')
    snake = pygame.image.load('snake.png')

    return {'wall':wall,'berry':raspberry,'snake':snake}


images = loadImages()
images['berry'].set_colorkey((255,0,255))

snakemap = loadMapFile('map.txt')
data = GameDate()

quitGame = False
isPlaying = True

while not quitGame:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
   
    if isPlaying:
        x = random.randint(1,38)
        y = random.randint(1,28)
        
        rrect = images['berry'].get_rect()
        rrect.left = data.berry.x *16
        rrect.top = data.berry.y * 16

        #do update stuff here
        
        updateGame(data,fpsClock.get_time())
        crashed = headHitWall(snakemap,data) or headHitBody(data)
        if crashed:
            loseLife(data)
            positionBerry(data)
        
        isPlaying = (data.lives >0)

        if (isPlaying):
            surface.fill((0,0,0))
            #do drawing stuff here
            drawWalls(surface,images['wall'],snakemap)
            surface.blit(images['berry'],rrect)
            drawSnake(surface,images['snake'],data)
            drawData(surface,data)
        
        else:
            keys = pygame.key.get_pressed()

            if(keys[K_SPACE]):
                isPlaying = True
                data = None
                data = GameDate()

            drawGameOver(surface)

        pygame.display.update()
        fpsClock.tick(30)


实现截图:

 

参考:

《Python, Pygame, and Raspberry Pi Game Development by Sloan Kelly》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值