make a game like mr. do!
import pygame
import random
# Initialize Pygame
pygame.init()
# Set up the display
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mr. Do!-like Game")
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# Player
player_size = 40
player_x = WIDTH // 2
player_y = HEIGHT // 2
player_speed = 5
# Cherries
cherry_size = 20
cherries = []
# Enemies
enemy_size = 30
enemies = []
# Score
score = 0
font = pygame.font.Font(None, 36)
def spawn_cherry():
x = random.randint(0, WIDTH - cherry_size)
y = random.randint(0, HEIGHT - cherry_size)
cherries.append(pygame.Rect(x, y, cherry_size, cherry_size))
def spawn_enemy():
x = random.randint(0, WIDTH - enemy_size)
y = random.randint(0, HEIGHT - enemy_size)
enemies.append(pygame.Rect(x, y, enemy_size, enemy_size))
# Game loop
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Move player
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= player_speed
if keys[pygame.K_RIGHT]:
player_x += player_speed
if keys[pygame.K_UP]:
player_y -= player_speed
if keys[pygame.K_DOWN]:
player_y += player_speed
# Keep player on screen
player_x = max(0, min(player_x, WIDTH - player_size))
player_y = max(0, min(player_y, HEIGHT - player_size))
# Spawn cherries
if random.randint(1, 60) == 1:
spawn_cherry()
# Spawn enemies
if random.randint(1, 180) == 1:
spawn_enemy()
# Check collisions
player_rect = pygame.Rect(player_x, player_y, player_size, player_size)
for cherry in cherries[:]:
if player_rect.colliderect(cherry):
cherries.remove(cherry)
score += 10
for enemy in enemies[:]:
if player_rect.colliderect(enemy):
running = False
# Draw everything
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, (player_x, player_y, player_size, player_size))
for cherry in cherries:
pygame.draw.rect(screen, RED, cherry)
for enemy in enemies:
pygame.draw.rect(screen, GREEN, enemy)
# Draw score
score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
2. The labyrinth
first attempt
put the player and the enemies into a labyrinth and make the enemies chace the player
second attempt
draw the labyrint and if the game is over, make it possible to start again. Add score for every cherry eaten
Now we got the labyrinth, not bad if it wasn’t for the fact that we cannot escape the enemies.
Let’s ask to be able to dig and destroy walls with a key and fire a ball with another that bounces on the wall and kill enemies the enemies. We got one ball and we get touch it after we throu it we can launch it again.

