6

OpenHarmony- 基于ArkUI (JS)实现数字排序小游戏

 2 years ago
source link: https://os.51cto.com/article/715636.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

OpenHarmony- 基于ArkUI (JS)实现数字排序小游戏-51CTO.COM

OpenHarmony- 基于ArkUI (JS)实现数字排序小游戏
作者:82王先生 2022-08-04 13:55:08
拼数字小游戏其实是借鉴了很多前辈写的案例,然后自己去动手写了一下。主要是学习使用OpenHarmony开发相关知识。
f386ce345d185d8f7cc670515af80d2f1a2f93.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

拼数字小游戏其实是借鉴了很多前辈写的案例,然后自己去动手写了一下。主要是学习使用OpenHarmony开发相关知识,包括一些API需要自己去踩踩坑才行,小游戏其中还有很多不足之处,后面有时间了会尝试做成闯关的类型,包括统计分数做一个排行榜等其他功能。

简单演示一下,因为是4*4的,想拼成可能要花费一些时间。

OpenHarmony- 基于ArkUI (JS)实现数字排序小游戏-开源基础软件社区

排列成功后的效果是这样的!

OpenHarmony- 基于ArkUI (JS)实现数字排序小游戏-开源基础软件社区
  1. 创建一个4*4的表格方阵,将一个空白方格和1到15的数字随意打乱在方阵中,使其随机分布。表格上方放一个定时器,用来记录游戏进行的时间,单位为秒,表格下方放一个“开始游戏”的按钮,点击后开始游戏。
  2. 单击控制鼠标,在表格方阵上向上、下、左、右随意一个方向进行移动,计时器开始计时,空白方格周围对应位置的方格会随着鼠标移动的方向,向对应的方向移动一格。
  3. 在进行多次的移动后,所有的数字按照顺序排列完成后,会弹出“你真滴棒!”的提示游戏完成的界面。

使用到的官方API

getContext

getContext(type: ‘2d’, options: ContextAttrOptions): CanvasRendering2dContext。

获取canvas绘图上下文 – 不支持在onInit和onReady中进行调用。

string

设置为’2d’,返回值为2D绘制对象,该对象可用于在画布组件上绘制矩形、文本、图片等。

options

ContextAttrOptions

当前仅支持配置是否开启抗锯齿功能,默认为关闭。

表1 ContextAttrOptions。

antialias

boolean

是否开启抗锯齿功能,默认为false。

​CanvasRenderingContext2D​

用于在画布组件上绘制矩形、文本、图片等。

fillRect

fillRect(x: number, y: number, width:number, height: number): void。

填充一个矩形。

number

指定矩形左上角点的x坐标。

number

指定矩形左上角点的y坐标。

width

number

指定矩形的宽度。

height

number

指定矩形的高度。

fillText

fillText(text: string, x: number, y: number): void。

绘制填充类文本。

string

需要绘制的文本内容。

number

需要绘制的文本的左下角x坐标。

number

需要绘制的文本的左下角y坐标。

1、html代码

<div class="container" >
    <text class="times">
        游戏用时:{{ currentTime}} 秒
    </text>
    <stack class="stack">
        <canvas class="canvas" ref="canvas" onswipe="onSwipeGrids"></canvas>
        <div class="success" show="{{isShow}}">
            <text class="gameOver">
                你真滴棒!
            </text>
        </div>
    </stack>
    <input type="button" value="开始游戏" class="tip" onclick="startGame"/>
</div>

2、css代码

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width:100%;
    height:100%;
    margin: 0 auto;
}
.times{
    font-size: 25px;
    text-align:center;
    width:300px;
    letter-spacing:0px;
}
.canvas{
    width:100%;
    height:100%;
    background-color: #FFEFD5     ;
}
.tip{
    
    width:150px;
    height:35px;
    background-color: #20B2AA;
    font-size:25px;
    margin-top:10px;
    margin-bottom: 5px;
}

.stack{
    width: 305px;
    height: 305px;
    margin-top: 10px;
}
.success {
    left:50px;
    top:95px;
    width: 220px;
    height: 130px;
    justify-content: center;
    align-items: center;
    background-color: #E9C2A6;
}
.gameOver {
    font-size: 38px;
    color: black;
}

3、 js代码

