编写类满天星游戏,目前自己设定需要用到的算法内容,包括第一点点击某一个图标后,自动检查图标上下左右是有与之相同的图形,如果包括自身在内有三个以上的图形,则可以消除。第二,当界面中有图形消除后,那么需要根据列来下移图标,同时产生新的图标。第三,自动检查界面中是否还有能够匹配的图案,如果没有,那么重新生成游戏。第四,游戏机制设定为倒计时,在倒计时完成前,尽可能多消除,多得分。并且考虑每次消除4个以上,按比例增加时间。

首先完成最简单的部分,配置pygame的基本参数,并且绘制游戏界面,也就是画横纵线。

考虑把游戏界面画成一个10*10的方格,并且在上方留出空位显示等分等信息,具体还需不需要别的,待定…

直接使用之前贪食蛇的画格子和初始化的代码,先略作修改。

import random
import time
import pygame
# 30帧
fps = 30
fps_clock = pygame.time.Clock()
screen_width = 1024
screen_height = 768
# 分辨率,标题
display = pygame.display.set_mode((screen_width, screen_height), 0, 32)
pygame.display.set_caption('好似满天星')
tile_size = 60
tile_width = 60
tile_height = 60
x_margin = 400
y_margin = 100
# 列
columns = 10
# 行
rows = 11
# 配色RGB
white = (255, 255, 255)
black = 'black'
bg_color = 'sky blue'
border_color = white
body_color = 'purple'
inter_body_color = 'green'
line_color = white
directions = ['up', 'down', 'left', 'right']
text_color = (144, 59, 28)
my_score = 0
snake = []
# 画格子
def draw_chest():
    for i in range(rows   1):
        pygame.draw.line(display, border_color, (x_margin/2, y_margin/2   i * tile_size),
                         (x_margin/2   (columns * tile_size), y_margin/2   i * tile_size), 2)
    for j in range(columns   1):
        pygame.draw.line(display, border_color, (x_margin/2   j * tile_size, y_margin/2),
                         (x_margin/2   j * tile_size, y_margin/2   (rows * tile_size)), 2)
if __name__ == '__main__':
    pygame.init()
    bad_touch = pygame.mixer.Sound('badswap.wav')
    match_three = pygame.mixer.Sound('match3.wav')
    match_more_than_three = pygame.mixer.Sound('match4.wav')
    display.fill(bg_color)
    while True:
        draw_chest()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
        pygame.display.update()
        fps_clock.tick(fps)

目前不知道后续还有些什么需求,所以简单修改一下,后期有需要再来修改代码。

运行结果如下:

有一个大体的框架了,接下来就是把星星放到游戏界面当中来了。嗯,因为我们有星星,所以我找了免费的饼干来代替星星。这些饼干也是五子连珠的棋子😄。

一共有七种饼干,考虑到游戏的难度,我们一开始只使用其中的四种。

把之前snake = []删除,新创建一个列表,用来存放"星星"

stars = [‘Cookie’, ‘Croissant’, ‘Cupcake’, ‘Danish’]

在方框内放满“星星”。

生成一个二维列表,列表中随机放入“星星”

def make_stars():
    board = []
    for i in range(rows):
        temp = []
        for j in range(columns):
            star = random.choice(stars)
            temp.append(star)
        board.append(temp)
    return board

还需要绘制星星的函数,在绘制星星之前呢,需要确定星星的位置,同时还是按照下标来计算游戏界面横纵坐标,那么:

def get_left_top_location(x, y):
    left_position = y * tile_size   x_margin/2
    top_position = x * tile_size   y_margin/2
    return left_position, top_position
def draw_stars(board):
    for i in range(len(board)):
        for j in range(len(board[i])):
            path = 'gems/'   board[i][j]   '.png'
            star = pygame.image.load(path)
            star = pygame.transform.scale(star, (tile_size-5, tile_size-5))
            left, top = get_left_top_location(i, j)
            # 微调一下,这样图片比较居中,谁让钉在左上角呢
            display.blit(star, (left 3, top 3))

在主程序中增加绘制星星代码

if __name__ == '__main__':
    pygame.init()
    bad_touch = pygame.mixer.Sound('badswap.wav')
    match_three = pygame.mixer.Sound('match3.wav')
    match_more_than_three = pygame.mixer.Sound('match4.wav')
    display.fill(bg_color)
    main_board = make_stars()
    print(main_board)
    while True:
        draw_chest()
        draw_stars(main_board)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
        pygame.display.update()
        fps_clock.tick(fps)

运行程序

感觉“星星”太少了,所以还是再加点吧。

stars = [‘Cookie’, ‘Croissant’, ‘Cupcake’, ‘Danish’, ‘Donut’, ‘Ginger’, ‘Macaroon’]

