笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。
1. 项目总体设计
(1)系统设计
-
menu
:菜单页面; -
playground
:游戏界面; -
settings
:设置界面。
(2)文件结构
-
templates
:管理 HTML 文件; -
urls
:管理路由,即链接与函数的对应关系; -
views
:管理 HTTP 函数; -
models
:管理数据库数据; -
static
:管理静态文件,比如:-
css
:对象的格式,比如位置、长宽、颜色、背景、字体大小等; -
js
:对象的逻辑,比如对象的创建与销毁、事件函数、移动、变色等; -
image
:图片; -
audio
:声音; - ……
-
-
consumers
:管理 WebSocket 函数。
(3)素材地址
- 背景图片:
- 下载方式:
wget --output-document=自定义图片名称 图片地址
; - 本地上传:
scp -P 20000 .\xxx.jpeg asanosaki@<公网IP>:
。
- 下载方式:
-
jQuery
库:-
<link rel="stylesheet" href="http://<公网IP>:8000/static/css/jquery-ui.min.css">
; -
<script src="http://<公网IP>:8000/static/js/jquery-3.6.1.min.js"></script>
。
-
2. 全局设置与项目结构创建
为了后期方便项目的维护管理,首先先将 game
中的 urls.py
、models.py
、views.py
删除,将其创建为一个目录,并在这三个目录下创建好 __init__.py
文件,注释掉上一节中在总 URL 文件中的配置信息,然后创建好 static
目录。
接着进行一些项目的全局设置,首先设置一下项目的时区,打开 ~/djangoapp/djangoapp/settings.py
,修改 TIME_ZONE
和 USE_TZ
:
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
如果 USE_TZ
设置为 True
时,Django 会使用系统默认设置的时区,即 America/Chicago
,此时的 TIME_ZONE
不管有没有设置都不起作用。
注意:由于我们是在云服务器上开发的,如果是 Windows 则设置 TIME_ZONE
是无效的,Django 会使用本机的时间。
然后将自己创建的 App 加载进来,找到 INSTALLED_APPS
,将 game/apps.py
添加进来:
INSTALLED_APPS = [
'game.apps.GameConfig', # 添加此行
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
找到 STATIC_URL = 'static/'
,在其附近添加几行:
import os # 在文件首部导入包
STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 表示要将静态文件放到static目录下
STATIC_URL = 'static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = 'media/'
我们在 game/static/
中创建 image/menu/
目录用来存放菜单界面的背景,将图片 background.png
放入该目录中即可在自己的网址上访问这张图片:http://<公网IP>:8000/static/image/menu/background.png
。
一般 CSS 文件只需要一个就行,因此只需要在 game/static/css/
中创建一个 game.css
文件即可。JS 文件最后一般会有很多,因此在 game/static/js/
中创建两个目录:dist
和 src
,分别表示最终合并在一起生成的 js
文件以及许多 js
源文件,我们可以写一个脚本完成合并操作,在 ~/djangoapp/
目录下创建一个 scripts
目录,然后在该目录中编写一个 compress_game_js.sh
文件:
#! /bin/bash
JS_PATH=/home/asanosaki/djangoapp/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
添加可执行权限:
chmod +x compress_game_js.sh
我们执行一下该脚本:./compress_game_js.sh
,可以看到 ~/djangoapp/game/static/js/dist/
中多了一个 game.js
文件。
此时我们先将代码上传至 Git:
cd ~/djangoapp/
git add .
git commit -m 'create project structure'
git push
3. 创建HTML
我们先在 templates
目录下创建三个目录:menu
、playground
、settings
。由于项目是前后端分离的,最后可以放在多种不同的终端上运行,因此我们再建一个 multiends
目录。
在 static/src
目录下也创建三个目录:menu
、playground
、settings
,然后再创建一个文件 zbase.js
,表示总文件,由于打包工具是按照字典序打包的,该文件中为总的 Class,会调用前面三个目录中的 Class,JS 在调用之前必须定义好,因此在打包时需要保证前面三个目录中的文件在 zbase.js
之前被打包,因此加一个字典序最大的字母在首部。
在 zbase.js
中定义好总类:
class AcGame {
constructor(id) {
}
}
在 templates/multiends/
中创建 web.html
,文件内容如下:
{% load static %}
<head>
<link rel="stylesheet" href="http://<公网IP>:8000/static/css/jquery-ui.min.css">
<script src="http://<公网IP>:8000/static/js/jquery-3.6.1.min.js"></script>
<link rel="stylesheet" href="{% static 'css/game.css' %}">
<script src="{% static 'js/dist/game.js' %}"></script>
</head>
<body style="margin: 0">
<div id="ac_game_1"></div>
<script>
$(document).ready(function() {
let ac_game = new AcGame("ac_game_1");
});
</script>
</body>
4. 创建Views与更新URL
我们先在 views
目录下创建三个目录:menu
、playground
、settings
,这三个目录都是存放 Python 文件的,因此每个目录下都需要一个 __init__.py
文件。
然后再在 views
目录下创建一个 index.py
作为总函数,该函数只会在 Web 端被调用,主要作用是用来返回上一节中的 HTML 文件的:
from django.shortcuts import render
def index(request):
return render(request, 'multiends/web.html') # 从templates目录之后开始写路径,因为Django默认会从templates开始找HTML
现在我们开始写路由,先在 urls
目录下创建三个目录:menu
、playground
、settings
,在每个目录下都创建一个 __init__.py
文件。接着同样创建一个 index.py
,用来将所有该路径下其它目录中的路径 Include 进来,可以参考总 URL 文件编写。
先在三个目录中也创建好 index.py
,内容如下:
from django.urls import path
urlpatterns = []
此前在 views
目录中实现的 index.py
为总函数,即整个项目只有一个主链接,因此 urls
目录中的 index.py
也要将其 Include 进来:
from django.urls import path, include
from game.views.index import index
urlpatterns = [
path('', index, name='index'),
path('menu/', include('game.urls.menu.index')),
path('playground/', include('game.urls.playground.index')),
path('settings/', include('game.urls.settings.index')),
]
最后修改一下总 URL 文件(~/djangoapp/djangoapp/
中的 urls.py
):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('game.urls.index')),
path('admin/', admin.site.urls),
]
此时梳理一下路由顺序:首先会进入到 ~/djangoapp/djangoapp/
中的 urls.py
中,然后发现浏览器链接中没有带后缀(例如 admin/
),所以会进到 game.urls.index
中,由于没有后缀因此又调用第一个路由,也就是直接调用 game.views.index
中的 index
函数,该函数会渲染 multiends/web.html
里面的内容。
Tips:浏览器中按 F12 打开控制台后如果看到报错:The Cross-Origin-Opener-Policy header has been ignored, because the URL's origin was untrustworthy. It was defined either in the final response or a redirect.
,表示出现了跨域问题,在 settings.py
中添加如下代码即可:
SECURE_CROSS_ORIGIN_OPENER_POLICY = 'None'
最后将代码上传至 Git:
git add .
git commit -m 'modify html & js & views & urls'
git push
5. 创建菜单
我们需要创建一个菜单对象,首先在 static/js/src/menu/
目录中创建一个 zbase.js
文件,内容如下:
class AcGameMenu {
constructor(root) { // root用来传AcGame对象
this.root = root;
// 如果是HTML对象通常会加一个'$'符号
this.$menu = $(`
<div class='ac_game_menu'>
</div>
`)
this.root.$ac_game.append(this.$menu); // 将this.$menu添加到主类的div中
}
}
然后在 game.css
中定义相应的样式:
.ac_game_menu {
width: 100%;
height: 100%;
background-image: url('/static/image/menu/background.png'); /* 注意不用带公网IP */
background-size: 100% 100%;
}
最后需要更新 static/js/src/
中的 zbase.js
文件:
class AcGame {
constructor(id) {
this.id = id;
this.$ac_game = $('#' + id); // jQuery通过id找对象的方式
this.menu = new AcGameMenu(this);
}
}
此时即可在页面中看到自己的背景图片(注意更新完 JS 文件后都需要执行一下打包脚本 compress_game_js.sh
)。
Tips:如果修改完 CSS 文件后网页没有变化说明页面把 CSS 文件缓存下来了,可以按 F12 打开控制台,在 Network 选项卡中勾选上 Disable cache
。
现在我们在菜单界面添加几个按钮,首先修改菜单目录中的 zbase.js
文件(修改完记得运行打包脚本):
class AcGameMenu {
constructor(root) { // root用来传AcGame对象
this.root = root;
// 如果是HTML对象通常会加一个'$'符号
this.$menu = $(`
<div class='ac_game_menu'>
<div class='ac_game_menu_btgroup'>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_single'>
单人模式
</div>
<br>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_multi'>
多人模式
</div>
<br>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_settings'>
设置
</div>
</div>
</div>
`);
this.root.$ac_game.append(this.$menu); // 将this.$menu添加到主类的div中
this.$single = this.$menu.find('.ac_game_menu_btgroup_bt_single'); // class名前面要加'.'
this.$multi = this.$menu.find('.ac_game_menu_btgroup_bt_multi');
this.$settings = this.$menu.find('.ac_game_menu_btgroup_bt_settings');
}
}
然后修改 game.css
设置一下按钮的样式:
.ac_game_menu {
width: 100%;
height: 100%;
background-image: url('/static/image/menu/background.png'); /* 注意不用带公网IP */
background-size: 100% 100%;
user-select: none;
}
.ac_game_menu_btgroup {
width: 20vw;
position: relative;
top: 35vh;
left: 19vw;
}
.ac_game_menu_btgroup_bt {
height: 7vh;
width: 18vw;
color: white;
font-size: 6vh;
line-height: 7vh;
font-style: italic;
padding: 2vh;
cursor: pointer;
text-align: center;
background-color: rgba(39, 21, 28, 0.6);
border-radius: 10px;
letter-spacing: 0.5vw;
}
.ac_game_menu_btgroup_bt:hover {
transform: scale(1.2);
transition: 100ms;
}
现在我们实现点击按钮切换页面的功能,需要给每个按钮绑定一个函数,我们可以定义一个 start
函数放在构造函数中,表示对象被创建出来时需要执行的一些初始化操作,即在 start
中可以绑定一些事件。
首先我们先把游戏界面的简易版本写出来,在 static/js/src/playground/
目录中创建一个 zbase.js
文件,内容如下:
class AcGamePlayground {
constructor(root) {
this.root = root;
this.$playground = $(`
<div>
游戏界面
</div>
`);
this.root.$ac_game.append(this.$playground);
this.start();
}
start() {
this.hide(); // 初始化时需要先关闭playground界面
}
// 显示playground界面
show() {
this.$playground.show();
}
// 关闭playground界面
hide() {
this.$playground.hide();
}
}
然后更新一下总的 zbase.js
文件:
class AcGame {
constructor(id) {
this.id = id;
this.$ac_game = $('#' + id); // jQuery通过id找对象的方式
this.menu = new AcGameMenu(this);
this.playground = new AcGamePlayground(this);
this.start();
}
start() {
}
}
最后在菜单界面中设置一下按钮点击的响应操作,点击单人模式按钮即可跳转到 AcGamePlayground
界面:文章来源:https://www.toymoban.com/news/detail-489272.html
class AcGameMenu {
constructor(root) { // root用来传AcGame对象
this.root = root;
// 如果是HTML对象通常会加一个'$'符号
this.$menu = $(`
<div class='ac_game_menu'>
<div class='ac_game_menu_btgroup'>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_single'>
单人模式
</div>
<br>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_multi'>
多人模式
</div>
<br>
<div class='ac_game_menu_btgroup_bt ac_game_menu_btgroup_bt_settings'>
设置
</div>
</div>
</div>
`);
this.root.$ac_game.append(this.$menu); // 将this.$menu添加到主类的div中
this.$single = this.$menu.find('.ac_game_menu_btgroup_bt_single'); // class名前面要加'.'
this.$multi = this.$menu.find('.ac_game_menu_btgroup_bt_multi');
this.$settings = this.$menu.find('.ac_game_menu_btgroup_bt_settings');
this.start();
}
start() {
this.add_listening_events();
}
// 给按钮绑定监听函数
add_listening_events() {
let outer = this;
// 注意在function中调用this指的是function本身,因此需要先将外面的this存起来
this.$single.click(function() {
outer.hide(); // 关闭menu界面
outer.root.playground.show(); // 显示playground界面
});
this.$multi.click(function() {
});
this.$settings.click(function() {
});
}
// 显示menu界面
show() {
this.$menu.show();
}
// 关闭menu界面
hide() {
this.$menu.hide();
}
}
最后将代码上传至 Git:文章来源地址https://www.toymoban.com/news/detail-489272.html
git add .
git commit -m 'modify html & css & menu & playground'
git push
到了这里,关于Django学习笔记-创建菜单界面的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!