【Python】【Pygame】游戏:抓球

来源:《Python编程 从入门到实践》13-5/14-1、14-2/

我感觉这个题目继续学习还可以优化,是一个不错的小游戏。等我学了记分再来继续改进。

抓球(13-5)

碗在底部左右移动,顶端随机掉落小球(有三次抓不住的机会),失败以后画面静止。
在这里插入图片描述

catch_ball.py

import pygame
from setting import Settings
import functions as f
from bowl import Bowl
from ball import Ball

def catch_ball():
    pygame.init()

    sets = Settings()

    screen = pygame.display.set_mode((sets.bg_width, sets.bg_height))
    pygame.display.set_caption('GAME: Catch Ball')

    bowl = Bowl(screen=screen, sets=sets)
    ball = Ball(screen=screen, sets=sets)

    while True:
        f.check_event(bowl=bowl) # 检测屏幕是否退出

        if sets.gameover == False :
            bowl.move_bowl(sets=sets) # 移动碗
            ball.drop_ball(sets=sets) # 掉落球
            f.update_ball(ball=ball, bowl=bowl, sets=sets)

        f.update_screen(screen=screen, sets=sets, bowl=bowl, ball=ball) #更新屏幕


        pygame.display.flip()

catch_ball()

setting.py

import pygame

class Settings():
    def __init__(self):
        self.gameover = False # 游戏结束标志
        self.catch_number = 0 # 接住的球数目

        self.bg_width = 800
        self.bg_height = 600
        self.bg_color = (255, 255, 255)

        self.ball_image = pygame.image.load('weixiao.bmp')
        self.ball_speed = 1
        self.ball_number = 3 # 球的数量

        self.bowl_image = pygame.image.load('wan.bmp')
        self.bowl_speed = 10

ball.py

import pygame
from pygame.sprite import Sprite
from random import randint

class Ball(Sprite):
    def __init__(self, sets, screen):
        super(Ball, self).__init__()
        self.image = sets.ball_image
        self.rect = self.image.get_rect()
        self.screen = screen
        self.screen_rect = self.screen.get_rect()
        self.number = sets.ball_number

        self.rect_width = self.rect.width
        self.rect_height = self.rect.height

        # 初始位置
        distant_x = randint(-4, 4) * self.rect_width
        self.rect.x = self.screen_rect.centerx + distant_x
        self.rect.y = 0

    def print_ball(self):
        self.screen.blit(self.image, self.rect)

    def drop_ball(self, sets):
        self.rect.y += sets.ball_speed

    def change_ball(self, sets):
        distant_x = randint(-4, 4) * self.rect_width
        self.rect.x = self.screen_rect.centerx + distant_x
        self.rect.y = 0

bowl.py

import pygame

class Bowl:
    def __init__(self, sets, screen):
        self.image = sets.bowl_image
        self.rect = self.image.get_rect()
        self.screen = screen
        self.moving = 0

        # 初始位置,屏幕底部中间
        self.rect.centerx = sets.bg_width / 2
        self.rect.centery = sets.bg_height - self.rect.height / 2

    def print_bowl(self):
        self.screen.blit(self.image, self.rect)

    def move_bowl(self, sets):
        if self.moving != 0 :
            if self.moving == 1 and self.rect.right < sets.bg_width:
                self.rect.centerx += sets.bowl_speed
            elif self.moving == -1 and self.rect.left > 0:
                self.rect.centerx -= sets.bowl_speed


functions.py

import sys
import pygame

# 检测屏幕退出
def check_event(bowl):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                sys.exit()
            if event.key == pygame.K_LEFT:
                bowl.moving = -1
            elif event.key == pygame.K_RIGHT:
                bowl.moving = 1
        elif event.type == pygame.KEYUP:
            bowl.moving = 0

# 更新屏幕
def update_screen(screen, sets, bowl, ball):
    screen.fill(sets.bg_color)
    bowl.print_bowl()
    ball.print_ball()

# 更新球
def update_ball(ball, bowl, sets):
    if pygame.sprite.collide_rect(ball ,bowl): # 碗接住了球
        ball.change_ball(sets)
        sets.catch_number += 1
        #print(sets.catch_number)
    if check_ball_edge(ball, sets): # 球到底了
        if ball.number > 0:
            ball.number -= 1
            #print(ball.number)
            ball.change_ball(sets)
        else:
            sets.gameover = True

