# 1 总体设计
## 1)基本技术路线
运用面向对象的设计理念,设计了病人类,牙医类,候诊椅类,诊疗椅类等,通过对这些类的封装,创立各个类的对象,并调用类的成员函数。
## 2)总体结构
软件总体结构如图 3-1 所示,包括:界面设计、算法设计、结果显示等。
界面设计方面包括使用 Unity3D 进行场景地图布置以及对病人和医生等人物建模,设置人物属性,设置地图属性等。
算法设计方面主要包括创建多线程进行多道缓冲区协同操作,利用信号量机制进行对临界资源的互斥同步访问。
结果显示方面主要包括界面实时参数显示和对实时数据进行保存。
![](https://www.writebug.com/myres/static/uploads/2021/12/13/58808b0fb98316ac0444581aa62e9d48.writebug)
图 3-1 软件总体结构图
### Unity 的 Update 主线程
Loom 类(子线程对 UI 的操作放到主线程的处理队列中)
### 主控类(maincontrol)
候诊椅(chair),病人(patient),治疗椅各一个类,包含以下几个属性:
两种椅子被占有的 bool,病人主动占有椅子的 bool
候诊椅有一个列表,包含了未被占有的椅子的 GameObject 对象,
人物有一个列表,包含了占有椅子的人物的 GameObject 对象,
线程数组,
计时变量,
多种 mutex,lock,以及一个对诊断椅子的 semaphore 的专用信号量。
可重用的读写文件类
## 3)模块功能及关系
主要分为病人线程模块、临界资源抢占模块、数据处理模块。
模块之间关系为临界资源抢占模块调用病人线程,线程模块用于临界资源的抢占模块,而数据处理模块是基于其他两个模块之上的。总的来说,各个模块之间互相影响,相辅相成。
具体模块见图 3-2。
![](https://www.writebug.com/myres/static/uploads/2021/12/13/06e883d492cf8add858192f0f8975967.writebug)
图 3-2 功能模块图
![](https://www.writebug.com/myres/static/uploads/2021/12/13/9cb8a59773c0e9567da13be9c89ee9bb.writebug)
## 4)总体流程
![image-20211213182622597](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211213182622597.png)
图 3-3 总体流程
## 5)线程创立
在 Update 里面调用 loom 类的函数可以保留子线程的操作到的消息处理队列中,然后主线程对队列的内容进行处理并且不会中断子线程的状态。
```c
Loom.RunAsync(() =>//子线程在里面写可以保持子线程状态
{
if (allbeoccupied == true)//如果队列小于 5 证明有一个座位被占了
{
//Debug.Log(onchairpersons.Count);
//抢占开始
for (int i = 0; i < onchairpersons.Count; i++)
{
th[i] = new Thread(Refresh2);//线程创建
th[i].Start(i); //线程创建
if (timer1 > time1)
{
timer1 = 0;//计时器清零
}
}
}
});
public void Refresh2(object o2)
{
temp = (int)o2;
Loom.QueueOnMainThread((parama) =>//操作放到主线程队列,对 Action 进行加锁回调,所以可以返回到在主线程操作 UI
{
se.WaitOne();//信号量 P 操作
//Debug.Log(temp + "抢占成功" + Time.deltaTime);
//Debug.Log(onchairpersons.Count + "shuliang");
if (onchairpersons.Count > 0)//onchairpersons.Count >-1&&
{
= onchairpersons[0];
//onchairpersons.RemoveAt(0);
if (onchairpersons[0].GetComponent<person>().gettwo == false)//没走到 workchair 就走
onchairpersons[0].GetComponent<person>().walk2();
if (onchairpersons[0].transform.position == GameObject.Find("work_chair").transform.position)
{
onchairpersons[0].GetComponent<person>().gettwo = true;
Debug.Log("到达了椅子");
//g = onchairpersons[0];
}
if (onchairpersons[0].GetComponent<person>().gettwo == true && onchairpersons[0].GetComponent<person>().getthreed == false)//向死亡点走路之前的判断
{
sleepcount += speed;
//Debug.LogError(sleepcount);
GameObject.Find("Canvas").GetComponent<Power>().mutex = true;
if (sleepcount >100)
{
onchairpersons[0].GetComponent<person>().walk3();
if (onchairpersons[0].transform.position == GameObject.Find("death").transform.position)
{
Debug.Log("到达了终点");
onchairpersons[0].GetComponent<person>().getthreed = true;
havedPer--;
ch.Add(onchairs[0]);//空椅子 ++
onchairpersons.RemoveAt(0);
onchairs.RemoveAt(0);
per.RemoveAt(0);
sleepcount = 0;
}
}
}
}
else
th[temp].Abort();//子线程中断
se.Release(1);//信号量 V 操作
}, null);
```
# 2 详细设计
## 1)进程操作函数、原语、API
#### 进程操作函数:
```c++
Loom.RunAsync(() =>//进程的状态保持进队列
{
}
Loom.QueueOnMainThread((parama) =>//对action进行加锁回调,在主线程的消息队列操作UI
{});
th[i] = new Thread(Refresh2);//子线程创建
th[i].Start(i);
```
在 unity 中没有对话框,需要调用 win32API 进行弹出对话框的操作等。
```c++
public class Messagebox
{
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);}
```
## 2)模块内部流程和实现算法
首先是多人对候诊椅的抢占,成功就可以更改状态为,失败继续找座位,人数超过座位数则加到等待队列中。然后再诊断椅状态位为未被使用的时候,所有在椅子上的人对诊断椅子进行抢占,抢占成功的执行走路函数,诊断结束释放后下一组人方可进行抢占。
实现算法:多线程抢占,抢占成功进行步行操作。
```c++
Semaphore se = new Semaphore(1,1);//初始允许请求为1,最大请求为1
Loom.QueueOnMainThread((parama) =>
{
se.WaitOne();//信号量P操作
if (onchairpersons.Count > 0)//onchairpersons.Count >-1&&
{
= onchairpersons[0];
//onchairpersons.RemoveAt(0);
if (onchairpersons[0].GetComponent<person>().gettwo == false)//没走到候诊椅workchair就走
onchairpersons[0].GetComponent<person>().walk2();//走路函数
if (onchairpersons[0].transform.position == GameObject.Find("work_chair").transform.position)
{
onchairpersons[0].GetComponent<person>().gettwo = true;
Debug.Log("到达了诊断椅");
}
if (onchairpersons[0].GetComponent<person>().gettwo == true && onchairpersons[0].GetComponent<person>().getthreed == false)
{
sleepcount += speed;
GameObject.Find("Canvas").GetComponent<Power>().mutex = true;
if (sleepcount >100)
{
onchairpersons[0].GetComponent<person>().walk3();
if (onchairpersons[0].transform.position == GameObject.Find("death").transform.position)
{
Debug.Log("到达了终点");
onchairpersons[0].GetComponent<person>().getthreed = true;
havedPer--;//人物个数
ch.Add(onchairs[0]);//空椅子++
onchairpersons.RemoveAt(0);
onchairs.RemoveAt(0);
per.RemoveAt(0);
sleepcount = 0;
}
}
}
}
else
th[temp].Abort();
se.Release(1);//信号量V操作
}, null);
```
# 3 编码设计
## 1)开发环境的设置和建立
Unity3D 开发环境,VS2017 环境,下载 unity 中专用 Visual Studio Tools for Unity
## 2)程序设计时要注意的事项
在 Unity 中,Update 是每一帧更新的,所以在这个里面设计的代码会被实时刷新到 UI,而且只有这一个入口函数,如果在此写线程代码则会提示:UI 操作只能在主线程调用。此时应该着重注意子线程调用主线程 UI 操作的问题。需要把对 UI 的操作,放到主线程得到 UI 消息处理队列中,进而让主线程去调用。
Awake 函数是在 Start 函数之前运行,也就是游戏的初始化的问题。每次重新加载场�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
本项目为使用Unity3D实现的牙医病人小游戏。运用面向对象的设计理念,设计了病人类,牙医类,候诊椅类,诊疗椅类等,通过对这些类的封装,创立各个类的对象,并调用类的成员函数。算法设计方面主要包括创建多线程进行多道缓冲区协同操作,利用信号量机制进行对临界资源的互斥同步访问。
资源推荐
资源详情
资源评论
收起资源包目录
基于Unity3D实现的牙医病人小游戏【100011407】 (1014个子文件)
00000000000000001000000000000000 4KB
00000000000000002000000000000000 4KB
00000000000000003000000000000000 4KB
00000000000000004000000000000000 4KB
00000000000000004100000000000000 4KB
00000000000000005000000000000000 4KB
00000000000000005100000000000000 4KB
00000000000000006000000000000000 4KB
00000000000000006100000000000000 4KB
00000000000000007000000000000000 4KB
00000000000000007100000000000000 4KB
00000000000000008000000000000000 4KB
00000000000000009000000000000000 4KB
0000000000000000a000000000000000 4KB
0000000000000000a100000000000000 4KB
0000000000000000b000000000000000 4KB
0000000000000000c000000000000000 4KB
0154171830d81f144ad84ceb67f7290a 4KB
0302f33119662454c8445257617c4e8e 5KB
0d3bb855445e36e479c85976fc88383a 5KB
101533b21ff3a3347aa5c95c93b6aec4 4KB
12fd8a0055b84bb59e84c9835a37e333 6KB
1621c1bfbaf4ed84380b14dc65dbec0d 4KB
1830dbe08c51ae3469494a8f861c9987 1.03MB
1c66cd3a244706a4b882ccfba0bdd8be 8KB
1c6d1fbb51834b64847b1b73a75bfc77 6KB
21eff446d50eaf44a85985cd4c0b6fa1 5KB
255827a44e2fc9248874d2222b2bcecd 6KB
2682a692a2be7e14e901a738c7806da0 5KB
2b1cc0d622c30c045832f0f805a1d184 6KB
2fe3476eabbbb6c448e6b55a2cc471f5 5KB
32188fd89022c154c81befa2f0e00be0 5KB
328cc881519068e4eb7db4bb907ad2d9 5KB
329eee4cdcfcc2147af099ec4dfd1796 4KB
38c8faf1788024c02930a0c68a6e0edc 4KB
405b9b51bb344a128608d968297df79c 4KB
4113173d5e95493ab8765d7b08371de4 7KB
4328a212447fc954e9736d12af7fea2c 4KB
49f5766d0d4954f44b85d4bbd7131677 5KB
4b3fa4bde7f1451a8218c03ee6a8ded8 4KB
4ba2329b63d54f0187bcaa12486b1b0f 4KB
506e46eace3867149b1f1ffce807bcf9 244KB
517af1b5b81b93b43b9745d58f017562 5KB
53ebcfaa2e1e4e2dbc85882cd5a73fa1 6KB
546e1f23917e4d94e86b08f13d462d1d 5KB
5782f9e9e6e0bb94bac99aeea24814fc 5KB
5b5a12845e49f7448ad66d558b6871b1 4KB
5f32cd94baa94578a686d4b9d6b660f7 7KB
60960c26f8c69b949bc4c294ccce1148 4KB
6981461fe431401459211818212a29cf 5KB
6a10b2909283487f913b00d94cd3faf5 7KB
739bbd9f364b4268874f9fd86ab3beef 5KB
7668179ede524d6396c8b7d84461ea29 8KB
80a3616ca19596e4da0f10f14d241e9f 9KB
8382b2bb260241859771b69b7f377a8d 4KB
844f815391db42d49455cbf1a7bfc434 7KB
84ca94c19f25ae14d83aa41bb3654390 5KB
852e56802eb941638acbb491814497b0 5KB
86f4de9468454445ac2f39e207fafa3a 5KB
870353891bb340e2b2a9c8707e7419ba 8KB
8c7d2091b8488494092ab375d57b2416 197KB
8e0cd8ed44d4412cbe0642067abc9e44 5KB
8e7066e382b0fc749b25dbb1a3004dfe 5KB
9078b7128e594410d9b89e5b24cffd01 5KB
9431e0c2beb1eac40b6a5f1517b6f296 5KB
97decbdab0634cdd991f8d23ddf0dead 4KB
97e45a023e16e7f4abc633cc28b9f5ab 2.17MB
aa422383b60ab7342b106339660051de 9KB
ade58a073e82de4438b6ff92d371338b 4KB
adebbd281f1a4ef3a30be7f21937e02f 5KB
AnnotationManager 4KB
DefaultWsdlHelpGenerator.aspx 59KB
DefaultWsdlHelpGenerator.aspx 57KB
ProjectSettings.asset 16KB
ProjectSettings.asset 16KB
InputManager.asset 6KB
QualitySettings.asset 5KB
InspectorExpandedItems.asset 4KB
EditorUserBuildSettings.asset 4KB
EditorUserSettings.asset 4KB
BuildSettings.asset 4KB
SpriteAtlasDatabase.asset 4KB
MonoManager.asset 4KB
GraphicsSettings.asset 2KB
Physics2DSettings.asset 1KB
NavMeshAreas.asset 1KB
UnityConnectSettings.asset 775B
DynamicsManager.asset 737B
EditorBuildSettings.asset 508B
EditorSettings.asset 456B
TagManager.asset 397B
AudioManager.asset 357B
TimeManager.asset 202B
NetworkManager.asset 151B
ClusterInputManager.asset 114B
assetDatabase3 3.53MB
AssetImportState 10B
globalgamemanagers.assets 24KB
globalgamemanagers.assets 24KB
sharedassets1.assets 18KB
共 1014 条
- 1
- 2
- 3
- 4
- 5
- 6
- 11
资源评论
神仙别闹
- 粉丝: 2671
- 资源: 7640
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功