喂饭级教程:看我如何用 ChatGPT-4o 做一款俄罗斯方块游戏!

公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

60fbb90642e10d22cd54eb42157c5baf.png

昨天发的一篇文章,讲的是用 Midjourney 加 Kimi 做一款像素游戏。发完后,朋友看到说:“这他妈是游戏嘛,这跟你儿子学的 Scratch 做的游戏有什么区别?”我当时听到很不服气,怎么能把我跟儿子比呢,我吃的盐比他吃的饭还多呢。

于是,我决定用行动来证明自己。昨晚,我开始让 ChatGPT-4o 帮我写一个俄罗斯方块的游戏。通过这次尝试,我希望向大家展示如何利用先进的 AI 技术,快速开发出一款经典的游戏。同时,也希望能够分享在这个过程中所遇到的挑战和解决方案。

好,我们接下来就开始今天的教程,如何用 ChatGPT-4o 制作一款俄罗斯方块的游戏。

第一步:规划方案

我先让 ChatGPT-4o 给我规划一下俄罗斯方块的游戏方案。

0672b6001b089578e4f20f5e1b984bf1.png
方案图

第二步:生成代码

我让 ChatGPT-4 给我生成详细的代码:“我想用 Python 做出这款游戏,请生成详细的代码吧。”

9b349b3a7133195c435c8a935702e1a9.png
图片链接

第三步:修复 bug

代码生成出来后,我把代码放到 VS 里面运行,产生了第一个 bug。我之前没有告诉 ChatGPT-4o,当第一行落地满了时需要自动消除。

第四步:修复 bug

这个时候,我们得找 ChatGPT-4o,让它修复这个 bug。

1e7fda54ac4f9a09fbaf790aaca9f24d.png
修复 bug 图1

ChatGPT-4o 修复了 bug,并告诉我它修复了哪些问题。

1e5aaaecb84877180673808275334b1d.png
修复 bug 图2

第五步:方块下降加速

玩的时候,我发现下落速度有点慢。于是,我又让 ChatGPT-4o 修改代码,加速下落速度。

3d32540b3cc6d21391457d1e6552ffba.png
加速修改图1

ChatGPT-4o 告诉我它修改了什么。

d0e75c406f8580fddb87f37c9fee509a.png
加速修改图2

第六步:给游戏加图片

其实到这里,这个教程可以结束了。不过,我觉得我们还得继续完善下,给游戏的方块加上点图片,这样会更好看一些。我问了下 GPT,我应该怎么把里面的方块加图片。

d2a50369054f5cc995bbdc500e1bfd7e.png
图片链接

同时,我也问他,在设计图片时尺寸应该是多大。

692c0b4aca34cdf21c288c23e7d52b56.png
图片链接

好了,既然我们知道了要设计多大的图片,那我们就得去弄图片。这时 GPT 正在写代码,但我们一时之间也没有头绪,应该设计什么样的方块图片。这时我想起,干脆用 Midjourney 来生成吧。

134144622d50999b0b59e08b84d822c2.png
图片链接

嗯,Midjourney 生成了 4 张图片供我参考,我选了第二张,然后我用 Pixelmator Pro 把背景去掉,让它变成透明的,并复制了七份。

acf9f376c45aed0450ba8a71de948608.png
图片链接

嗯,将就着用,然后在游戏里面显示的就是下面的效果了。

丑是丑了点,不过,都到这里了,要什么自行车。

本来到这里,教程实际上应该结束了。不过,既然已经进展到这里,我想增加一些复杂度:让 GPT 设计一个带有开场画面的游戏开始界面。

d0fbb58e26fb6994a44752e10bfcc1aa.png
图片链接

与此同时,我去找 Midjourney 又给我生成了一张背景图片。

bfed510184e0b87f8e97225d52008215.png
图片链接

很好,运行游戏的时候是下面这样的,不过它怎么直接让我回车进入呢?我不是说用鼠标点击开始再进去吗?

e9eea5ed5ff9178d2feb06d64903fda7.png
图片链接

很好,我让它修改下,他给我弄了一个按钮,但是按钮很丑,我又让它给我修改代码。

a8d9a5791044143583303ab83cd12a43.png 49b138a6e53028f3357aafc66d865ecf.png

很好,这个时候我得去弄一个按钮,这个按钮,还不错,我就用它了。

f6e8fe3b9eb8f7b206be35b7e7f63ca3.png

最终我们的教程来到了最后,是看成品的时候了。

小结

