10、战绩系统与界面优化

源码地址https://gitee.com/pxlsdz/hyld

演示地址http://121.199.59.80/hyld/

1. 加密、压缩js代码

安装terser

sudo apt-get update
sudo apt-get install npm
sudo npm install terser -g

terser不仅支持文件输入,也支持标准输入。结果会输出到标准输出中。

使用方式:

terser xxx.js -c -m

scripts/compress_game_js.sh

#! /bin/bash

JS_PATH=/home/sdz/project/hyld/game/static/js/
JS_PATH_DIST=${JS_PATH}dist/
JS_PATH_SRC=${JS_PATH}src/

find $JS_PATH_SRC -type f -name '*.js' | sort | xargs cat | terser -c -m > ${JS_PATH_DIST}game.js
echo yes | python3 /home/sdz/project/hyld/manage.py collectstatic

2. 清理监听函数

AcAPP关闭之前触发的事件可以通过如下api添加:

AcWingOS.api.window.on_close(func);

game/static/js/src/playground/zbase.js

create_uuid() {
    let res = "";
    for (let i = 0; i < 8; i++) {
        let x = parseInt(Math.floor(Math.random() * 10)); // 返回[0, 1)之间的数
        res += x;
    }
    return res;
}

start() {
    let outer = this;
    let uuid = this.create_uuid();
    $(window).resize(`resize.${uuid}`, function () {
        outer.resize();
    });

    //   关闭窗口,关闭上面对应的
    if (this.root.AcWingOS) {
        this.root.AcWingOS.api.window.on_close(function () {
            $(window).off(`resize.${uuid}`);
        });
    }

}

注意:

  • 同一个页面中,多个acapp引入的js代码只会加载一次,因此AC_GAME_OBJECTS等全局变量是同一个页面、同一个acapp的所有窗口共用的。
  • 各自创建的局部变量是独立的,比如new AcGame()创建出的对象各个窗口是独立的。

3. 编写每局游戏的结束界面

game/static/js/src/playground/score_board/zbase.js

class ScoreBoard extends HyldObject {
    constructor(playground) {
        super();
        this.playground = playground;
        this.ctx = this.playground.game_map.ctx;

        this.state = null;  // win: 胜利,lose:失败

        this.win_img = new Image();
        this.win_img.src = "https://cdn.acwing.com/media/article/image/2021/12/17/1_8f58341a5e-win.png";

        this.lose_img = new Image();
        this.lose_img.src = "https://cdn.acwing.com/media/article/image/2021/12/17/1_9254b5f95e-lose.png";
    }

    start() {
    }

    add_listening_events() {
        let outer = this;
        let $canvas = this.playground.game_map.$canvas;

        $canvas.on('click', function() {
            outer.playground.hide();
            outer.playground.root.menu.show();
        });
    }

    win() {
        this.state = "win";

        let outer = this;
        setTimeout(function() {
            outer.add_listening_events();
        }, 1000);
    }

    lose() {
        this.state = "lose";

        let outer = this;
        setTimeout(function() {
            outer.add_listening_events();
        }, 1000);
    }

    late_update() {
        this.render();
    }

    render() {
        let len = this.playground.height / 2;
        if (this.state === "win") {
            this.ctx.drawImage(this.win_img, this.playground.width / 2 - len / 2, this.playground.height / 2 - len / 2, len, len);
        } else if (this.state === "lose") {
            this.ctx.drawImage(this.lose_img, this.playground.width / 2 - len / 2, this.playground.height / 2 - len / 2, len, len);
        }
    }
}

注意:

触发时机:一定要有this.playground.state ==="fighting",需要好好考虑条件

game/static/js/src/playground/palyer/zbase.js

update_win() {
    if(this.playground.state ==="fighting" && this.character === "me" && this.playground.players.length === 1){
        this.playground.state =  "over";
        this.playground.score_board.win();
    }
}



if (this.character === "me"){
    if(this.playground.state === "fighting") {
        this.playground.state = "over";
        this.playground.score_board.lose();
    }
}

playground需要删除诸多里面的元素

资源地址:

  1. 获胜图标
  2. 失败图标

4. 更新战绩

注意极端情况,考虑到两个小球互相发子弹,然后一前一后消失,导致房间失效。

   async def attack(self, data):
        # 可能回出现极端情况
        if not self.room_name:
            return
        players = cache.get(self.room_name)

        if not players:
            return

        for player in players:
            if player['uuid'] == data['attackee_uuid']:
                player['hp'] -= 25

        remain_cnt = 0
        for player in players:
            if player['hp'] > 0:
                remain_cnt += 1

        if remain_cnt > 1:
            if self.room_name:
                cache.set(self.room_name, players, 3600)
        else:
            def dp_update_player_score(username, score):
                player = Player.objects.get(user__username=username)
                player.score += score
                player.save()
            for player in players:
                if player['hp'] <= 0:
                    await database_sync_to_async(dp_update_player_score)(player['username'], -5)
                else:
                    await database_sync_to_async(dp_update_player_score)(player['username'], 10)

        await self.channel_layer.group_send(
            self.room_name,
            {
                'type': "group_send_event",
                'event': "attack",
                'attackee_uuid': data["attackee_uuid"],
                'uuid': data['uuid'],
                'x': data['x'],
                'y': data['y'],
                'angle': data['angle'],
                'damage': data['damage'],
                'ball_uuid': data['ball_uuid'],
            }
        )

    async def blink(self, data):
        await self.channel_layer.group_send(
            self.room_name,
            {
                'type': "group_send_event",
                'event': "blink",
                'uuid': data['uuid'],
                'tx': data['tx'],
                'ty': data['ty'],
            }
        )

5. 添加favicon.ico

game/templates/multiends/web.html

{% load static %}

<head>
    <link rel="stylesheet" href="https://cdn.acwing.com/static/jquery-ui-dist/jquery-ui.min.css">
    <script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script>
    <link rel="stylesheet" href="{% static 'css/game.css' %}">
     <link rel="icon" href="https://cdn.acwing.com/media/article/image/2021/12/17/1_be4c11ce5f-acapp.png">
</head>

<body style="margin: 0">
    <div id="hyld"></div>
    <script type="module">
        import {Hyld} from "{% static 'js/dist/game.js' %}";
        $(document).ready(function(){
            let hyld = new Hyld("hyld");
        });
    </script>
</body>

资源地址:

posted @ 2022-01-12 22:30  pxlsdz  阅读(3760)  评论(0编辑  收藏  举报