28分钟完成一款Python游戏,《客服戏翻总裁牌》

这篇博客介绍了如何使用Python的pygame库开发一个简单的年会抽奖游戏。游戏背景设定为寻找隐藏的总裁头像,抽中即有机会赢得大奖。作者详细讲解了从创建游戏背景、设置卡片布局、实现卡片点击检测到翻转牌面的过程,并加入了随机中奖功能,使得游戏更具趣味性。最后,文章提供了完整的代码示例。
摘要由CSDN通过智能技术生成

游戏背景

本篇博客创意来源:CSDN 新星计划 Python 赛道群
本游戏开发难度:入门级
游戏试用场景:年会抽奖少儿编程
游戏需求描述:随机生成一定数量的格子,然后埋入总裁头像,抽中总裁奖励奥迪一辆

准备素材

没错,CSDN 总裁和副总裁,请把专业团队打在评论区。

稍后游戏中,我们将使用二者头像,制作一款充满金钱味道的游戏。

游戏使用的 Python 框架是 pygame,该库小巧轻便,非常好使。

制作游戏背景

为了让游戏充满 金钱 味道,我特意制作了一个游戏背景图片。接下来就使用 pygame 实现一下吧。

通过 pygame.image.load 加载背景图,如果背景图尺寸不合适,可以通过 pygame.transform.scale 对素材进行缩放。

import pygame
import sys
from pygame.locals import *


class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((900, 600))
        pygame.display.set_caption("总裁翻牌")

    def set_bg(self):
        bg = pygame.image.load("images/bg.png")
        # width, height = bg.get_size()
        # 素材缩小
        # pygame.transform.scale(bg,(width,height))
        self.screen.blit(bg, (0, 0))

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

            self.set_bg()
            pygame.display.update()


if __name__ == '__main__':
    g = Game()
    g.run()

缩放这部分可以学习如下内容:

# 快速缩放,size 相同,缩小后会增大像素密度
pygame.transform.scale()

# 平滑缩放,size 会变化,像素密度比较平均
pygame.transform.smoothscale()

运行 Python 代码,一张充满金钱味道的图片展现在了眼前。

零基础学python要多久 python自学行吗 免费python全套教程

既然游戏设置了 900x600 大小,下面需要进行简单的计算,在此游戏窗口内可以放置多少总裁牌子。

为了让大家看的更加清晰,制作一张说明图,如下所示,除了各个方格之间的距离,注意下图各个方格的左上角坐标。

零基础学python要多久 python自学行吗 免费python全套教程
直接使用硬编码的办法,实现对方格渲染的计算,下述代码用到了 pygame 中的精灵类,Card 类继承自该类。

import pygame
import sys
from pygame.locals import *