在第六步过程中,产生了一些 bug。我们和 GPT 的对话太长了,它开始有点敷衍,导致游戏里的方块落地就自动消失,而不是行

填满的时候才消失。最终经过多次修复,问题得以解决。

完整教程总结

通过这次教程,我们成功地利用 ChatGPT-4o 以及相关工具开发了一款功能完整的俄罗斯方块游戏。整个过程涵盖了从初步规划、代码生成到解决 Bug,以及添加图片和设计开局画面的各个环节。

关键步骤回顾

  1. 规划方案:明确游戏的功能和设计需求。

  2. 生成代码:使用 ChatGPT-4o 生成初步代码,并进行调试和优化。

  3. 修复 Bug:通过 ChatGPT-4o 的帮助,解决代码中的问题。

  4. 添加图片:利用 Midjourney 生成游戏所需的图片,并进行优化。

  5. 设计开局画面:通过添加背景图片和可点击的“开始”按钮,提升游戏的用户体验。

反思与展望

在这个项目中,我不仅体验到了利用 AI 进行游戏开发的便捷性,还学到了如何在遇到问题时,通过多次调试和优化,最终实现目标。虽然过程中出现了多次 Bug,但通过坚持不懈的尝试和修复,最终达到了预期的效果。

未来,我们可以考虑进一步优化游戏,比如:

  • 增加更多游戏模式和难度级别。

  • 优化游戏性能,提升用户体验。

  • 添加音效和背景音乐,增强游戏的娱乐性。

实验目的总结

  1. 实现一个完整的 Tetris 游戏,包括开局画面和游戏主循环。

  2. 在开局画面中使用背景图片和可点击的“开始”按钮。

  3. 确保游戏逻辑正确,包括方块的移动、旋转、合并以及行的清除。

实验步骤回顾

  1. 基础实现

  • 初步实现了一个基本的 Tetris 游戏,包括方块的移动、旋转和落下。

  • 实现了行的检测和清除逻辑。

改进和修复

  • 修复了方块未填满行时消失的 bug。

  • 确保方块只有在行完全填满时才会消失。

开局画面

  • 添加了开局画面,包含背景图片和“开始”按钮。

  • 修改代码,实现通过点击按钮来开始游戏。

使用图片作为按钮

  • 将“开始”按钮替换为图片,实现更直观的用户界面。

最终代码

我实现了一个功能完整的 Tetris 游戏,包含以下关键功能:

  • 开局画面,使用背景图片和图片按钮。

  • 方块的移动、旋转和正确的碰撞检测。

  • 正确的行清除逻辑,只有在行完全填满时才清除。

  • 游戏结束时显示“Game Over”并提供重新开始的选项。

import pygame
import random

# Initialize Pygame
pygame.init()

# Screen dimensions
screen_width = 300
screen_height = 600
block_size = 30

# Load images for each tetromino (designed at 120x120 pixels)
image_filenames = {
    'I': 'I.png',
    'J': 'J.png',
    'L': 'L.png',
    'O': 'O.png',
    'S': 'S.png',
    'T': 'T.png',
    'Z': 'Z.png'
}

# Scale images to the desired block size
images = {key: pygame.transform.scale(pygame.image.load(filename), (block_size, block_size))
          for key, filename in image_filenames.items()}

# Load start screen background image
start_bg = pygame.transform.scale(pygame.image.load('start_bg.png'), (screen_width, screen_height))
# Load start button image
start_button_img = pygame.image.load('start_button.png')
start_button_img = pygame.transform.scale(start_button_img, (150, 50))

# Tetromino shapes and corresponding image keys
shapes = [
    ([[1, 1, 1, 1]], 'I'),
    ([[1, 1, 1], [0, 1, 0]], 'T'),
    ([[1, 1, 0], [0, 1, 1]], 'Z'),
    ([[0, 1, 1], [1, 1, 0]], 'S'),
    ([[1, 1], [1, 1]], 'O'),
    ([[1, 1, 1], [1, 0, 0]], 'L'),
    ([[1, 1, 1], [0, 0, 1]], 'J')
]

# Initialize the screen
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Tetris")

# Clock
clock = pygame.time.Clock()
fps = 30

# Grid dimensions
grid_width = screen_width // block_size
grid_height = screen_height // block_size

# Create the grid
grid = [[0 for _ in range(grid_width)] for _ in range(grid_height)]

class Tetromino:
    def __init__(self, shape, image_key):
        self.shape = shape
        self.image_key = image_key
        self.x = grid_width // 2 - len(shape[0]) // 2
        self.y = 0

    def rotate(self):
        self.shape = [list(row) for row in zip(*self.shape[::-1])]

