鴻蒙元服務實戰(zhàn)-笑笑五子棋(5)
來到最后一章了,這一章節(jié)講兩個部分。一是笑笑五子棋的卡片制作,二就是發(fā)布上架。
卡片介紹
Form Kit(卡片開發(fā)框架)提供了一種在桌面、鎖屏等系統(tǒng)入口嵌入顯示應用信息的開發(fā)框架和 API,可以將應用內(nèi)用戶關注的重要
信息或常用操作抽取到服務卡片(以下簡稱“卡片”)上,通過將卡片添加到桌面上,以達到信息展示、服務直達的便捷體驗效果。
新建卡片
卡片類型分為兩種:
- 靜態(tài)卡片 功能稍弱
- 動態(tài)卡片 功能強一些
- 選擇卡片的屬性
- 然后你就得到了以下文件
卡片文件解釋
EntryFormAbility.ets
entry/src/main/ets/entryformability/EntryFormAbility.ets
該文件可以定義卡片的生命周期,傳遞數(shù)據(jù)給卡片等
WidgetCard
entry/src/main/ets/widget/pages/WidgetCard.ets
該文件是卡片的主要展示和業(yè)務功能頁面。 卡片外觀、功能主要由它來提供
form_config.json
entry/src/main/resources/base/profile/form_config.json
該文件是卡片的配置文件,比如卡片的圖標、卡片的名字、卡片的種類等等都可以在這配置
獲取卡片寬度
卡片的 api 和元服務的 api 稍有區(qū)別,所以在開發(fā)的需要額外注意
這里在 entry/src/main/ets/entryformability/EntryFormAbility.ets
內(nèi),可以設置卡片創(chuàng)建的時獲取卡片的寬度
因為卡片有不同的規(guī)格尺寸,所以可以動態(tài)來獲取。
onAddForm(want: Want) {
let formData: Record< string, number > = {
"canwidth": px2vp((want.parameters?.[formInfo.FormParam.WIDTH_KEY] as number) * 2),
};
return formBindingData.createFormBindingData(formData);
}
卡片中是無法使用 AppStorage
,所以需要使用 Localstorage 來代替,進行數(shù)據(jù)傳遞
卡片中接收
@Entry
@Component
struct WidgetCard {
@LocalStorageProp("canwidth")
canwidth: number = 0
@LocalStorageProp("canwidth")
canheight: number = 0
完成卡片下棋邏輯
因為卡片的下棋邏輯和宿主-元服務本身幾乎一致。因此在實際開發(fā)中,可以將它們共同的邏輯抽離出來方便管理。這里就 cv 復用了。
@Entry
@Component
struct WidgetCard {
@LocalStorageProp("canwidth")
canwidth: number = 0
@LocalStorageProp("canwidth")
canheight: number = 0
settings: RenderingContextSettings = new RenderingContextSettings(true);
ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// 棋盤參數(shù)
gridSize: number = 15;
cellSize: number = this.canwidth / this.gridSize;
radius: number = this.cellSize / 2 - 5; // 棋子的半徑
// 棋盤數(shù)據(jù)
board: number[][] = []
currentPlayer: number = 1; // 當前玩家 (1: 黑子, 2: 白子)
gameOver: boolean = false;
@State
textContent: string = ""
// 處理玩家落子
handleClick = async (event: ClickEvent) = > {
if (this.gameOver) {
return;
}
const x = event.x;
const y = event.y;
const col = Math.floor(x / this.cellSize);
const row = Math.floor(y / this.cellSize);
if (this.board[row] && this.board[row][col] === 0) {
this.board[row][col] = this.currentPlayer;
this.drawBoard();
if (this.checkWin(row, col)) {
this.textContent = this.currentPlayer === 1 ? '黑子勝利!' : '白子勝利!';
this.gameOver = true;
// AlertDialog.show({ message: this.textContent })
} else {
this.currentPlayer = this.currentPlayer === 1 ? 2 : 1;
this.textContent = this.currentPlayer === 1 ? '輪到黑子落子' : '輪到白子落子';
}
} else {
// promptAction.showToast({ message: `請點擊中棋盤對位位置` })
}
}
aboutToAppear(): void {
}
// 繪制棋盤
drawBoard = () = > {
this.ctx.clearRect(0, 0, this.canwidth, this.canwidth);
// 繪制網(wǎng)格
this.ctx.strokeStyle = "#000";
this.ctx.lineWidth = 1;
for (let i = 0; i < this.gridSize; i++) {
this.ctx.beginPath();
this.ctx.moveTo(this.cellSize * i, 0);
this.ctx.lineTo(this.cellSize * i, this.canwidth);
this.ctx.stroke();
this.ctx.beginPath();
this.ctx.moveTo(0, this.cellSize * i);
this.ctx.lineTo(this.canwidth, this.cellSize * i);
this.ctx.stroke();
}
// 繪制已落的棋子
for (let row = 0; row < this.gridSize; row++) {
for (let col = 0; col < this.gridSize; col++) {
if (this.board[row][col] !== 0) {
this.ctx.beginPath();
this.ctx.arc(col * this.cellSize + this.cellSize / 2, row * this.cellSize + this.cellSize / 2, this.radius, 0,
2 * Math.PI);
this.ctx.fillStyle = this.board[row][col] === 1 ? 'black' : 'white';
this.ctx.fill();
this.ctx.stroke();
}
}
}
}
// 判斷是否有五子連珠
checkWin = (row: number, col: number) = > {
interface abc {
dr: number
dc: number
}
const directions: abc[] = [
{ dr: 0, dc: 1 }, // 水平
{ dr: 1, dc: 0 }, // 垂直
{ dr: 1, dc: 1 }, // 主對角線
{ dr: 1, dc: -1 }// 副對角線
];
for (let i = 0; i < directions.length; i++) {
const dr = directions[i].dr
const dc = directions[i].dc
let count = 1;
// 向一個方向檢查
for (let i = 1; i < 5; i++) {
let r = row + dr * i;
let c = col + dc * i;
if (r >= 0 && r < this.gridSize && c >= 0 && c < this.gridSize && this.board[r][c] === this.currentPlayer) {
count++;
} else {
break;
}
}
// 向另一個方向檢查
for (let i = 1; i < 5; i++) {
let r = row - dr * i;
let c = col - dc * i;
if (r >= 0 && r < this.gridSize && c >= 0 && c < this.gridSize && this.board[r][c] === this.currentPlayer) {
count++;
} else {
break;
}
}
// 如果連續(xù)五個相同的棋子,則勝利
if (count >= 5) {
return true;
}
}
return false;
}
// 初始化游戲
initGame = () = > {
this.board = []
for (let index = 0; index < this.gridSize; index++) {
const arr: number[] = []
for (let index2 = 0; index2 < this.gridSize; index2++) {
arr.push(0)
}
this.board.push(arr)
}
this.currentPlayer = 1;
this.gameOver = false;
this.textContent = '輪到黑子落子';
this.drawBoard();
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
Canvas(this.ctx)
.width(this.canwidth)
.height(this.canwidth)
.backgroundColor(Color.Orange)
.onReady(() = > {
this.cellSize = this.canwidth / this.gridSize;
this.radius = this.cellSize / 2 - 5; // 棋子的半徑
this.initGame()
})
.onClick(
this.handleClick
)
Text(this.textContent)
.fontSize(14)
.padding(5)
.fontColor(Color.White)
.fontWeight(700)
}
.width("100%")
.height("100%")
}
}
調(diào)整卡片的圖標和名字
主要業(yè)務開發(fā)完畢了,可以調(diào)整卡片的展示信息
這部分信息在 entry/src/main/resources/base/profile/form_config.json
中配置:
displayName
標題description
簡介
{
"forms": [
{
"name": "widget",
"displayName": "$string:widget_display_name",
"description": "$string:widget_desc",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDynamic": true,
"isDefault": true,
"updateEnabled": false,
"scheduledUpdateTime": "10:30",
"updateDuration": 1,
"defaultDimension": "4*4",
"supportDimensions": [
"2*2",
"4*4"
]
}
]
}
發(fā)布上架
最后,如果要將卡片發(fā)布上架,還需要做一些小處理
- 設置你的元服務的展示圖標
- 配置證書
- 打包成 Hap
- 在 AGC 平臺上發(fā)布上架等等
- 具體流程可以參考底部的文章
參考鏈接
- 卡片開發(fā)
- [HarmonyOS Next 實戰(zhàn)卡片開發(fā) 01](https://juejin.cn/post/7432314654287872010)
- [HarmonyOS Next 實戰(zhàn)卡片開發(fā) 02](https://juejin.cn/post/7433035654400245811)
- [HarmonyOS Next 實戰(zhàn)卡片開發(fā) 03](https://juejin.cn/post/7433422988358189107)
- [HarmonyOS Next 最新 元服務新建到上架全流程](https://juejin.cn/post/7441761663701041161)
代碼倉庫
https://gitee.com/ukSir/laughing-at-gomoku
總結(jié)
至此,笑笑五子棋的開發(fā)上架流程已經(jīng)完畢。
如果你興趣想要了解更多的鴻蒙應用開發(fā)細節(jié)和最新資訊,歡迎在評論區(qū)留言或者私信或者看我個人信息,可以加入技術(shù)交流群。
審核編輯 黃宇
-
API
+關注
關注
2文章
1537瀏覽量
63023 -
Canvas
+關注
關注
0文章
20瀏覽量
11105 -
鴻蒙
+關注
關注
57文章
2457瀏覽量
43447
發(fā)布評論請先 登錄
相關推薦
評論