Harmony OS 5 完成一个简易的鸿蒙棋牌游戏思路

package com.example.chess;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.TableLayout;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.components.Component.DrawTask;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;

public class ChessAbility extends Ability {
    private static final int BOARD_SIZE = 9; // 9x10棋盘
    private static final int GRID_SIZE = 60; // 网格大小
    private ChessPiece[][] board = new ChessPiece[10][9]; // 10行9列
    private ChessPiece selectedPiece = null;
    
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        DirectionalLayout layout = new DirectionalLayout(this);
        ChessBoard boardView = new ChessBoard(this);
        layout.addComponent(boardView);
        super.setUIContent(layout);
        
        initBoard(); // 初始化棋盘
// 初始化棋子位置

    private void initBoard() {
        // 红方棋子
        board[0][0] = new ChessPiece(ChessPiece.ROOK, ChessPiece.RED, 0, 0);
        board[0][1] = new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 0, 1);
        board[0][2] = new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 0, 2);
        board[0][3] = new ChessPiece(ChessPiece.GUARD, ChessPiece.RED, 0, 3);
        board[0][4] = new ChessPiece(ChessPiece.KING, ChessPiece.RED, 0, 4);
        board[0][5] = new ChessPiece(ChessPiece.GUARD, ChessPiece.RED, 0, 5);
        board[0][6] = new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 0, 6);
        board[0][7] = new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 0, 7);
        board[0][8] = new ChessPiece(ChessPiece.ROOK, ChessPiece.RED, 0, 8);
        board[2][1] = new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 2, 1);
        board[2][7] = new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 2, 7);
        board[3][0] = new ChessPiece(ChessPiece.PAWN, ChessPiece.RED, 3, 0);
        // ... 其他棋子初始化类似

        // 黑方棋子
        board[9][0] = new ChessPiece(ChessPiece.ROOK, ChessPiece.BLACK, 9, 0);
        // ... 其他棋子初始化