def draw_grid():
    for y in range(grid_height):
        for x in range(grid_width):
            if grid[y][x] != 0:
                screen.blit(images[grid[y][x]], (x * block_size, y * block_size))
            pygame.draw.rect(screen, (255, 255, 255), (x * block_size, y * block_size, block_size, block_size), 1)

def check_collision(shape, offset):
    off_x, off_y = offset
    for y, row in enumerate(shape):
        for x, cell in enumerate(row):
            if cell and (x + off_x < 0 or x + off_x >= grid_width or y + off_y >= grid_height or grid[y + off_y][x + off_x]):
                return True
    return False

def merge(shape, offset, image_key):
    off_x, off_y = offset
    for y, row in enumerate(shape):
        for x, cell in enumerate(row):
            if cell:
                grid[y + off_y][x + off_x] = image_key

def clear_lines():
    global grid
    lines_cleared = 0
    new_grid = []
    for row in grid:
        if all(cell != 0 for cell in row):
            lines_cleared += 1
        else:
            new_grid.append(row)
    new_grid = [[0 for _ in range(grid_width)] for _ in range(lines_cleared)] + new_grid
    grid = new_grid
    return lines_cleared

def draw_tetromino(tetromino):
    for y, row in enumerate(tetromino.shape):
        for x, cell in enumerate(row):
            if cell:
                screen.blit(images[tetromino.image_key], ((tetromino.x + x) * block_size, (tetromino.y + y) * block_size))

def draw_text(text, size, color, x, y):
    font = pygame.font.Font(None, size)
    text_surface = font.render(text, True, color)
    text_rect = text_surface.get_rect(center=(x, y))
    screen.blit(text_surface, text_rect)