class Card(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.image = pygame.image.load("images/card.png")
        width, height = self.image.get_size()
        self.rect = (x, y, width, height)


class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((900, 600))
        pygame.display.set_caption("总裁翻牌")
        self.clock = pygame.time.Clock()
        self.start_point = (40, 45)

    def set_bg(self):
        bg = pygame.image.load("images/bg.png")
        # width, height = bg.get_size()
        # 素材缩小
        # pygame.transform.scale(bg,(width,height))
        self.screen.blit(bg, (0, 0))

    # 绘制牌子
    def set_card(self):

        for num in range(7 * 4):
            if num // 7 == 0:
                x = num * 120 + 40
                y = 45
            elif num // 7 == 1:
                x = (num - 7) * 120 + 40
                y = 175
            elif num // 7 == 2:
                x = (num - 7 * 2) * 120 + 40
                y = 305
            elif num // 7 == 3:
                x = (num - 7 * 3) * 120 + 40
                y = 435
            card = Card(x, y)
            self.screen.blit(card.image, card.rect)

    def run(self):
        x = 40
        y = 45
        while True:
            self.clock.tick(60)
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()

            self.set_bg()
            self.set_card()

            pygame.display.update()


if __name__ == '__main__':
    g = Game()
    g.run()

代码运行得到如下,卡片使用铜钱图片即可,素材提前进行了裁剪。
零基础学python要多久 python自学行吗 免费python全套教程

卡片点击事件

下面要实现的一个重要操作,鼠标可点击卡片区域。

基于上文的代码,进行了一点点的封装,具体实现如下:

import pygame
import sys
from pygame.locals import *


class Card(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.image = pygame.image.load("images/card.png")
        width, height = self.image.get_size()
        self.rect = (x, y, width, height)


class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((900, 600))
        pygame.display.set_caption("总裁翻牌")
        self.clock = pygame.time.Clock()

        self.card_nums = 28
        self.points = self.all_point()
        
	# 封装坐标计算函数
    def all_point(self):
        points = []
        for num in range(self.card_nums):
            if num // 7 == 0:
                x = num * 120 + 40
                y = 45
            elif num // 7 == 1:
                x = (num - 7) * 120 + 40
                y = 175
            elif num // 7 == 2:
                x = (num - 7 * 2) * 120 + 40
                y = 305
            elif num // 7 == 3:
                x = (num - 7 * 3) * 120 + 40
                y = 435
            points.append((x, y))
        return points

    def set_bg(self):
        bg = pygame.image.load("images/bg.png")
        # width, height = bg.get_size()
        # 素材缩小
        # pygame.transform.scale(bg,(width,height))
        self.screen.blit(bg, (0, 0))

    # 绘制牌子
    def set_card(self):

        for num in self.points:
            x, y = num
            card = Card(x, y)
            self.screen.blit(card.image, card.rect)

    # 计算鼠标点击卡片
    def mouse_card(self, mosx, mosy):
        for x, y in self.points:

            if (mosx >= x and mosx <= (x + 100)) and (mosy >= y and mosy <= (y + 100)):
                print("点了")

    def run(self):

        while True:
            self.clock.tick(60)
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()

                if event.type == MOUSEBUTTONDOWN:
                    mosx, mosy = event.pos
                    self.mouse_card(mosx, mosy)

            self.set_bg()
            self.set_card()

            pygame.display.update()

if __name__ == '__main__':
    g = Game()
    g.run()

此时当你点击任意卡片的时候,会提示是否被点中,同时将坐标生成函数进行了封装与提炼。

 def all_point(self):
        points = []
        for num in range(self.card_nums):
            if num // 7 == 0:
                x = num * 120 + 40
                y = 45
            elif num // 7 == 1:
                x = (num - 7) * 120 + 40
                y = 175
            elif num // 7 == 2:
                x = (num - 7 * 2) * 120 + 40
                y = 305
            elif num // 7 == 3:
                x = (num - 7 * 3) * 120 + 40
                y = 435
            points.append((x, y))
        return points

只获取被点中还不可以,还需要进行翻牌,这步操作需要使用 Python 中的 enumerate 函数,循环的同时获取序号。

   # 计算鼠标点击卡片
    def mouse_card(self, mosx, mosy):
        for i, (x, y) in enumerate(self.points):

            if (mosx >= x and mosx <= (x + 100)) and (mosy >= y and mosy <= (y + 100)):
                print("翻牌,点到卡片序号为", i)

零基础学python要多久 python自学行吗 免费python全套教程

翻总裁的牌

上文实现的是翻牌触发,下面实现牌面的转换。此时用到的依旧是对卡片顺序的验证,修改逻辑代码如下,只展示有变化部分代码。

import pygame
import sys
from pygame.locals import *


class Card(pygame.sprite.Sprite):
    def __init__(self, x, y, card_state):
        self.image = pygame.image.load("images/card.png")
        width, height = self.image.get_size()
        self.rect = (x, y, width, height)
        # 切换卡片牌面
        self.card_state = card_state

    def update(self):
        # 当牌面为 2 时显示哭脸
        if self.card_state == 2:
            self.image = pygame.image.load("images/cry.png")


class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((900, 600))
        pygame.display.set_caption("总裁翻牌")
        self.clock = pygame.time.Clock()

        self.card_nums = 28
        self.points = self.all_point()

        # 点击卡片记录数组
        self.click_list = []

    def set_bg(self):
        bg = pygame.image.load("images/bg.png")
        # width, height = bg.get_size()
        # 素材缩小
        # pygame.transform.scale(bg,(width,height))
        self.screen.blit(bg, (0, 0))

    # 绘制牌子
    def set_card(self):
        for i, num in enumerate(self.points):
            x, y = num
            card_state = 1
            # 卡片是否被点击
            if i in self.click_list:
                card_state = 2

            card = Card(x, y, card_state)
            card.update()
            self.screen.blit(card.image, card.rect)

    # 计算鼠标点击卡片
    def mouse_card(self, mosx, mosy):
        for i, (x, y) in enumerate(self.points):
            if (mosx >= x and mosx <= (x + 100)) and (mosy >= y and mosy <= (y + 100)):
                print("翻牌,点到卡片序号为", i)
                self.click_list.append(i)

运行代码得到如下效果,点一个哭一个。

零基础学python要多久 python自学行吗 免费python全套教程

翻开 CSDN 总裁之牌

游戏已经到了最后一步,下面可以实现抽总裁卡,Card 类增加几个状态,即可实现。

    def update(self):
        # 当牌面为 2 时显示哭脸
        if self.card_state == 2:
            self.image = pygame.image.load("images/cry.png")

        if self.card_state == 3:
            self.image = pygame.image.load("images/fuzong.png")
            self.image = pygame.transform.scale(self.image, (100, 100))

        if self.card_state == 4:
            self.image = pygame.image.load("images/zong.jpg")
            self.image = pygame.transform.scale(self.image, (100, 100))

为了游戏的趣味性,加入随机效果,使用 numpy 搞定。

 # 随机生成数组,中奖为1,不中奖为0
        self.win_list = list(np.random.randint(0, 3, 28))
        print(self.win_list)

最终的游戏代码为:

import pygame
import sys
from pygame.locals import *
import numpy as np


class Card(pygame.sprite.Sprite):
    def __init__(self, x, y, card_state):
        self.image = pygame.image.load("images/card.png")
        width, height = self.image.get_size()
        self.rect = (x, y, width, height)
        # 切换卡片牌面
        self.card_state = card_state

    def update(self):
        # 当牌面为 2 时显示哭脸
        if self.card_state == 2:
            self.image = pygame.image.load("images/cry.png")

        if self.card_state == 3:
            self.image = pygame.image.load("images/fuzong.png")
            self.image = pygame.transform.scale(self.image, (100, 100))

        if self.card_state == 4:
            self.image = pygame.image.load("images/zong.jpg")
            self.image = pygame.transform.scale(self.image, (100, 100))


class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((900, 600))
        pygame.display.set_caption("总裁翻牌")
        self.clock = pygame.time.Clock()

        self.card_nums = 28
        self.points = self.all_point()

        # 点击卡片记录数组
        self.click_list = []

        # 随机生成数组,中奖为1,不中奖为0
        self.win_list = list(np.random.randint(0, 3, 28))

    def all_point(self):
        pass

    def set_bg(self):
        bg = pygame.image.load("images/bg.png")
        # width, height = bg.get_size()
        # 素材缩小
        # pygame.transform.scale(bg,(width,height))
        self.screen.blit(bg, (0, 0))

    # 绘制牌子
    def set_card(self):
        for i, num in enumerate(self.points):
            x, y = num
            card_state = 1
            # 卡片是否被点击
            if i in self.click_list:
                card_state = 2
            # 卡片是否被点击
            if i in self.click_list and self.win_list[i] == 1:
                card_state = 3
            # 卡片是否被点击
            if i in self.click_list and self.win_list[i] == 2:
                card_state = 4

            card = Card(x, y, card_state)
            card.update()
            self.screen.blit(card.image, card.rect)

    # 计算鼠标点击卡片
    def mouse_card(self, mosx, mosy):
        for i, (x, y) in enumerate(self.points):
            if (mosx >= x and mosx <= (x + 100)) and (mosy >= y and mosy <= (y + 100)):
                print("翻牌,点到卡片序号为", i)
                self.click_list.append(i)

    def run(self):

        while True:
            self.clock.tick(60)
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()

                if event.type == MOUSEBUTTONDOWN:
                    mosx, mosy = event.pos
                    self.mouse_card(mosx, mosy)

            self.set_bg()
            self.set_card()

            pygame.display.update()


if __name__ == '__main__':
    g = Game()
    g.run()

零基础学python要多久 python自学行吗 免费python全套教程
完整代码下载:下载地址

上一篇博客中奖ID如下:

恭喜 Xiao_Chen001,抓紧联系擦姐吧。

零基础学python要多久 python自学行吗 免费python全套教程

抽奖环节

只要评论数过 50
随机抽取一名幸运读者
奖励 39.9 元爬虫 100 例专栏 1 折购买券一份,只需 3.99 元

今天是持续写作的第 158 / 200 天。
求点赞、求评论、求收藏。

评论 126
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想橡皮擦

如有帮助,来瓶可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值