ChatGPT is a truly amazing tool.
I believe it has the potential to change our world and improve our productivity by 10x.
It complements Google search in a way like no other tool before.
I have decided to try it out over the weekend and develop a simple Python game using it.
In this short article I will show you how you can use Chat GPT to create a simple version of Arkanoid game in Python.
The results are astonishing and this is what I managed to achieve within a couple of hours and no knowledge of pygame at all.
The way it leads you through a design is just unbelievable.
Check out the end result below:
import pygame
def create_paddle(window_size, paddle_width=150, paddle_height=20, paddle_color=(255, 255, 255)):
"""Create a paddle object and return it.
Keyword arguments:
window_size -- a tuple containing the width and height of the window
paddle_width -- the width of the paddle (default 150)
paddle_height -- the height of the paddle (default 20)
paddle_color -- the color of the paddle (default white)
"""
paddle_x = (window_size[0] - paddle_width) // 2
paddle_y = window_size[1] - paddle_height - 10
return pygame.Rect(paddle_x, paddle_y, paddle_width, paddle_height)
def create_ball(window_size, ball_radius=10, ball_color=(255, 255, 255), ball_initial_position=(400, 300)):
"""Create a ball object and return it.
Keyword arguments:
window_size -- a tuple containing the width and height of the window
ball_radius -- the radius of the ball (default 10)
ball_color -- the color of the ball (default white)
ball_initial_position -- a tuple containing the initial x and y coordinates of the ball (default (400, 300))
"""
x, y = ball_initial_position
ball = pygame.draw.circle(screen, ball_color, (x, y), ball_radius)
return ball, ball_radius
def create_bricks(window_size, brick_size, brick_color, num_rows, num_columns):
"""Create a grid of bricks and return a list of brick rectangles.
Keyword arguments:
window_size -- a tuple containing the width and height of the window
brick_size -- a tuple containing the width and height of each brick
brick_color -- the color of the bricks
num_rows -- the number of rows of bricks
num_columns -- the number of columns of bricks
"""
bricks = []
brick_width, brick_height = brick_size
for i in range(num_rows):
for j in range(num_columns):
brick_x = j * (brick_width + 5) + 10
brick_y = i * (brick_height + 5) + 60
brick = pygame.Rect(brick_x, brick_y, brick_width, brick_height)
bricks.append(brick)
pygame.draw.rect(screen, brick_color, brick)
return bricks
def move_paddle(paddle, velocity, window_size):
"""Move the paddle by the specified velocity.
Keyword arguments:
paddle -- the paddle to move
velocity -- the velocity of the paddle
window_size -- a tuple containing the width and height of the window
"""
paddle.move_ip(velocity, 0)
if paddle.left < 0:
paddle.left = 0
elif paddle.right > window_size[0]:
paddle.right = window_size[0]
def game_over_message(screen, font, score):
"""Display a game over message on the screen.
Keyword arguments:
screen -- the pygame screen object
font -- the pygame font object
score -- the current score
"""
game_over_text = font.render("Game Over! Score: " + str(score), True, (255, 255, 255))
game_over_rect = game_over_text.get_rect()
game_over_rect.center = (screen.get_width() // 2, screen.get_height() // 2)
screen.blit(game_over_text, game_over_rect)
def game_over(screen, font):
"""Display a "Game Over!" message and wait for the user to press the R key to restart the game.
Keyword arguments:
screen -- the screen to draw the message on
font -- the font to use for the message
"""
# Redraw the screen
screen.fill((0, 0, 0))
# Render the game over text
game_over_message(screen, font, score)
pygame.display.flip()
# Wait for the user to press the R key
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or ((event.type == pygame.KEYDOWN) and (event.key == pygame.K_ESCAPE)):
pygame.quit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
return
def reset_game(window_size):
"""Reset the ball, ball velocity, paddle, and bricks to their initial positions.
Keyword arguments:
window_size -- the size of the window
Returns:
A tuple containing the reset values of ball, ball_velocity, paddle, bricks, and ball_radius.
"""
ball, ball_radius = create_ball(window_size)
ball_velocity = [4, -4]
paddle = create_paddle(window_size)
bricks = create_bricks(window_size, (75, 25), (255, 255, 255), 5, 10)
return ball, ball_velocity, paddle, bricks, ball_radius
# Initialize pygame
pygame.init()
# Set the window size
window_size = (800, 600)
# Create the window
screen = pygame.display.set_mode(window_size)
# Set the title of the window
pygame.display.set_caption("Arkanoid")
# Initialize the font module
pygame.font.init()
# Set the font and font size
font = pygame.font.Font(None, 36)
# Initialize the score
score = 0
# Create the game objects
paddle = create_paddle(window_size)
# Create the ball
ball, ball_radius = create_ball(window_size)
brick_color = (255, 255, 255)
bricks = create_bricks(window_size, (75, 25), brick_color, 5, 10)
# Set the initial velocity of the ball
ball_velocity = [4, 4]
# Run the game loop
clock = pygame.time.Clock()
is_reset = False
paddle_velocity = 0
while True:
is_reset = False
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT or ((event.type == pygame.KEYDOWN) and (event.key == pygame.K_ESCAPE)):
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
paddle_velocity = -10
elif event.key == pygame.K_RIGHT:
paddle_velocity = 10
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
paddle_velocity = 0
# Update the position of the paddle
move_paddle(paddle, paddle_velocity, window_size)
# Update the ball's position
ball.x += ball_velocity[0]
ball.y += ball_velocity[1]
# Check for collisions with the paddle, walls, and bricks
if ball.colliderect(paddle):
ball_velocity[1] = -abs(ball_velocity[1])
elif ball.left < 0 or ball.right > window_size[0]:
ball_velocity[0] = -ball_velocity[0]
elif ball.top < 0:
ball_velocity[1] = abs(ball_velocity[1])
elif ball.bottom > window_size[1]:
game_over(screen, font)
ball, ball_velocity, paddle, bricks, ball_radius = reset_game(window_size)
score = 0
is_reset = True
if not is_reset:
for brick in bricks:
if ball.colliderect(brick):
ball_velocity[1] = abs(ball_velocity[1])
bricks.remove(brick)
# Update the score (e.g. when a brick is destroyed)
score += 1
break
if not bricks:
game_over(screen, font)
ball, ball_velocity, paddle, bricks, ball_radius = reset_game(window_size)
score = 0
# Redraw the screen
screen.fill((0, 0, 0))
pygame.draw.rect(screen, (255, 255, 255), paddle)
pygame.draw.circle(screen, (255, 255, 255), (ball.x, ball.y), ball_radius)
# Redraw the bricks
for brick in bricks:
pygame.draw.rect(screen, brick_color, brick)
# Render the score text
score_text = font.render(f"Score: {score}", True, (255, 255, 255))
# Draw the score text on the screen
screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
# Quit pygame
pygame.quit()
And here are a couple of screenshots from the game:
At the end you can see the exact questions I have asked ChatGPT.
It tends to get confused sometimes, but overall if you ask it to correct itself it actually understands the hints that you are giving to it.
I had to google only a few small things like the fact you have to run `pygame.display.flip()` or manually adjust offsets in places that it did not fully understand.
It also suffers from network/performance issues (it sometimes suddenly stops responding mid-sentence), but these will most likely get fixed soon.
To summarize, I can see a future where things like games can be created with both ChatGPT and Stable Diffusion in a way like never before.
This will unblock the creativity in everyone of us and allow us to truly speak things into reality.