感觉好多了。接下来开始消除吧。

消除部分,比较简单,需要编写的内容主要是当鼠标点击时,我们需要知道是哪个位置的哪个“星星”被点击了,也就是说我们需要定位到main_board的具体下标是多少。是[0][0],[1][2],或者是别的。然后我们确定位置和“星星后”,找到该位置“星星”的上下左右,看能否找到相同的“星星”,如果有且数量大于或者等于3,那么可以实现消除。同时为了以后动画效果,我准备使用一个列表中带字典变量的方式来存储这些相同的“星星”的位置和种类信息。

先完成第一步,对应二维列表下标。

# 将游戏中的界面坐标转换为main_board中的位置
def get_spot_clicked(board, x, y):
    for i in range(len(board)):
        for j in range(len(board[i])):
            # 注意在二维数组里我们的查询顺序是比如maze[3][5]代表第四行第六列,但是对应游戏界面的坐标则3用来计算y坐标,5用来计算x坐标
            left, top = get_left_top_location(i, j)
            tile_rect = pygame.Rect(left, top, tile_width, tile_height)
            if tile_rect.collidepoint(x, y):
                return i, j
    return None, None

然后在主循环中加入鼠标响应代码。根据鼠标点击位置,打印出二维列表下标,看看效果。

            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.MOUSEBUTTONUP:
                # 鼠标左键点击后抬起
                if event.button == 1:
                    pos_x, pos_y = event.pos
                    print(get_spot_clicked(main_board, pos_x, pos_y))

实际测试,鼠标点击位置和二维列表下标匹配。

接下来则需要开始寻找点击位置四个方向上是否有相同"星星"。

# 查找"星星"的相同情况
def check_around(board, star_pos):
    store_stars = set()
    has_three_stars = False
    shape_type = board[star_pos[0]][star_pos[1]]
    # 查找上下两个方向是否有与当前棋子类型一样的棋子
    store_stars.add(star_pos)
    # 向上的方向上寻找
    star_i = star_pos[0] - 1
    up_and_down_star = set()
    while star_i >= 0 and board[star_i][star_pos[1]] == shape_type:
        store_stars.add((star_i, star_pos[1]))
        star_i -= 1
    # 向下的方向寻找
    star_i = star_pos[0]   1
    while star_i < rows and board[star_i][star_pos[1]] == shape_type:
        store_stars.add((star_i, star_pos[1]))
        star_i  = 1
    # 向左的方向上寻找
    star_j = star_pos[1] - 1
    while star_j >= 0 and board[star_pos[0]][star_j] == shape_type:
        store_stars.add((star_pos[0], star_j))
        star_j -= 1
    # 向右的方向寻找
    star_j = star_pos[1]   1
    while star_j < columns and board[star_pos[0]][star_j] == shape_type:
        store_stars.add((star_pos[0], star_j))
        star_j  = 1
    if len(store_stars) >= 3:
        has_three_stars = True
    return store_stars, has_three_stars

该函数返回所有需要消除的点的二维列表下标。再编写一个函数用于清除对坐标的二维列表中的内容。把需要清除的位置设定为empty。然后在主循环中调用。

def remove_stars(board, removed_stars):
    for star in removed_stars:
        board[star[0]][star[1]] = 'empty'
                if event.button == 1:
                    pos_x, pos_y = event.pos
                    x, y = get_spot_clicked(main_board, pos_x, pos_y)
                    need_to_removed, remove_or_not = check_around(main_board, (x, y))
                    if remove_or_not:
                        remove_stars(main_board, need_to_removed)
                        display.fill(bg_color)
                        draw_chest()
                        draw_stars(main_board)

运行程序。

程序报错了,因为绘制“星星”的函数并没有考虑到二维列表的内容为empty的情况,所以需要修改这个函数内容。

def draw_stars(board):
    for i in range(len(board)):
        for j in range(len(board[i])):
            if board[i][j] != 'empty':
                path = 'gems/'   board[i][j]   '.png'
                star = pygame.image.load(path)
                star = pygame.transform.scale(star, (tile_size-5, tile_size-5))
                left, top = get_left_top_location(i, j)
                display.blit(star, (left 3, top 3))

运行程序

确实能消除了,但是出现了一个意外情况,比如上图[4][3]这个位置的甜甜圈有三个相同的图形,我所编写的算法里,只是检查了点击处的上下左右,那么如果我点击[4][3]这个位置,[4][2],[4][3],[5][3]的内容都会消失,这个没问题,但是如果我点击的是[5][3],那么根据算法,该位置上有左右仅有一个相同的,所以不会发生消除情况。这貌似与满天星游戏方式不同,所以,我们需要修改消除算法。算法应该修改为从一个位置出发,寻找上下左右相同的图标,如果找到,再以该位置作为中心,继续寻找上下左右是否有相同点,直到没有为止。可以考虑使用回溯 栈的方式来修改算法。

