【新星计划python赛道】pygame让你一步步实现翻牌游戏(金币旋转、大头贴等),打造更有趣的新星之旅

最近参加了新星计划,玩一下,然后我们的导师@梦想橡皮擦就提到,看能不能把我们赛道的博主的头像整成一个消消乐的翻牌游戏,我觉得挺好玩的,所以也就借这个机会试一把。
效果演示一把:
在这里插入图片描述

嘻嘻,有兴趣的朋友欢迎往下看。附上源码的哦。

码字不易,且行且珍惜,感谢支持!

一、先实现m*n的游戏框框

(一)核心函数

def divide(start,end,m,n):
    bglist = []
    y = end[1]-start[1]
    x = end[0]-start[0]
    width = int(x/m)
    height = int(y/n)
    i=0
    j=0
    while i<m:
        while j<n:
            bglist.append((start[0]+i*width,start[1]+j*height,width-1,height-1))
            j += 1
        i += 1
        j = 0
    return bglist

start:开始坐标
end:结束坐标
m,n:表示m行n列

(二)完整代码

import pygame,sys

def divide(start,end,m,n):
    bglist = []
    y = end[1]-start[1]
    x = end[0]-start[0]
    width = int(x/m)
    height = int(y/n)
    i=0
    j=0
    while i<m:
        while j<n:
            bglist.append((start[0]+i*width,start[1]+j*height,width-1,height-1))
            j += 1
        i += 1
        j = 0

    return bglist


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((800,500))
    pygame.display.set_caption("豆腐块也有春天V1.0")
    clock = pygame.time.Clock()

    bglist = divide((0,0),(800,500),10,10)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or event.type == pygame.K_F1:
                pygame.quit()
                sys.exit()
        screen.fill((0,0,0))
        for bg in bglist:
            pygame.draw.rect(screen,(255,0,0),bg)
        clock.tick(30)
        pygame.display.flip()

(三)运行效果

初始化一个800X600的窗口,然后分成10X10的格子。
起点(0,0),终点(800,600)
在这里插入图片描述
初始化一个500X500的窗口,然后分成10X10的格子。
起点(0,0),终点(800,600)
在这里插入图片描述
初始化一个800X600的窗口,然后分成10X10的格子。
起点(100,100),终点(700,500)
在这里插入图片描述

二、相关资源准备

(一)初始化first_image的头像资源

def init_image():
    path = './user1/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)

    bglist = []
    for file in files:
        picture = pygame.transform.scale(pygame.image.load(file), (50, 50))
        dSurface = picture.convert()
        # dSurface = pygame.image.load(file).convert()
        bglist.append(dSurface)
        # bglist.append(pygame.image.load(file).convert_alpha())

    return bglist

(二)初始化金币的图片资源

def init_score():
    path = './score/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)
    bglist = []
    for file in files:
        bglist.append(pygame.image.load(file).convert_alpha())
    return bglist

三、实现豆腐块part类

(一)初始化豆腐块的变量

    def __init__(self,bglist,scorelist,rect,screen,x,y,screen1):
        self.rect = rect  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1     # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 1   # 金币旋转的循环次数
        self.run_flag = 0   # 记录显示金币的当前页面
        # self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage_list = bglist     # 1、显示初始的头像图
        self.firstimage = random.choice(bglist)
        self.scorelist = scorelist # 2、显示金币的旋转图
        self.screen = screen   # 显示屏幕
        self.screen1 = screen1
        self.font1 = pygame.font.Font(r'C:\Windows\Fonts\simsun.ttc', 32)

        self.resx = x+20
        self.resy = y+10
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)

(二)金币旋转函数实现

    def score_run(self):
        if self.times>0:
            screen.blit(self.scorelist[self.run_flag], self.rect)
            self.run_flag += 1
            if self.run_flag==7:
                self.run_flag=0
                self.times -= 1
        else:
            self.flag = 3

在这里插入图片描述

完整的实现过程可以参看我的另一篇文章《pygame实现简单的金币旋转效果,不到50行代码哦!》

(三)重置函数reset实现

    def reset(self):
        self.rect = (random.randint(100,400),random.randint(100,400),50,50)  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1  # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 2  # 金币旋转的循环次数
        self.run_flag = 0  # 记录显示金币的当前页面
        self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage = random.choice(bglist)
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)

(四)金币移动到得分函数实现

    def move(self):
        if abs(self.posx-self.resx)>=10 or abs(self.posx-self.resx)>=10:
            self.posx += self.r * math.cos(self.angle)
            self.posy +=  self.r * math.sin(self.angle)
            # self.xpos, self.ypos = (self.xpos + section * cosa, self.ypos - section * sina)
            self.newRect = self.scorelist[5].get_rect(center=(self.posx, self.posy))
            self.screen1.blit(self.scorelist[5], self.newRect)
        else:
            self.flag = 4

