İçeriğe atla

Oda tarifleri

Takımları otomatik dengele

Yeni oyuncuları daha küçük takıma yerleştirin, biri ayrıldığında yeniden dengeleyin ve takımlar hazır olduğunda maçları başlatın.

Bu oda, kırmızı ve maviyi birbirinden en fazla bir oyuncu farkla tutar, takımlar doluyken fazla oyuncuları izleyici olarak bekletir ve her iki takımda da bir oyuncu olduğu anda maçı başlatır.

host.mjs
import { createRoom } from 'ball2d/node';

const TEAM_SIZE = 3;

const room = await createRoom({
  apiKey: process.env.BALL2D_API_KEY,
  roomName: '3v3 balanced',
  noPlayer: true,
  maxPlayers: 10,
  public: true,
});

const team = (id) =>
  room.getPlayerList().filter((p) => p.team === id);

async function balance() {
  // Fill the smaller team from the spectators, oldest first.
  for (const spectator of team(0)) {
    const [red, blue] = [team(1).length, team(2).length];
    if (Math.min(red, blue) >= TEAM_SIZE) break;
    await room.setPlayerTeam(spectator.id, red <= blue ? 1 : 2);
  }
  // Move one player across if the teams differ by two or more.
  const [red, blue] = [team(1), team(2)];
  if (Math.abs(red.length - blue.length) >= 2) {
    const larger = red.length > blue.length ? red : blue;
    await room.setPlayerTeam(
      larger.at(-1).id,
      larger === red ? 2 : 1,
    );
  }
  if (
    team(1).length > 0 &&
    team(2).length > 0 &&
    room.getScores() === null
  )
    await room.startGame();
}

let queue = Promise.resolve();
const rebalance = () => {
  queue = queue
    .then(balance)
    .catch((error) => console.error('Balance failed:', error));
};

room.onPlayerJoin = rebalance;
room.onPlayerLeave = rebalance;
room.onGameStop = rebalance;

await room.setTeamsLock(true);
await room.setDefaultStadium('Classic');
console.log(room.roomLink);

Nasıl çalışır

  • Aynı anda tek bir dengeleme. Katılmalar ve ayrılmalar birlikte gelebilir. Her çalıştırmayı queue üzerine zincirlemek, her dengelemenin öncekinin sonucunu görmesini sağlar.
  • Bekledikten sonra okuyun. team(), her await sonrasında kadroyu okur; böylece her karar geçerli takımları kullanır.
  • Takımlar kilitli. setTeamsLock(true), oyuncuların kendilerini değiştirerek dengelemeyi bozmasını önler. Kodunuz yine de herkesi taşıyabilir.
  • En son taşınan gider. Takım değiştiren bir oyuncu kadronun sonuna taşınır; bu nedenle larger.at(-1), o takıma en son katılan oyuncudur.

Varyasyonlar

  • Sayı yerine yeteneğe göre dengeleyin: her oyuncu kimliği için bir Map içinde bir puan tutun ve her izleyiciyi toplamı daha düşük olan takıma atayın.
  • Kaybeden takımı değiştirin: onTeamVictory içinde, kaybedenleri bir sonraki balance() çağrısından önce izleyicilere taşıyın.