Falling Stars Game: Powered by Amazon Q CLI
The Falling Stars Game is an addictive arcade game I built entirely using Amazon Q CLI, a generative AI coding assistant that made turning my ideas into reality a breeze. Using Python and Pygame, this game puts you in control of an airship, catching falling objects, dodging deadly ones, and snagging power-ups to rack up points. In this post, I’ll dive into how Amazon Q CLI brought this game to life, highlight the game’s core features, and share a glimpse of the development process with a screenshot of Amazon Q in action. Whether you’re a coder or a gamer, this project shows what AI can do!
Installing Amazon Q CLI on Windows via WSL
Amazon Q CLI doesn't have a native Windows version, but it can be easily installed and used through the Windows Subsystem for Linux (WSL). This method gives you access to a Linux environment directly from your Windows machine, making it straightforward to work with the CLI tools designed for Linux.
Here's a step-by-step guide to get Amazon Q CLI running on Windows using WSL with Ubuntu:
Installing Amazon Q CLI on Ubuntu (WSL)
- Check glibc Version Before downloading, determine which installer version you need by checking your glibc version:
ldd --version
If glibc is 2.34 or newer, use the standard version.
If glibc is older, use the musl version.
- Download the Appropriate Installer Choose the correct command based on your architecture and glibc version.
Standard version (glibc 2.34+)
Linux x86-64:
curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-x86_64-linux.zip" -o "q.zip"
Linux ARM (aarch64):
curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-aarch64-linux.zip" -o "q.zip"
Musl version (glibc < 2.34)
Linux x86-64 (musl):
curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-x86_64-linux-musl.zip" -o "q.zip"
Linux ARM (aarch64, musl):
curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-aarch64-linux-musl.zip" -o "q.zip"
- Install Amazon Q CLI Unzip the package and run the installer:
unzip q.zip
./q/install.sh
By default, Amazon Q CLI will be installed to: ~/.local/bin.
- Configure AWS Credentials (Optional)
If you haven't already, configure your AWS credentials within the WSL environment:
aws configure
This step is necessary for Amazon Q CLI to interact with your AWS account.
- Configure your AWS credentials within the WSL environment using the following command:
q login
For additional options and detailed instructions for other platforms, refer to the official Amazon Q CLI Installation Documentation.
Amazon Q CLI: My Coding Sidekick
Amazon Q CLI is an AI tool that generates code, suggests features, and debugs issues through simple command-line prompts. I used it to build Falling Stars Game from the ground up, starting with basic concepts and iterating to a polished product. With prompts like “create a Pygame game where a player catches falling objects,” Amazon Q churned out working code, suggested additions like power-ups and levels, and helped fix bugs when things went off track. Its ability to understand my intent and provide Pygame-specific solutions saved hours of work.
The CLI’s conversational style let me refine the game step-by-step, from spawning objects to adding sound effects. For example, when collision detection was glitchy, a prompt like “fix object collision in Pygame” got me a corrected algorithm. The screenshot below (to be added) captures Amazon Q in action, showing how it shaped the game’s core mechanics.
Amazon Q CLI in Action
Initially, I gave a simple prompt to Amazon Q, like:
'Can you guide me to create a game using Pygame?'
It gave me the Python code for the game in a single file, so I asked to structure it like a proper project. As a result, Amazon Q provided me with the following file structure for my game project:
Amazon Q suggested this clean setup for the game:
falling_stars_game/
├── README.md
├── assets
│   ├── images
│   │   ├── background.jpg
│   │   ├── dangerous_object.png
│   │   ├── normal_object.png
│   │   ├── player.png
│   │   ├── powerup_life.png
│   │   ├── powerup_slower.png
│   │   ├── powerup_wider.png
│   │   └── special_object.png
│   └── sounds
│       ├── background.mp3
│       ├── catch.wav
│       ├── gameover.wav
│       └── powerup.wav
├── run_game.py
└── src
    └── game.py
