2. 创建菜单界面

2022-11-14 17:56:33 浏览数 (1)

2.1 项目设计


2.1.1 项目系统设计

  • menu:菜单页面
  • playground:游戏界面
  • settings:设置界面

对于复杂的界面设计,我们在每个界面下递归细分功能模块,直到实现最基本的功能模块。模块化设计便于项目创建、更新和维护。

代码语言:javascript复制
project/  #项目系统设计
|-- menu  #菜单界面
|-- playground  #游戏界面
|   |-- maps  #地图
|   |-- players  #人物
|   |   |-- atcions  #人物动作
|   |   |-- movements  #人物移动
|   |   `-- talents  #人物属性
|   `-- time  #时间
`-- settings  #设置界面

2.1.2 项目文件结构


对于一个 Django 项目,有如下框架:

代码语言:javascript复制
django_project/  
|-- django_project  #整个Django项目的配置
|   |-- __init__.py  #初始化文件
|   |-- __pycache__
|   |   |-- __init__.cpython-38.pyc
|   |   `-- settings.cpython-38.pyc
|   |-- asgi.py  #异步通信服务启动文件
|   |-- settings.py  #项目的全局配置文件
|   |-- urls.py  #项目的全局路由设置
|   `-- wsgi.py  #web网关服务启动文件
|-- manage.py  #命令行工具
`-- project  #子应用
    |-- __init__.py
    |-- admin.py
    |-- apps.py
    |-- consumers  #管理 websocket 函数
    |-- migrations
    |   `-- __init__.py
    |-- models  #管理数据库数据
    |-- static  #管理静态文件
    |   |-- audio  #声音
    |   |-- css  #对象格式
    |   |-- image  #图片
    |   `-- js  #对象逻辑(脚本)
    |-- templates  #管理html
    |-- tests.py
    |-- urls  #管理路由
    `-- views  #管理http函数

我们在 python 中调用 import urls.xxx 时,需要索引文件 __init__.py。为了便于维护 urls.pyviews.pymodels.py,我们将其转为文件夹的方式存储,并在这三个文件夹目录下都添加 __init__.py 文件。

对于 templatesurlsviews 等的文件夹,最好都建立文件夹menuplaygroundsettings 文件夹,用于细分模块设计。

对于 css 一般不需要细分。

对于 js 需要分为 distsrc 两个文件,dist 是最终打包好的 .js 文件,src 用于存储开发时的各种模块化的 .js 文件供。

我们可以在 acappp/ 下创建一个文件夹 scripts,用来存储各种脚本,将 src 打包为 dist,创建打包 src 的脚本 compress_game_js.sh 如下

代码语言:javascript复制
#!/bin/bash

JS_PATH=~/workspace/ac_app/ACApp/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 > ${JS_PATH_DIST}game.js

记得加上可执行权限:

代码语言:javascript复制
chmod  x compress_game_js.sh

2.1.3 项目全局配置


添加子应用

打开/game/apps.py,找到 class GameConfig,然后在全局的 settings.py里找到INSTALLED_APPS,在里面加入 :

代码语言:javascript复制
'game.apps.GameConfig',

以便将创建的 game 加入进去。

静态文件地址设置

打开 settings.py,找到 STATIC_URL = '/static/' ,在该条目上方加入:

代码语言:javascript复制
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

此外按照上述方式再加入:

代码语言:javascript复制
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'     
  • 一般来说,static存开发的文件,media存用户的文件。

同时要记得import osos.path()是将路径合并在一起。通过该操作可以使我们的静态文件会放到这个目录下。

代码语言:javascript复制
import os
from pathlib import Path  

2. 2 菜单界面结构创建


2.2.1 html 文件结构


首先进入 /game/templates/,创建三个文件夹 menuplaygroundsettings 文件夹,便于模块化设计。为了支持多种终端上运行,再创建一个文件夹 multiends 存储 html 文件。

先实现网页端,创建 web.html

代码语言:javascript复制
{% load static %}  <!--查找并载入静态文件static的文件夹-->

<head>
    <!--<head></head>存放所有的html资源文件-->
    <!--引入jQuery的css-->
    <link rel="stylesheet" href="https://cdn.acwing.com/static/jquery-ui-dist/jquery-ui.min.css">
    <!--引入jQuery的js-->  
    <script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script>  
    <!--引入自己写的game.css-->
    <link rel="stylesheet" href="{% static 'css/game.css' %}">
    <!--引入自己写的game.js-->
    <script src="{% static 'js/dist/game.js' %}"></script>
</head>

<body style="margin: 0">
    <!--<body></body>以后的网站内容都放在这里面-->
    <!--创建游戏框架-->
    <div id="ac_game_12345678"></div>
    <!--引入js代码,以后前端渲染的部分都在js里面-->
    <script>
        $(document).ready(function(){
            let ac_game = new AcGame("ac_game_12345678");
        });
    </script>
</body>

js 在客户端渲染,而 viewsurls 在后端处理,由此实现前后端分离,能够减轻服务器的压力,并能适应多终端的开发需求。


2.2.2 js 对象文件结构


html 文件的 <body>内的 <script> 将页面渲染交给客户,调用 let ac_game = AcGame(); 创建一个 js 对象,接下来实现这个创建 js 对象的文件。

进入 /game/static/js/,同样创建三个文件夹 menuplaygroundsettings,再创建一个总文件 zbase.js。由于打包时按照文件名字典序排列的,可以保证在打包的时 zbase.js 在最后打包。

代码语言:javascript复制
class AcGame {
    constructor(id) {
    }    
}

web.html 中的 let ac_game = AcGame() 括号里面添加 id,即 AcGame("ac_game_12345678"),表示渲染<div id="ac_game_12345678">


2.2.3 views 文件结构


进入 /game/views,同样创建三个文件夹 menuplaygroundsettings,在这三个文件夹里存放需要被调用的 .py 文件,故都要添加索引 __init__.py

/game/views/ 里面写总的 index.py

代码语言:javascript复制
from django.shortcuts import render # 从django.shortcuts引入render

def index(request):
    return render(request, "multiends/web.html") # 返回响应,渲染"/game/templates/multiends/web.html"

这个 index.py 只会在 htmlWeb 中被调用,未来其他东西都不会调用他它,主要用来访问刚刚写的 html

其中 from django.shortcuts import renderDjango 的渲染工具,render 用来渲染 html 文件,通过 Python 来把 html 的内容写到网页上去。此处的路径是从 /game/templates/ 开始的。


2.2.4 urls 文件结构


进入 /game/urls,同样创建三个文件夹 menuplaygroundsettings,在这三个文件夹里存放需要被调用的 .py 文件,故都要添加索引 __init__.py

每个文件夹下添加对应的路由 index.py,格式如下:

代码语言:javascript复制
from django.urls import path

urlpatterns = [
----
]

最后在 /game/urls/ 里面写总的 index.py

代码语言:javascript复制
from django.urls import path, include # 引入路径管理
from game.views.index import index # 引入自己写的python

urlpatterns = [
    path('', index, name='index'), # 到"/"的路由
    path('menu/', include('game.urls.menu.index')), # 到"menu/"的路由
    path('playground/', include('game.urls.playground.index')), # 到"playground/"的路由
    path('settings/', include('game.urls.settings.index')), # 到"settings/"的路由
]

2.3 菜单界面文件创建


2.3.1 创建 js 对象文件


进入 game/static/js/src/zbase.js,增添内容为:

代码语言:javascript复制
class AcGame {
    constructor(id) {
        this.id = id;  //将id存下来
        this.$ac_game = $(`#`   id);  // 查找#id的html对象
        this.menu = new AcGameMenu(this);  //创建AcGame的AcGameMenu界面对象
        this.playground = new AcGamePlayground(this);  //创建AcGame的AcGameMenu界面对象
    }
}    

