鱼C论坛

 找回密码
 立即注册
查看: 1686|回复: 1

[作品展示] 看完小甲鱼书后,自己动手编写的贪吃蛇游戏

[复制链接]
发表于 2020-11-24 18:45:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
看完小甲鱼书后,自己动手编写的贪吃蛇游戏
import sys
from pygame.locals import *
import pygame
from random import *

WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = (0,255,0)
REN = (255,0,0)
BLUE = (0,0,255)

pygame.init()
pygame.mixer.init()
pygame.font.init()

# 导入文字
words = pygame.font.Font("font/font.ttf", 45)

# 暂停文字
words_text = words.render("Suspended",True,BLUE)

# 结束对话框
words_text_GAMEOVER = words.render("GAMEOVER",True,BLUE)

# 重来按键字
wods_text_Reopen = words.render("Press F1 to restart",True,BLUE)

# 导入背景音音效
pygame.mixer.music.load("bgm/我不信这么高雅的作品破不了100播放量1.mp3")
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play()

# 导入音效
chi = pygame.mixer.Sound("bgm/录音1.wav")
chi.set_volume(0.5)
stop_sound = pygame.mixer.Sound("bgm/暂停.wav")
chi.set_volume(0.2)

size = width, height = 400, 400
screen = pygame.display.set_mode(size)
pygame.display.set_caption("欧阳麟君")
clock = pygame.time.Clock()