assets/: Holds images and sounds.
src/game.py: Core game logic.
run_game.py: Launches the game.
README.md: Guides setup and gameplay.
Game Overview
Falling Stars Game is a fast-paced arcade challenge set on an 800x600 screen. You control a movable brick wall to catch falling stars for points while avoiding red ones that end the game. Power-ups occasionally drop to give you an edge. With custom graphics, sound effects, and toggleable music, the game feels polished and immersive. A five-level difficulty system keeps the gameplay engaging. Every component — from the game loop to the user interface — was built using the Amazon Q CLI.
Key Features
Objects in the game:
- ⭐ Purple-background star: +1 point, falls at a steady speed.
- ⭐ White-background star (Special): +5 points, faster and harder to catch.
- 🔥 Red fire object: Game over if caught — avoid at all costs.
- ❤️ Heart: Grants an extra life.
- ⏱️ Green timer clock: Temporarily slows down all falling objects, making them easier to catch.
- 🔷 Blue wider object: Temporarily increases the width of your brick wall, making catching objects easier.
Levels:
- Five levels, advancing every 50 points. Higher levels mean faster objects, quicker spawns, and more green objects.
Visuals & Audio:
- Custom .png images for the brick wal, objects, and power-ups. 
- Sounds for catches (catch.wav), power-ups (powerup.wav), and game over (gameover.wav). 
- Background music (background.mp3), toggleable with the M key. 
- UI shows score, level, lives (as icons), and power-up timers. 
Controls:
- Left/Right Arrows: Move the airship.
- P: Pause/unpause.
- M: Toggle music.
- R: Restart after game over.
Code Highlights
Here's the complete game.py implementation:
import pygame
import random
import sys
import os
from pathlib import Path
# Get the base directory
BASE_DIR = Path(__file__).resolve().parent.parent
ASSETS_DIR = BASE_DIR / "assets"
IMAGES_DIR = ASSETS_DIR / "images"
SOUNDS_DIR = ASSETS_DIR / "sounds"
# Initialize Pygame
pygame.init()
pygame.mixer.init()  # Initialize sound mixer
# Screen dimensions
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
PURPLE = (128, 0, 128)
# Create the screen
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Falling Stars Game")
# Load images
try:
    background_img = pygame.image.load(IMAGES_DIR / "background.jpg").convert()
    background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
    # Load normal player image
    player_img = pygame.image.load(IMAGES_DIR / "player.png").convert_alpha()
    # Scale the player image to the correct size for the game
    player_img = pygame.transform.scale(player_img, (100, 80))  # Increased height to show more of the image
    normal_obj_img = pygame.image.load(IMAGES_DIR / "normal_object.png").convert_alpha()
    normal_obj_img = pygame.transform.scale(normal_obj_img, (50, 50))
    special_obj_img = pygame.image.load(IMAGES_DIR / "special_object.png").convert_alpha()
    special_obj_img = pygame.transform.scale(special_obj_img, (50, 50))
    dangerous_obj_img = pygame.image.load(IMAGES_DIR / "dangerous_object.png").convert_alpha()
    dangerous_obj_img = pygame.transform.scale(dangerous_obj_img, (50, 50))
    powerup_wider_img = pygame.image.load(IMAGES_DIR / "powerup_wider.png").convert_alpha()
    powerup_wider_img = pygame.transform.scale(powerup_wider_img, (50, 50))
    powerup_slower_img = pygame.image.load(IMAGES_DIR / "powerup_slower.png").convert_alpha()
    # Make the slower powerup larger (60x60 pixels)
    powerup_slower_img = pygame.transform.scale(powerup_slower_img, (60, 60))
    powerup_life_img = pygame.image.load(IMAGES_DIR / "powerup_life.png").convert_alpha()
    powerup_life_img = pygame.transform.scale(powerup_life_img, (50, 50))
    # Dictionary to store images for easy access
    images = {
        'player': player_img,
        'normal': normal_obj_img,
        'special': special_obj_img,
        'dangerous': dangerous_obj_img,
        'wider': powerup_wider_img,
        'slower': powerup_slower_img,
        'extra_life': powerup_life_img
    }
except Exception as e:
    print(f"Error loading images: {e}")
    # We'll use colored rectangles if images fail to load
    images = {}
# Load sounds
try:
    catch_sound = pygame.mixer.Sound(SOUNDS_DIR / "catch.wav")
    powerup_sound = pygame.mixer.Sound(SOUNDS_DIR / "powerup.wav")
    game_over_sound = pygame.mixer.Sound(SOUNDS_DIR / "gameover.wav")
    # Set volume
    catch_sound.set_volume(0.5)
    powerup_sound.set_volume(0.7)
    game_over_sound.set_volume(0.8)
    # Try to load background music
    try:
        pygame.mixer.music.load(SOUNDS_DIR / "background.mp3")
        pygame.mixer.music.set_volume(0.3)
        pygame.mixer.music.play(-1)  # -1 means loop indefinitely
        music_playing = True
    except:
        print("Background music not found")
        music_playing = False