以上实现的是整个 js 对象文件的定义部分,接下来在各个模块里实现相应的 js 对象文件。

进入 game/static/js/src/menu,创建 zbase.js

代码语言:javascript复制
class AcGameMenu {
    constructor(root) {
        this.root = root;  //将信息存下来
        this.$menu = $(`
<div class="ac_game_menu">
    <div class="ac_game_menu_field">
        <div class="ac_game_menu_field_item ac_game_menu_field_item_single_mod">
            单人模式
        </div>
        <br>
        <div class="ac_game_menu_field_item ac_game_menu_field_item_multi_mod">
            多人模式
        </div>
        <br>
        <div class="ac_game_menu_field_item ac_game_menu_field_item_settings">
            设置
        </div>
    </div>
</div>
`);  //创建一个html对象menu
        this.root.$ac_game.append(this.$menu);  //将html对象加入到这个游戏里面
        this.$single_mod = this.$menu.find('.ac_game_menu_field_item_single_mod');  //找到class对应的对象
        this.$multi_mod = this.$menu.find('.ac_game_menu_field_item_multi_mod');
        this.$settings = this.$menu.find('.ac_game_menu_field_item_settings');

        this.start();

    }
    start() {
        this.add_listening_events();
    }

    add_listening_events() {  //监听函数,监听按钮是否被click过
        let outer = this;
        this.$single_mod.click(function(){  //切换页面的逻辑
            outer.hide();  //关闭当前界面
            outer.root.playground.show();  //打开playground页面
        });
        this.$multi_mod.click(function(){
            console.log("click mulit_mod");
        });
        this.$settings.click(function(){
            console.log("click settings");
        });
    }

