
鸿蒙跨端古诗接龙游戏开发指南 原创
鸿蒙跨端古诗接龙游戏开发指南
一、系统架构设计
基于HarmonyOS的AI能力和分布式技术,构建古诗接龙游戏系统:
游戏逻辑层:管理游戏状态和规则
AI生成层:使用NLP模型生成古诗下一句
用户交互层:提供游戏界面和输入
跨端同步层:多设备间同步游戏状态和玩家信息
!https://example.com/harmony-poetry-game-arch.png
二、核心代码实现
游戏服务封装
// PoetryGameService.ets
import ai from ‘@ohos.ai’;
import distributedData from ‘@ohos.distributedData’;
import { PlayerInfo, GameState, PoetryLine } from ‘./PoetryTypes’;
class PoetryGameService {
private static instance: PoetryGameService = null;
private modelManager: ai.ModelManager;
private dataManager: distributedData.DataManager;
private gameListeners: GameListener[] = [];
private currentGame: GameState | null = null;
private constructor() {
this.initModelManager();
this.initDataManager();
public static getInstance(): PoetryGameService {
if (!PoetryGameService.instance) {
PoetryGameService.instance = new PoetryGameService();
return PoetryGameService.instance;
private initModelManager(): void {
try {
this.modelManager = ai.createModelManager(getContext());
// 加载古诗生成模型
this.modelManager.loadModel({
modelName: 'poetry_generation',
modelPath: 'resources/rawfile/poetry.model',
callback: (err, data) => {
if (err) {
console.error('加载古诗模型失败:', JSON.stringify(err));
}
});
catch (err) {
console.error('初始化模型管理器失败:', JSON.stringify(err));
}
private initDataManager(): void {
this.dataManager = distributedData.createDataManager({
bundleName: ‘com.example.poetrygame’,
area: distributedData.Area.GLOBAL,
isEncrypted: true
});
this.dataManager.registerDataListener('game_state_sync', (data) => {
this.handleSyncData(data);
});
public async createGame(players: PlayerInfo[]): Promise<GameState> {
try {
// 随机选择一首古诗开头
const openings = [
"床前明月光",
"春眠不觉晓",
"白日依山尽",
"红豆生南国",
"锄禾日当午"
];
const openingLine = openings[Math.floor(Math.random() * openings.length)];
const gameState: GameState = {
gameId: Date.now().toString(),
players: players,
currentPlayer: players[0].deviceId,
poetryLines: [{
text: openingLine,
author: "系统",
deviceId: "system"
}],
startTime: Date.now(),
status: "playing"
};
this.currentGame = gameState;
this.syncGameState(gameState);
return gameState;
catch (err) {
console.error('创建游戏失败:', JSON.stringify(err));
throw err;
}
public async generateNextLine(previousLine: string): Promise<PoetryLine> {
try {
const input = {
previous_line: previousLine,
max_length: 10 // 生成最多10个字符
};
const output = await this.modelManager.runModel({
modelName: 'poetry_generation',
input: input
});
return {
text: output.result.line,
author: "AI",
deviceId: "ai"
};
catch (err) {
console.error('生成古诗失败:', JSON.stringify(err));
throw err;
}
public async submitPlayerLine(line: string, player: PlayerInfo): Promise<GameState> {
if (!this.currentGame) {
throw new Error(‘当前没有进行中的游戏’);
const newLine: PoetryLine = {
text: line,
author: player.nickname,
deviceId: player.deviceId
};
const updatedGame: GameState = {
...this.currentGame,
poetryLines: [...this.currentGame.poetryLines, newLine],
currentPlayer: this.getNextPlayerId(player.deviceId)
};
this.currentGame = updatedGame;
this.syncGameState(updatedGame);
return updatedGame;
private getNextPlayerId(currentPlayerId: string): string {
if (!this.currentGame) return currentPlayerId;
const currentIndex = this.currentGame.players.findIndex(
=> p.deviceId === currentPlayerId
);
const nextIndex = (currentIndex + 1) % this.currentGame.players.length;
return this.currentGame.players[nextIndex].deviceId;
private syncGameState(state: GameState): void {
this.dataManager.syncData('game_state_sync', {
type: 'game_state',
data: state,
timestamp: Date.now()
});
private handleSyncData(data: any): void {
if (!data || data.type !== 'game_state') return;
this.currentGame = data.data;
this.notifyGameStateChanged(data.data);
private notifyGameStateChanged(state: GameState): void {
this.gameListeners.forEach(listener => {
listener.onGameStateChanged?.(state);
});
public addListener(listener: GameListener): void {
if (!this.gameListeners.includes(listener)) {
this.gameListeners.push(listener);
}
public removeListener(listener: GameListener): void {
this.gameListeners = this.gameListeners.filter(l => l !== listener);
}
interface GameListener {
onGameStateChanged?(state: GameState): void;
export const poetryGameService = PoetryGameService.getInstance();
主游戏界面
// GameScreen.ets
import { poetryGameService } from ‘./PoetryGameService’;
import { PlayerInfo, GameState, PoetryLine } from ‘./PoetryTypes’;
@Component
export struct GameScreen {
@State currentGame: GameState | null = null;
@State playerInput: string = ‘’;
@State isGenerating: boolean = false;
@State showAIResult: boolean = false;
@State aiGeneratedLine: PoetryLine | null = null;
@State currentPlayer: PlayerInfo | null = null;
// 模拟玩家信息(实际应从设备获取)
private localPlayer: PlayerInfo = {
deviceId: ‘device_001’,
nickname: ‘玩家1’,
avatar: ‘resources/rawfile/avatar1.png’
};
// 模拟其他玩家(实际应通过分布式能力发现)
private otherPlayers: PlayerInfo[] = [
deviceId: ‘device_002’,
nickname: '玩家2',
avatar: 'resources/rawfile/avatar2.png'
},
deviceId: ‘device_003’,
nickname: '玩家3',
avatar: 'resources/rawfile/avatar3.png'
];
aboutToAppear() {
poetryGameService.addListener({
onGameStateChanged: (state) => {
this.handleGameStateChanged(state);
});
this.startNewGame();
aboutToDisappear() {
poetryGameService.removeListener({
onGameStateChanged: (state) => {
this.handleGameStateChanged(state);
});
build() {
Column() {
// 标题栏
Row() {
Text('古诗接龙')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Button('新游戏')
.width(100)
.onClick(() => {
this.startNewGame();
})
.padding(10)
.width('100%')
// 玩家信息
if (this.currentGame) {
Row() {
ForEach(this.currentGame.players, (player) => {
Column() {
Image(player.avatar)
.width(40)
.height(40)
.borderRadius(20)
.border({
width: player.deviceId === this.currentGame?.currentPlayer ? 2 : 0,
color: '#409EFF'
})
Text(player.nickname)
.fontSize(12)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ right: 15 })
.opacity(player.deviceId === this.currentGame?.currentPlayer ? 1 : 0.6)
})
.width(‘100%’)
.margin({ bottom: 20 })
// 古诗接龙内容
if (this.currentGame?.poetryLines) {
Column() {
ForEach(this.currentGame.poetryLines, (line, index) => {
Column() {
Row() {
if (line.deviceId ! 'system' && line.deviceId ! 'ai') {
Image(this.getPlayerAvatar(line.deviceId))
.width(24)
.height(24)
.borderRadius(12)
.margin({ right: 10 })
Text(line.text)
.fontSize(18)
.fontColor(line.deviceId === 'ai' ? '#888888' : '#333333')
if (index === this.currentGame!.poetryLines.length - 1) {
Text('___')
.fontSize(18)
.fontColor('#409EFF')
.margin({ left: 5 })
}
.margin({ bottom: 5 })
Text(line.author)
.fontSize(12)
.fontColor('#888888')
.margin({ left: line.deviceId === 'system' ? 0 : 34 })
.margin({ bottom: 15 })
})
.width(‘100%’)
.padding(15)
.backgroundColor('#F9F9F9')
.borderRadius(8)
.margin({ bottom: 20 })
// 玩家输入区域
if (this.currentGame?.currentPlayer === this.localPlayer.deviceId) {
Column() {
TextInput({ placeholder: '输入下一句古诗...', text: this.playerInput })
.height(60)
.width('100%')
.fontSize(16)
.onChange((value: string) => {
this.playerInput = value;
})
Row() {
Button('提交')
.width(120)
.height(50)
.fontSize(18)
.onClick(() => {
this.submitLine();
})
.margin({ right: 15 })
Button('AI提示')
.width(120)
.height(50)
.fontSize(18)
.onClick(() => {
this.requestAIHelp();
})
.margin({ top: 10 })
.width(‘100%’)
}
.width('100%')
.height('100%')
.padding(20)
// AI生成结果弹窗
if (this.showAIResult && this.aiGeneratedLine) {
DialogComponent({
title: 'AI生成建议',
content: this.buildAIResultContent(),
confirm: {
value: '使用这句',
action: () => this.useAILine()
},
cancel: {
value: '换一句',
action: () => this.requestAIHelp()
})
}
private buildAIResultContent(): void {
Column() {
Text(this.aiGeneratedLine!.text)
.fontSize(20)
.fontColor(‘#333333’)
.margin({ bottom: 20 })
Text('AI生成,仅供参考')
.fontSize(14)
.fontColor('#888888')
.padding(20)
.width('100%')
private async startNewGame(): Promise<void> {
try {
const players = [this.localPlayer, ...this.otherPlayers];
this.currentGame = await poetryGameService.createGame(players);
catch (err) {
console.error('开始新游戏失败:', JSON.stringify(err));
prompt.showToast({ message: '开始游戏失败,请重试' });
}
private async submitLine(): Promise<void> {
if (!this.playerInput.trim()) {
prompt.showToast({ message: ‘请输入诗句’ });
return;
try {
await poetryGameService.submitPlayerLine(
this.playerInput,
this.localPlayer
);
this.playerInput = '';
catch (err) {
console.error('提交诗句失败:', JSON.stringify(err));
prompt.showToast({ message: '提交失败,请重试' });
}
private async requestAIHelp(): Promise<void> {
if (!this.currentGame || this.currentGame.poetryLines.length === 0) return;
this.isGenerating = true;
try {
const lastLine = this.currentGame.poetryLines[
this.currentGame.poetryLines.length - 1
].text;
this.aiGeneratedLine = await poetryGameService.generateNextLine(lastLine);
this.showAIResult = true;
catch (err) {
console.error('获取AI提示失败:', JSON.stringify(err));
prompt.showToast({ message: '获取提示失败,请重试' });
finally {
this.isGenerating = false;
}
private async useAILine(): Promise<void> {
if (!this.aiGeneratedLine) return;
try {
await poetryGameService.submitPlayerLine(
this.aiGeneratedLine.text,
this.localPlayer
);
this.showAIResult = false;
this.aiGeneratedLine = null;
catch (err) {
console.error('使用AI诗句失败:', JSON.stringify(err));
prompt.showToast({ message: '提交失败,请重试' });
}
private handleGameStateChanged(state: GameState): void {
this.currentGame = state;
this.currentPlayer = state.players.find(
=> p.deviceId === state.currentPlayer
) || null;
private getPlayerAvatar(deviceId: string): string {
const player = this.currentGame?.players.find(p => p.deviceId === deviceId);
return player?.avatar || 'resources/rawfile/default_avatar.png';
}
类型定义
// PoetryTypes.ets
export interface PlayerInfo {
deviceId: string;
nickname: string;
avatar: string;
export interface PoetryLine {
text: string;
author: string;
deviceId: string;
export interface GameState {
gameId: string;
players: PlayerInfo[];
currentPlayer: string;
poetryLines: PoetryLine[];
startTime: number;
status: “waiting” “playing”
“finished”;
三、项目配置与权限
权限配置
// module.json5
“module”: {
"requestPermissions": [
“name”: “ohos.permission.USE_AI”,
"reason": "使用AI模型生成古诗"
},
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”,
"reason": "同步游戏状态"
],
"abilities": [
“name”: “MainAbility”,
"type": "page",
"visible": true
]
}
四、总结与扩展
本古诗接龙游戏系统实现了以下核心功能:
多人联机游戏:支持多设备玩家实时参与
AI智能提示:为玩家提供古诗接龙建议
回合制游戏:按照顺序轮流接龙
跨设备同步:实时同步游戏状态和玩家操作
扩展方向:
难度分级:根据玩家水平设置不同难度
诗词库扩展:支持更多诗词类型和朝代
评分系统:评估玩家接龙的诗句质量
社交分享:分享游戏过程和精彩诗句
历史记录:保存经典接龙对局
语音输入:支持语音输入诗句
通过HarmonyOS的AI能力和分布式技术,我们构建了一个寓教于乐的古诗接龙游戏,既能让玩家感受中华诗词的魅力,又能体验多设备协同游戏的乐趣。
