diff --git a/goldminer/.gitignore b/goldminer/.gitignore new file mode 100644 index 00000000..9372b48b --- /dev/null +++ b/goldminer/.gitignore @@ -0,0 +1,41 @@ +# 环境变量 +.env + +# Docker相关 +.docker +docker-volume/ + +# Node.js +node_modules/ +npm-debug.log + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# 操作系统 +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/goldminer/README.md b/goldminer/README.md index d31926ef..278c76e7 100644 --- a/goldminer/README.md +++ b/goldminer/README.md @@ -1,26 +1,102 @@ # 黄金矿工游戏 -一个使用Flask后端和Vue前端实现的简单黄金矿工游戏。 +一个基于Vue和Flask的在线黄金矿工游戏,支持实时排行榜和玩家互动功能。 ## 项目结构 +- `frontend/`: Vue.js前端代码 +- `backend/`: Flask后端代码 +- `docker-compose.yml`: Docker编排配置文件 + +## 本地开发 + +### 前端开发 + +```bash +cd frontend +npm install +npm run serve ``` -goldminer/ -├── backend/ # Flask后端 -│ ├── app.py # 主应用程序 -│ └── requirements.txt -├── frontend/ # Vue前端 -│ ├── public/ -│ ├── src/ -│ │ ├── components/ -│ │ │ └── Game.vue # 游戏组件 -│ │ ├── App.vue # 主应用组件 -│ │ └── main.js # 入口文件 -│ ├── package.json -│ └── vue.config.js -└── start.bat # 一键启动批处理文件 + +前端服务将运行在 http://localhost:8080 + +### 后端开发 + +```bash +cd backend +pip install -r requirements.txt +python run_server.py ``` +后端服务将运行在 http://localhost:5000 + +## Docker部署 + +项目已配置Docker支持,可以使用Docker Compose进行一键部署。 + +### 前置条件 + +- 安装 [Docker](https://www.docker.com/get-started) +- 安装 [Docker Compose](https://docs.docker.com/compose/install/) + +### 运行步骤 + +1. 在项目根目录创建`.env`文件,配置环境变量(可选,已提供默认值): + +``` +# 数据库配置 +DB_HOST=mysql2.sqlpub.com +DB_PORT=3307 +DB_USER=goldminer +DB_PASSWORD=nBAWq9DDwJ14Fugq +DB_NAME=goldminer + +# 应用配置 +SECRET_KEY=dev_key_for_goldminer +``` + +2. 使用Docker Compose构建和启动服务: + +```bash +docker-compose up -d +``` + +3. 访问应用: + - 前端: http://localhost:8080 + +### 查看日志 + +```bash +# 查看所有服务日志 +docker-compose logs + +# 查看特定服务日志 +docker-compose logs backend +docker-compose logs frontend +``` + +### 停止服务 + +```bash +docker-compose down +``` + +## 游戏功能 + +- 登录和注册用户 +- 经典的黄金矿工游戏玩法 +- 实时排行榜 +- 在线玩家状态显示 +- 游戏历史记录 +- 聊天室功能 + +## 技术栈 + +- 前端: Vue 3, Socket.io-client +- 后端: Flask, Flask-SocketIO +- 数据库: MySQL +- 容器化: Docker, Docker Compose + ## 系统架构 下图展示了黄金矿工游戏的系统架构: @@ -37,6 +113,20 @@ goldminer/ - 数据库名称:goldminer - 连接地址:mysql2.sqlpub.com:3307 +## 游戏说明 + +- 使用鼠标点击或空格键发射绳索 +- 松开鼠标或空格键收回绳索 +- 按P键暂停游戏 +- 收集金块和钻石以获得分数 +- 达到目标分数进入下一关 +- 寻找特殊道具提升能力 + +## 特殊道具 + +- 速度提升:增加绳索伸缩速度 +- 磁力钩:增加抓取范围 + ## 安装和运行 ### 快速启动(推荐) diff --git a/goldminer/backend/.dockerignore b/goldminer/backend/.dockerignore new file mode 100644 index 00000000..53ba9ab8 --- /dev/null +++ b/goldminer/backend/.dockerignore @@ -0,0 +1,12 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +env/ +venv/ +.env +.git +.gitignore +.DS_Store +*.log \ No newline at end of file diff --git a/goldminer/backend/Dockerfile b/goldminer/backend/Dockerfile new file mode 100644 index 00000000..d293a127 --- /dev/null +++ b/goldminer/backend/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.9-slim + +WORKDIR /app + +# 复制依赖文件 +COPY requirements.txt . + +# 安装依赖 +RUN pip install --no-cache-dir -r requirements.txt + +# 复制所有后端源码 +COPY . . + +# 设置环境变量 +ENV PYTHONUNBUFFERED=1 +ENV FLASK_APP=app.py + +# 暴露端口 +EXPOSE 5000 + +# 启动命令 +CMD ["python", "run_server.py"] \ No newline at end of file diff --git a/goldminer/backend/run_server.py b/goldminer/backend/run_server.py index 90afc7c4..d7954bed 100644 --- a/goldminer/backend/run_server.py +++ b/goldminer/backend/run_server.py @@ -6,4 +6,4 @@ if __name__ == '__main__': init_db() print("启动后端服务器...") print("监听所有网络接口 (0.0.0.0:5000)") - socketio.run(app, debug=True, host='0.0.0.0', port=5000) \ No newline at end of file + socketio.run(app, debug=True, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True) \ No newline at end of file diff --git a/goldminer/docker-compose.yml b/goldminer/docker-compose.yml new file mode 100644 index 00000000..995f8228 --- /dev/null +++ b/goldminer/docker-compose.yml @@ -0,0 +1,34 @@ +services: + # 后端服务 + backend: + build: ./backend + container_name: goldminer-backend + restart: always + environment: + - DB_HOST=${DB_HOST:-mysql2.sqlpub.com} + - DB_PORT=${DB_PORT:-3307} + - DB_USER=${DB_USER:-goldminer} + - DB_PASSWORD=${DB_PASSWORD:-nBAWq9DDwJ14Fugq} + - DB_NAME=${DB_NAME:-goldminer} + - SECRET_KEY=${SECRET_KEY:-dev_key_for_goldminer} + networks: + - app-network + + # 前端服务 + frontend: + build: + context: ./frontend + args: + - NODE_ENV=production + container_name: goldminer-frontend + restart: always + depends_on: + - backend + ports: + - "8080:80" + networks: + - app-network + +networks: + app-network: + driver: bridge \ No newline at end of file diff --git a/goldminer/frontend/.dockerignore b/goldminer/frontend/.dockerignore new file mode 100644 index 00000000..883676aa --- /dev/null +++ b/goldminer/frontend/.dockerignore @@ -0,0 +1,11 @@ +node_modules +.git +.gitignore +dist +npm-debug.log +.DS_Store +.env +.env.local +.env.development.local +.env.test.local +.env.production.local \ No newline at end of file diff --git a/goldminer/frontend/Dockerfile b/goldminer/frontend/Dockerfile new file mode 100644 index 00000000..d7fb4076 --- /dev/null +++ b/goldminer/frontend/Dockerfile @@ -0,0 +1,37 @@ +FROM node:18-alpine AS build-stage + +WORKDIR /app + +# 显示npm版本和node版本 +RUN node -v && npm -v + +# 复制依赖文件 +COPY package*.json ./ + +# 安装Vue CLI和项目依赖 +RUN npm install -g @vue/cli && npm install + +# 复制所有前端源码 +COPY . . + +# 构建生产环境代码 +RUN echo "Building with vue-cli-service..." && \ + npx vue-cli-service build || \ + ./node_modules/.bin/vue-cli-service build || \ + vue-cli-service build + +# 确保dist目录存在 +RUN ls -la dist || exit 1 + +# 第二阶段:使用nginx提供静态文件 +FROM nginx:stable-alpine AS production-stage + +# 从构建阶段复制构建结果到nginx默认目录 +COPY --from=build-stage /app/dist /usr/share/nginx/html + +# 复制自定义nginx配置 +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/goldminer/frontend/nginx.conf b/goldminer/frontend/nginx.conf new file mode 100644 index 00000000..ed6367f2 --- /dev/null +++ b/goldminer/frontend/nginx.conf @@ -0,0 +1,40 @@ +server { + listen 80; + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + # 静态资源请求直接访问 + location / { + try_files $uri $uri/ /index.html; + } + + # API请求代理到后端服务 + location /api/ { + proxy_pass http://backend:5000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Socket.IO请求代理到后端服务 + location /socket.io/ { + proxy_pass http://backend:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_cache_bypass $http_upgrade; + } + + # 错误页面 + error_page 404 /index.html; + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} \ No newline at end of file diff --git a/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json b/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json index c9150af3..97ce52dd 100644 --- a/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json +++ b/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json @@ -1 +1 @@ -[{"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"1","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"2","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"3","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"4","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"5","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"6","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"7","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"8","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"9","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"10","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"11"},{"size":420,"mtime":1750247900833,"results":"12","hashOfConfig":"13"},{"size":1555,"mtime":1750247900833,"results":"14","hashOfConfig":"13"},{"size":1004,"mtime":1750247900829,"results":"15","hashOfConfig":"13"},{"size":4492,"mtime":1750247900833,"results":"16","hashOfConfig":"13"},{"size":3472,"mtime":1750260439376,"results":"17","hashOfConfig":"13"},{"size":11652,"mtime":1750247900833,"results":"18","hashOfConfig":"13"},{"size":16278,"mtime":1750247900831,"results":"19","hashOfConfig":"13"},{"size":30598,"mtime":1750260439905,"results":"20","hashOfConfig":"13"},{"size":5735,"mtime":1750247900831,"results":"21","hashOfConfig":"13"},{"size":13225,"mtime":1750247900832,"results":"22","hashOfConfig":"13"},{"size":4152,"mtime":1750247900831,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"1bydp2x",{"filePath":"27","messages":"28","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"29","messages":"30","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"32","messages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"34","messages":"35","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"38","messages":"39","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"40","messages":"41","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"44","messages":"45","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"46","messages":"47","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[]] \ No newline at end of file +[{"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"1","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"2","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"3","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"4","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"5","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"6","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"7","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"8","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"9","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"10","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"11"},{"size":420,"mtime":1750247900833,"results":"12","hashOfConfig":"13"},{"size":1555,"mtime":1750247900833,"results":"14","hashOfConfig":"13"},{"size":1004,"mtime":1750247900829,"results":"15","hashOfConfig":"13"},{"size":4492,"mtime":1750247900833,"results":"16","hashOfConfig":"13"},{"size":3472,"mtime":1750260439376,"results":"17","hashOfConfig":"13"},{"size":11652,"mtime":1750247900833,"results":"18","hashOfConfig":"13"},{"size":16278,"mtime":1750247900831,"results":"19","hashOfConfig":"13"},{"size":30598,"mtime":1750262074470,"results":"20","hashOfConfig":"13"},{"size":5735,"mtime":1750247900831,"results":"21","hashOfConfig":"13"},{"size":13225,"mtime":1750247900832,"results":"22","hashOfConfig":"13"},{"size":4152,"mtime":1750247900831,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"1bydp2x",{"filePath":"27","messages":"28","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"29","messages":"30","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"32","messages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"34","messages":"35","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"38","messages":"39","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"40","messages":"41","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"44","messages":"45","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"46","messages":"47","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[]] \ No newline at end of file