// 棋子类

    static class ChessPiece {
        public static final int KING = 0;
        public static final int GUARD = 1;
        public static final int ELEPHANT = 2;
        public static final int HORSE = 3;
        public static final int ROOK = 4;
        public static final int CANNON = 5;
        public static final int PAWN = 6;
        
        public static final int RED = 0;
        public static final int BLACK = 1;
        
        int type;
        int color;
        int row;
        int col;
        
        public ChessPiece(int type, int color, int row, int col) {
            this.type = type;
            this.color = color;
            this.row = row;
            this.col = col;
// 检查移动是否合法(简化版)

        public boolean isValidMove(int newRow, int newCol, ChessPiece[][] board) {
            // 实现具体棋子移动规则
            return true;
}

    // 棋盘视图
    class ChessBoard extends Component {
        private Paint boardPaint;
        private Paint highlightPaint;
        
        public ChessBoard(Context context) {
            super(context);
            initPaints();
            setClickedListener(this::onBoardClick);
private void initPaints() {

            boardPaint = new Paint();
            boardPaint.setColor(new Color(0, 0, 0));
            boardPaint.setStrokeWidth(2);
            
            highlightPaint = new Paint();
            highlightPaint.setColor(new Color(255, 255, 0, 100));
@Override

        public void onDraw(Component component, Canvas canvas) {
            super.onDraw(component, canvas);
            drawBoard(canvas);
            drawPieces(canvas);
            drawHighlights(canvas);
// 绘制棋盘网格

        private void drawBoard(Canvas canvas) {
            for (int i = 0; i <= BOARD_SIZE; i++) {
                // 画横线
                canvas.drawLine(0, i  GRID_SIZE, BOARD_SIZE  GRID_SIZE, i * GRID_SIZE, boardPaint);
                // 画竖线(前5列)
                canvas.drawLine(i  GRID_SIZE, 0, i  GRID_SIZE, 4 * GRID_SIZE, boardPaint);
                // 画竖线(后5列)
                canvas.drawLine(i  GRID_SIZE, 5  GRID_SIZE, i  GRID_SIZE, 9  GRID_SIZE, boardPaint);
// 画楚河汉界

            canvas.drawText("楚河        汉界", BOARD_SIZE/2  GRID_SIZE - 80, 4.5f  GRID_SIZE, boardPaint);
// 绘制棋子

        private void drawPieces(Canvas canvas) {
            for (int r = 0; r < 10; r++) {
                for (int c = 0; c < 9; c++) {
                    ChessPiece piece = board[r][c];
                    if (piece != null) {
                        int x = c * GRID_SIZE + GRID_SIZE/2;
                        int y = r * GRID_SIZE + GRID_SIZE/2;
                        
                        // 绘制棋子背景
                        Paint piecePaint = new Paint();
                        piecePaint.setColor(piece.color == ChessPiece.RED ? 
                                 Color.RED : Color.BLACK);
                        canvas.drawCircle(x, y, GRID_SIZE/2 - 5, piecePaint);
                        
                        // 绘制棋子文字
                        Paint textPaint = new Paint();
                        textPaint.setColor(Color.WHITE);
                        textPaint.setTextSize(30);
                        canvas.drawText(getPieceName(piece.type), x - 15, y + 10, textPaint);
}

}

        
        // 获取棋子名称
        private String getPieceName(int type) {
            switch(type) {
                case ChessPiece.KING: return "将";
                case ChessPiece.ROOK: return "车";
                case ChessPiece.HORSE: return "马";
                case ChessPiece.CANNON: return "炮";
                case ChessPiece.GUARD: return "士";
                case ChessPiece.ELEPHANT: return "象";
                case ChessPiece.PAWN: return "兵";
                default: return "";
}

        
        // 绘制选中高亮
        private void drawHighlights(Canvas canvas) {
            if (selectedPiece != null) {
                int x = selectedPiece.col * GRID_SIZE;
                int y = selectedPiece.row * GRID_SIZE;
                canvas.drawRect(x, y, x + GRID_SIZE, y + GRID_SIZE, highlightPaint);
}

        
        // 棋盘点击处理
        private boolean onBoardClick(Component component, TouchEvent event) {
            if (event.getAction() != TouchEvent.PRIMARY_POINT_DOWN) {
                return false;
int col = (int)(event.getPointerPosition(0).getX() / GRID_SIZE);

            int row = (int)(event.getPointerPosition(0).getY() / GRID_SIZE);
            
            // 边界检查
            if (row < 0 |row >= 10
col < 0
| col >= 9) return true;
            
            ChessPiece clickedPiece = board[row][col];
            
            if (selectedPiece == null) {
                // 选择棋子
                if (clickedPiece != null) {
                    selectedPiece = clickedPiece;
                    invalidate();
} else {

                // 移动棋子
                if (selectedPiece.isValidMove(row, col, board)) {
                    board[selectedPiece.row][selectedPiece.col] = null;
                    selectedPiece.row = row;
                    selectedPiece.col = col;
                    board[row][col] = selectedPiece;
selectedPiece = null;

                invalidate();
return true;

}

代码解析:
整体结构

ChessAbility:主Ability,负责初始化界面和棋盘

ChessPiece:棋子数据类,存储棋子类型、颜色和位置

ChessBoard:自定义棋盘组件,处理绘制和交互
核心功能实现

棋盘绘制:使用Canvas绘制9×10的网格和"楚河汉界"

棋子表示:用类封装棋子类型(将/车/马/炮等)和颜色(红/黑)

交互逻辑:

点击棋子时高亮选中

再次点击合法位置时移动棋子

移动验证:isValidMove()方法预留了棋子规则实现接口
鸿蒙特性实现

使用Component的自定义绘制能力(onDraw方法)

通过setClickedListener处理触摸事件

使用Canvas进行2D图形绘制

颜色管理使用Color和Paint类
棋子移动规则要点(需在isValidMove中完善):

将/帅:只能在九宫内直线移动一步

士/仕:九宫内斜线移动一步

象/相:田字移动,不能过河

车:直线任意距离移动

马:日字移动,需考虑蹩马腿

炮:直线移动,吃子需隔一子

兵/卒:只能向前,过河后可左右移动

扩展建议:
游戏状态管理

添加游戏状态(等待/结束)

实现胜负判定逻辑

添加计时功能
视觉优化

使用图片替代文字表示棋子

添加棋子移动动画

实现吃子特效
多人对战

添加蓝牙对战功能

实现网络对战模块

添加AI对战功能
音效与震动

添加棋子移动音效

实现胜负提示音

关键操作添加震动反馈

鸿蒙开发注意事项:
图形绘制使用ohos.agp.render.Canvas类

事件处理使用ohos.multimodalinput.event包

布局推荐使用DirectionalLayout或TableLayout

资源管理使用ResourceTable访问资源文件
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值