(五)主体run函数实现

    def run(self):
        if self.flag==1:
            self.screen.blit(self.firstimage,self.rect)
        elif self.flag==2:
            self.score_run()
        elif self.flag==3:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))
            self.move()
        elif self.flag==5:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))

在这里插入图片描述

完整的实现过程可以参看我的另一篇文章《【新星计划python赛道】pygame实现翻牌游戏的豆腐块,豆腐块也有春天!》

(六)完整的part类代码

class Part:
    def __init__(self,bglist,scorelist,rect,screen,x,y,screen1):
        self.rect = rect  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1     # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 1   # 金币旋转的循环次数
        self.run_flag = 0   # 记录显示金币的当前页面
        # self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage_list = bglist     # 1、显示初始的头像图
        self.firstimage = random.choice(bglist)
        self.scorelist = scorelist # 2、显示金币的旋转图
        self.screen = screen   # 显示屏幕
        self.screen1 = screen1
        self.font1 = pygame.font.Font(r'C:\Windows\Fonts\simsun.ttc', 32)

        self.resx = x+20
        self.resy = y+10
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)

    def move(self):
        if abs(self.posx-self.resx)>=10 or abs(self.posx-self.resx)>=10:
            self.posx += self.r * math.cos(self.angle)
            self.posy +=  self.r * math.sin(self.angle)
            # self.xpos, self.ypos = (self.xpos + section * cosa, self.ypos - section * sina)
            self.newRect = self.scorelist[5].get_rect(center=(self.posx, self.posy))
            self.screen1.blit(self.scorelist[5], self.newRect)
        else:
            self.flag = 4


    def run(self):
        if self.flag==1:
            self.screen.blit(self.firstimage,self.rect)
        elif self.flag==2:
            self.score_run()
        elif self.flag==3:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))
            self.move()
        elif self.flag==5:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))
        # elif self.flag==4:
        #     self.reset()
            # if random.randint(0,10)==1:
            #     self.reset()


    def score_run(self):
        if self.times>0:
            screen.blit(self.scorelist[self.run_flag], self.rect)
            self.run_flag += 1
            if self.run_flag==7:
                self.run_flag=0
                self.times -= 1
        else:
            self.flag = 3

    def getrect(self):
        return pygame.Rect(self.rect)

    def reset(self):
        self.rect = (random.randint(100,400),random.randint(100,400),50,50)  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1  # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 2  # 金币旋转的循环次数
        self.run_flag = 0  # 记录显示金币的当前页面
        self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage = random.choice(bglist)
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)

四、主体流程实现

(一)初始化pygame窗口

    pygame.init()
    screen = pygame.display.set_mode((700,600))
    # 显示金币皮肤
    screen1 = pygame.Surface((700,600))
    pygame.display.set_caption("豆腐块也有春天V1.0")

(二)初始化资源信息

    # 初始化矩形框的信息
    rectlist = divide((100,50),(600,550),10,10)
    # 初始化图像信息
    bglist = init_image()
    # 初始化金币信息
    score_list = init_score()
    # 初始化得分位置信息及得分初始化为0分
    dirx=400
    diry=20
    total = 0

(三)初始化豆腐块

    # 存储豆腐块列表
    partlist = []
    for bg in rectlist:
        partlist.append(Part(bglist,score_list,bg,screen,dirx,diry,screen1))

(四)循环主体函数

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or event.type == pygame.K_F1:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                pos = x, y = pygame.mouse.get_pos()  # 获取鼠标位置,鼠标就是需要打击的目标
                for p1 in partlist:
                    if p1.getrect().collidepoint(pos):
                        if p1.flag == 1:
                            p1.flag = 2
                            break
        screen.fill((0,0,0))
        screen1.fill((128, 128, 128))
        screen1.set_colorkey((128, 128, 128))
        for p1 in partlist:
            p1.run()
            if p1.flag==4:
                total += p1.score
                p1.flag = 5
        display(screen,total,dirx,diry)
        screen.blit(screen1,(0,0))
        # for bg in rectlist:
        #     pygame.draw.rect(screen,(255,0,0),bg)
        clock.tick(30)
        pygame.display.flip()

五、完整代码

代码不易,但是还是分享给大家,请大家多多支持!!!

import pygame,sys
import random
import os
import math

