截止到上一章节,我们的项目一直是部署在云服务器上,包括编写代码以及调试运行也是在云服务器上,现在我们尝试将其放回 Windows 本地环境运行。
1. 将项目传到本地
这一步可以使用 Git 也可以使用 SCP,由于之前项目上传在 AcGit 上,只能在 AC Terminal 中拉取,因此使用 SCP 远程传输:
1 scp -r -P 20000 asanosaki@<公网IP>:djangoapp . # 在要存放项目的目录执行该指令
2. 虚拟环境配置
我们需要先配置一个和云服务上相同的虚拟环境,首先在 VS Code 中打开该项目并且打开终端,在项目根目录下创建虚拟环境:
虚拟环境创建成功之后,一般不会自动启用,所以需要启用它,进入 venv/Scripts
目录运行脚本 Activate.ps1
:
1 2 cd .\venv\Scripts\ .\Activate.ps1
此时在 VS Code 中可以看到命令行首部多了 (venv)
,说明已进入虚拟环境,然后在右下角选择虚拟环境中的解释器即可。
现在我们在虚拟环境中安装所需的环境:
3. 修改项目相关文件
首先修改一下我们的打包脚本 compress_game_js.sh
:
1 2 3 4 5 6 7 # ! /bin/bash JS_PATH=../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
然后打开 Git Bash,进入 scripts
文件夹即可运行脚本:
然后将 djangoapp/settings.py
中的 Redis 配置删除,即删除以下这段话:
1 2 3 4 5 6 7 8 9 10 CACHES = { 'default' : { 'BACKEND' : 'django_redis.cache.RedisCache' , 'LOCATION' : 'redis://127.0.0.1:6379/1' , "OPTIONS" : { "CLIENT_CLASS" : "django_redis.client.DefaultClient" , }, }, } USER_AGENTS_CACHE = 'default'
同样在该文件中需要将 localhost
添加到 ALLOWED_HOSTS
中:
1 ALLOWED_HOSTS = ["8.130.54.44" , "app4007.acapp.acwing.com.cn" , "localhost" ]
然后将 AcWing 一键授权登录的相关文件夹删除:game/views/settings/acwing
、game/urls/settings/acwing
,然后修改 urls/settings/index.py
中的路由:
1 2 3 4 5 6 7 8 9 10 11 12 from django.urls import pathfrom game.views.settings.getinfo import getinfofrom game.views.settings.login import myloginfrom game.views.settings.logout import mylogoutfrom game.views.settings.register import registerurlpatterns = [ path('getinfo/' , getinfo, name='settings_getinfo' ), path('login/' , mylogin, name='settings_login' ), path('logout/' , mylogout, name='settings_logout' ), path('register/' , register, name='settings_register' ), ]
修改 AcGame
类,去掉 AcWingOS API,且改为非模块化引入 JS 方式,即去掉 export
关键字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class AcGame { constructor (id ) { this .id = id; this .$ac_game = $('#' + id); this .settings = new Settings (this ); this .menu = new AcGameMenu (this ); this .playground = new AcGamePlayground (this ); this .start (); } start ( ) { } }
同时前端的 web.html
文件也需要修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {% load static %} <head > <link rel ="stylesheet" href ="{% static 'css/jquery-ui.min.css' %}" > <script src ="{% 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 >
最后修改 Settings
类,去掉 AcWing 一键登录功能,且修改 ajax
请求的地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 class Settings { constructor (root ) { this .root = root; this .platform = 'WEB' ; this .username = '' ; this .avatar = '' ; this .$settings = $(` <div class='ac_game_settings'> <div class='ac_game_settings_login'> <div class='ac_game_settings_title'> Login </div> <div class='ac_game_settings_username'> <div class='ac_game_settings_item'> <input type='text' placeholder='Username'> </div> </div> <div class='ac_game_settings_password'> <div class='ac_game_settings_item'> <input type='password' placeholder='Password'> </div> </div> <div class='ac_game_settings_submit'> <div class='ac_game_settings_item'> <button>Login</button> </div> </div> <div class='ac_game_settings_errormessage'> </div> <div class='ac_game_settings_option'> Register </div> </div> <div class='ac_game_settings_register'> <div class='ac_game_settings_title'> Register </div> <div class='ac_game_settings_username'> <div class='ac_game_settings_item'> <input type='text' placeholder='Username'> </div> </div> <div class='ac_game_settings_password ac_game_settings_password_first'> <div class='ac_game_settings_item'> <input type='password' placeholder='Password'> </div> </div> <div class='ac_game_settings_password ac_game_settings_password_second'> <div class='ac_game_settings_item'> <input type='password' placeholder='Confirm Password'> </div> </div> <div class='ac_game_settings_submit'> <div class='ac_game_settings_item'> <button>Register</button> </div> </div> <div class='ac_game_settings_errormessage'> </div> <div class='ac_game_settings_option'> Login </div> </div> </div> ` ); this .$login = this .$settings .find ('.ac_game_settings_login' ); this .$login_username = this .$login .find ('.ac_game_settings_username input' ); this .$login_password = this .$login .find ('.ac_game_settings_password input' ); this .$login_submit = this .$login .find ('.ac_game_settings_submit button' ); this .$login_errormessage = this .$login .find ('.ac_game_settings_errormessage' ); this .$login_register = this .$login .find ('.ac_game_settings_option' ); this .$login .hide (); this .$register = this .$settings .find ('.ac_game_settings_register' ); this .$register_username = this .$register .find ('.ac_game_settings_username input' ); this .$register_password = this .$register .find ('.ac_game_settings_password_first input' ); this .$register_confirm_password = this .$register .find ('.ac_game_settings_password_second input' ); this .$register_submit = this .$register .find ('.ac_game_settings_submit button' ); this .$register_errormessage = this .$register .find ('.ac_game_settings_errormessage' ); this .$register_login = this .$register .find ('.ac_game_settings_option' ) this .$register .hide (); this .root .$ac_game .append (this .$settings ); this .start (); } start ( ) { this .getinfo (); this .add_listening_events (); } add_listening_events ( ) { this .add_listening_events_login (); this .add_listening_events_register (); } add_listening_events_login ( ) { let outer = this ; this .$login_register .click (function ( ) { outer.register (); }); this .$login_submit .click (function ( ) { outer.login_on_remote (); }); } add_listening_events_register ( ) { let outer = this ; this .$register_login .click (function ( ) { outer.login (); }); this .$register_submit .click (function ( ) { outer.register_on_remote (); }); } login_on_remote ( ) { let outer = this ; let username = this .$login_username .val (); let password = this .$login_password .val (); this .$login_errormessage .empty (); $.ajax ({ url : 'http://localhost:8000/settings/login/' , type : 'GET' , data : { username : username, password : password, }, success : function (resp ) { console .log (resp); if (resp.result === 'success' ) { location.reload (); } else { outer.$login_errormessage .html (resp.result ); } } }); } register_on_remote ( ) { let outer = this ; let username = this .$register_username .val (); let password = this .$register_password .val (); let confirm_password = this .$register_confirm_password .val (); this .$register_errormessage .empty (); $.ajax ({ url : 'http://localhost:8000/settings/register/' , type : 'GET' , data : { username : username, password : password, confirm_password : confirm_password, }, success : function (resp ) { console .log (resp); if (resp.result === 'success' ) { location.reload (); } else { outer.$register_errormessage .html (resp.result ); } } }); } logout_on_remote ( ) { if (this .platform === 'ACAPP' ) return false ; $.ajax ({ url : 'http://localhost:8000/settings/logout/' , type : 'GET' , success : function (resp ) { console .log (resp); if (resp.result === 'success' ) { location.reload (); } } }); } register ( ) { this .$login .hide (); this .$register .show (); } login ( ) { this .$register .hide (); this .$login .show (); } getinfo ( ) { let outer = this ; $.ajax ({ url : 'http://localhost:8000/settings/getinfo/' , type : 'GET' , data : { platform : outer.platform , }, success : function (resp ) { console .log (resp); if (resp.result === 'success' ) { outer.username = resp.username ; outer.avatar = resp.avatar ; outer.hide (); outer.root .menu .show (); } else { outer.login (); } } }); } hide ( ) { this .$settings .hide (); } show ( ) { this .$settings .show (); } }
顺带还需要修改一下 game.css
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 .ac_game_menu { width : 100% ; height : 100% ; background-image : url ('/static/image/menu/background2.jpeg' ); background-size : 100% 100% ; user-select: none; } .ac_game_menu_btgroup { width : 20vw ; position : relative; top : 30% ; left : 20% ; } .ac_game_menu_btgroup_bt { height : 7vh ; width : 15vw ; color : white; font-size : 3vh ; line-height : 7vh ; font-style : italic; 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 ; } .ac_game_playground { height : 100% ; width : 100% ; user-select: none; } .ac_game_settings { width : 100% ; height : 100% ; background-image : url ('/static/image/menu/background2.jpeg' ); background-size : 100% 100% ; user-select: none; } .ac_game_settings_login { height : 32vh ; width : 20vw ; position : relative; top : 50% ; left : 50% ; transform : translate (-50% , -50% ); background-color : rgba (0 , 0 , 0 , 0.7 ); border-radius : 5px ; } .ac_game_settings_register { height : 39vh ; width : 20vw ; position : relative; top : 50% ; left : 50% ; transform : translate (-50% , -50% ); background-color : rgba (0 , 0 , 0 , 0.7 ); border-radius : 5px ; } .ac_game_settings_title { color : white; font-size : 3.5vh ; text-align : center; height : 7vh ; line-height : 7vh ; } .ac_game_settings_username { display : block; height : 7vh ; } .ac_game_settings_password { display : block; height : 7vh ; } .ac_game_settings_submit { display : block; height : 7vh ; } .ac_game_settings_errormessage { color : red; font-size : 1.5vh ; display : inline; float : left; padding-left : 1vw ; } .ac_game_settings_option { color : white; font-size : 1.5vh ; display : inline; float : right; padding-right : 1vw ; cursor : pointer; } .ac_game_settings_item { width : 100% ; height : 100% ; } .ac_game_settings_item > input { width : 90% ; line-height : 3vh ; position : relative; top : 50% ; left : 50% ; transform : translate (-50% , -50% ); } .ac_game_settings_item > button { color : black; width : 30% ; line-height : 3vh ; font-size : 2vh ; position : relative; top : 50% ; left : 50% ; transform : translate (-50% , -50% ); background-color : rgb (199 , 237 , 204 ); border-radius : 7px ; cursor : pointer; }
到此已经可以在本地运行该项目了,我们也可以根据 Django 学习笔记-实现联机对战(上) 和 Django 学习笔记-实现联机对战(下) 统一长度单位以及添加闪现技能与技能冷却,因为这些部分与云端内容无关。
最后我们将 .git
文件夹删除,重新上传至 Github(先创建一个仓库 Small_Ball_Fight
):
1 2 3 4 5 git init git remote add origin git@github.com:AsanoSaki/Small_Ball_Fight.git git add . git commit -m "create small ball fight" git push --set-upstream origin master
上一章:Django学习笔记-Web端授权AcWing一键登录 。
下一章:Django学习笔记-AcApp端授权AcWing一键登录 。