using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace SimpleAirCombat
{
public partial class GameForm : Form
{
private Player player;
private List<Enemy> enemies = new List<Enemy>();
private List<Bullet> bullets = new List<Bullet>();
private int score = 0;
private int lives = 3;
private bool gameOver = false;
private bool gameStarted = false;
private Random random = new Random();
private int enemySpawnCounter = 0;
private const int ENEMY_SPAWN_RATE = 30;
public GameForm()
{
InitializeComponent();
this.Text = "简易飞机大战";
this.ClientSize = new Size(800, 600);
this.DoubleBuffered = true;
this.BackColor = Color.Black;
this.KeyDown += GameForm_KeyDown;
this.KeyPreview = true;
player = new Player();
player.Position = new Point(this.ClientSize.Width / 2 - 25, this.ClientSize.Height - 100);
gameTimer.Interval = 20;
gameTimer.Tick += GameTimer_Tick;
gameTimer.Start();
}
private void GameForm_KeyDown(object sender, KeyEventArgs e)
{
if (!gameStarted && e.KeyCode == Keys.Space)
{
StartGame();
return;
}
if (gameOver && e.KeyCode == Keys.R)
{
ResetGame();
return;
}
if (gameStarted && !gameOver)
{
const int moveSpeed = 8;
if (e.KeyCode == Keys.Left || e.KeyCode == Keys.A)
{
player.Position = new Point(
Math.Max(0, player.Position.X - moveSpeed),
player.Position.Y);
}
else if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D)
{
player.Position = new Point(
Math.Min(this.ClientSize.Width - player.Width, player.Position.X + moveSpeed),
player.Position.Y);
}
else if (e.KeyCode == Keys.Up || e.KeyCode == Keys.W)
{
player.Position = new Point(
player.Position.X,
Math.Max(0, player.Position.Y - moveSpeed));
}
else if (e.KeyCode == Keys.Down || e.KeyCode == Keys.S)
{
player.Position = new Point(
player.Position.X,
Math.Min(this.ClientSize.Height - player.Height, player.Position.Y + moveSpeed));
}
else if (e.KeyCode == Keys.Space)
{
Shoot();
}
}
}
private void StartGame()
{
gameStarted = true;
gameOver = false;
score = 0;
lives = 3;
enemies.Clear();
bullets.Clear();
}
private void ResetGame()
{
StartGame();
}
private void Shoot()
{
bullets.Add(new Bullet(new Point(
player.Position.X + player.Width / 2 - 3,
player.Position.Y
)));
}
private void GameTimer_Tick(object sender, EventArgs e)
{
if (!gameStarted || gameOver) return;
enemySpawnCounter++;
if (enemySpawnCounter >= ENEMY_SPAWN_RATE)
{
SpawnEnemy();
enemySpawnCounter = 0;
}
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update();
if (bullets[i].Position.Y < -20)
{
bullets.RemoveAt(i);
}
}
for (int i = enemies.Count - 1; i >= 0; i--)
{
enemies[i].Update();
if (enemies[i].Position.Y > this.ClientSize.Height)
{
enemies.RemoveAt(i);
}
}
for (int i = bullets.Count - 1; i >= 0; i--)
{
Rectangle bulletRect = new Rectangle(bullets[i].Position, bullets[i].Size);
for (int j = enemies.Count - 1; j >= 0; j--)
{
Rectangle enemyRect = new Rectangle(enemies[j].Position, enemies[j].Size);
if (bulletRect.IntersectsWith(enemyRect))
{
bullets.RemoveAt(i);
enemies.RemoveAt(j);
score += 10;
break;
}
}
}
Rectangle playerRect = new Rectangle(player.Position, player.Size);
for (int i = enemies.Count - 1; i >= 0; i--)
{
Rectangle enemyRect = new Rectangle(enemies[i].Position, enemies[i].Size);
if (playerRect.IntersectsWith(enemyRect))
{
enemies.RemoveAt(i);
lives--;
if (lives <= 0)
{
gameOver = true;
}
break;
}
}
this.Invalidate();
}
private void SpawnEnemy()
{
int x = random.Next(0, this.ClientSize.Width - 40);
enemies.Add(new Enemy(new Point(x, -40)));
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
if (!gameStarted)
{
DrawStartScreen(g);
return;
}
if (gameOver)
{
DrawGameOverScreen(g);
return;
}
g.Clear(Color.Black);
DrawStars(g);
player.Draw(g);
foreach (var bullet in bullets)
{
bullet.Draw(g);
}
foreach (var enemy in enemies)
{
enemy.Draw(g);
}
DrawGameInfo(g);
}
private void DrawStars(Graphics g)
{
for (int i = 0; i < 50; i++)
{
int x = (i * 73) % this.ClientSize.Width;
int y = (i * 47) % this.ClientSize.Height;
int size = (i % 2) + 1;
g.FillEllipse(Brushes.White, x, y, size, size);
}
}
private void DrawGameInfo(Graphics g)
{
Font font = new Font("Arial", 14, FontStyle.Bold);
string scoreText = $"得分: {score}";
string livesText = $"生命: {lives}";
g.DrawString(scoreText, font, Brushes.White, 10, 10);
g.DrawString(livesText, font, Brushes.White, 10, 40);
}
private void DrawStartScreen(Graphics g)
{
Font titleFont = new Font("Arial", 36, FontStyle.Bold);
Font instrFont = new Font("Arial", 18, FontStyle.Regular);
string title = "飞机大战";
string instruction = "按空格键开始游戏";
SizeF titleSize = g.MeasureString(title, titleFont);
SizeF instrSize = g.MeasureString(instruction, instrFont);
g.DrawString(title, titleFont, Brushes.Gold,
(this.ClientSize.Width - titleSize.Width) / 2,
this.ClientSize.Height / 3);
g.DrawString(instruction, instrFont, Brushes.LightGreen,
(this.ClientSize.Width - instrSize.Width) / 2,
this.ClientSize.Height / 2);
player.Draw(g, new Point(this.ClientSize.Width / 2 - 25, this.ClientSize.Height * 2 / 3));
}
private void DrawGameOverScreen(Graphics g)
{
Font gameOverFont = new Font("Arial", 36, FontStyle.Bold);
Font scoreFont = new Font("Arial", 24, FontStyle.Regular);
Font restartFont = new Font("Arial", 18, FontStyle.Regular);
string gameOverText = "游戏结束";
string scoreText = $"最终得分: {score}";
string restartText = "按R键重新开始";
SizeF gameOverSize = g.MeasureString(gameOverText, gameOverFont);
SizeF scoreSize = g.MeasureString(scoreText, scoreFont);
SizeF restartSize = g.MeasureString(restartText, restartFont);
g.DrawString(gameOverText, gameOverFont, Brushes.Red,
(this.ClientSize.Width - gameOverSize.Width) / 2,
this.ClientSize.Height / 3);
g.DrawString(scoreText, scoreFont, Brushes.Yellow,
(this.ClientSize.Width - scoreSize.Width) / 2,
this.ClientSize.Height / 2 - 30);
g.DrawString(restartText, restartFont, Brushes.LightGreen,
(this.ClientSize.Width - restartSize.Width) / 2,
this.ClientSize.Height * 2 / 3);
}
#region Game Elements
public class Player
{
public Point Position { get; set; }
public Size Size { get; } = new Size(50, 40);
public int Width => Size.Width;
public int Height => Size.Height;
public void Draw(Graphics g)
{
Draw(g, Position);
}
public void Draw(Graphics g, Point position)
{
g.FillRectangle(Brushes.DodgerBlue, position.X + 15, position.Y, 20, 30);
g.FillRectangle(Brushes.CornflowerBlue, position.X, position.Y + 10, 50, 10);
g.FillRectangle(Brushes.RoyalBlue, position.X + 22, position.Y + 30, 6, 10);
g.FillEllipse(Brushes.SkyBlue, position.X + 20, position.Y + 5, 10, 10);
}
}
public class Enemy
{
public Point Position { get; private set; }
public Size Size { get; } = new Size(40, 40);
private int speed;
public Enemy(Point position)
{
Position = position;
speed = new Random().Next(3, 7);
}
public void Update()
{
Position = new Point(Position.X, Position.Y + speed);
}
public void Draw(Graphics g)
{
g.FillEllipse(Brushes.IndianRed, Position.X + 5, Position.Y + 5, 30, 30);
g.FillEllipse(Brushes.DarkRed, Position.X + 10, Position.Y + 10, 20, 20);
g.DrawLine(new Pen(Color.Black, 2), Position.X + 20, Position.Y, Position.X + 20, Position.Y + 40);
g.DrawLine(new Pen(Color.Black, 2), Position.X, Position.Y + 20, Position.X + 40, Position.Y + 20);
}
}
public class Bullet
{
public Point Position { get; private set; }
public Size Size { get; } = new Size(6, 20);
private int speed = 10;
public Bullet(Point position)
{
Position = position;
}
public void Update()
{
Position = new Point(Position.X, Position.Y - speed);
}
public void Draw(Graphics g)
{
g.FillRectangle(Brushes.Gold, Position.X, Position.Y, 6, 15);
g.FillEllipse(Brushes.Orange, Position.X, Position.Y, 6, 10);
g.FillRectangle(Brushes.Yellow, Position.X + 1, Position.Y + 15, 4, 5);
}
}
#endregion
#region Windows Form Designer Generated Code
private System.ComponentModel.IContainer components = null;
private Timer gameTimer;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.gameTimer = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
this.gameTimer.Enabled = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 600);
this.Name = "GameForm";
this.Text = "简易飞机大战";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new GameForm());
}
}
}