Remaking Battle City with Amazon Q CLI

I'm not gonna lie, I got an email from Amazon saying that if I give Amazon Q CLI a try, I can get a free T-shirt, so here it is.

Why Battle City?

Prompting Tips That Worked

Using Q felt like working with a helpful dev buddy. The trick? Be clear and specific:

As long as you explain clearly what you want to achieve, and preferrably in small chunk, Amazon Q will most likely get it right.

Classic Challenges

I dabbled with game making a while back, and there are a few typical challenges that all game makers usually have to solve. But thankfully, Amazon Q took care of them pretty efficiently.

Huge Time-Savers

Q CLI generated a bunch of things, well okay, all the things:

Took me about 3 hours typing some prompts, while I'm pretty sure it may take me weeks to produce this clone.

Cool Code Snippet

Amazon Q itself thinks the drawing for tank explosion is pretty cool, because it "simulates realistic particle physics".

draw() {                                                                                                        
        // Save context state                                                                                       
        ctx.save();                                                                                                 
                                                                                                                    
        // Set global composite operation for glow effect                                                           
        ctx.globalCompositeOperation = 'lighter';                                                                   
                                                                                                                    
        // Draw explosion center glow                                                                               
        const gradient = ctx.createRadialGradient(                                                                  
            this.x, this.y, 0,                                                                                      
            this.x, this.y, 30 * this.size * (1 - this.frame / this.maxFrames)                                      
        );                                                                                                          
                                                                                                                    
        gradient.addColorStop(0, `rgba(255, 255, 200, ${0.8 * (1 - this.frame / this.maxFrames)})`);                
        gradient.addColorStop(0.4, `rgba(255, 120, 50, ${0.6 * (1 - this.frame / this.maxFrames)})`);               
        gradient.addColorStop(1, `rgba(255, 20, 0, ${0.1 * (1 - this.frame / this.maxFrames)})`);                   
                                                                                                                    
        ctx.fillStyle = gradient;                                                                                   
        ctx.beginPath();                                                                                            
        ctx.arc(this.x, this.y, 30 * this.size * (1 - this.frame / (this.maxFrames * 1.5)), 0, Math.PI * 2);        
        ctx.fill();                                                                                                 
                                                                                                                    
        // Draw particles                                                                                           
        for (const particle of this.particles) {                                                                    
            if (particle.life <= 0) continue;                                                                       
                                                                                                                    
            const alpha = particle.life / particle.maxLife;                                                         
            ctx.fillStyle = particle.color + Math.floor(alpha * 255).toString(16).padStart(2, '0');                 
                                                                                                                    
            ctx.beginPath();                                                                                        
            ctx.arc(                                                                                                
                this.x + particle.x,                                                                                
                this.y + particle.y,                                                                                
                particle.size * alpha,                                                                              
                0,                                                                                                  
                Math.PI * 2                                                                                         
            );                                                                                                      
            ctx.fill();                                                                                             
        }                                                                                                           
                                                                                                                    
        // Draw shock wave                                                                                          
        if (this.frame < this.maxFrames / 2) {                                                                      
            ctx.strokeStyle = `rgba(255, 255, 255, ${0.5 * (1 - this.frame / (this.maxFrames / 2))})`;              
            ctx.lineWidth = 2;                                                                                      
            ctx.beginPath();                                                                                        
            ctx.arc(this.x, this.y, this.frame * 2 * this.size, 0, Math.PI * 2);                                    
            ctx.stroke();                                                                                           
        }                                                                                                           
                                                                                                                    
        // Restore context state                                                                                    
        ctx.restore();                                                                                              
    }                                   

Screenshots

Battle City gameplay showing the player tank and map layout
Level 1
Battle City gameplay showing combat with enemy tanks
Level 2

Final Thoughts

Giving my understanding of how complex game making is, and Amazon Q actually got it done pretty nicely, I think it really opens up possibilities. Maybe I will try to create a minigame site with Amazon Q's help!

You can give it a try and see for yourself

Score: 0
Level: 1
Health: 3
Enemies: 0/20
GAME OVER

Battle City Clone

  • ⬆️ Arrow Up: Move tank up
  • ⬇️ Arrow Down: Move tank down
  • ⬅️ Arrow Left: Move tank left
  • ➡️ Arrow Right: Move tank right
  • 🔫 Spacebar: Fire

Destroy enemy tanks and protect your base!