var grids;
var context;
var timer;
const sideLen = 70; // 方格的边长
const margin = 5; // 方格的间距
export default {
    data: {
        currentTime: '0.0', // 游戏用时
        isShow: false, // 控制‘你真滴棒’弹出框的显示或隐藏
    },
    onInit() {
        // 二维数组grids
        grids = [[1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
        [13, 14, 15, 0]];
    },

    isInitGrids() {
        let array = ["left", "up", "right", "down"];
        for (let i = 0; i < 100; i++) {
            let randomIndex = Math.floor(Math.random() * 4); // 生成随机整数
            let direction = array[randomIndex]; // 获取上下左右方向值
            this.changeGrids(direction);
        }
    },
    onReady() {
        this.isInitGrids();
    },
    onShow() {
        context = this.$refs.canvas.getContext('2d'); // 获取canvas绘图上下文
        this.drawGrids();
    },
    drawGrids() {
        for (let row = 0; row < 4; row++) {
            for (let column = 0; column < 4; column++) {
                let gridStr = grids[row][column].toString();
                context.fillStyle = "#87CEEB"; // context的方格的颜色
                let leftTopX = column * (margin + sideLen) + margin; // X坐标
                let leftTopY = row * (margin + sideLen) + margin; // y坐标
                context.fillRect(leftTopX, leftTopY, sideLen, sideLen); // 填充
                context.textBaseline = 'top'
                context.font = "30px";
                if (gridStr != "0") { // 除空白格外其他的格子
                    context.fillStyle = "#000000"; // 数字的颜色
                    let offsetX = (4 - gridStr.length) * (sideLen / 8);
                    let offsetY = (sideLen - 30) / 2;
                    context.fillText(gridStr, leftTopX + offsetX, leftTopY + offsetY); // 绘制填充文本
                }
            }
        }
    },
   // 点击开始游戏后计时的方法
    runIt() {
        this.currentTime = (Math.floor(parseFloat(this.currentTime) * 10 + 1) / 10).toString();
        if (parseFloat(this.currentTime) % 1 == 0) {
            this.currentTime = this.currentTime + ".0";
        }
    },
    // 滑动事件的方法
    onSwipeGrids(e) {
        this.changeGrids(e.direction);
        this.drawGrids();
        // 如果this.gameOver()返回true,则清除定时,显示“你真滴棒”表示游戏结束
        if (this.gameOver()) {
            clearInterval(timer);
            this.isShow = true;
        }
    },
    // 判断游戏结束的函数
    gameOver() {
        // 定义一个成功的二维数组oriGrids
        let oriGrids = [[1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
        [13, 14, 15, 0]];
        for (let row = 0; row < 4; row++) {
            for (let column = 0; column < 4; column++) {
                // 如果二维数组grids不等于二维数组oriGrids返回false继续游戏
                if (grids[row][column] != oriGrids[row][column]) {
                    return false;
                }
            }
        }
        return true; // 结束游戏
    },
    // 点击挪动网格
    changeGrids(direction) {
        let x;
        let y;
        for (let row = 0; row < 4; row++) {
            for (let column = 0; column < 4; column++) {
                if (grids[row][column] == 0) { // 拿到坐标
                    x = row;
                    y = column;
                    break;
                }
            }
        }
        let temp;
        if (this.isShow == false) {
            if (direction == 'up' && (x + 1) < 4) { // 向上移动(x+1必须小于四)
                temp = grids[x + 1][y];
                grids[x + 1][y] = grids[x][y];
                grids[x][y] = temp;
            } else if (direction == 'down' && (x - 1) > -1) { // 向下移动(x-1必须大于负一)
                temp = grids[x - 1][y];
                grids[x - 1][y] = grids[x][y];
                grids[x][y] = temp;
            } else if (direction == 'left' && (y + 1) < 4) { // 向左移动(y + 1必须小于四)
                temp = grids[x][y + 1];
                grids[x][y + 1] = grids[x][y];
                grids[x][y] = temp;
            } else if (direction == 'right' && (y - 1) > -1) { // 向右移动(y-1必须大于负一)
                temp = grids[x][y - 1];
                grids[x][y - 1] = grids[x][y];
                grids[x][y] = temp;
            }
        }
    },
    startGame() {
        timer = setInterval(this.runIt, 100); // 1秒定时执行
        this.isInitGrids();
        this.currentTime = "0.0"; // 初始化游戏用时
        this.isShow = false;
        this.onShow();
    }
}

H5中使用的样式或者方法有些是在OpenHarmony开发过程中无法使用的,要进行FA开发需要多读OpenHarmony的文档,后续的开发中也需要多踩坑,多总结,多练习!

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK