Skip to content

Commit b0b8512

Browse files
author
573270407@qq.com
committed
- 添加按钮来观看不同状态下的感染情况
- 添加截图来说明
1 parent 427e233 commit b0b8512

File tree

4 files changed

+177
-33
lines changed

4 files changed

+177
-33
lines changed

src/Constants.java

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import java.util.Timer;
2+
13
/**
24
* 模拟参数
35
*
@@ -8,26 +10,32 @@
810
*/
911
public class Constants {
1012

11-
public static int ORIGINAL_COUNT = 50;//初始感染数量
12-
public static float BROAD_RATE = 0.8f;//传播率
13-
public static float SHADOW_TIME = 140;//潜伏时间,14天为140
14-
public static int HOSPITAL_RECEIVE_TIME = 10;//医院收治响应时间,1天
15-
public static int BED_COUNT = 1000;//医院床位
16-
/**
17-
* 流动意向平均值,建议调整范围:[-0.99,0.99]
18-
* <p>
19-
* -0.99 人群流动最慢速率,甚至完全控制疫情传播
20-
* 0.99为人群流动最快速率, 可导致全城感染
21-
*/
22-
public static float u = 0.99f;
23-
public static int CITY_PERSON_SIZE = 5000;//城市总人口数量
24-
public static float FATALITY_RATE = 0.50f;//fatality_rate病死率,根据2月6日数据估算(病死数/确诊数)为0.02
25-
public static int DIE_TIME = 100;//死亡时间均值,10天,从发病(确诊)时开始计时
26-
public static double DIE_VARIANCE = 1;//死亡时间方差
27-
/**
28-
* 城市大小即窗口边界,限制不允许出城
29-
*/
30-
public static final int CITY_WIDTH = 700;
31-
public static final int CITY_HEIGHT = 800;
13+
public static int ORIGINAL_COUNT = 50;// 初始感染数量
14+
public static float BROAD_RATE = 0.8f;// 传播率
15+
public static float SHADOW_TIME = 140;// 潜伏时间,14天为140
16+
public static int HOSPITAL_RECEIVE_TIME = 10;// 医院收治响应时间,1天
17+
public static int BED_COUNT = 1000;// 医院床位
18+
19+
// public static int NEED_BED_COUNT = 0;// 急需医院床位
20+
/**
21+
* 流动意向平均值,建议调整范围:[-0.99,0.99]
22+
* <p>
23+
* -0.99 人群流动最慢速率,甚至完全控制疫情传播 0.99为人群流动最快速率, 可导致全城感染
24+
*/
25+
public static float u = -0.99f;
26+
public static int CITY_PERSON_SIZE = 5000;// 城市总人口数量
27+
public static float FATALITY_RATE = 0.50f;// fatality_rate病死率,根据2月6日数据估算(病死数/确诊数)为0.02
28+
public static int DIE_TIME = 100;// 死亡时间均值,10天,从发病(确诊)时开始计时
29+
public static double DIE_VARIANCE = 1;// 死亡时间方差
30+
/**
31+
* 城市大小即窗口边界,限制不允许出城
32+
*
33+
*
34+
*/
35+
public static final int CITY_WIDTH = 700;
36+
public static final int CITY_HEIGHT = 800;//整个窗体的高度
37+
38+
39+
public static Timer timer = new Timer();
3240

3341
}

src/Main.java

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
import java.util.List;
44
import java.util.Random;
5+
import java.awt.event.ActionListener;
6+
import java.awt.event.ActionEvent;
7+
import java.awt.Component;
8+
import java.awt.Dimension;
9+
import java.awt.event.MouseAdapter;
10+
import java.awt.event.MouseEvent;
11+
import javax.swing.event.MenuListener;
12+
13+
import javax.swing.event.MenuEvent;
514