except Exception as e:
    print(f"Error loading sounds: {e}")
    # Create dummy sound objects
    catch_sound = None
    powerup_sound = None
    game_over_sound = None
    music_playing = False
# Player settings
player_width = 100
player_height = 80  # Increased height to show more of the image
player_x = SCREEN_WIDTH // 2 - player_width // 2
player_y = SCREEN_HEIGHT - 90  # Moved player up a bit to accommodate taller image
player_speed = 10
player_lives = 3
# Object settings
object_size = 50
objects = []
spawn_timer = 0
# Power-up settings
powerups = []
powerup_timer = 0
powerup_delay = 300  # Frames between powerup spawns
active_powerups = {}
wider_level = 1  # Track the current width level (1=normal, 2=double, 3=triple)
# Game settings
score = 0
level = 1
font = pygame.font.Font(None, 36)
small_font = pygame.font.Font(None, 24)
clock = pygame.time.Clock()
game_over = False
paused = False
music_playing = music_playing if 'music_playing' in locals() else False
# Level settings
level_settings = {
    1: {"spawn_delay": 60, "object_speed": 3, "special_chance": 0.1},
    2: {"spawn_delay": 50, "object_speed": 4, "special_chance": 0.15},
    3: {"spawn_delay": 40, "object_speed": 5, "special_chance": 0.2},
    4: {"spawn_delay": 30, "object_speed": 6, "special_chance": 0.25},
    5: {"spawn_delay": 20, "object_speed": 7, "special_chance": 0.3}
}
# Current level settings
current_settings = level_settings[1]
spawn_delay = current_settings["spawn_delay"]
object_speed = current_settings["object_speed"]
special_chance = current_settings["special_chance"]
def draw_player(x, y):
    if 'player' in images:
        # If we have a player image, use it
        if 'wider' in active_powerups and active_powerups['wider'] > 0:
            # Draw multiple player images side by side based on wider_level
            img_width = player_img.get_width()
            # Draw the images side by side with slight overlap
            for i in range(wider_level):
                pos_x = x + (i * (img_width - 20))  # Overlap by 20 pixels
                screen.blit(images['player'], (pos_x, y))
        else:
            # Use normal airship image
            screen.blit(images['player'], (x, y))
    else:
        # Fallback to a rectangle
        if 'wider' in active_powerups and active_powerups['wider'] > 0:
            pygame.draw.rect(screen, BLUE, [x, y, player_width, player_height])
        else:
            pygame.draw.rect(screen, BLUE, [x, y, 100, player_height])
    # Draw player lives
    for i in range(player_lives):
        if 'extra_life' in images:
            screen.blit(pygame.transform.scale(images['extra_life'], (20, 20)), (10 + i * 30, 40))
        else:
            pygame.draw.rect(screen, RED, [10 + i * 30, 40, 20, 20])
def create_object():
    x = random.randint(0, SCREEN_WIDTH - object_size)
    obj_type = random.choices(
        ['normal', 'special', 'dangerous'], 
        weights=[0.7, special_chance, 0.3-special_chance], 
        k=1
    )[0]
    speed_variation = random.uniform(0.8, 1.2)
    if obj_type == 'normal':
        color = RED
        points = 1
        speed = object_speed * speed_variation
    elif obj_type == 'special':
        color = GREEN
        points = 5
        speed = object_speed * 1.2 * speed_variation
    else:  # dangerous
        color = PURPLE
        points = 0  # Points don't matter as game will end if caught
        speed = object_speed * 0.9 * speed_variation
    return {'x': x, 'y': 0, 'type': obj_type, 'color': color, 'points': points, 'speed': speed}
def create_powerup():
    x = random.randint(0, SCREEN_WIDTH - object_size)
    powerup_type = random.choice(['wider', 'slower', 'extra_life'])
    if powerup_type == 'wider':
        color = YELLOW
        size = object_size
    elif powerup_type == 'slower':
        color = (0, 255, 255)  # Cyan
        size = 60  # Larger size for slower powerup
    else:  # extra_life
        color = (255, 105, 180)  # Pink
        size = object_size
    return {'x': x, 'y': 0, 'type': powerup_type, 'color': color, 'speed': object_speed * 0.7, 'size': size}
def draw_objects():
    for obj in objects:
        if obj['type'] in images:
            screen.blit(images[obj['type']], (obj['x'], obj['y']))
        else:
            pygame.draw.rect(screen, obj['color'], [obj['x'], obj['y'], object_size, object_size])