# 查找"星星"的相同情况
def check_around(board, star_pos):
    stars_temp = []
    store_stars = set()
    has_three_stars = False
    shape_type = board[star_pos[0]][star_pos[1]]
    # 查找上下两个方向是否有与当前棋子类型一样的棋子
    store_stars.add(star_pos)
    stars_temp.append(star_pos)
    while len(stars_temp):
        current_star = stars_temp[0]
        del stars_temp[0]
        # 向上的方向上寻找
        star_i = current_star[0] - 1

        while star_i >= 0 and board[star_i][current_star[1]] == shape_type:
            if (star_i, current_star[1]) not in store_stars:
                store_stars.add((star_i, current_star[1]))
                stars_temp.append((star_i, current_star[1]))
            star_i -= 1
        # 向下的方向寻找
        star_i = current_star[0]   1
        while star_i < rows and board[star_i][current_star[1]] == shape_type:
            if (star_i, current_star[1]) not in store_stars:
                store_stars.add((star_i, current_star[1]))
                stars_temp.append((star_i, current_star[1]))
            star_i  = 1
        # 向左的方向上寻找
        star_j = current_star[1] - 1
        while star_j >= 0 and board[current_star[0]][star_j] == shape_type:
            if (current_star[0], star_j) not in store_stars:
                store_stars.add((current_star[0], star_j))
                stars_temp.append((current_star[0], star_j))
            star_j -= 1
        # 向右的方向寻找
        star_j = current_star[1]   1
        while star_j < columns and board[current_star[0]][star_j] == shape_type:
            if (current_star[0], star_j) not in store_stars:
                store_stars.add((current_star[0], star_j))
                stars_temp.append((current_star[0], star_j))
            star_j  = 1
        if len(store_stars) >= 2:
            has_three_stars = True
    #print('stars: ', store_stars)
    #input()
    return store_stars, has_three_stars

修改以后,从任意点击位置开始,都可以发现所有相同“星星了”

马上开始比较麻烦的地方了,动画下移。

关于动画下移的思路则是首先,按列寻找需要下移的“星星”,找到以后,无论这个星星(不加引号了,太麻烦),下面有多少空间都只移动一格,找到所有的需要移动的星星,动画移动一格,然后再寻找可以移动的星星,移动一格,再寻找,直到没有可以移动的为止。

到此这篇关于pygame实现一个类似满天星游戏流程详解的文章就介绍到这了,更多相关pygame满天星游戏内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

pygame实现一个类似满天星游戏流程详解的更多相关文章

  1. jQuery实现简单的抽奖游戏

    这篇文章主要为大家详细介绍了jQuery实现简单的抽奖游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  3. Java实现空指针后的猜拳游戏

    “java.lang.NullPointerException” 空指针异常可以说是Java程序最容易出现的异常了,小编写了一个 IDEA 插件,每当程序出现空指针异常时就会弹出一个“猜拳游戏”窗口,该窗口不能直接关闭,只有当你游戏获胜时,窗口才会自动关闭

  4. 基于Python自制视觉桌上冰球小游戏

    这篇文章主要和大家分享一下如何使用 mediapipe+opencv 制作桌上冰球的交互式小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

  5. Python Pygame实战之趣味篮球游戏的实现

    这篇文章主要为大家分享了一个基于Python和Pygame实现的一个趣味篮球游戏,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下

  6. Vue+TailWindcss实现一个简单的闯关小游戏

    本文将利用Vue+TailWindcss实现一个简单的闯关小游戏,玩家须躲避敌人与陷阱到达终点且拥有多个关卡,感兴趣的小伙伴可以了解一下

  7. Python pygame 项目实战事件监听

    这篇文章主要介绍了Python pygame 项目实战事件监听,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

  8. Android 实现抖音小游戏潜艇大挑战的思路详解

    《潜水艇大挑战》是抖音上的一款小游戏,最近特别火爆,很多小伙伴都玩过。接下来通过本文给大家分享Android 手撸抖音小游戏潜艇大挑战的思路,需要的朋友可以参考下

  9. 教你使用python做一个“罚点球”小游戏

    这篇文章主要介绍了用python做一个“罚点球”小游戏,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  10. 基于Python编写一个中秋节嫦娥投食小游戏

    今天给大家带来的是给玉兔投喂月饼的小游戏。八月十五中秋夜晚,让我们对着月亮许愿:希望我们在意和在意我们的人,诸邪避退、百事无忌、平安喜乐、万事胜意。提前祝大家中秋节快乐

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部