感染是一种引人入胜的游戏,建议在室外或大型开放区域播放,以便为活动提供更多空间
目录
规则
感染是一种模拟疾病传播的分布式游戏。目标是在每个玩家死亡之前停止爆发!
- 角色数量: 1名法师,4名或更多额外角色。“主”和所有其他玩家需要一个带电池组的micro:bit。
在这个游戏中,“主”micro:bit感染了一个单独的初始玩家(“患者零”)。受感染的玩家会立即感染,但在孵化期间不会出现任何疾病迹象。当两个micro:bits彼此足够接近以“收缩疾病”时,疾病就会传播。孵化期后,屏幕上出现一张悲伤的脸。疾病期过后,玩家最终会死亡,并且屏幕上会显示一个头骨。死亡的玩家已退出游戏。
如果至少有一名玩家幸免于爆发,则赢得比赛。
按A+B进入“主”模式(游戏中只有一个主)。
等待玩家配对。配对播放器的数量将显示在屏幕上。配对时,播放器屏幕上会出现一个字母,这封信是玩家的身份。
一旦您的所有玩家都注册了,请按A+B开始感染游戏。游戏随机挑选一名玩家作为患者零。
如果足够接近(检测到足够的RSSI),并且如果TRANSMISSIONPROB达到疾病转移的某个概率(),则运动员将疾病传播给另一个运动员。在孵化阶段(INCUBATION)期间,玩家不会出现任何疾病迹象(幸福的脸)。在那个阶段之后,玩家生病并在屏幕上显示一张悲伤的脸。在生病(悲伤)的脸后,玩家死了,头骨出现了。
一旦游戏结束,微:位将显示玩家的ID( ,,A …),健康,谁传染这些玩家的ID。Master micro:bit将显示患者零的身份。
游戏中使用的图标:
- 配对:
IconNames.Ghost - 配对:
IconNames.Happy - 死:
IconNames.Skull - 生病:
IconNames.Sad - 孵化:
IconNames.Confused - 健康:
IconNames.Happy
项目分享
此代码使用块中不支持的语言功能,例如switch或enum。因此,它不会转换回块。
https://makecode.microbit.org/_gymCJCWPbiDu
JavaScript代码
/**
* Infection game
*
* Flash all micro:bit will this script
*
* Press A+B to enter master mode (1 per game)
*
* Wait for players to be paired. The number of paired player will display on screen.
* An icon will appear on player's screen.
*
* Press A+B to start the infection game. The master will pick a random
* player as patient zero.
*
* A player will transmit the disease if close enough (RSSI)
* and with a certain probability (TRANSMISSIONPROB).
* During the incudation phase (INCUBATION), the player does not show any sign
* of illness. After that phase, the sad face shows up.
*
* The game will automatically stop once all players are dead or healthy. The master can
* also press A+B again to stop the game.
*
* Once the game is over, the micro:bit will show the player id (A,B,C...), health and
* who infected him.
*
* Icons used in the game:
*
* Pairing: IconNames.Ghost
* Paired: IconNames.Happy
* Dead: IconNames.Skull
* Sick: IconNames.Sad
* Incubating: IconNames.Confused
* Healthy: IconNames.Happy
*
*/
const INCUBATION = 20000; // time before showing symptoms
const DEATH = 40000; // time before dying off the disease
const RSSI = -45; // db
const TRANSMISSIONPROB = 40; // % probability to transfer disease
enum GameState {
Stopped,
Pairing,
Running,
Over
}
enum HealthState {
Healthy,
Incubating,
Sick,
Dead
}
const GameIcons = {
Pairing: IconNames.Ghost,
Paired: IconNames.Happy,
Dead: IconNames.Skull,
Sick: IconNames.Sad,
Incubating: IconNames.Confused,
Healthy: IconNames.Happy
}
const playerIcons = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
class Player {
id: number;
icon: number;
health: HealthState;
show() {
basic.showString(playerIcons[this.icon]);
}
}
// common state
let state = GameState.Stopped;
// master state
let master = false;
let patientZero: Player;
const players: Player[] = [];
// player state
let paired = false;
let infectedBy = -1; // who infected (playerIcon)
let infectedTime = 0; // local time when infection happened
let playerIcon = -1; // player icon and identity
let health = HealthState.Healthy;
// get a player instance (creates one as needed)
function player(id: number): Player {for (const p of players)if (p.id == id) return p;
// add player to gamelet p = new Player();
p.id = id;
p.icon = (players.length + 1) % playerIcons.length;
p.health = HealthState.Healthy;
players.push(p);
serial.writeLine(`player ==> ${p.id}`)
return p;
}
function allDead(): boolean {for (const p of players)if (p.health != HealthState.Dead) return false;return true;
}
function gameOver() {
state = GameState.Over;if (patientZero)
patientZero.show();
}
function gameFace() {switch (state) {case GameState.Stopped:
basic.showIcon(GameIcons.Pairing);break;case GameState.Pairing:if (playerIcon > -1)
basic.showString(playerIcons[playerIcon]);else
basic.showIcon(paired ? GameIcons.Paired : GameIcons.Pairing, 1);break;case GameState.Running:switch (health) {case HealthState.Dead:
basic.showIcon(GameIcons.Dead, 1);break;case HealthState.Sick:
basic.showIcon(GameIcons.Sick, 1);break;default:
basic.showIcon(GameIcons.Healthy, 1);break;
}break;case GameState.Over:// show id
basic.showString(playerIcons[playerIcon]);
basic.pause(2000);// show healthswitch (health) {case HealthState.Dead:
basic.showIcon(GameIcons.Dead, 2000);break;case HealthState.Sick:
basic.showIcon(GameIcons.Sick, 2000);break;case HealthState.Incubating:
basic.showIcon(GameIcons.Incubating, 2000);break;default:
basic.showIcon(GameIcons.Healthy, 2000);break;
}// show how infectedif (infectedBy > -1) {
basic.showString(" INFECTED BY");
basic.showString(playerIcons[infectedBy]);
basic.pause(2000);
} else {
basic.showString(" PATIENT ZERO");
basic.pause(2000);
}// show score
game.showScore();
basic.pause(1000);break;
}
}
// master button controller
input.onButtonPressed(Button.AB, () => {// register as masterif (state == GameState.Stopped && !master) {
master = true;
paired = true;
state = GameState.Pairing;
serial.writeLine("registered as master");
radio.setTransmitPower(7); // beef up master signal
basic.showString("0");return;
}
if (!master) return; // master only beyond this
// launch gameif (state == GameState.Pairing) {// pick 1 player and infect him
patientZero = players[Math.random(players.length)];while (patientZero.health == HealthState.Healthy) {
radio.sendValue("infect", patientZero.id);
basic.pause(100);
}
// all ready
state = GameState.Running;
serial.writeLine(`game started ${players.length} players`);
// show startup
basic.showIcon(GameIcons.Dead);
} // end game else if (state == GameState.Running) {
gameOver();
}
})
radio.setGroup(42);
radio.setTransmitSerialNumber(true)
radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, serial: id }) => {if (master) {if (receivedString == "pair") {// register playerlet n = players.length;let p = player(id);// show player number if changedif (n != players.length) {
led.stopAnimation();
basic.showNumber(players.length);
}
}else if (receivedString == "health") {let p = player(id);
p.health = receivedNumber;// check if all infectedif (allDead())
gameOver();
}
} else {if (receivedString == "state") {// update game state
state = receivedNumber as GameState;
} else if (infectedBy < 0 &&
receivedString == "infect"
&& receivedNumber == control.deviceSerialNumber()) {// infected by master
infectedBy = 0; // infected my master
infectedTime = input.runningTime();
health = HealthState.Incubating;
serial.writeLine(`infected ${control.deviceSerialNumber()}`);
}if (receivedString == "h" + control.deviceSerialNumber().toString() &&
health < receivedNumber) {
health = receivedNumber;
}switch (state) {case GameState.Pairing:// medium range in pairing modeif (!paired &&
receivedString == "paired"
&& receivedNumber == control.deviceSerialNumber()) {// paired!
serial.writeLine(`player paired ==> ${control.deviceSerialNumber()}`)
paired = true;return;
}else if (paired && receivedString == "i" + control.deviceSerialNumber().toString()) {
playerIcon = receivedNumber;
}break;case GameState.Running:// broadcast infection statusif (health == HealthState.Healthy && receivedString == "transmit") {
serial.writeLine(`signal: ${signal}`);if (signal > RSSI &&Math.random(100) > TRANSMISSIONPROB) {
infectedBy = receivedNumber;
infectedTime = input.runningTime();
health = HealthState.Incubating;
}
} else if (health != HealthState.Dead
&& receivedString == "health" && signal > RSSI) {
game.addScore(1);
}break;
}
}
})
// main game loop
basic.forever(() => {if (master) {switch (state) {case GameState.Pairing:// tell each player they are registeredfor (const p of players) {
radio.sendValue("paired", p.id);
radio.sendValue("i" + p.id, p.icon);
}
serial.writeLine(`pairing ${players.length} players`);
basic.pause(500);break;case GameState.Running:for (const p of players) {
radio.sendValue("h" + p.id, p.health);
}break;case GameState.Over:if (patientZero)
patientZero.show();break;
}
radio.sendValue("state", state); // keep broadcasting the game state
} else { // player loopswitch (state) {case GameState.Pairing:// broadcast player idif (playerIcon < 0)
radio.sendValue("pair", control.deviceSerialNumber());else if (infectedBy > -1)
radio.sendValue("health", health);break;case GameState.Running:// update health statusif (health != HealthState.Healthy && input.runningTime() - infectedTime > DEATH)
health = HealthState.Dead;else if (health != HealthState.Healthy && input.runningTime() - infectedTime > INCUBATION)
health = HealthState.Sick;// transmit diseaseif (health == HealthState.Incubating || health == HealthState.Sick)
radio.sendValue("transmit", playerIcon);
radio.sendValue("health", health);break;
}// show current animation
gameFace();
}
})
basic.showIcon(GameIcons.Pairing)
