def draw_powerups():
    for pu in powerups:
        if pu['type'] in images:
            # Special handling for the slower powerup to make it larger
            if pu['type'] == 'slower':
                screen.blit(images[pu['type']], (pu['x'] - 5, pu['y'] - 5))  # Adjust position to center it
            else:
                screen.blit(images[pu['type']], (pu['x'], pu['y']))
        else:
            # Fallback to colored rectangles
            if pu['type'] == 'slower':
                # Draw a larger rectangle for slower powerup
                pygame.draw.rect(screen, pu['color'], [pu['x'] - 5, pu['y'] - 5, 60, 60])
                # Draw a "S" on the powerup
                text = small_font.render("S", True, BLACK)
                screen.blit(text, (pu['x'] + 25, pu['y'] + 20))
            else:
                pygame.draw.rect(screen, pu['color'], [pu['x'], pu['y'], object_size, object_size])
                # Draw a "P" on the powerup
                text = small_font.render("P", True, BLACK)
                screen.blit(text, (pu['x'] + 20, pu['y'] + 15))
def show_score():
    score_text = font.render(f"Score: {score}", True, WHITE)
    level_text = font.render(f"Level: {level}", True, WHITE)
    lives_text = font.render(f"Lives: {player_lives}", True, WHITE)
    screen.blit(score_text, (10, 10))
    screen.blit(level_text, (SCREEN_WIDTH - 120, 10))
    screen.blit(lives_text, (10, 50))
    # Show music status
    music_text = small_font.render("Music: " + ("ON" if music_playing else "OFF") + " (M to toggle)", True, WHITE)
    screen.blit(music_text, (SCREEN_WIDTH - 220, 50))
    # Show active powerups with icons
    y_offset = 90
    for powerup_type, time_left in active_powerups.items():
        if time_left > 0:
            if powerup_type in images:
                # Draw a small version of the powerup icon
                small_icon = pygame.transform.scale(images[powerup_type], (20, 20))
                screen.blit(small_icon, (10, y_offset))
                # For wider powerup, show the current level
                if powerup_type == 'wider':
                    powerup_text = small_font.render(f"{powerup_type.capitalize()} (x{wider_level}): {time_left//60}s", True, YELLOW)
                else:
                    powerup_text = small_font.render(f"{powerup_type.capitalize()}: {time_left//60}s", True, YELLOW)
                screen.blit(powerup_text, (35, y_offset + 2))  # Align text with icon
            else:
                # Fallback if image not available
                if powerup_type == 'wider':
                    powerup_text = small_font.render(f"{powerup_type.capitalize()} (x{wider_level}): {time_left//60}s", True, YELLOW)
                else:
                    powerup_text = small_font.render(f"{powerup_type.capitalize()}: {time_left//60}s", True, YELLOW)
                screen.blit(powerup_text, (10, y_offset))
            y_offset += 25
def check_level_up():
    global level, current_settings, spawn_delay, object_speed, special_chance
    # Level up every 50 points
    new_level = min(5, 1 + score // 50)
    if new_level > level:
        level = new_level
        current_settings = level_settings[level]
        spawn_delay = current_settings["spawn_delay"]
        object_speed = current_settings["object_speed"]
        special_chance = current_settings["special_chance"]
        # Show level up message
        return True
    return False
def apply_powerup(powerup_type):
    global player_width, object_speed, player_lives, wider_level
    if powerup_type == 'wider':
        # Increase the wider level (max 3)
        wider_level = min(3, wider_level + 1)
        # Set width based on wider_level
        if wider_level == 2:
            player_width = 160  # Enough for 2 images with overlap
        elif wider_level == 3:
            player_width = 220  # Enough for 3 images with overlap
        active_powerups['wider'] = 600  # 10 seconds (60 fps * 10)
    elif powerup_type == 'slower':
        object_speed *= 0.7
        active_powerups['slower'] = 300  # 5 seconds
    elif powerup_type == 'extra_life':
        player_lives = min(5, player_lives + 1)
    # Play powerup sound
    if powerup_sound:
        powerup_sound.play()
def update_powerups():
    global player_width, object_speed, wider_level
    for powerup_type in list(active_powerups.keys()):
        active_powerups[powerup_type] -= 1
        if active_powerups[powerup_type] <= 0:
            # Powerup expired
            if powerup_type == 'wider':
                player_width = 100  # Reset to default airship width
                wider_level = 1     # Reset wider level
            elif powerup_type == 'slower':
                object_speed = current_settings["object_speed"]  # Reset to level default
            del active_powerups[powerup_type]
def show_message(message, y_offset=0):
    text = font.render(message, True, WHITE)
    text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + y_offset))
    # Draw a semi-transparent background for the text
    s = pygame.Surface((text_rect.width + 20, text_rect.height + 20))
    s.set_alpha(200)
    s.fill(BLACK)
    screen.blit(s, (text_rect.x - 10, text_rect.y - 10))
    screen.blit(text, text_rect)
