简单版开心消消乐(python实现)

一、pycharm 安装

1.1 pycharm 下载

pycharm官网

点击上面官网链接,

在这里插入图片描述

点击 Download 按钮

在这里插入图片描述

【专业版只有30天试用期,所以我们下载社区版】
鼠标滚轮下滑,找到 PyCharm Community Edition,点击下载

在这里插入图片描述

下载完成后则进行安装

1.2 pycharm 安装

二、创建 python 项目

2.1 创建项目

2.2 配置项目环境

点击右上角设置

在这里插入图片描述

先点击 Project ,再点击 Python Interpreter ,然后点击 + 号

在这里插入图片描述

在搜索框输入 pygame ,选择第一个,点击 install Package

在这里插入图片描述

等待安装结束即可,可以发现多了一个 pygame 包,然后点击 ok 即可

在这里插入图片描述

2.3 编写项目代码

任务要求
画方块在屏幕上画出5行5列的方块,方块颜色随机

main.py 代码如下:

import random
import time
import pygame
import sys

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600


def change_color():
    """ 产生随机颜色 """
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


def draw_block(x, y, row, col, width, height):
    """ 在屏幕上画方块 """
    for i in range(0, row):
        for j in range(0, col):
            pygame.draw.rect(screen, change_color(), (x + i * width, y + j * height, width, height))


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

    while True:
        draw_block(50, 50, 5, 5, 50, 50)
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
        time.sleep(0.3)

运行结果如下:

在这里插入图片描述

三、撰写代码

3.1 读取文件

任务要求
显示图片在2.3任务的基础上,把每一个方块替换为图片

在项目创建 image 文件夹,图片资源可以在文章顶部下载:

在这里插入图片描述

main.py 代码如下:

import random
import time
import pygame
import sys
import os

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600


def change_color():
    """ 产生随机颜色 """
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


def draw_block(x, y, row, col, width, height):
    """ 在屏幕上画方块 """
    for i in range(0, row):
        for j in range(0, col):
            r = random.randint(1, 7)
            pygame.draw.rect(screen, change_color(), (x + i * width, y + j * height, width, height))
            screen.blit(pygame.image.load(os.path.join('./image', ' (' + str(r) + ').png')),
                        (x + i * width, y + j * height))


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

    while True:
        draw_block(50, 50, 10, 10, 50, 50)
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
        time.sleep(0.3)

运行结果如下:

在这里插入图片描述

3.2 响应鼠标事件

3.2.1 示例 1

在这里插入图片描述
可以从 pygame 的 event 变量的 type 属性来确定事件类型,而 pygame 的 MOUSEBUTTONDOWN 常量则表示鼠标点击事件。

完整 main.py 代码如下:

import random
import time
import pygame
import sys
import os

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
DRAW_BLOCK = 111
DRAW_PIC = 222
DRAW_CIRCLE = 333


def change_color():
    """ 产生随机颜色 """
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


