#2020征文-手表#深鸿会深大小组:OpenHarmony小游戏:贪吃蛇

目录:
前言
概述
项目的创建
完成基本布局
把蛇、食物、地面绘制出来
让蛇动起来
吃到食物的判定
游戏的重新开始与计分
结语
源码包

前言

随着学习的深入,我们决定把经典游戏贪吃蛇移植到鸿蒙上,这篇文章用于记录学习中的感悟,也为了分享给对鸿蒙有兴趣的初学者们,希望在这个过程中能够相互交流、共同进步。

一同参与编写的还有:

mb5fa4e07864f6f

Linzijiandevx

Zy82243480

WeChat15820482064

概述

使用工具:DevEco Studio 下载地址:[https://developer.harmonyos.com/cn/develop/deveco-studio]
要完成贪吃蛇游戏,我们需要完成的工作有:

  1. 项目的创建
  2. 完成基本布局
  3. 把蛇、食物、地面绘制出来
  4. 让蛇动起来
  5. 吃到食物的判定
  6. 游戏的重新开始与计分

项目的创建

打开DevEco Studio,然后在左上角的file上选择new->new project创建新项目,为项目命名(不能有中文)。

我们要做的工作主要是修改下图的.hml,.js,.css文件:

完成基本布局

下面是我们这步要实现的效果图

首先我们在hml文件中把组件组织起来:

把原有div组件中的text组件的文字改为当前分数,把该text的class值设为score类,并动态绑定一个变量score,接着设立一个新的组件stack,class类值设为stack,在这个stack组件中放置一个canvas组件,class值设为canvas,ref值设为canvas。

在stack组件后面再添加一个input组件,type值为button,class值设为bit,value设为“重新开始”。

<div class="container">
    <text class="score">
        当前分数: {{score}}
    </text>
    <stack class="stack">
        <canvas class="canvas" ref="canvas" ></canvas>
    </stack>
    <input type="button" value="重新开始" class="bit" onclick="reStart" />
</div>

然后我们在css文件中把hml中的要应用的class值设定好。

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 454px;
    height: 454px;
}
.score {
    font-size: 18px;
    text-align:center;
    width:300px;
    height:20px;
    letter-spacing:0px;
    margin-button:5px;
}
.canvas{
    align-items: center;
    flex-direction: column;
    width:320px;
    height:320px;
    background-color: #BBADA0;
}
.bit{
    width:150px;
    height:30px;
    background-color:#AD9D8F;
    font-size:24px;
    margin-top:10px;
}
.stack{
    width: 305px;
    height: 305px;
    margin-top: 10px;
}

在js文件中,先设定score的值为0:

export default {
    data: {
        score:0
    }
}

然后点击previewer可以看到我们要的预览效果。

把蛇、食物、地面绘制出来

在这一步中我们主要是对js文件进行修改:

首先我们初始化一下我们的矩阵,并定义蛇的初始位置(此处也可以让蛇随机生成,方法不唯一),初始化SX,SY数组与矩阵对应,建立与数字对应的颜色字典。
我们利用getContext函数用以得到绘图组件。
首先给边长和边距赋值,其次定义函数draw()用于绘制所有格子,编译行、列索引,并将行列索引获得的数字转换为字符串,然后赋值给变量gridStr。最后通过字典获得对应格子的颜色并赋值给context.fillStyle,并调用context.fillRect来绘制矩形(左上角X,左上角Y,长,宽)

const SIDELEN = 25; //总体布局大小(边长)
const MARGIN = 5; //总体布局大小(边距)
 draw() {
        for (let i = 0;i < 10; i++) {
            for (let j = 0;j < 10; j++) {
                let gridStr = map[i][j].toString();
                let leftTopX = j * (MARGIN + SIDELEN) + MARGIN;
                let leftTopY = i * (MARGIN + SIDELEN) + MARGIN;
                context.fillStyle = CORLOR[gridStr];
                context.fillRect(leftTopX,leftTopY,SIDELEN,SIDELEN);
            }
        }
    },

绘制蛇和食物
首先定义各类常数和颜色

var SX;//蛇
var SY;//蛇
var GX = 2; //苹果的位置
var GY = 2; //苹果的位置
const CORLOR = {
    "0": "#AD9D8F", //地面
    "1": "#EEE4DA", //蛇头
    "2": "#EEE32A", //蛇身
    "3": "#F67C5F" //食物
}

然后用二维数组设置蛇和食物的初始位置,其中SX和SY的第一个元素,即0和1,代表蛇头的位置;第二个元素,即0和0,代表蛇身的位置。

initMap() {
        map = [[2, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 3, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
        SX = [0, 0];
        SY = [1, 0];
    },

设置用于初始化的函数。
onInit()分别初始化分数、蛇和十五的位置、蛇行走的方向,并隐藏“游戏结束”的字样。
onReady()为生命周期事件,通过this.$refs.canvas来获得组件canvas的对象实例,然后调用getContext()函数传入实参2d来获得2d绘制引擎,然后赋值给变量context。由于context可能会在其他地方用到,故声明其为全局变量。
onShow()设置蛇前进的速度以及调用绘制蛇、食物、地面的函数。

总的代码如下:

var map //地图
var SX;//蛇
var SY;//蛇
var GX = 2; //苹果的位
var GY = 2; //苹果的位置
var context;

const SIDELEN = 25; //总体布局大小
const MARGIN = 5; //总体布局大小
const CORLOR = {
    "0": "#AD9D8F", //地面
    "1": "#EEE4DA", //蛇头
    "2": "#EEE32A", //蛇身
    "3": "#F67C5F" //食物
}

export default {
    data: {
        score: 0,
        isshow: false
    },
    onInit() {//代表初始化
        this.score=0;
        this.initMap();
        Xstep = 0;
        Ystep = 1;
        GX = 2;
        GY = 2;
        clearInterval(timer);
        this.isshow=false;
    },
    onReady() {//程序的准备
        context = this.$refs.canvas.getContext('2d');
    },
    onShow() {//游戏界面的展示
        timer = setInterval(this.run,500);
        this.draw();
    },
    initMap() {
        map = [[2, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 3, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
        SX = [0, 0];
        SY = [1, 0];
    },
    draw() {
        for (let i = 0;i < 10; i++) {
            for (let j = 0;j < 10; j++) {
                let gridStr = map[i][j].toString();
                let leftTopX = j * (MARGIN + SIDELEN) + MARGIN;
                let leftTopY = i * (MARGIN + SIDELEN) + MARGIN;
                context.fillStyle = CORLOR[gridStr];
                context.fillRect(leftTopX,leftTopY,SIDELEN,SIDELEN);
            }
        }
    },

效果图如下:

解锁更多章节>>>

作者:Linzijiandevx
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

【有奖直播-HarmonyOS驱动框架调试总结 火热报名中!】

posted @ 2020-12-08 15:37  HarmonyOS技术社区  阅读(175)  评论(0编辑  收藏  举报