python——pygame制作恶搞舍友小游戏

一、实验目的

以经典的飞机大战代码为参考,实现食物在舍友之间的单向传递,共有三次失误机会,机会全部用完后则视为游戏失败。

二、游戏操作

舍友一:A:向左移动,D:向右移动

舍友二:左方向键:向左移动,右方向键:向右移动

空格键:向对面的舍友发射食物

三、游戏成品

python——pygame制作恶搞舍友小游戏_第1张图片

 python——pygame制作恶搞舍友小游戏_第2张图片

python——pygame制作恶搞舍友小游戏_第3张图片

四、游戏代码

import sys
import pygame
import time
import setting
pygame.init()


#主窗口
scene_image = pygame.display.set_mode((800,600))
scene_rect = scene_image.get_rect()
scene_image.fill(setting.color_1)

#标题栏
pygame.display.set_caption("双人成行")

zhangjin_image = pygame.image.load('zhangjin.bmp')
zhangjin_image = pygame.transform.scale(zhangjin_image,(90,80))
zhangjin_image = pygame.transform.rotate(zhangjin_image,90)
zhangjin_rect = zhangjin_image.get_rect()
zhangjin_rect.midtop = scene_rect.midtop
zhangjin_rect.y = scene_rect.y+20

liyi_image = pygame.image.load('liyi.bmp')
liyi_image = pygame.transform.scale(liyi_image,(90,80))  #更改liyi大小
liyi_rect = liyi_image.get_rect()
liyi_rect.midbottom = scene_rect.midbottom
liyi_rect.bottom = scene_rect.bottom -20

liyi_moving_left = False
liyi_moving_right = False

zhangjin_moving_left = False
zhangjin_moving_right = False

#食物
foods = pygame.sprite.Group()
# foods = []
lives_isleft = 0
#文字
button_rect = pygame.Rect(0,0,200,50)
button_rect.center = scene_rect.center
play_font = pygame.font.SysFont(None,48)
play_image = play_font.render("play",True,setting.color_2,setting.color_3)
play_rect = play_image.get_rect()
play_rect.center = button_rect.center


#统计信息
score = 0
food_points = 1
score_str = str(score)
score_font = pygame.font.SysFont(None,36)
score_image = score_font.render(f"recent score:{score_str}",True,setting.color_3,setting.color_1)
score_rect = score_image.get_rect()
score_rect.right = scene_rect.right - 20
score_rect.top = 20
scene_image.blit(score_image,score_rect)

high_score = 0
high_score_str = str(high_score)
high_score_font = pygame.font.SysFont(None,36)
high_score_image = high_score_font.render(f"highest score:{high_score_str}",True,setting.color_3,setting.color_1)
high_score_rect = high_score_image.get_rect()
high_score_rect.midtop =score_rect.midbottom
high_score_rect.right = score_rect.right
scene_image.blit(high_score_image,high_score_rect)
pygame.display.flip()

#剩余可不吃
zhuzi_group = pygame.sprite.Group()
for zhuzi_number in range(setting.zhuzi_limit - 1):
    zhuzi = pygame.sprite.Sprite()
    zhuzi.image = pygame.image.load('zhuzi.bmp')
    zhuzi.image = pygame.transform.scale(zhuzi.image, (45, 40))
    zhuzi.rect = zhuzi.image.get_rect()
    zhuzi.rect.x = 5+(zhuzi.rect.width + 5) * zhuzi_number
    zhuzi.rect.y = 5
    zhuzi_group.add(zhuzi)
zhuzi_group.draw(scene_image)

