0°

(十九)基础例子:感染

感染是一种引人入胜的游戏,建议在室外或大型开放区域播放,以便为活动提供更多空间

规则

感染是一种模拟疾病传播的分布式游戏。目标是在每个玩家死亡之前停止爆发!

  • 角色数量: 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

项目分享

此代码使用块中不支持的语言功能,例如switchenum。因此,它不会转换回块。

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)

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论