183 lines
4.4 KiB
Markdown
183 lines
4.4 KiB
Markdown
# boardgame-core
|
||
|
||
基于 Preact Signals 的桌游状态管理库。
|
||
|
||
## 特性
|
||
|
||
- **响应式状态管理**: 使用 [@preact/signals-core](https://preactjs.com/guide/v10/signals/) 实现细粒度响应式
|
||
- **类型安全**: 完整的 TypeScript 支持
|
||
- **核心概念**:
|
||
- **Part**: 游戏组件(棋子、卡牌、板块)
|
||
- **Region**: 容器区域(支持 keyed/unkeyed 两种模式)
|
||
- **Placement**: Part 在 Region 中的引用
|
||
|
||
## 安装
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
### 1. 创建游戏状态
|
||
|
||
```typescript
|
||
import { createGameState } from 'boardgame-core';
|
||
|
||
const gameState = createGameState({
|
||
id: 'game-1',
|
||
name: 'My Board Game',
|
||
});
|
||
```
|
||
|
||
### 2. 创建 Parts(游戏组件)
|
||
|
||
```typescript
|
||
import { createMeepleAction, createCardAction, createTileAction } from 'boardgame-core';
|
||
|
||
// 创建棋子
|
||
const meeple = createMeepleAction(gameState, 'meeple-1', 'red', {
|
||
name: 'Player 1',
|
||
});
|
||
|
||
// 创建卡牌
|
||
const card = createCardAction(gameState, 'card-1', {
|
||
suit: 'hearts',
|
||
value: 10,
|
||
});
|
||
|
||
// 创建板块
|
||
const tile = createTileAction(gameState, 'tile-1', {
|
||
pattern: 'forest',
|
||
rotation: 90,
|
||
});
|
||
```
|
||
|
||
### 3. 创建 Regions(区域)
|
||
|
||
```typescript
|
||
import { createRegionAction, RegionType } from 'boardgame-core';
|
||
|
||
// Unkeyed Region - 适用于牌库、弃牌堆等
|
||
const deck = createRegionAction(gameState, {
|
||
id: 'deck',
|
||
type: RegionType.Unkeyed,
|
||
name: 'Draw Deck',
|
||
});
|
||
|
||
// Keyed Region - 适用于版图、玩家区域等有固定位置的区域
|
||
const board = createRegionAction(gameState, {
|
||
id: 'board',
|
||
type: RegionType.Keyed,
|
||
name: 'Game Board',
|
||
});
|
||
|
||
// 带容量的区域(如手牌限制)
|
||
const hand = createRegionAction(gameState, {
|
||
id: 'hand',
|
||
type: RegionType.Unkeyed,
|
||
capacity: 5,
|
||
});
|
||
```
|
||
|
||
### 4. 创建 Placements(放置)
|
||
|
||
```typescript
|
||
import { createPlacementAction } from 'boardgame-core';
|
||
|
||
// 将棋子放置在版图上
|
||
const placement = createPlacementAction(gameState, {
|
||
id: 'placement-1',
|
||
partId: 'meeple-1',
|
||
regionId: 'board',
|
||
position: { x: 3, y: 4 },
|
||
});
|
||
```
|
||
|
||
### 5. 使用 Actions 操作状态
|
||
|
||
```typescript
|
||
import {
|
||
movePlacementAction,
|
||
flipPlacementAction,
|
||
setSlotAction,
|
||
updatePartAction,
|
||
} from 'boardgame-core';
|
||
|
||
// 移动 Placement 到另一个区域
|
||
movePlacementAction(gameState, 'placement-1', 'hand');
|
||
|
||
// 翻转卡牌(面朝上/面朝下)
|
||
flipPlacementAction(gameState, 'placement-1');
|
||
|
||
// 在 Keyed Region 中设置槽位
|
||
setSlotAction(gameState, 'board', 'A1', 'placement-1');
|
||
|
||
// 更新 Part 属性
|
||
updatePartAction(gameState, 'meeple-1', { metadata: { score: 10 } });
|
||
```
|
||
|
||
## API 参考
|
||
|
||
### Part Actions
|
||
|
||
| Action | 描述 |
|
||
|--------|------|
|
||
| `createPartAction` | 创建通用 Part |
|
||
| `createMeepleAction` | 创建棋子 |
|
||
| `createCardAction` | 创建卡牌 |
|
||
| `createTileAction` | 创建板块 |
|
||
| `updatePartAction` | 更新 Part 属性 |
|
||
| `removePartAction` | 移除 Part |
|
||
| `getPartAction` | 获取 Part |
|
||
|
||
### Region Actions
|
||
|
||
| Action | 描述 |
|
||
|--------|------|
|
||
| `createRegionAction` | 创建 Region |
|
||
| `getRegionAction` | 获取 Region |
|
||
| `removeRegionAction` | 移除 Region |
|
||
| `addPlacementToRegionAction` | 添加 Placement 到 Unkeyed Region |
|
||
| `removePlacementFromRegionAction` | 从 Region 移除 Placement |
|
||
| `setSlotAction` | 设置 Keyed Region 的槽位 |
|
||
| `getSlotAction` | 获取 Keyed Region 的槽位 |
|
||
| `clearRegionAction` | 清空 Region |
|
||
| `getRegionPlacementCountAction` | 获取 Region 中 Placement 数量 |
|
||
| `isRegionEmptyAction` | 检查 Region 是否为空 |
|
||
| `isRegionFullAction` | 检查 Region 是否已满 |
|
||
|
||
### Placement Actions
|
||
|
||
| Action | 描述 |
|
||
|--------|------|
|
||
| `createPlacementAction` | 创建 Placement |
|
||
| `getPlacementAction` | 获取 Placement |
|
||
| `removePlacementAction` | 移除 Placement |
|
||
| `movePlacementAction` | 移动 Placement 到另一个 Region |
|
||
| `updatePlacementPositionAction` | 更新 Placement 位置 |
|
||
| `updatePlacementRotationAction` | 更新 Placement 旋转角度 |
|
||
| `flipPlacementAction` | 翻转 Placement |
|
||
| `updatePlacementPartAction` | 更新 Placement 的 Part 引用 |
|
||
| `swapPlacementsAction` | 交换两个 Placement 的位置 |
|
||
| `setPlacementFaceAction` | 设置 Placement 面朝上/下 |
|
||
| `getPlacementsInRegionAction` | 获取 Region 中的所有 Placements |
|
||
| `getPlacementsOfPartAction` | 获取 Part 的所有 Placements |
|
||
|
||
## 运行测试
|
||
|
||
```bash
|
||
npm test # 监视模式
|
||
npm run test:run # 运行一次
|
||
```
|
||
|
||
## 构建
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
## 许可证
|
||
|
||
MIT
|