# Main game loop
running = True
level_up_message_timer = 0
show_level_up = False
while running:
    # Handle events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_p:
                paused = not paused
            elif event.key == pygame.K_m:
                # Toggle music on/off
                if music_playing:
                    pygame.mixer.music.pause()
                    music_playing = False
                else:
                    try:
                        pygame.mixer.music.unpause()
                        music_playing = True
                    except:
                        # If music wasn't loaded or was stopped (not paused)
                        try:
                            pygame.mixer.music.play(-1)
                            music_playing = True
                        except:
                            pass
            elif event.key == pygame.K_r and game_over:
                # Reset game
                game_over = False
                score = 0
                level = 1
                player_lives = 3
                player_width = 100
                wider_level = 1  # Reset wider level
                objects = []
                powerups = []
                active_powerups = {}
                player_x = SCREEN_WIDTH // 2 - player_width // 2
                current_settings = level_settings[1]
                spawn_delay = current_settings["spawn_delay"]
                object_speed = current_settings["object_speed"]
                special_chance = current_settings["special_chance"]
                # Restart background music
                try:
                    pygame.mixer.music.play(-1)
                except:
                    pass
    # Draw background
    if 'background' in locals() and background_img:
        screen.blit(background_img, (0, 0))
    else:
        # Fallback to a gradient background
        for y in range(0, SCREEN_HEIGHT, 2):
            color_value = 50 + (y / SCREEN_HEIGHT * 50)
            pygame.draw.rect(screen, (50, 50, color_value), [0, y, SCREEN_WIDTH, 2])
    if not game_over and not paused:
        # Move player
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] and player_x > 0:
            player_x -= player_speed
        if keys[pygame.K_RIGHT] and player_x < SCREEN_WIDTH - player_width:
            player_x += player_speed
        # Update powerups
        update_powerups()
        # Spawn new objects
        spawn_timer += 1
        if spawn_timer >= spawn_delay:
            objects.append(create_object())
            spawn_timer = 0
        # Spawn powerups
        powerup_timer += 1
        if powerup_timer >= powerup_delay:
            powerups.append(create_powerup())
            powerup_timer = 0
        # Move objects
        for obj in objects[:]:
            obj['y'] += obj['speed']
            # Check if object is caught
            if (obj['y'] + object_size > player_y and 
                obj['y'] < player_y + player_height and
                obj['x'] + object_size > player_x and
                obj['x'] < player_x + player_width):
                objects.remove(obj)
                # Check if dangerous object was caught
                if obj['type'] == 'dangerous':
                    # Game over immediately if dangerous object is caught
                    game_over = True
                    if game_over_sound:
                        game_over_sound.play()
                    # Stop background music
                    pygame.mixer.music.stop()
                else:
                    # Add points for non-dangerous objects
                    score += obj['points']
                    # Play catch sound
                    if catch_sound:
                        catch_sound.play()
                    # Check for level up
                    if check_level_up():
                        show_level_up = True
                        level_up_message_timer = 180  # Show for 3 seconds
            # Check if object is missed
            elif obj['y'] > SCREEN_HEIGHT:
                objects.remove(obj)
                if obj['type'] != 'dangerous':  # Only lose lives for non-dangerous objects
                    player_lives -= 1
                    if player_lives <= 0:
                        game_over = True
                        if game_over_sound:
                            game_over_sound.play()
                        # Stop background music
                        pygame.mixer.music.stop()
        # Move powerups
        for pu in powerups[:]:
            pu['y'] += pu['speed']
            # Check if powerup is caught
            if (pu['y'] + (pu['size'] if 'size' in pu else object_size) > player_y and 
                pu['y'] < player_y + player_height and
                pu['x'] + (pu['size'] if 'size' in pu else object_size) > player_x and
                pu['x'] < player_x + player_width):
                powerups.remove(pu)
                apply_powerup(pu['type'])
            # Check if powerup is missed
            elif pu['y'] > SCREEN_HEIGHT:
                powerups.remove(pu)
    # Draw everything
    draw_player(player_x, player_y)
    draw_objects()
    draw_powerups()
    show_score()
    # Show level up message
    if show_level_up:
        level_up_message_timer -= 1
        show_message(f"Level Up! Level {level}", -50)
        if level_up_message_timer <= 0:
            show_level_up = False
    if game_over:
        show_message("Game Over! Press R to restart")
        show_message("Final Score: " + str(score), 50)
    if paused:
        show_message("PAUSED - Press P to continue")
    # Update display
    pygame.display.flip()
    clock.tick(60)