def check_ball_edge(ball, sets):
    if ball.rect.bottom >= sets.bg_height:
        return True
    else:
        return False

结果

在这里插入图片描述

改进1(14-1)

开始显示按钮(按下p游戏开始),游戏失败以后结束游戏并且重新显示p,再按一次重新开始。
只重写改进模块。

catch_ball.py

import pygame
from setting import Settings
import functions as f
from bowl import Bowl
from ball import Ball
from button import Button

def catch_ball():
    pygame.init()

    sets = Settings()

    screen = pygame.display.set_mode((sets.bg_width, sets.bg_height))
    pygame.display.set_caption('GAME: Catch Ball')

    bowl = Bowl(screen=screen, sets=sets)
    ball = Ball(screen=screen, sets=sets)
    star_button = Button(screen=screen, sets=sets, test="Star(P)")

    while True:
        f.check_event(bowl=bowl, sets=sets, ball=ball) # 检测屏幕是否退出

        if sets.gameover == False :
            bowl.move_bowl(sets=sets) # 移动碗
            ball.drop_ball(sets=sets) # 掉落球
            f.update_ball(ball=ball, bowl=bowl, sets=sets)

        # 更新屏幕
        f.update_screen(screen=screen, sets=sets, bowl=bowl, ball=ball, button=star_button)

        pygame.display.flip()

catch_ball()

setting.py

import pygame

class Settings():
    def __init__(self):
        self.gameover = True # 游戏结束标志
        self.catch_number = 0 # 接住的球数目

        self.bg_width = 800
        self.bg_height = 600
        self.bg_color = (255, 255, 255)

        self.ball_image = pygame.image.load('weixiao.bmp')
        self.ball_speed = 1
        self.ball_number = 3 # 球的数量

        self.bowl_image = pygame.image.load('wan.bmp')
        self.bowl_speed = 10

        self.button_width = 200
        self.button_height = 50
        self.button_bg_color = (0, 0, 0)
        self.button_word_color = (200, 0, 0)

functions.py

import sys
import pygame

# 检测屏幕退出
def check_event(bowl, sets, ball):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                sys.exit()
            if event.key == pygame.K_LEFT:
                bowl.moving = -1
            if event.key == pygame.K_RIGHT:
                bowl.moving = 1
            if event.key == pygame.K_p: # 按下P开始
                reset_game(sets, ball) # 重置游戏
        elif event.type == pygame.KEYUP:
            bowl.moving = 0

def reset_game(sets, ball):
    sets.gameover = False
    ball.number = 3

# 更新屏幕
def update_screen(screen, sets, bowl, ball, button):
    screen.fill(sets.bg_color)
    bowl.print_bowl()
    ball.print_ball()
    if sets.gameover == True:
        button.draw_button()

# 更新球
def update_ball(ball, bowl, sets):
    if pygame.sprite.collide_rect(ball ,bowl): # 碗接住了球
        ball.change_ball(sets)
        sets.catch_number += 1
        #print(sets.catch_number)
    if check_ball_edge(ball, sets): # 球到底了
        if ball.number > 0:
            ball.number -= 1
            #print(ball.number)
            ball.change_ball(sets)
        else:
            sets.gameover = True

def check_ball_edge(ball, sets):
    if ball.rect.bottom >= sets.bg_height:
        return True
    else:
        return False

button.py

这个是新加的

import pygame.font

class Button():
    def  __init__(self, screen, sets, test):
        self.screen = screen
        self.screen_rect = self.screen.get_rect()
        self.sets = sets
        self.test = test # 文字

        self.width = self.sets.button_width
        self.height = self.sets.button_height
        self.button_bg_color = self.sets.button_bg_color
        self.button_word_color = self.sets.button_word_color
        self.font = pygame.font.SysFont(None, 48)

        # rect对象
        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.center = self.screen_rect.center

        self.prep_test(test) # 建立按钮标签,只需要建立一次

    # 建立按钮
    def prep_test(self, test):
        # 将文本转化为图像
        self.test_image = self.font.render(self.test, True, self.button_word_color,self.button_bg_color)
        self.test_image_rect = self.test_image.get_rect()
        self.test_image_rect.center = self.rect.center

    # 绘制按钮
    def draw_button(self):
        self.screen.fill(self.button_bg_color, self.rect)
        self.screen.blit(self.test_image, self.test_image_rect)

结果

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值