C#利用多线程制作打字游戏(求助关闭的问题)
23:06 唉,终于把第10章的那个理论作业打字游戏做完了(^_^当然是在看答案的情况下),呵呵,还蛮好玩的,原来打字游戏就是这样子做出来的啊,呵。。下面是做法:
在VS2005中新建一个C#的Windows应用程序,然后把一个Timer控件拉到form里,设置控件的间隔时间为1000,即1秒,然后双击Timer控件,进到timer1_Tick()事件代码编辑区,加入如下代码:
private void timer1_Tick(object sender, EventArgs e)
{
Label lbl = new Label();
lbl.AutoSize = true;
lbl.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
lbl.Name = "label1";
lbl.Size = new System.Drawing.Size(19, 18);
lbl.Top = 0;
//利用随机函数让标签的位置不一样,且标签内容也不一样,a~Z的ASCII码为65~122
Random random = new Random();
lbl.Left = random.Next(0,this.Width);
int i;
do
{
i = 65 + random.Next(57);
} while (i >= 91 && i <= 96); //91~96为非字母
lbl.Text = Convert.ToChar(i).ToString();
this.Controls.Add(lbl);
Letter l = new Letter(lbl,this);
ThreadStart ts = new ThreadStart(l.run); //计时器每跳动一次就启动一个线程,线程控制字母下落
Thread t = new Thread(ts);
t.Start();
}
另外再新建一个Letter类,此类中有个run方法,用于控制字母的下落,Letter类代码如下:
public class Letter
{
//让字母动起来的类
private Label lbl;
private Form frm;
const int speed = 1; //下落速度
public Letter(Label lbl, Form frm)
{
this.lbl = lbl;
this.frm = frm;
}
public void run()
{
try
{
while (this.lbl.Top != this.frm.Height - 20)
{
//当字母还没有落到窗口底部的时候就一直下落
if (lbl == null)
{
Thread.CurrentThread.Abort();
}
this.lbl.Top += speed * 5;
Thread.Sleep(100);
}
if (Thread.CurrentThread.IsAlive)
{
Thread.CurrentThread.Abort();
}
}
catch (Exception ex)
{
Console.WriteLine("错误:" + ex.Message);
Console.WriteLine("错误:" + ex.StackTrace);
}
finally
{
if (!lbl.Disposing)
lbl.Dispose();
frm.Controls.Remove(lbl);
}
}
}
让字母动起来的原理就是当字母没有移动到屏幕底的时候就循环的让Y轴坐标加上速度值即可,当落到底部的时候则用Thread.CurrentThread.Abort();该方法来终止当前运行的线程。
这样主要的工作就已经完成,接下来的就是收尾工作,双击窗体进入Form1_Load(object sender, EventArgs e)事件代码编辑区,输入代码:
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
即窗体加载的时候让计时器开始计时,这样每隔一秒便引发timer1_Tick()事件一次,而在事件里又新建一个Lable控件,里面的文字为随机字母,且控件通过另外一个线程不停的向下移动直到底部,然后还有最后一部,就是响应键盘的按键,按下对应的键后相应的字母消失,进入窗体的Form1_KeyPress()事件,输入如下代码:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
foreach (Label lbl in this.Controls)
{
if (lbl == null)
{
break;
}
if (e.KeyChar == lbl.Text[0])
{
lbl.Dispose();
this.Controls.Remove(lbl);
}
}
}
通过foreach循环判断按下的键是否是窗体中字母控件的内容,是的话则Dispose掉,即释放资源并从当前窗体中Remove掉。
整个打字游戏的代码也就这样,当然,还有很多缺陷,我就是就发现当我点击窗体右上角的叉叉关掉程序的时候,窗口是不见了,可是当我再次在运行的时候,VS却提示我说已经有一个进程在运行,不能运行的,我打开任务管理器,是发现了一个同名的进程,然后我在任务管理器关掉后,在VS里再次运行就能运行了,然后再关到窗体,发现窗体是关掉了,可是进程却没有消除,郁闷,不知道是怎么回事哦,估计应该是还有线程在运行的,所以进程就没有关吧,只是把窗体给关了。。。
希望有高手能帮我解决一下该问题,多谢!!!
[解决办法]
LZ够猛!多线程不是这么用的,系统资源会耗尽的,:)
估计你的线程没有全部杀掉啊。
建议LZ修改成使用ThreadPool吧,这样容易管理点。