    //api接口函数
    show() {  //打开界面
        this.$menu.show();
    }

    hide() {  //关闭界面
        this.$menu.hide();
    }

}
  • jquery 库提供了 api 接口 append(this.menu),目的是将 this.menu加入到
  • <div class="ac_game_menu">$menu 内定义一个 ac_game_menu,该样式从 /game/static/css/game.css 中调用,其他同理。

同理进入 /game/static/js/src/playground,创建 zbase.js

代码语言:javascript复制
class AcGamePlayground {
    constructor(root) {
        this.root = root;
        this.$playground = $(`<div>游戏界面</div>`);

        this.hide();  //默认先关闭
        this.root.$ac_game.append(this.$playground);

        this.start();
    }

    start() {
    }

    show() { // 打开playground界面
        this.$playground.show();
    }

    hide() { // 关闭playground界面
        this.$playground.hide();
    }

}

本节重点在于菜单界面的创建,至此简单实现了菜单界面跳转到游戏界面的按钮功能,后续添加实现其他功能。


2.3.2 创建 css 文件


js 对象文件创建完毕后,前端调用会在用户端进行渲染,其 html 样式仍需要从 /game/css 里调用。

首先下载一些静态资源,如背景图片等:

代码语言:javascript复制
wget --output-document=自定义图片名称 图片地址

进入 /game/static/css/,打开 game.css

代码语言:javascript复制
/*主菜单界面创建时的css样式*/
.ac_game_menu {
    width: 100%;
    height: 100%;
    background-image: url("/static/image/menu/background.png"); /*背景图片地址*/
    background-size: 100% 100%;
    user-select: none;
}

/*主菜单的css样式*/
.ac_game_menu_field {
    width = 20vw;
    position: relative;
    top: 40vh;
    left: 19vw;
}

/*主菜单条目的css样式*/
.ac_game_menu_field_item {
    color: white;
    width: 18vw;
    height: 7vh;
    font-size: 6vh;
    font-style: italic;
    padding: 2vh;
    text-align: center;
    background-color: rgba(39, 21, 28, 0.6);
    border-radius: 20px;
    letter-spacing: 0.5vw;
    cursor: pointer;
}

/*hover 控制鼠标悬浮效果*/
.ac_game_menu_field_item:hover {
    transform: scale(1.15);
    transition: 130ms;
}

2.3.3 打包文件


实现完菜单界面的对应文件后,我们利用之前设计的打包脚本,将这些文件打包到 /game/static/js/dist

回到 scripts 文件夹,运行打包脚本:

代码语言:javascript复制
./compress_game_js.sh

最后启动服务查看菜单界面:

代码语言:javascript复制
python3 manage.py runserver 0.0.0.0:8000

0 人点赞