def game_over():
    draw_text("Game Over", 74, (255, 255, 255), screen_width // 2, screen_height // 2 - 50)
    draw_text("Press R to Restart", 36, (255, 255, 255), screen_width // 2, screen_height // 2 + 20)
    pygame.display.flip()
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    waiting = False
                    main()

def start_screen():
    start_button_rect = start_button_img.get_rect(center=(screen_width // 2, screen_height // 2))
    while True:
        screen.blit(start_bg, (0, 0))
        draw_text("Tetris", 74, (255, 255, 255), screen_width // 2, screen_height // 4)
        screen.blit(start_button_img, start_button_rect.topleft)
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if start_button_rect.collidepoint(event.pos):
                    return

def main():
    global grid
    grid = [[0 for _ in range(grid_width)] for _ in range(grid_height)]
    current_tetromino = Tetromino(*random.choice(shapes))
    next_tetromino = Tetromino(*random.choice(shapes))
    fall_time = 0
    fall_speed = 500  # Initial fall speed in milliseconds
    score = 0
    level = 1
    lines_cleared = 0

    while True:
        screen.fill((0, 0, 0))
        draw_grid()
        draw_tetromino(current_tetromino)
        draw_text(f"Score: {score}", 24, (255, 255, 255), screen_width - 70, 30)
        draw_text(f"Level: {level}", 24, (255, 255, 255), screen_width - 70, 60)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    current_tetromino.x -= 1
                    if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                        current_tetromino.x += 1
                if event.key == pygame.K_RIGHT:
                    current_tetromino.x += 1
                    if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                        current_tetromino.x -= 1
                if event.key == pygame.K_DOWN:
                    current_tetromino.y += 1
                    if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                        current_tetromino.y -= 1
                if event.key == pygame.K_UP:
                    current_tetromino.rotate()
                    if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                        current_tetromino.rotate()
                        current_tetromino.rotate()
                        current_tetromino.rotate()

        keys = pygame.key.get_pressed()
        if keys[pygame.K_DOWN]:
            fall_speed = 50  # Increase fall speed when down key is pressed
        else:
            fall_speed = 500  # Default fall speed

        fall_time += clock.get_rawtime()
        clock.tick()
        if fall_time >= fall_speed:
            current_tetromino.y += 1
            if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                current_tetromino.y -= 1
                merge(current_tetromino.shape, (current_tetromino.x, current_tetromino.y), current_tetromino.image_key)
                lines = clear_lines()
                lines_cleared += lines
                score += lines * 100
                if lines_cleared >= level * 10:
                    level += 1
                    fall_speed = max(100, fall_speed - 20)
                current_tetromino = next_tetromino
                next_tetromino = Tetromino(*random.choice(shapes))
                if check_collision(current_tetromino.shape, (current_tetromino.x, current_tetromino.y)):
                    game_over()
            fall_time = 0

        draw_tetromino(current_tetromino)
        pygame.display.update()

if __name__ == "__main__":
    start_screen()
    main()

通过这个项目,我们不仅完成了一款俄罗斯方块游戏,还积累了丰富的开发经验。希望大家在未来的项目中,也能利用 AI 工具,创造出更多有趣且实用的应用。

本文转载自:「AI面」,原文:https://url.hi-linux.com/NJRwi,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

13e43e29af5c6878b4a75f48692a3816.gif

🚀 最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。

📕 关注『奇妙的 Linux 世界』公众号,带你开启有趣新生活!更多好用好玩的软件资源,可访问 https://666666.dev 免费获取。

ded3ffe609ce74900d62ff52229c8093.png

你可能还喜欢

点击下方图片即可阅读

cb7e904a06ee0bfce7cb619c752f6836.png

Github 星标 5.2K: 一款开源、自托管、高度定制化的仪表面板,助你轻松管理所有订阅源

522fed35a1282f620f632ac5a65f55c2.png
点击上方图片,『美团|饿了么』外卖红包天天免费领

1fa14d5f2e8536f6fb69a76f56adbd10.png

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当然可以!你可以使用 Python 开发一个俄罗斯方块游戏。 先安装 Pygame 库,这是一个专门用于制作游戏的库。然后,你可以使用 Pygame 创建游戏窗口,设置游戏速度,加载图像,以及监听玩家的输入。 接下来,你需要编写代码来生成、移动和旋转方块。你可以使用随机数生成随机方块,并编写代码来移动和旋转它们。 最后,你需要编写代码来检测方块是否到达底部,并维护分数和游戏结束的逻辑。 总体而言,开发俄罗斯方块游戏是一个较为复杂的项目,需要一定的 Python 编程知识和游戏开发经验。但如果你坚持不懈,一定可以完成这个游戏的开发。 ### 回答2: 俄罗斯方块一款非常经典的游戏,我们可以使用Python来实现这个游戏。首先,我们需要用Python中的图形库来创建游戏窗口,例如使用Pygame库。 其次,我们需要定义方块的形状和移动规则。俄罗斯方块有七种不同的形状,每个方块都由四个小方块组成,可以旋转和移动。我们可以使用一个二维数组来表示每个方块的形状和位置。 然后,我们需要在游戏窗口中显示方块和背景。可以使用颜色来表示方块的不同形状,并使用二维数组来表示游戏窗口的背景。 接下来,我们需要实现方块的移动和旋转功能。通过监听键盘事件,当玩家按下方向键时,我们可以改变方块的位置。当玩家按下旋转键时,我们可以旋转方块。同时,我们需要检测方块的移动和旋转是否合法,如果发生碰撞或超出边界,则需要停止移动或旋转。 最后,我们需要实现消除行的功能。当一行被填满时,我们可以将该行从游戏窗口中删除,并将上方的方块往下移动一行。通过持续消除行,直到游戏窗口的最上方被方块填满或超出边界,游戏结束。 通过以上步骤,我们可以用Python实现一个简单的俄罗斯方块游戏。当然,还可以对游戏进行更多的优化和增加其他功能,例如计分系统、难度递增等。希望这个回答对你有帮助! ### 回答3: 俄罗斯方块是一个非常经典的游戏,我们可以使用Python来编写一个简单的俄罗斯方块游戏。 首先,我们需要导入pygame库来实现游戏界面和交互。然后,我们可以创建一个游戏窗口,并设置适当的大小。 接下来,我们需要创建俄罗斯方块的方块结构。我们可以使用一个二维数组来表示方块的形状,每个方块可以由4个小方块组成。我们还需要一个变量来表示当前方块的位置和状态。 然后,我们需要实现游戏的核心逻辑。在每一帧中,我们可以检查用户输入,比如左右移动方块或旋转方块。我们还需要检测方块是否与其他方块相碰撞,以及是否到达游戏界面的边界或底部。 当方块到达底部或无法再下降时,我们需要判断是否有满行,并消除满行的方块。如果有满行,我们需要更新分数,并更新方块的位置和状态。如果方块无法继续移动,游戏结束。 最后,我们可以在游戏界面中显示得分和下一个方块的预览。我们还可以实现一些额外的功能,比如暂停游戏或重新开始游戏。 使用Python编写俄罗斯方块游戏可以让我们练习Python语法和面向对象编程的能力。同时,通过编写一个完整的游戏,我们可以提高逻辑思维和问题解决能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值