def main():


    # 用来倒计时后关闭游戏
    count_GAMEOVER = 0 

    # 蛇的像素大小
    she_size = 40
    
    # 2个 for 循环 遍历坐标位置,默认是用1234这样的,具体像素可以自己乘以具体像素的大小就好了
    shetou_overlap = []
    for i in range(0,10):
        for b in range(0,10):
            shetou_overlap.insert(0,list((i*she_size,b*she_size)))
            
    # 蛇头
    shetou = [[4*she_size,3*she_size]]

    # 给个对象指定蛇头第一个位置,用来刷新蛇吃到的食物变成蛇头
    shetou_1 = shetou[0]

    # 先生成一个随机对象,用来生成食物的初始随机位置,判断是否随机食物初始化在蛇头上,是的话就重新生成
    shiwu = choice(shetou_overlap)
    while shiwu == shetou[0]:
        choice(shetou_overlap)
    # 生成一个副蛇身用来判断是否被撞
    shetou_to = []
    
    # 判断食物是否被吃
    food = False
    # 开局随机上下左右移动
    move = choice(("upper","lower","Left","right"))
    # 给个加速器
    conut = 0
    # 修改这里提高速度
    speed = 20

    # 给个判断,用来暂停游戏
    stop = True

    # 用来切换暂停图片
    suspend_picture = False

    # 按回车开始
    kaishi = True
    
    # 用来控制流程
    running = True
    
    # 3条命
    she_life = 3
    while running:
        
        # 随着吃到越多的食物就开始越来越快
        if len(shetou) > 10:
            speed = 15
        elif len(shetou) >20:
            speed = 13
        elif len(shetou) > 30:
            speed = 7
        
        # 给一个对象,用来后边生成食物来随机
        shiwu_random = []
        shiwu_random += shetou_overlap
        
        # 给一个对象,用来后边生成食物来随机
        shiwu_random 
        # 绘制背景 
        screen.fill(WHITE)
        ##########################下面宫格线条绘制 ##########################
        # 横
        pygame.draw.aaline(screen,BLACK,(0,0),(400,0),1)
        pygame.draw.aaline(screen,BLACK,(0,40),(400,40),1)
        pygame.draw.aaline(screen,BLACK,(0,80),(400,80),1)
        pygame.draw.aaline(screen,BLACK,(0,120),(400,120),1)
        pygame.draw.aaline(screen,BLACK,(0,160),(400,160),1)
        pygame.draw.aaline(screen,BLACK,(0,200),(400,200),1)
        pygame.draw.aaline(screen,BLACK,(0,240),(400,240),1)
        pygame.draw.aaline(screen,BLACK,(0,280),(400,280),1)
        pygame.draw.aaline(screen,BLACK,(0,320),(400,320),1)
        pygame.draw.aaline(screen,BLACK,(0,360),(400,360),1)

        # 竖
        pygame.draw.aaline(screen,BLACK,(40,0),(40,400),1)
        pygame.draw.aaline(screen,BLACK,(80,0),(80,400),1)
        pygame.draw.aaline(screen,BLACK,(120,0),(120,400),1)
        pygame.draw.aaline(screen,BLACK,(160,0),(160,400),1)
        pygame.draw.aaline(screen,BLACK,(200,0),(200,400),1)
        pygame.draw.aaline(screen,BLACK,(240,0),(240,400),1)
        pygame.draw.aaline(screen,BLACK,(280,0),(280,400),1)
        pygame.draw.aaline(screen,BLACK,(320,0),(320,400),1)
        pygame.draw.aaline(screen,BLACK,(360,0),(360,400),1)
        ########################## 上面宫格线条绘制 ##########################
        
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
                     
            # 当用户按下空格之后
            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    stop_sound.play(-1)
                    pygame.mixer.music.stop() 
                    stop = not stop
                    suspend_picture = not suspend_picture
                    if stop:
                        pygame.mixer.music.play()

        # 控制游戏流程
        if stop and she_life > 0:
            stop_sound.stop()
            # 获取用户按键
            key_pressed = pygame.key.get_pressed()
            
            if key_pressed[K_a] or key_pressed[K_LEFT]:# 左
                move = "Left"

            if key_pressed[K_d] or key_pressed[K_RIGHT]:# 右
                move = "right"
                
            if key_pressed[K_w] or key_pressed[K_UP]: # 上
                move = "upper"

            if key_pressed[K_s] or key_pressed[K_DOWN]: #下
                move = "lower"

                
            """
                因为移动蛇头的话,肉眼看到的正常情况是往前进一步,
                蛇尾少一步所以移动先添加一个,给头减少,
                另一个作为尾部,用来判断是吃了食物,
                如果吃了食物直接添加到头部,尾部不动。
                如果没吃食物则移动时减少尾部,

                """        
            # 自动移动,当给定的计时器达到判断的数后
            if conut > speed:
                conut = 0
                if move == "upper": #上
                    shetou.insert(0,list(shetou[0]))
                    shetou[0][1] -= she_size
                    
                elif move == "lower":#下
                    shetou.insert(0,list(shetou[0]))
                    shetou[0][1] += she_size
                    
                elif move == "Left":#左
                    shetou.insert(0,list(shetou[0]))
                    shetou[0][0] -= she_size
                    
                elif move == "right":#右
                    shetou.insert(0,list(shetou[0]))
                    shetou[0][0] += she_size

                #  判断是否吃了食物        
                if shetou[0] == shiwu:
                    food = not food
                    chi.play()
                else:
                    # 没吃的话移动会减少一个
                    shetou.pop(-1)
                    
                # 防止新的生成在蛇身上,所有来2个for 循环遍历完全部,有就删除在重新生成
                if food:
                    for i in shetou_overlap:
                        for b in shetou:
                            if i == b:
                                #print(b)
                                shiwu_random.remove(b)
                    #print(shiwu_random)
                    shiwu = choice(shiwu_random)
                    #print(shiwu,"后面")
                    food = not food
                    
                # 撞墙后
                
                if shetou[0][0] < 0 or shetou[0][0] > width-she_size\
                or shetou[0][1] < 0 or shetou[0][1] > height - she_size:
                    she_life -= 1
                    conut = 0
                    shiwu = choice(shiwu_random)
                    shetou = [[4*she_size,3*she_size]]
                    
                # 判断是否撞到了蛇身
                
                if len(shetou) > 2:
                    # 副蛇身+= 蛇身,然后判断是否撞蛇身
                    shetou_to += shetou 
                    for each in range(len(shetou_to)-1):
                        if shetou_to[each+1] == shetou_to[0]:
                            she_life -= 1
                            conut = 0
                            shiwu = choice(shiwu_random)
                            shetou = [[4*she_size,3*she_size]]
                            
            # 重新赋值。不然一直加值                
            shetou_to = []
            
            #移动蛇身
            for each in shetou:
                    pygame.draw.rect(screen,REN,(each[0],each[1],she_size,she_size),0)
                    pygame.draw.rect(screen,GREEN,(shetou[0][0],shetou[0][1],she_size,she_size),0)
                    pygame.draw.rect(screen,BLACK,(shiwu[0],shiwu[1],she_size,she_size),0)

            conut += 1

        # 暂停时切换的图片
        elif suspend_picture:
            screen.blit(words_text,(width//2 -100, height // 2-50))
            conut = 0
            
        elif she_life <= 0:
            screen.blit(words_text_GAMEOVER,(width//2 -100, height // 2-50))
            screen.blit(wods_text_Reopen,(width // 2-180,height// 2 -150))
            # 停止背景音乐
            pygame.mixer.music.stop()
            
            # 停止全部音效
            pygame.mixer.stop()
            count_GAMEOVER += 1

            # 获取用户按键
            key_pressed = pygame.key.get_pressed()
            
            # 倒计时后退出游戏
            if count_GAMEOVER >= 1000:
                pygame.quit()
                sys.exit()
                
            # 倒计时前按下F1则重开
            elif key_pressed[K_F1]:
                main()
                
        pygame.display.flip()
        # 修改帧数的话会影响速度,默认60就好了
        clock.tick(60)
       
if __name__ == "__main__":
    main()
    
    

利用绘图模块整的,算是很完善了,
没有弄游戏开始前的界面,有大佬在的话可以帮改改
没有弄蛇头指定一个方向之后就不能回头,2个蛇身可以回头,3个蛇身就会判断为自杀撞蛇身死完
没有弄计分板一类的,
用现成的素材文字,中文会乱码,就英文代替
大小跟蛇身大小可改,不过结束界面跟暂停界面的文字尺寸应该还是居中的吧,没弄过大一点的游戏尺寸


游戏规则
空格暂停,
生命3条
撞墙死完,
撞自己死亡
吃到10蛇身加速
吃到20蛇身加速
吃到30蛇身加速【可以自己改。代码哪里注释了】
3条命死亡后可以按F1重来,
若是死亡后没按F1,等待一段时间则自动关闭游戏




害。折腾了好几天。掉头发,刚学完基础,日子还长着,
若是代码还有可以完善或者好的逻辑流程,欢迎大佬指出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-11-24 18:53:07 | 显示全部楼层
忘了上素材了

bgm.zip

132.04 KB, 下载次数: 7

BGM

bgm.zip

1.48 MB, 下载次数: 4

BGM

font.zip

38.21 KB, 下载次数: 4

bgm.zip

1.48 MB, 下载次数: 2

BGM

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 22:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表