class Part:
    def __init__(self,bglist,scorelist,rect,screen,x,y,screen1):
        self.rect = rect  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1     # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 1   # 金币旋转的循环次数
        self.run_flag = 0   # 记录显示金币的当前页面
        # self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage_list = bglist     # 1、显示初始的头像图
        self.firstimage = random.choice(bglist)
        self.scorelist = scorelist # 2、显示金币的旋转图
        self.screen = screen   # 显示屏幕
        self.screen1 = screen1
        self.font1 = pygame.font.Font(r'C:\Windows\Fonts\simsun.ttc', 32)

        self.resx = x+20
        self.resy = y+10
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)

    def move(self):
        if abs(self.posx-self.resx)>=10 or abs(self.posx-self.resx)>=10:
            self.posx += self.r * math.cos(self.angle)
            self.posy +=  self.r * math.sin(self.angle)
            # self.xpos, self.ypos = (self.xpos + section * cosa, self.ypos - section * sina)
            self.newRect = self.scorelist[5].get_rect(center=(self.posx, self.posy))
            self.screen1.blit(self.scorelist[5], self.newRect)
        else:
            self.flag = 4


    def run(self):
        if self.flag==1:
            self.screen.blit(self.firstimage,self.rect)
        elif self.flag==2:
            self.score_run()
        elif self.flag==3:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))
            self.move()
        elif self.flag==5:
            text1 = self.font1.render('%s' % self.score, True, (251,174,63))
            screen.blit(text1, (self.rect[0]+self.rect[2]/2-10,self.rect[1]+self.rect[3]/2-10))
        # elif self.flag==4:
        #     self.reset()
            # if random.randint(0,10)==1:
            #     self.reset()


    def score_run(self):
        if self.times>0:
            screen.blit(self.scorelist[self.run_flag], self.rect)
            self.run_flag += 1
            if self.run_flag==7:
                self.run_flag=0
                self.times -= 1
        else:
            self.flag = 3

    def getrect(self):
        return pygame.Rect(self.rect)

    def reset(self):
        self.rect = (random.randint(100,400),random.randint(100,400),50,50)  # 用于记录豆腐块的矩形框大小及显示位置(posx,posy,width、height)
        self.flag = 1  # 1、显示初始的头像图;2、显示金币的旋转图;3、显示最终的数字图,并将金币移到结果区
        self.score = random.randint(1, 10)  # 金钱
        self.times = 2  # 金币旋转的循环次数
        self.run_flag = 0  # 记录显示金币的当前页面
        self.pos = None  # 金币需要移动的位置
        self.scale = 20  # 金币需要移动的位置时显示的大小
        self.firstimage = random.choice(bglist)
        self.initx = self.posx = self.rect[0]+self.rect[2]/2
        self.inity = self.posy = self.rect[1]+self.rect[3]/2
        self.r = 15
        self.angle = math.atan2(self.resy-self.posy,self.resx-self.posx)
        self.fangle = math.degrees(self.angle)


def init_image():
    path = './user1/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)

    bglist = []
    for file in files:
        picture = pygame.transform.scale(pygame.image.load(file), (50, 50))
        dSurface = picture.convert()
        # dSurface = pygame.image.load(file).convert()
        bglist.append(dSurface)
        # bglist.append(pygame.image.load(file).convert_alpha())

    return bglist

def init_score():
    path = './score/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)
    bglist = []
    for file in files:
        picture = pygame.transform.scale(pygame.image.load(file), (50, 50))
        dSurface = picture.convert_alpha()
        bglist.append(dSurface)

    return bglist

def display(screen,total,x,y):
    font1 = pygame.font.Font(r'C:\Windows\Fonts\simsun.ttc', 22)
    text1 = font1.render('得分:%s' % total, True, (255,0,0))
    screen.blit(text1, (x,y))


def divide(start,end,m,n):
    bglist = []
    y = end[1]-start[1]
    x = end[0]-start[0]
    width = int(x/m)
    height = int(y/n)
    i=0
    j=0
    while i<m:
        while j<n:
            bglist.append((start[0]+i*width,start[1]+j*height,width-1,height-1))
            j += 1
        i += 1
        j = 0

    return bglist


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((700,600))
    # 显示金币皮肤
    screen1 = pygame.Surface((700,600))
    pygame.display.set_caption("豆腐块也有春天V1.0")
    clock = pygame.time.Clock()
    # 初始化矩形框的信息
    rectlist = divide((100,50),(600,550),10,10)
    # 初始化图像信息
    bglist = init_image()
    # 初始化金币信息
    score_list = init_score()
    # 初始化得分位置信息及得分初始化为0分
    dirx=400
    diry=20
    total = 0

    # 存储豆腐块列表
    partlist = []
    for bg in rectlist:
        partlist.append(Part(bglist,score_list,bg,screen,dirx,diry,screen1))
        # pygame.draw.rect(screen, (255, 0, 0), bg)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or event.type == pygame.K_F1:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                pos = x, y = pygame.mouse.get_pos()  # 获取鼠标位置,鼠标就是需要打击的目标
                for p1 in partlist:
                    if p1.getrect().collidepoint(pos):
                        if p1.flag == 1:
                            p1.flag = 2
                            break
        screen.fill((0,0,0))
        screen1.fill((128, 128, 128))
        screen1.set_colorkey((128, 128, 128))
        for p1 in partlist:
            p1.run()
            if p1.flag==4:
                total += p1.score
                p1.flag = 5
        display(screen,total,dirx,diry)
        screen.blit(screen1,(0,0))
        clock.tick(30)
        pygame.display.flip()

六、运行效果

在这里插入图片描述

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值