615
/**
716
* 模拟程序主入口
@@ -24,13 +33,80 @@ private static void initPanel() {
2433
MyPanel p = new MyPanel();
2534
Thread panelThread = new Thread(p);
2635
JFrame frame = new JFrame();
27-
frame.add(p);
36+
frame.getContentPane().add(p);
2837
frame.setSize(Constants.CITY_WIDTH + hospitalWidth + 300, Constants.CITY_HEIGHT);
2938
frame.setLocationRelativeTo(null);
30-
frame.setVisible(true);
3139
frame.setTitle("瘟疫传播模拟——————新冠状病毒");
3240
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3341
panelThread.start();// 开启画布线程,即世界线程,接着看代码的下一站可以转MyPanel.java
42+
43+
JPopupMenu popupMenu = new JPopupMenu();
44+
addPopup(frame, popupMenu);
45+
46+
JMenuItem menuItem = new JMenuItem("关于");
47+
menuItem.addActionListener(new ActionListener() {
48+
public void actionPerformed(ActionEvent e) {
49+
50+
JOptionPane.showMessageDialog(null, "武汉加油!湖北加油!中国加油!");
51+
}
52+
});
53+
popupMenu.add(menuItem);
54+
55+
JMenuBar menuBar = new JMenuBar();
56+
frame.setJMenuBar(menuBar);
57+
58+
JMenu menu = new JMenu("控制人口流动");
59+
menu.addMenuListener(new MenuListener() {
60+
public void menuCanceled(MenuEvent e) {
61+
}
62+
63+
public void menuDeselected(MenuEvent e) {
64+
}
65+
66+
public void menuSelected(MenuEvent e) {
67+
68+
Constants.u = -0.99f;
69+
resetWorld();
70+
71+
}
72+
});
73+
74+
menuBar.add(menu);
75+
76+
JMenu menu_1 = new JMenu("不控制人口流动");
77+
menu_1.addMenuListener(new MenuListener() {
78+
79+
public void menuCanceled(MenuEvent e) {
80+
}
81+
82+
public void menuDeselected(MenuEvent e) {
83+
}
84+
85+
public void menuSelected(MenuEvent e) {
86+
Constants.u = 0.99f;
87+
resetWorld();
88+
}
89+
});
90+
menuBar.add(menu_1);
91+
92+
frame.setVisible(true);
93+
}
94+
95+
/**
96+
* 重新开始
97+
*/
98+
static void resetWorld() {
99+
List<Person> people = PersonPool.getInstance().getPersonList();
100+
for (Person person : people) {
101+
person.setState(Person.State.NORMAL);
102+
}
103+
104+
List<Bed> beds = Hospital.getInstance().getBeds();
105+
for (Bed bed : beds) {
106+
bed.setEmpty(true);
107+
}
108+
109+
initInfected();
34110
}
35111

36112
/**
@@ -64,4 +140,23 @@ private static void initInfected() {
64140
}
65141
}
66142

143+
private static void addPopup(Component component, final JPopupMenu popup) {
144+
component.addMouseListener(new MouseAdapter() {
145+
public void mousePressed(MouseEvent e) {
146+
if (e.isPopupTrigger()) {
147+
showMenu(e);
148+
}
149+
}
150+
151+
public void mouseReleased(MouseEvent e) {
152+
if (e.isPopupTrigger()) {
153+
showMenu(e);
154+
}
155+
}
156+
157+
private void showMenu(MouseEvent e) {
158+
popup.show(e.getComponent(), e.getX(), e.getY());
159+
}
160+
});
161+
}
67162
}

src/MyPanel.java

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,26 @@ public MyPanel() {
2424
public void paint(Graphics g) {
2525
// 保留每次绘制的图像
2626
super.paint(g);
27-
g.setColor(new Color(0x00ff00));// 设置医院边界颜色
28-
// 绘制医院边界
29-
g.drawRect(Hospital.getInstance().getX(), Hospital.getInstance().getY(), Hospital.getInstance().getWidth(),
30-
Hospital.getInstance().getHeight());
3127
// 写标题
3228
g.setFont(new Font("微软雅黑", Font.BOLD, 16));
33-
g.setColor(new Color(0x00ff00));
29+
g.setColor(new Color(0xffffff));
3430
g.drawString("医院", Hospital.getInstance().getX() + Hospital.getInstance().getWidth() / 4,
3531
Hospital.getInstance().getY() - 16);
32+
33+
g.setColor(new Color(0xffffff));// 设置医院边界颜色,白色
34+
// 绘制医院边界
35+
g.drawRect(Hospital.getInstance().getX(), Hospital.getInstance().getY(), Hospital.getInstance().getWidth(),
36+
Hospital.getInstance().getHeight());
37+
38+
g.setColor(new Color(0xffffff));
39+
int ref = 15;
40+
g.drawLine(Hospital.getInstance().getX() + Hospital.getInstance().getWidth() + ref, 0,
41+
Hospital.getInstance().getX() + Hospital.getInstance().getWidth() + ref, Constants.CITY_HEIGHT);
42+
3643
// 绘制代表人类的圆点
3744
// 以单个人为单位的数组,即人群
3845
List<Person> people = PersonPool.getInstance().getPersonList();
39-
// 人群数为0不继续执行
46+
// 总人数为0不继续执行
4047
if (people == null) {
4148
return;
4249
}
@@ -119,23 +126,51 @@ public void paint(Graphics g) {
119126
* 医院床位满了之后,新确诊的都没有床位可用,都属于急需病床
120127
*
121128
* 急需病床数=确诊人数-空余床位
122-
*/ int needBeds = PersonPool.getInstance().getPeopleSize(Person.State.CONFIRMED)
129+
*/
130+
int needBeds = PersonPool.getInstance().getPeopleSize(Person.State.CONFIRMED)
123131
- Math.max(Constants.BED_COUNT - PersonPool.getInstance().getPeopleSize(Person.State.FREEZE), 0);
124132
g.drawString("急需病床:" + (needBeds > 0 ? needBeds : 0), captionStartOffsetX,
125133
captionStartOffsetY + 7 * captionSize);
134+
126135
g.setColor(new Color(0xccbbcc));
127136
g.drawString("病死人数:" + PersonPool.getInstance().getPeopleSize(Person.State.DEATH), captionStartOffsetX,
128137
captionStartOffsetY + 8 * captionSize);
129138
g.setColor(new Color(0xffffff));
130139
// 每秒增加一天
131140
g.drawString("世界时间(天):" + (int) (worldTime / 10.0), captionStartOffsetX, captionStartOffsetY + 9 * captionSize);
132141