while True:

    pygame.mixer.music.play(-1)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                liyi_moving_left = True
            if event.key == pygame.K_RIGHT:
                liyi_moving_right = True
            if event.key == pygame.K_a:
                zhangjin_moving_left = True
            if event.key == pygame.K_d:
                zhangjin_moving_right = True
            if event.key == pygame.K_q:
                sys.exit()
            if event.key == pygame.K_SPACE:
                if len(foods) < setting.foods_number:
                    food = pygame.sprite.Sprite()
                    f = pygame.image.load('food.bmp')
                    f = pygame.transform.scale(f, (20, 20))
                    food.rect = f.get_rect()
                    food.image = f
                    food.rect.midbottom = liyi_rect.midtop
                    foods.add(food)
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                liyi_moving_left = False
            if event.key == pygame.K_RIGHT:
                liyi_moving_right = False
            if event.key == pygame.K_a:
                zhangjin_moving_left = False
            if event.key == pygame.K_d:
                zhangjin_moving_right = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            if button_rect.collidepoint(mouse_pos):
                lives_isleft = setting.zhuzi_limit
                pygame.mouse.set_visible(False)
                foods.empty()
    if lives_isleft > 0:
        if liyi_moving_left and liyi_rect.left > 0:
            liyi_rect.x -= setting.speed
        if liyi_moving_right and liyi_rect.right < scene_rect.right:
            liyi_rect.x += setting.speed
        if zhangjin_moving_left and zhangjin_moving_left > 0:
            zhangjin_rect.x -= setting.speed
        if zhangjin_moving_right and zhangjin_moving_right < scene_rect.right:
            zhangjin_rect.x += setting.speed

        zhangjin_sprite = pygame.sprite.Sprite()
        zhangjin_sprite.rect = zhangjin_rect
        zhangjin_sprite.image = zhangjin_image

        scene_image.fill(setting.color_1)
        scene_image.blit(zhangjin_image, zhangjin_rect)
        scene_image.blit(liyi_image, liyi_rect)


        # 张锦没吃上food
        for item in foods:
            item.rect.y -= setting.speed
            if item.rect.bottom < 0:
                lives_isleft -= 1
                foods.remove(item)
            scene_image.blit(food.image, item)
            if lives_isleft == 0:
                # time.sleep(0.5)
                liyi_rect.bottom = scene_rect.bottom - 20
                zhangjin_rect.y = scene_rect.y + 20
                foods.empty()
                # 张锦
                zhangjin_rect = zhangjin_image.get_rect()
                zhangjin_rect.midtop = scene_rect.midtop
                zhangjin_rect.y = scene_rect.y + 20

                # 李毅
                liyi_rect = liyi_image.get_rect()
                liyi_rect.midbottom = scene_rect.midbottom
                liyi_rect.bottom = scene_rect.bottom - 20

       #张锦和food碰撞
        if pygame.sprite.spritecollide(zhangjin_sprite,foods,True):
            score += 1
        if score > high_score:
            high_score = score
        # 统计信息
        score_str = str(score)
        score_font = pygame.font.SysFont(None, 36)
        score_image = score_font.render(f"recent score:{score_str}", True, setting.color_3, setting.color_1)
        score_rect = score_image.get_rect()
        score_rect.right = scene_rect.right - 20
        score_rect.top = 20
        scene_image.blit(score_image, score_rect)

        high_score_str = str(high_score)
        high_score_font = pygame.font.SysFont(None, 36)
        high_score_image = high_score_font.render(f"highest score:{high_score_str}", True, setting.color_3,
                                                  setting.color_1)
        high_score_rect = high_score_image.get_rect()
        high_score_rect.midtop = score_rect.midbottom
        high_score_rect.right = score_rect.right
        scene_image.blit(high_score_image, high_score_rect)
        pygame.display.flip()

        # 剩余可不吃
        zhuzi_group = pygame.sprite.Group()
        for zhuzi_number in range(lives_isleft - 1):
            zhuzi = pygame.sprite.Sprite()
            zhuzi.image = pygame.image.load('zhuzi.bmp')
            zhuzi.image = pygame.transform.scale(zhuzi.image, (45, 40))
            zhuzi.rect = zhuzi.image.get_rect()
            zhuzi.rect.x = 5 + (zhuzi.rect.width + 5) * zhuzi_number
            zhuzi.rect.y = 5
            zhuzi_group.add(zhuzi)
        zhuzi_group.draw(scene_image)

    else:
        pygame.draw.rect(scene_image,setting.color_4,button_rect)
        scene_image.blit(play_image,play_rect)
        pygame.mouse.set_visible(True)
        score = 0



    pygame.display.flip()
    time.sleep(setting.time)

 五、分段解析

1、实现长按方向键连续移动

liyi_moving_left = False
liyi_moving_right = False
zhangjin_moving_left = False
zhangjin_moving_right = False

while True:
        for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                liyi_moving_left = True
            if event.key == pygame.K_RIGHT:
                liyi_moving_right = True
            if event.key == pygame.K_a:
                zhangjin_moving_left = True
            if event.key == pygame.K_d:
                zhangjin_moving_right = True
            if event.key == pygame.K_q:
                sys.exit()
            if event.key == pygame.K_SPACE:
                if len(foods) < setting.foods_number:
                    food = pygame.sprite.Sprite()
                    f = pygame.image.load('food.bmp')
                    f = pygame.transform.scale(f, (20, 20))
                    food.rect = f.get_rect()
                    food.image = f
                    food.rect.midbottom = liyi_rect.midtop
                    foods.add(food)
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                liyi_moving_left = False
            if event.key == pygame.K_RIGHT:
                liyi_moving_right = False
            if event.key == pygame.K_a:
                zhangjin_moving_left = False
            if event.key == pygame.K_d:
                zhangjin_moving_right = False
                if liyi_moving_left and liyi_rect.left > 0:
            liyi_rect.x -= setting.speed
        if liyi_moving_right and liyi_rect.right < scene_rect.right:
            liyi_rect.x += setting.speed
        if zhangjin_moving_left and zhangjin_moving_left > 0:
            zhangjin_rect.x -= setting.speed
        if zhangjin_moving_right and zhangjin_moving_right < scene_rect.right:
            zhangjin_rect.x += setting.speed

 根据pygame中event.get()函数对键盘,鼠标等动作的捕捉,可以初步实现一令一动的目的。但是要实现连续移动,就要设置moving_right,moving_left两个阀门,当其为true的时候,x轴位置可以连续发生改变

2、按钮以及文本的显示实现

