一.前言

     本学期对于鸿蒙开发的学习,做一个简单点的鸿蒙小游戏作为此次学习的大作业,以此展现自己的进步。很常见的小游戏,我把它叫做“别让小球落在地面上”,其实就是玩家需要接住从天而降的小球,避免错过或接错的小游戏,那我们现在就开始吧!


二.环境搭建

这个小游戏是基于华为鸿蒙操作系统(HarmonyOS)和鸿蒙应用开发工具(Huawei DevEco Studio)实现的。因此需要提前搭配好我们的开发环境。当然了,还未搭建环境的小伙伴也没关系,以下是官方的环境搭建地址:

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/deveco_overview-0000001053582387-V3?catalogVersion=V3

三.具体项目

1. 创建新项目

打开DevEco Studio,选择“Create HarmonyOS Project”,然后选择“Empty Ability”模板,点击“Next”。

2. 配置项目信息

按照提示填写项目名称、包名等信息,点击“Finish”完成项目创建。


3.编写代码

3.1编写游戏页面
3.1.1 xml文件

在“entry > src > main > resources > base”目录下创建一个名为“game.hml”的XML文件

<div class="container">
    <image class="background" src="common/background.png"></image>
    <image class="player" src="common/player.png"></image>
    <list class="object-list">
        <list-item class="object" for="obj in objects">
            <image class="object-image" src="common/object{{$idx}}.png"></image>
        </list-item>
    </list>
    <text class="score-text">得分: {{$score}}</text>
</div>
3.1.2 css文件

在“entry > src > main > resources > base”目录下创建一个名为“game.css”的CSS文件

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
}

.background {
    width: 100%;
    height: 100%;
}

.player {
    width: 60px;
    height: 60px;
    position: absolute;
    bottom: 50px;
    animation-name: move-up-down;
    animation-duration: 1s;
    animation-iteration-count: infinite;
}

@keyframes move-up-down {
    0% {
        bottom: 50px;
    }
    50% {
        bottom: 150px;
    }
    100% {
        bottom: 50px;
    }
}

.object-list {
    flex-wrap: wrap;
    justify-content: space-around;
    align-items: center;
    width: 100%;
    height: 100%;
}

.object {
    width: 60px;
    height: 60px;
    position: absolute;
    opacity: 0;
    animation-name: fade-in;
    animation-duration: 1s;
}

@keyframes fade-in {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

.object-image {
    width: 100%;
    height: 100%;
}

.score-text {
    font-size: 32px;
    margin-top: 20px;
}
3.2 创建游戏逻辑类

在“entry > src > main > js > default”目录下创建一个名为“Game.js”的文件

export default class Game {
    constructor() {
        this.objects = [];
        this.score = 0;
        this.isGameOver = false;
    }

    start() {
        setInterval(() => {
            if (!this.isGameOver) {
                const objIndex = Math.floor(Math.random() * 3);
                const obj = {
                    src: `common/object${objIndex + 1}.png`,
                    x: Math.random() * window.innerWidth - 60,
                    y: -60,
                };
               

this.objects.push(obj);
                setTimeout(() => {
                    this.checkCollision(obj);
                }, 1000);
            }
        }, 2000);
    }

    checkCollision(obj) {
        if (obj.y > window.innerHeight + 60) {
            this.isGameOver = true;
            return;
        }

        if (obj.x < this.player.x - 60 || obj.x > this.player.x + 60) {
            this.score++;
            this.objects.splice(this.objects..indexOf(obj), 1);
            obj.y = -60;
            return;
        }

        if (obj.y > this.player.y - 60 && obj.y < this.player.y + 60) {
            this.score++;
            this.objects.splice(this.objects.indexOf(obj), 1);
            obj.y = -60;
        } else if (obj.y < this.player.y - 60) {
            this.isGameOver = true;
        }
    }
}
3.3 更新页面类

打开“entry > src > main > js > default > index.js”文件

// import feature modules
import featureAbility from '@ohos.ability.featureAbility';

// import UI modules
import ui from '@ohos.ui';

// import game class
import Game from './Game';

// extend Ability类
class MainAbility extends featureAbility {
    onWindowStageCreate(want) {
        // 调用基础能力类 onCreate 方法
        super.onWindowStageCreate(want);
        // 初始化游戏对象
        this.game = new Game();
        // 启动游戏
        this.game.start();

        // 关联页面类和逻辑类
        var element = document.getElementById('gamePage');
        if (!element) {
            element = document.createElement('div');
            element.id = 'gamePage';
            document.body.appendChild(element);
        }

        var context = new ui.Context(element);
        var result = ui.inflate(
            './pages/game.hml',
            context
        );
        this.gamePage = result.root;
        this.gamePage.context = context;
        context.setVirtualizer(this.gamePage);

```

this.gamePage.onunload = () => {
    this.game.isGameOver = true;
}

// 更新游戏数据到页面
let score = 0;
Object.defineProperty(this.gamePage, 'score', {
    get() {
        return score;
    },
    set(value) {
        score = value;
        this.gamePage.updateData({
            score: score,
        });
    },
});

// 更新对象数据到页面
this.game.objects.forEach((obj, index) => {
    Object.defineProperty(this.gamePage, `object${index}`, {
        get() {
            return obj;
        },
        set(value) {
            obj = value;

四.总结

       对我来说,这次练习让我在鸿蒙开发的学习上认识到了很多的不足,很多地方暂时还没有能力去完善去优化,让我在今后的学习中能够更加深入的去思考和学习。对于本次的案例由于其他知识的欠缺,只是一个小游戏的基础,如果想要制作这个小游戏相信大家可以比我做得更好,把它优化的更像一个游戏,那就到这里喽!