# Quit the game
pygame.quit()
sys.exit()
Progressive Widening Power-up
The game implements a unique widening system where collecting multiple power-ups increases your paddle width in stages:
def apply_powerup(powerup_type):
    global player_width, object_speed, player_lives, wider_level
    if powerup_type == 'wider':
        wider_level = min(3, wider_level + 1)
        if wider_level == 2:
            player_width = 160
        elif wider_level == 3:
            player_width = 220
        active_powerups['wider'] = 600
Multiple Object Types
The game features three types of falling objects with different behaviors:
def create_object():
    obj_type = random.choices(
        ['normal', 'special', 'dangerous'],
        weights=[0.7, special_chance, 0.3-special_chance],
        k=1
    )[0]
    if obj_type == 'normal':
        color = RED
        points = 1
    elif obj_type == 'special':
        color = GREEN
        points = 5
    else:  # dangerous
        color = PURPLE
        points = 0  # Game over if caught
Level System
The game automatically progresses through 5 difficulty levels:
level_settings = {
    1: {"spawn_delay": 60, "object_speed": 3, "special_chance": 0.1},
    2: {"spawn_delay": 50, "object_speed": 4, "special_chance": 0.15},
    3: {"spawn_delay": 40, "object_speed": 5, "special_chance": 0.2},
    4: {"spawn_delay": 30, "object_speed": 6, "special_chance": 0.25},
    5: {"spawn_delay": 20, "object_speed": 7, "special_chance": 0.3}
}
What Stands Out:
- Assets: Loads images and sounds with fallbacks (gradient background, colored rectangles).
- Spawning: create_object balances object types with random.choices, adjusting for level difficulty.
- Power-Ups: apply_powerup dynamically adjusts paddle width and object speed.
- UI: Shows lives as icons, power-up timers, and a semi-transparent message box for pause/game over.
- Loop: Runs at 60 FPS, handling input, updates, and rendering.
- Amazon Q structured the code cleanly, using pathlib for paths and suggesting a level_settings dictionary for easy tweaks.
Building with Amazon Q CLI
Developing the game was a smooth ride with Amazon Q CLI:
- Starting Out: A prompt like “set up a Pygame game with a moving paddle” gave me the initial loop and player controls.
- Adding Objects: “Add falling objects with different types” led to the create_object function, with Amazon Q suggesting weighted probabilities for balance.
- Power-Ups: “Implement power-ups for wider paddle and extra lives” introduced the wider_level system and timers.
- Polish: Prompts like “add background music and UI” brought in audio and a clean interface with lives displayed as icons.
- Debugging: When power-ups didn’t reset properly, “fix power-up expiration” got me the update_powerups function. Amazon Q also caught asset loading errors early.
- The CLI’s speed and smarts made iterating fun, though I had to be specific with prompts to get exactly what I wanted, like centering the “S” on the slower power-up.
How to Play game:
- clone the project repository
git clone https://github.com/rifkhan107/falling_stars_game-amazaon-q
- Install pygame
pip install pygame
- cd falling_stars_game
cd falling_stars_game
python3 run_game.py
Play:
- Use Left/Right arrows to move.
- Catch red/green objects, dodge purple.
- Grab power-ups for advantages.
- P (pause), M (music toggle), R (restart).
- Takeaways
Amazon Q CLI was a powerhouse:
- Wins: Fast code generation, creative ideas (like the wider paddle progression), and quick fixes.
- Hurdles: Needed clear prompts for complex features; minor manual tweaks for polish.
What’s Next?
With Amazon Q, I could:
- Save high scores to a file.
- Add a “shield” power-up to block purple objects.
- Build a start menu with options.
Final Thoughts
Falling Stars Game is proof Amazon Q CLI can turn a game idea into reality fast. It’s fun to play, looks sharp, and was built with AI smarts. Add the screenshot to see Amazon Q in action, then try the game or use Q to code your own. Happy gaming and coding!
 
 
              
 
                      



 
    
Top comments (2)
Superb bruh♥️🙌🏻
Thanks Bruhh 😁