# 热门搜索 #
搜索
喂饭级教程,看我如何用ChatGPT-4o做一款俄罗斯方块游戏!
7828点击    2024-05-27 09:49

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


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


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


第一步:规划方案


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



第二步:生成代码


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




第三步:修复bug


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



第四步:继续修复bug


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



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




第五步:方块下降加速


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



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



第六步:给游戏加图片


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



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



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



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



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



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


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



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



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



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



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



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



小结


在第六步过程中,产生了一些 bug。我们和 GPT 的对话太长了,它开始有点敷衍,导致游戏里的方块落地就自动消失,而不是行填满的时候才消失。最终经过多次修复,问题得以解决。


完整教程总结


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


关键步骤回顾


  1. 规划方案:明确游戏的功能和设计需求。
  2. 生成代码:使用 ChatGPT-4o 生成初步代码,并进行调试和优化。
  3. 修复 Bug:通过 ChatGPT-4o 的帮助,解决代码中的问题。
  4. 添加图片:利用 Midjourney 生成游戏所需的图片,并进行优化。
  5. 设计开局画面:通过添加背景图片和可点击的“开始”按钮,提升游戏的用户体验。


反思与展望


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


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


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


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


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


实验目的总结


  1. 实现一个完整的 Tetris 游戏,包括开局画面和游戏主循环。
  2. 在开局画面中使用背景图片和可点击的“开始”按钮。
  3. 确保游戏逻辑正确,包括方块的移动、旋转、合并以及行的清除。


实验步骤回顾


  • 基础实现:


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


    (2)实现了行的检测和清除逻辑。


  • 改进和修复:


    (1)修复了方块未填满行时消失的 bug。


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


  • 开局画面:


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


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


  • 使用图片作为按钮:


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


最终代码


我实现了一个功能完整的 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, (15050))


# Tetromino shapes and corresponding image keys

shapes = [

    ([[1111]], 'I'),

    ([[111], [010]], 'T'),

    ([[110], [011]], 'Z'),

    ([[011], [110]], 'S'),

    ([[11], [11]], 'O'),

    ([[111], [100]], 'L'),

    ([[111], [001]], '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, (255255255), (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, (255255255), screen_width // 2, screen_height // 2 - 50)

    draw_text("Press R to Restart"36, (255255255), 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, (00))

        draw_text("Tetris"74, (255255255), 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((000))

        draw_grid()

        draw_tetromino(current_tetromino)

        draw_text(f"Score: {score}"24, (255255255), screen_width - 7030)

        draw_text(f"Level: {level}"24, (255255255), screen_width - 7060)


        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


00:27

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


文章来源于“作者AI 面”,作者“作者AI 面


2

关键词: chatGPT , GPT-4o , openai , AI做游戏
AITNT资源拓展
根据文章内容,系统为您匹配了更有价值的资源信息。内容由AI生成,仅供参考
1
免费使用GPT-4o

【免费】ffa.chat是一个完全免费的GPT-4o镜像站点,无需魔法付费,即可无限制使用GPT-4o等多个海外模型产品。

在线使用:https://ffa.chat/