一、需求分析
1、界面設計 佈局
- 需要哪些內容控件
- 容器的概念
- 集合的概念
2、開始遊戲
- 字母的生成 26個字母 ASCII碼值
- 字母的載體 控件
- 字母、位置、大小、顏色
- 要求隨機的
- 計時器
3、字母從上往下運動
- TOP變化
- 注意:垃圾回收問題,未消除的字母進行銷燬,釋放資源
- 計時器
4、需要產生對應的從下往上生成字母子彈,打掉字母
- 處理與鍵盤之間的交互,鍵盤相關事件
- 字母需要轉換,ASCII碼值
- 知識點:事件參數:EventArgs e
- 子彈從下往上運動
- 子彈與字母相遇,兩者消失
5、添加動畫效果、音效等
二、代碼實現
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//導入媒體命名空間
using System.Media;
namespace PlaneTest_02
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//初始化panel
Panel game = new Panel();
//初始化pictureBox
PictureBox plane = new PictureBox();
//初始化一個播放器
SoundPlayer sound = new SoundPlayer();
//創建爆炸效果圖
ImageList imageList = new ImageList();
//初始化隨機數對象
Random ra = new Random();
//添加timer1,控制字母生成
Timer timer1 = new Timer();
//添加timer2,控制字母、子彈運動
Timer timer2 = new Timer();
//添加timer3,控制爆炸效果圖的播放
Timer timer3 = new Timer();
//設置遊戲開始按鈕
Button beginBtn = new Button();
//實現記錄分數
Label result = new Label();
//記錄分數
int count = 0;
//實現記錄失誤
Label list = new Label();
//記錄失誤
int rex = 0;
private void Form1_Load(object sender, EventArgs e)
{
//設置窗體屬性
this.Text = "天天打字母";
this.Size = new Size(1000,700);
this.CenterToScreen();
//設置game屬性
game.Size = new Size(800,650);
game.BackColor = Color.SkyBlue;
game.BorderStyle = BorderStyle.Fixed3D;
game.Location = new Point(5,5);
this.Controls.Add(game);
//設置plane屬性
plane.Image = Image.FromFile("../../images/plane/plane4.png");
plane.SizeMode = PictureBoxSizeMode.AutoSize;
plane.Location = new Point(game.Width/2-plane.Width/2,game.Height-plane.Height);
plane.Tag = "plane";
game.Controls.Add(plane);
//設置timer1屬性,此計時器控制字母生成
timer1.Tick += Timer1_Tick;
timer1.Interval = 1000;
//設置timer2屬性,此計時器控制字母運動
timer2.Tick += Timer2_Tick;
timer2.Interval = 200;
//添加鍵盤按下事件
this.KeyPress += Form1_KeyPress;
//設置按鈕屬性
beginBtn.Text = "開始遊戲";
beginBtn.Size = new Size(100,30);
beginBtn.Location = new Point(game.Width+50, 20);
this.Controls.Add(beginBtn);
//生成按鈕點擊事件
beginBtn.Click += BeginBtn_Click;
//設置記錄分數label的屬性
result.Size = new Size(50,50);
result.BackColor = Color.White;
result.Location = new Point(beginBtn.Left+ beginBtn.Width/2-result.Width/2, beginBtn.Top+ beginBtn.Height+10);
result.TextAlign = ContentAlignment.MiddleCenter;
result.Font = new Font("楷體", 22);
result.ForeColor = Color.Green;
this.Controls.Add(result);
//設置記錄失誤label的屬性
list.Size = new Size(50, 50);
list.BackColor = Color.White;
list.Location = new Point(beginBtn.Left + beginBtn.Width / 2 - list.Width / 2, result.Top + result.Height + 10);
list.TextAlign = ContentAlignment.MiddleCenter;
list.Font = new Font("楷體", 22);
list.ForeColor = Color.Red;
this.Controls.Add(list);
}
/// <summary>
/// 按鈕點擊事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BeginBtn_Click(object sender, EventArgs e)
{
if (beginBtn.Text == "開始遊戲")
{
//開啓計時器
timer1.Start();
timer2.Start();
timer3.Start();
beginBtn.Text = "暫停遊戲";
//開啓窗體獲取鍵盤事件的焦點
this.KeyPreview = true;
}
else
{
//關閉計時器
timer1.Stop();
timer2.Stop();
timer3.Stop();
beginBtn.Text = "開始遊戲";
//關閉窗體獲取鍵盤事件的焦點
this.KeyPreview = false;
}
}
/// <summary>
/// 字母生成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer1_Tick(object sender, EventArgs e)
{
//初始化label
Label zimu = new Label();
zimu.Text = ((char)ra.Next(97, 123)).ToString();
zimu.ForeColor = Color.FromArgb(ra.Next(255), ra.Next(255), ra.Next(255));
zimu.Font = new Font("楷體",ra.Next(30, 41));
zimu.Location = new Point(ra.Next(game.Width - zimu.Width),0);
zimu.AutoSize = true;
zimu.TextAlign = ContentAlignment.MiddleCenter;
zimu.Tag = "zimu";
game.Controls.Add(zimu);
}
/// <summary>
/// 字母運動
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer2_Tick(object sender, EventArgs e)
{
result.Text = count.ToString();
list.Text = rex.ToString();
//遍歷panel中的控件
foreach (Control item in game.Controls)
{
//判斷控制爲label
if (item.GetType().Name == "Label")
{
//判斷其tag爲字母的tag
if (item.Tag.ToString() == "zimu" || item.Tag.ToString() == "change")
{
item.Top += 10;
//釋放資源
if (item.Top > plane.Top - 40)
{
rex++;
item.Dispose();
}
}
}
//判斷爲PictureBox
if (item.GetType().Name == "PictureBox")
{
//判斷其tag爲子彈的tag
if (item.Tag.ToString() == "zidan")
{
item.Top -= 40;
//判斷字母與子彈相遇
//遍歷panel中的所有控件
foreach (Control it in game.Controls)
{
//判斷控件類型
if (it.GetType().Name == "Label")
{
//判斷tag
if (it.Tag.ToString() == "change")
{
//判斷相遇
if (it.Top + it.Height >= item.Top)
{
count++;
//銷燬
item.Dispose();
it.Dispose();
//添加爆炸音效
//設置路徑
sound.SoundLocation = "../../sound/Bomb.wav";
//播放
sound.Play();
//設置爆炸效果圖大小
imageList.ImageSize = new Size(50, 50);
//創建爆炸圖片
PictureBox Bomb = new PictureBox();
Bomb.Size = new Size(50, 50);
Bomb.Tag = 0;
Bomb.Location = new Point(it.Left+it.Width/2-Bomb.Width/2,it.Top+it.Height/2-Bomb.Height/2);
game.Controls.Add(Bomb);
//創建字符串表示路徑
string path;
for (int i = 0; i < 32; i++)
{
if (i<10)
{
path = String.Concat("../../images/Bomb/1000", i.ToString(), ".png");
}
else
{
path = String.Concat("../../images/Bomb/100", i.ToString(), ".png");
}
imageList.Images.Add(Image.FromFile(path));
Bomb.Image = imageList.Images[Convert.ToInt32(Bomb.Tag)];
}
//設置控制爆炸圖播放效果計時器(timer3)的屬性
timer3.Tick += Timer3_Tick;
timer3.Tag = Bomb;
timer3.Interval = 30;
timer3.Start();
}
}
}
}
}
}
}
}
/// <summary>
/// 控制爆炸圖片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer3_Tick(object sender, EventArgs e)
{
//通過事件發起者(sender),獲取計時器的tag
Timer timerBox = sender as Timer;
//通過計時器的tag,找到Bomb的tag
PictureBox pictureBox = timerBox.Tag as PictureBox;
//pictureBox的image與imageList的images相關聯
pictureBox.Image = imageList.Images[Convert.ToInt32(pictureBox.Tag)];
//給pictureBox的tag+1
pictureBox.Tag = Convert.ToInt32(pictureBox.Tag) + 1;
if (Convert.ToInt32(pictureBox.Tag) >= 31)
{
timerBox.Dispose();
pictureBox.Dispose();
}
}
/// <summary>
/// 鍵盤事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
//遍歷panel中的控件
foreach (Control item in game.Controls)
{
//判斷是控件
if (item.GetType().Name == "Label")
{
//判斷其tag是字母
if (item.Tag.ToString() == "zimu")
{
if (item.Text == e.KeyChar.ToString())
{
//改變字母的tag
item.Tag = "change";
//改變plane座標
plane.Location = new Point(item.Left + item.Width / 2 - plane.Width / 2, game.Height - plane.Height);
//生成子彈
PictureBox zidan = new PictureBox();
zidan.Image = Image.FromFile("../../images/Bullet/Ammo_enemy3.png");
zidan.SizeMode = PictureBoxSizeMode.AutoSize;
zidan.Tag = "zidan";
zidan.Location = new Point(item.Left + item.Width / 2 - zidan.Width / 2, game.Height - plane.Height);
game.Controls.Add(zidan);
//字母與子彈對應,則跳出當前循環
return;
}
}
}
}
}
}
}
三、運行結果