import pygame
import random
# Initialize Pygame
pygame.init()
# Set up the display
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mr. Do!-like Game")
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WALL_COLOR = (100, 50, 0) # Brown color for walls
# Grid settings
GRID_SIZE = 40
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
# Font
font = pygame.font.Font(None, 36)
# Game variables
player_x = player_y = 1
enemies = []
cherries = []
score = 0
game_over = False
def create_labyrinth():
labyrinth = [[1 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
def create_path(x, y):
labyrinth[y][x] = 0
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
random.shuffle(directions)
for dx, dy in directions:
nx, ny = x + dx*2, y + dy*2
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT and labyrinth[ny][nx] == 1:
labyrinth[y + dy][x + dx] = 0
create_path(nx, ny)
create_path(1, 1)
return labyrinth
def place_cherries():
cherries = []
for _ in range(20):
x, y = random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)
if labyrinth[y][x] == 0:
cherries.append((x, y))
return cherries
def place_enemies():
enemies = []
for _ in range(3):
while True:
x, y = random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)
if labyrinth[y][x] == 0 and (x, y) != (player_x, player_y):
enemies.append([x, y])
break
return enemies
def move_towards(enemy, target_x, target_y):
dx = target_x - enemy[0]
dy = target_y - enemy[1]
if abs(dx) > abs(dy):
return (enemy[0] + (1 if dx > 0 else -1), enemy[1])
else:
return (enemy[0], enemy[1] + (1 if dy > 0 else -1))
def draw_game():
screen.fill(BLACK)
# Draw labyrinth
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
if labyrinth[y][x] == 1:
pygame.draw.rect(screen, WALL_COLOR, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE))
pygame.draw.rect(screen, BLACK, (x * GRID_SIZE + 2, y * GRID_SIZE + 2, GRID_SIZE - 4, GRID_SIZE - 4))
# Draw player
pygame.draw.circle(screen, WHITE, (player_x * GRID_SIZE + GRID_SIZE // 2, player_y * GRID_SIZE + GRID_SIZE // 2), GRID_SIZE // 2 - 2)
# Draw cherries
for cherry in cherries:
pygame.draw.circle(screen, RED, (cherry[0] * GRID_SIZE + GRID_SIZE // 2, cherry[1] * GRID_SIZE + GRID_SIZE // 2), GRID_SIZE // 4)
# Draw enemies
for enemy in enemies:
pygame.draw.rect(screen, GREEN, (enemy[0] * GRID_SIZE + 2, enemy[1] * GRID_SIZE + 2, GRID_SIZE - 4, GRID_SIZE - 4))
# Draw score
score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
if game_over:
game_over_text = font.render("Game Over! Press R to Restart", True, WHITE)
screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - game_over_text.get_height() // 2))
pygame.display.flip()
def reset_game():
global player_x, player_y, enemies, cherries, score, game_over, labyrinth
player_x = player_y = 1
labyrinth = create_labyrinth()
cherries = place_cherries()
enemies = place_enemies()
score = 0
game_over = False
# Initial game setup
reset_game()
# Game loop
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if game_over:
if event.key == pygame.K_r:
reset_game()
else:
new_x, new_y = player_x, player_y
if event.key == pygame.K_LEFT:
new_x -= 1
elif event.key == pygame.K_RIGHT:
new_x += 1
elif event.key == pygame.K_UP:
new_y -= 1
elif event.key == pygame.K_DOWN:
new_y += 1
if 0 <= new_x < GRID_WIDTH and 0 <= new_y < GRID_HEIGHT and labyrinth[new_y][new_x] == 0:
player_x, player_y = new_x, new_y
if not game_over:
# Move enemies
for enemy in enemies:
new_pos = move_towards(enemy, player_x, player_y)
if labyrinth[new_pos[1]][new_pos[0]] == 0:
enemy[0], enemy[1] = new_pos
# Check collisions
if (player_x, player_y) in cherries:
cherries.remove((player_x, player_y))
score += 10
if [player_x, player_y] in enemies:
game_over = True
draw_game()
clock.tick(10) # Slower speed for grid-based movement
pygame.quit()
3. Ball bouncing
Make the player able to destroy walls with “z” and to launch a ball with “x”. The has a diagonal direction and bounces on the walls. If it reaches an enemy, kills the enemy and return to the player that can launch one ball at the time until it returns it back. If the player get into the ball the ball stops to move and the player can launch the ball again.
Claude stopped me for a couple of hour because I exeeded my messages, so I turned to Chat GPT to correct a bug there was in the code and it gave me this
import pygame
import random
import math
# Initialize Pygame
pygame.init()
# Set up the display
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mr. Do!-like Game")
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WALL_COLOR = (100, 50, 0)
BALL_COLOR = (255, 165, 0) # Orange
# Grid settings
GRID_SIZE = 40
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
# Font
font = pygame.font.Font(None, 36)
# Game variables
player_x = player_y = 1
player_direction = 0 # 0: right, 1: down, 2: left, 3: up
enemies = []
cherries = []
score = 0
game_over = False
# Ball variables
ball_x = ball_y = None
ball_direction = None
ball_active = False
def create_labyrinth():
labyrinth = [[1 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
def create_path(x, y):
labyrinth[y][x] = 0
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
random.shuffle(directions)
for dx, dy in directions:
nx, ny = x + dx*2, y + dy*2
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT and labyrinth[ny][nx] == 1:
labyrinth[y + dy][x + dx] = 0
create_path(nx, ny)
create_path(1, 1)
return labyrinth
def place_cherries():
return [(x, y) for y in range(GRID_HEIGHT) for x in range(GRID_WIDTH)
if labyrinth[y][x] == 0 and random.random() < 0.1]
def place_enemies():
enemy_list = []
while len(enemy_list) < 3:
x, y = random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)
if labyrinth[y][x] == 0 and (x, y) != (player_x, player_y):
enemy_list.append([x, y])
return enemy_list
def move_towards(enemy, target_x, target_y):
dx = target_x - enemy[0]
dy = target_y - enemy[1]
if abs(dx) > abs(dy):
return (enemy[0] + (1 if dx > 0 else -1), enemy[1])
else:
return (enemy[0], enemy[1] + (1 if dy > 0 else -1))
def launch_ball():
global ball_x, ball_y, ball_direction, ball_active
if not ball_active:
ball_x, ball_y = player_x, player_y
ball_direction = player_direction
ball_active = True
def move_ball():
global ball_x, ball_y, ball_direction, ball_active, enemies, score
if ball_active:
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
dx, dy = directions[ball_direction]
new_x, new_y = ball_x + dx, ball_y + dy
if 0 <= new_x < GRID_WIDTH and 0 <= new_y < GRID_HEIGHT:
if labyrinth[new_y][new_x] == 1:
if dx != 0 and labyrinth[ball_y][new_x] == 1:
ball_direction = (ball_direction + 2) % 4 # Reverse x direction
elif dy != 0 and labyrinth[new_y][ball_x] == 1:
ball_direction = (ball_direction + 2) % 4 # Reverse y direction
else:
ball_direction = (ball_direction + 1) % 4 # Change direction
else:
ball_x, ball_y = new_x, new_y
# Check for enemy collision
for enemy in enemies[:]:
if ball_x == enemy[0] and ball_y == enemy[1]:
enemies.remove(enemy)
score += 50
ball_active = False
return
# Check for player collision
if ball_x == player_x and ball_y == player_y:
ball_active = False
else:
ball_active = False # Deactivate ball at screen edge
def draw_game():
screen.fill(BLACK)
# Draw labyrinth
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
if labyrinth[y][x] == 1:
pygame.draw.rect(screen, WALL_COLOR, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE))
pygame.draw.rect(screen, BLACK, (x * GRID_SIZE + 2, y * GRID_SIZE + 2, GRID_SIZE - 4, GRID_SIZE - 4))
# Draw player
pygame.draw.circle(screen, WHITE, (player_x * GRID_SIZE + GRID_SIZE // 2, player_y * GRID_SIZE + GRID_SIZE // 2), GRID_SIZE // 2 - 2)
# Draw cherries
for cherry in cherries:
pygame.draw.circle(screen, RED, (cherry[0] * GRID_SIZE + GRID_SIZE // 2, cherry[1] * GRID_SIZE + GRID_SIZE // 2), GRID_SIZE // 4)
# Draw enemies
for enemy in enemies:
pygame.draw.rect(screen, GREEN, (enemy[0] * GRID_SIZE + 2, enemy[1] * GRID_SIZE + 2, GRID_SIZE - 4, GRID_SIZE - 4))
# Draw ball
if ball_active:
pygame.draw.circle(screen, BALL_COLOR, (ball_x * GRID_SIZE + GRID_SIZE // 2, ball_y * GRID_SIZE + GRID_SIZE // 2), GRID_SIZE // 4)
# Draw score
score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
if game_over:
game_over_text = font.render("Game Over! Press R to Restart", True, WHITE)
screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - game_over_text.get_height() // 2))
pygame.display.flip()
def reset_game():
global player_x, player_y, player_direction, enemies, cherries, score, game_over, labyrinth, ball_active
player_x = player_y = 1
player_direction = 0
labyrinth = create_labyrinth()
cherries = place_cherries()
enemies = place_enemies()
score = 0
game_over = False
ball_active = False
# Initial game setup
reset_game()
# Game loop
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if game_over:
if event.key == pygame.K_r:
reset_game()
else:
new_x, new_y = player_x, player_y
if event.key == pygame.K_LEFT:
new_x -= 1
player_direction = 2
elif event.key == pygame.K_RIGHT:
new_x += 1
player_direction = 0
elif event.key == pygame.K_UP:
new_y -= 1
player_direction = 3
elif event.key == pygame.K_DOWN:
new_y += 1
player_direction = 1
elif event.key == pygame.K_z:
# Destroy wall
dx, dy = [(1, 0), (0, 1), (-1, 0), (0, -1)][player_direction]
wall_x, wall_y = player_x + dx, player_y + dy
if 0 <= wall_x < GRID_WIDTH and 0 <= wall_y < GRID_HEIGHT:
if labyrinth[wall_y][wall_x] == 1:
labyrinth[wall_y][wall_x] = 0
score += 5
elif event.key == pygame.K_x:
launch_ball()
if 0 <= new_x < GRID_WIDTH and 0 <= new_y < GRID_HEIGHT and labyrinth[new_y][new_x] == 0:
player_x, player_y = new_x, new_y
if not game_over:
# Move enemies
for enemy in enemies:
new_pos = move_towards(enemy, player_x, player_y)
if labyrinth[new_pos[1]][new_pos[0]] == 0:
enemy[0], enemy[1] = new_pos
# Move ball
move_ball()
# Check collisions
if (player_x, player_y) in cherries:
cherries.remove((player_x, player_y))
score += 10
if [player_x, player_y] in enemies:
game_over = True
draw_game()
clock.tick(10) # Slower speed for grid-based movement
pygame.quit()
As you can see the game is getting some sense, even if the tajectory of the ball is not what I intended but it comes back and works well apart for the direction, but that can be fixed in the next post. Bye.
Subscribe to the newsletter for updates
Tkinter templatesTwitter: @pythonprogrammi - python_pygame
Claude's Games
1. Memory gameVideos
Speech recognition gamePygame's Platform Game