button_rect = pygame.Rect(0,0,200,50)
button_rect.center = scene_rect.center
play_font = pygame.font.SysFont(None,48)
play_image = play_font.render("play",True,setting.color_2,setting.color_3)
play_rect = play_image.get_rect()
play_rect.center = button_rect.center
#变量的赋值

pygame.draw.rect(scene_image,setting.color_4,button_rect)
scene_image.blit(play_image,play_rect)
#参数的调用

pygame中的文本是以image格式实现,rect规定了大小以及位置信息,image则代表了内容(对于文字来说就是文字颜色,背景色,文本内容等信息,对于图片来说就是图片地址)

3、鼠标的隐藏和出现

pygame.mouse.set_visible(False)

set_Visible函数中参数False代表鼠标消失,True代表鼠标出现

4、统计信息的实现方法

#统计信息
score = 0
food_points = 1
score_str = str(score)
score_font = pygame.font.SysFont(None,36)
score_image = score_font.render(f"recent score:{score_str}",True,setting.color_3,setting.color_1)
score_rect = score_image.get_rect()
score_rect.right = scene_rect.right - 20
score_rect.top = 20
scene_image.blit(score_image,score_rect)

high_score = 0
high_score_str = str(high_score)
high_score_font = pygame.font.SysFont(None,36)
high_score_image = high_score_font.render(f"highest score:{high_score_str}",True,setting.color_3,setting.color_1)
high_score_rect = high_score_image.get_rect()
high_score_rect.midtop =score_rect.midbottom
high_score_rect.right = score_rect.right
scene_image.blit(high_score_image,high_score_rect)
pygame.display.flip()


while true:
        #张锦和food碰撞
        if pygame.sprite.spritecollide(zhangjin_sprite,foods,True):
            score += 1
        if score > high_score:
            high_score = score
        # 统计信息
        score_str = str(score)
        score_font = pygame.font.SysFont(None, 36)
        score_image = score_font.render(f"recent score:{score_str}",True,setting.color_3, setting.color_1)
        score_rect = score_image.get_rect()
        score_rect.right = scene_rect.right - 20
        score_rect.top = 20
        scene_image.blit(score_image, score_rect)

        high_score_str = str(high_score)
        high_score_font = pygame.font.SysFont(None, 36)
        high_score_image = high_score_font.render(f"highest score:{high_score_str}",True, setting.color_3,setting.color_1)
        high_score_rect = high_score_image.get_rect()
        high_score_rect.midtop = score_rect.midbottom
        high_score_rect.right = score_rect.right
        scene_image.blit(high_score_image, high_score_rect)
        pygame.display.flip()

用image规定文本内容,用rect规定文本的出现坐标,当舍友头像与食物发生碰撞的时候,说明成功进食,所以score加1,当当前分数高于最高分时,将目前分数赋值给最高分,每次重新开始游戏前将score归零

5、当出现没有及时享用的食物到达边框

zhuzi_group = pygame.sprite.Group()
        for zhuzi_number in range(lives_isleft - 1):
            zhuzi = pygame.sprite.Sprite()
            zhuzi.image = pygame.image.load('zhuzi.bmp')
            zhuzi.image = pygame.transform.scale(zhuzi.image, (45, 40))
            zhuzi.rect = zhuzi.image.get_rect()
            zhuzi.rect.x = 5 + (zhuzi.rect.width + 5) * zhuzi_number
            zhuzi.rect.y = 5
            zhuzi_group.add(zhuzi)
        zhuzi_group.draw(scene_image)

左上角生命值减一(注:左上角生命+1为总生命值)

6、屏幕中最多出现十个食物

foods_number = 10

if event.key == pygame.K_SPACE:
    if len(foods) < foods_number:
        food = pygame.sprite.Sprite()
        f = pygame.image.load('food.bmp')
        f = pygame.transform.scale(f, (20, 20))
        food.rect = f.get_rect()
        food.image = f
        food.rect.midbottom = liyi_rect.midtop
        foods.add(food)

for item in foods:
    item.rect.y -= setting.speed
    if item.rect.bottom < 0:
        lives_isleft -= 1
        foods.remove(item)
    scene_image.blit(food.image, item)
    if lives_isleft == 0:
        # time.sleep(0.5)
        liyi_rect.bottom = scene_rect.bottom - 20
        zhangjin_rect.y = scene_rect.y + 20
        foods.empty()
        # 张锦
        zhangjin_rect = zhangjin_image.get_rect()
        zhangjin_rect.midtop = scene_rect.midtop
        zhangjin_rect.y = scene_rect.y + 20

        # 李毅
        liyi_rect = liyi_image.get_rect()
        liyi_rect.midbottom = scene_rect.midbottom
        liyi_rect.bottom = scene_rect.bottom - 20

食物最终有两种状态,当被舍友享用之后score加一,反之,到达边界后,生命值减一,并且将其移出食物所在列表,保持屏幕上最多有十个食物的规定。如果生命值耗费完,将页面恢复为最初的样子,且出现可重新开始游戏的字样。

完结撒花!

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