def draw_block(x, y, row, col, width, height, type):
    """ 在屏幕上画方块 """
    for i in range(0, row):
        for j in range(0, col):
            if type == DRAW_BLOCK:
                pygame.draw.rect(screen, change_color(), (x + i * width, y + j * height, width, height))
            elif type == DRAW_PIC:
                r = random.randint(1, 7)
                screen.blit(pygame.image.load(os.path.join('./image', ' (' + str(r) + ').png')),
                            (x + i * width, y + j * height))
            else:
                continue


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

    while True:
        draw_block(50, 50, 10, 10, 50, 50, DRAW_PIC)
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                print(x, y, y // 50, x // 50)
        time.sleep(0.3)

运行结果如下:

  点击方块时,终端会显示鼠标点击坐标和对应方块的行、列。

在这里插入图片描述

3.2.2 示例 2

在示例 1 的基础上,点击对应方块,对应方块就消除。

代码如下:

import random
import time
import pygame
import sys
import os

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
DRAW_BLOCK = 111
DRAW_PIC = 222
DRAW_CIRCLE = 333


def change_color():
    """ 产生随机颜色 """
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


def draw_block(x, y, row, col, width, height, type):
    """ 在屏幕上画方块 """
    for i in range(0, row):
        for j in range(0, col):
            if type == DRAW_BLOCK:
                pygame.draw.rect(screen, change_color(), (x + i * width, y + j * height, width, height))
            elif type == DRAW_PIC:
                r = random.randint(1, 6)
                screen.blit(pygame.image.load(os.path.join('./image', 'd (' + str(r) + ').png')),
                            (x + i * width, y + j * height))
            else:
                continue


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
    draw_block(50, 50, 10, 10, 50, 50, DRAW_PIC)
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                print(x, y, y // 50, x // 50)
                pygame.draw.rect(screen, (255, 255, 255), (x // 50 * 50, y // 50 * 50, 50, 50))
                pygame.display.update()
        time.sleep(0.3)

运行结果如下:

在这里插入图片描述

3.3 封装成类

3.3.1 封装成类

在这里插入图片描述

在目录下新建 MagicBlock.py 文件,文件代码如下:

import random
import pygame

TYPE_RECT = 0
TYPE_IMAGE = 1
img_list = list()

for i in range(1, 6):
    img_list.append(pygame.image.load('./image/d (' + str(i) + ').png'))


class Block:
    def __init__(self, left, top):
        self.screen = None
        self.left = 50 + left
        self.top = 50 + top
        self.type = TYPE_IMAGE
        self.random_index = random.randint(0, 4)

    def change_color(self):
        r = random.randint(0, 255)
        g = random.randint(0, 255)
        b = random.randint(0, 255)
        return r, g, b

    def draw(self, screen, width, height):
        position = self.left, self.top, width, height
        self.screen = screen
        if self.type == TYPE_RECT:
            pygame.draw.rect(self.screen, self.change_color(), position)
        elif self.type == TYPE_IMAGE:
            screen.blit(img_list[self.random_index], (self.left, self.top))

更改 main.py 文件,更改后代码如下:

import random
import time
import pygame
import sys
import os

from MagicBlock import Block

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
DRAW_BLOCK = 111
DRAW_PIC = 222
DRAW_CIRCLE = 333


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

    for i in range(10):
        for j in range(10):
            block = Block(50 * i, 50 * j)
            block.draw(screen, 50, 50)
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                print(x, y, y // 50, x // 50)
                pygame.draw.rect(screen, (255, 255, 255), (x // 50 * 50, y // 50 * 50, 50, 50))
                pygame.display.update()
        time.sleep(0.3)

运行结果如下:

在这里插入图片描述

3.3.2 继续封装

修改 MagicBlock.py 的代码为:

import random
import pygame

TYPE_RECT = 0
TYPE_IMAGE = 1
img_list = list()

for i in range(1, 6):
    img_list.append(pygame.image.load('./image/d (' + str(i) + ').png'))


def change_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


class Block:
    def __init__(self, screen, block_type):
        self.screen = screen
        self.left = 0
        self.top = 0
        self.type = block_type
        self.random_index = random.randint(0, 4)

    def draw(self, screen, width, height):
        position = self.left, self.top, width, height
        self.screen = screen
        if self.type == TYPE_RECT:
            pygame.draw.rect(self.screen, change_color(), position)
        elif self.type == TYPE_IMAGE:
            screen.blit(img_list[self.random_index], (self.left, self.top))

    def mouse_clicked(self):
        pygame.draw.rect(self.screen, change_color(), (self.left, self.top, 50, 50))
        pygame.display.update()


class MagicBlock:
    def __init__(self, start_x, start_y, row, col, screen, block_width, block_height, block_type):
        self.start_x = start_x
        self.start_y = start_y
        self.row = row
        self.col = col
        self.screen = screen
        self.block_width = block_width
        self.block_height = block_height
        self.type = block_type
        self.blocks = [[0] * self.col for _ in range(row)]
        self.init_blocks()

    def init_blocks(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j] = Block(self.screen, self.type)
                self.blocks[r][j].left = self.start_x + r * self.block_width
                self.blocks[r][j].top = self.start_y + j * self.block_height

    def draw(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j].draw(self.screen, self.block_width, self.block_height)

    def mouse_clicked(self, x, y):
        if 0 < x - self.start_x < self.col * self.block_width and 0 < y-self.start_y < self.row * self.block_height:
            self.blocks[(x - self.start_x) // self.block_width][(y - self.start_y) // self.block_height].mouse_clicked()

修改 main.py 的代码为:

import random
import time
import pygame
import sys
import os

from MagicBlock import MagicBlock

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 700
TYPE_RECT = 0
TYPE_IMAGE = 1


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.blit(pygame.image.load('./image/background.png'), (0, 0))

    magic_block = MagicBlock(100, 50, 10, 10, screen, 50, 50, TYPE_IMAGE)
    magic_block.draw()

    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                magic_block.mouse_clicked(x, y)
        time.sleep(0.3)

运行结果如下:

在这里插入图片描述

3.4 消除逻辑

修改 magicBlock.py 文件代码如下:

import random
import queue
import pygame

TYPE_RECT = 0
TYPE_IMAGE = 1
img_list = list()
block_queue = queue.Queue()

for i in range(1, 6):
    img_list.append(pygame.image.load('./image/d (' + str(i) + ').png'))


def change_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


class Block:
    def __init__(self, screen, block_type):
        self.screen = screen
        self.left = 0
        self.top = 0
        self.type = block_type
        self.random_index = random.randint(0, 4)

    def draw(self, screen, width, height):
        position = self.left, self.top, width, height
        self.screen = screen
        if self.type == TYPE_RECT:
            pygame.draw.rect(self.screen, change_color(), position)
        elif self.type == TYPE_IMAGE:
            screen.blit(img_list[self.random_index], (self.left, self.top))

    def mouse_clicked(self):
        if block_queue.qsize() < 2:
            block_queue.put(self)
        if block_queue.qsize() >= 2:
            t1 = block_queue.get()
            t2 = block_queue.get()
            if t1.random_index == t2.random_index:
                pygame.draw.rect(self.screen, change_color(), (t1.left, t1.top, 50, 50))
                pygame.draw.rect(self.screen, change_color(), (t2.left, t2.top, 50, 50))
                pygame.display.update()


# class Blocks:
#     def __init__(self, row, col):
#         self.row = row
#         self.col = col
#         self.blocks = [[Block(50 * i, 50 * j) for i in range(row)] for j in range(col)]
#
#     def draw(self, screen, width, height):
#         for i in range(self.row):
#             for j in range(self.col):
#                 self.blocks[i][j].draw(screen, width, height)

class MagicBlock:
    def __init__(self, start_x, start_y, row, col, screen, block_width, block_height, block_type):
        self.start_x = start_x
        self.start_y = start_y
        self.row = row
        self.col = col
        self.screen = screen
        self.block_width = block_width
        self.block_height = block_height
        self.type = block_type
        self.blocks = [[0] * self.col for _ in range(row)]
        self.init_blocks()

    def init_blocks(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j] = Block(self.screen, self.type)
                self.blocks[r][j].left = self.start_x + r * self.block_width
                self.blocks[r][j].top = self.start_y + j * self.block_height

    def draw(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j].draw(self.screen, self.block_width, self.block_height)

    def mouse_clicked(self, x, y):
        if 0 < x - self.start_x < self.col * self.block_width and 0 < y - self.start_y < self.row * self.block_height:
            self.blocks[(x - self.start_x) // self.block_width][(y - self.start_y) // self.block_height].mouse_clicked()
            print((x - self.start_x) // self.block_width, (y - self.start_y) // self.block_height)
        else:
            print('f')

运行结果如下:

点击相同才可以消去,不同则不会
在这里插入图片描述

四、完整代码

4.1 项目结构

image 图片资源在文章顶部可以下载
MagicBlock.py 文件用于实现方块类
main.py 文件实现游戏流程
在这里插入图片描述

4.2 文件代码

4.2.1 MagicBlock.py 文件

import random
import queue
import pygame

TYPE_RECT = 0
TYPE_IMAGE = 1
img_list = list()
block_queue = queue.Queue()

for i in range(1, 6):
    img_list.append(pygame.image.load('./image/d (' + str(i) + ').png'))


def change_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return r, g, b


class Block:
    def __init__(self, screen, block_type):
        self.screen = screen
        self.left = 0
        self.top = 0
        self.type = block_type
        self.random_index = random.randint(0, 4)

    def draw(self, screen, width, height):
        position = self.left, self.top, width, height
        self.screen = screen
        if self.type == TYPE_RECT:
            pygame.draw.rect(self.screen, change_color(), position)
        elif self.type == TYPE_IMAGE:
            screen.blit(img_list[self.random_index], (self.left, self.top))

    def mouse_clicked(self):
        if block_queue.qsize() < 2:
            block_queue.put(self)
        if block_queue.qsize() >= 2:
            t1 = block_queue.get()
            t2 = block_queue.get()
            if t1.random_index == t2.random_index:
                pygame.draw.rect(self.screen, change_color(), (t1.left, t1.top, 50, 50))
                pygame.draw.rect(self.screen, change_color(), (t2.left, t2.top, 50, 50))
                pygame.display.update()


# class Blocks:
#     def __init__(self, row, col):
#         self.row = row
#         self.col = col
#         self.blocks = [[Block(50 * i, 50 * j) for i in range(row)] for j in range(col)]
#
#     def draw(self, screen, width, height):
#         for i in range(self.row):
#             for j in range(self.col):
#                 self.blocks[i][j].draw(screen, width, height)

class MagicBlock:
    def __init__(self, start_x, start_y, row, col, screen, block_width, block_height, block_type):
        self.start_x = start_x
        self.start_y = start_y
        self.row = row
        self.col = col
        self.screen = screen
        self.block_width = block_width
        self.block_height = block_height
        self.type = block_type
        self.blocks = [[0] * self.col for _ in range(row)]
        self.init_blocks()

    def init_blocks(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j] = Block(self.screen, self.type)
                self.blocks[r][j].left = self.start_x + r * self.block_width
                self.blocks[r][j].top = self.start_y + j * self.block_height

    def draw(self):
        for r in range(self.row):
            for j in range(self.col):
                self.blocks[r][j].draw(self.screen, self.block_width, self.block_height)

    def mouse_clicked(self, x, y):
        if 0 < x - self.start_x < self.col * self.block_width and 0 < y - self.start_y < self.row * self.block_height:
            self.blocks[(x - self.start_x) // self.block_width][(y - self.start_y) // self.block_height].mouse_clicked()
            print((x - self.start_x) // self.block_width, (y - self.start_y) // self.block_height)
        else:
            print('f')

4.2.2 main.py 文件

import random
import time
import pygame
import sys
import os


from MagicBlock import MagicBlock

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 700
TYPE_RECT = 0
TYPE_IMAGE = 1

# def change_color():
#     """ 产生随机颜色 """
#     r = random.randint(0, 255)
#     g = random.randint(0, 255)
#     b = random.randint(0, 255)
#     return r, g, b
#
#
# def draw_block(x, y, row, col, width, height, type):
#     """ 在屏幕上画方块 """
#     for i in range(0, row):
#         for j in range(0, col):
#             if type == DRAW_BLOCK:
#                 pygame.draw.rect(screen, change_color(), (x + i * width, y + j * height, width, height))
#             elif type == DRAW_PIC:
#                 r = random.randint(1, 6)
#                 screen.blit(pygame.image.load(os.path.join('./image', 'd (' + str(r) + ').png')),
#                             (x + i * width, y + j * height))
#             else:
#                 continue


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_HEIGHT, SCREEN_WIDTH))
    pygame.display.set_caption("happy remove")
    screen.blit(pygame.image.load('./image/background.png'), (0, 0))

    # blocks = Blocks(10, 10)
    # blocks.draw(screen, 50, 50)

    # for i in range(10):
    #     for j in range(10):
    #         block = Block(50 * i, 50 * j)
    #         block.draw(screen, 50, 50)

    # draw_block(50, 50, 10, 10, 50, 50, DRAW_PIC)

    magic_block = MagicBlock(100, 50, 10, 10, screen, 50, 50, TYPE_IMAGE)
    magic_block.draw()

    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                magic_block.mouse_clicked(x, y)
        time.sleep(0.3)
开心消消乐(Candy Crush Saga)是一款非常受欢迎的休闲消除类游戏,但直接使用Python开发一个完整的游戏本可能会比较复杂,因为这类游戏通常由专业的游戏引擎和大量的图形资源构建而成。然而,如果你对Python有兴趣,你可以尝试用Python做一些简单的益智游戏或者实现一些基本的游戏逻辑,比如模拟消消过程、计分系统等,作为学习游戏开发的入门项目。 以下是一个简化的Python示例,演示如何创建一个非常基础的消除游戏概念: ```python import random class Block: def __init__(self, color): self.color = color class GameGrid: def __init__(self, size=5): self.size = size self.blocks = [[Block(random.choice(['red', 'blue', 'green'])) for _ in range(size)] for _ in range(size)] def move_down(self): new_grid = [ * self.size for _ in range(self.size)] for i in range(1, self.size): for j in range(self.size): if self.blocks[i-1][j].color != 0: # 如果上方有颜色,向下移动 new_grid[i][j] = self.blocks[i-1][j] self.blocks = new_grid # 示例游戏运行 game = GameGrid() for _ in range(10): # 模拟消除10次 game.move_down() print("消除后:") for row in game.blocks: print(row) ``` 这个例子中,我们创建了两个类`Block`和`GameGrid`,用于表示游戏中的方块和游戏网格。`move_down`方法模拟消除动作。这只是一个非常基础的框架,要制作类似开心消消乐游戏,你需要更深入地学习图形界面库(如Pygame),以及游戏逻辑的复杂设计。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值