142+
g.setColor(new Color(0xffffff));
143+
g.drawLine(captionStartOffsetX, captionStartOffsetY + 9 * captionSize + 5, captionStartOffsetX + 300,
144+
captionStartOffsetY + 9 * captionSize + 5);
145+
146+
g.drawString("人群移动意向:" +new Person(null,0,0).wantMoveSubs(Constants.u), captionStartOffsetX, captionStartOffsetY + 10 * captionSize);
147+
148+
149+
150+
//失控
151+
if(PersonPool.getInstance().getPeopleSize(Person.State.NORMAL)<=3) {
152+
153+
154+
g.setFont(new Font("微软雅黑", Font.BOLD, 50));
155+
g.setColor(new Color(0xffffff));
156+
g.drawString("不抛弃!不放弃!", getWidth()/100,
157+
getHeight()/2);
158+
159+
}
160+
//控制住了
161+
if(PersonPool.getInstance().getPeopleSize(Person.State.SHADOW)==0&&PersonPool.getInstance().getPeopleSize(Person.State.CONFIRMED)==0) {
162+
163+
g.setFont(new Font("微软雅黑", Font.BOLD, 50));
164+
g.setColor(new Color(0xffffff));
165+
g.drawString("防疫阻击战获得了胜利!!!", getWidth()/100,
166+
getHeight()/2);
167+
}
168+
169+
133170
}
134171

135172
public static int worldTime = 0;// 世界时间
136173

137-
public Timer timer = new Timer();
138-
139174
/*
140175
*
141176
* 不断调用paint方法,刷新图形
@@ -161,7 +196,7 @@ public void run() {
161196
*/
162197
@Override
163198
public void run() {
164-
timer.schedule(new MyTimerTask(), 0, 100);// 启动世界计时器,时间开始流动(突然脑补DIO台词:時は停た)
199+
Constants.timer.schedule(new MyTimerTask(), 0, 100);// 启动世界计时器,时间开始流动(突然脑补DIO台词:時は停た)
165200
}
166201

167202
}

src/Person.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ public boolean wantMove() {
8181
return MathUtil.stdGaussian(sig, Constants.u) > 0;
8282
}
8383

84+
String wantMoveSubs(float x) {
85+
return x > 0.5 ? "人们随意走动" : "人们限制出行";
86+
}
87+
8488
private int state = State.NORMAL;
8589

8690
public int getState() {
@@ -252,9 +256,11 @@ public void update() {
252256
if (bed == null) {
253257

254258
// 没有床位了,报告需求床位数
259+
// Constants.NEED_BED_COUNT++;
255260

256261
} else {
257262
// 安置病人
263+
// 移到医院区域,这个时候小点依然是红色。会出现这种情况:一轮循环在下一轮开始前移动很多红点到医院区域,下一轮开始之后才变为蓝色
258264
useBed = bed;
259265
state = State.FREEZE;
260266
setX(bed.getX());

0 commit comments

Comments
 (0)