浏览代码

日常开发

林旭祥 1 月之前
父节点
当前提交
797c06a048
共有 6 个文件被更改,包括 62 次插入35 次删除
  1. 1 0
      .env.development
  2. 1 0
      .env.production
  3. 54 32
      src/views/game/basketball.vue
  4. 4 1
      src/views/game/index.vue
  5. 1 1
      src/views/home/index.vue
  6. 1 1
      src/views/sunshineRun/index.vue

+ 1 - 0
.env.development

@@ -1,4 +1,5 @@
 # 开发环境
+APP_ENV = dev
 VITE_APP_BASE_API = 'https://api-aiexamtst.tropsx.com'
 VITE_APP_PORT = 80
 # 是否在打包时开启压缩,支持 gzip 和 brotli

+ 1 - 0
.env.production

@@ -1,4 +1,5 @@
 # 生产环境
+APP_ENV = pro
 VITE_APP_BASE_API = 'https://api-edu.tropsx.com'
 VITE_APP_PORT = 80
 # 是否在打包时开启压缩,支持 gzip 和 brotli

+ 54 - 32
src/views/game/basketball.vue

@@ -2,8 +2,8 @@
   <div class="game-container">
     <canvas id="canvas" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @touchstart="handleTouchStart"
       @touchend="handleTouchEnd"></canvas>
-    <canvas ref="canvasRef" :width="clientObj.width" :height="clientObj.height"
-      style="position:fixed;left: 0; top: 0;"></canvas>
+    <!-- <canvas ref="canvasRef" :width="clientObj.width" :height="clientObj.height"
+      style="position:fixed;left: 0; top: 0;"></canvas> -->
   </div>
 </template>
 
@@ -288,7 +288,6 @@ const getCanvas = () => {
 
 // 游戏主类的响应式状态
 const gameState = reactive({
-  version: '0.1',
   balls: [],
   hoops: [],
   texts: [],
@@ -296,8 +295,8 @@ const gameState = reactive({
   score: 0,
   started: false,
   gameOver: false,
-  ballX: 320 / 2,
-  ballY: 880,
+  ballX: (640 - 93) / 2, // 篮球初始X坐标(居中)
+  ballY: 880, // 篮球初始Y坐标(底部)
   ballVel: 300,
   ballAngleVel: 100,
   ballAngle: 0,
@@ -399,9 +398,9 @@ class Ball {
       this.falling = true;
     }
 
-    if (this.x + 47 > 640) {
+    if (this.x + 47 > clientObj.value.width) {
       this.vx = this.vx * -1;
-      this.x = 640 - 47;
+      this.x = clientObj.value.width - 47;
     }
 
     if (this.x - 47 < 0) {
@@ -483,7 +482,7 @@ const handleTouchEnd = () => {
 // 键盘事件处理函数
 const handleKeyDown = (event: KeyboardEvent) => {
   if (gameState.state !== 'play') return;
-  
+
   if (event.key === 'ArrowLeft') {
     gameState.keyLeft = true;
   } else if (event.key === 'ArrowRight') {
@@ -507,27 +506,27 @@ const handleKeyUp = (event: KeyboardEvent) => {
 // 游戏方法
 const setupCanvas = () => {
   gameState.canvas = document.getElementById('canvas');
-  gameState.canvas.width = 640;
-  gameState.canvas.height = 960;
+  gameState.canvas.width = clientObj.value.width;
+  gameState.canvas.height = clientObj.value.height;
   // gameState.canvas.width = document.documentElement.clientWidth / 2;
   // gameState.canvas.height = document.documentElement.clientHeight;
   gameState.ctx = gameState.canvas.getContext('2d');
 };
 
 const resizeToWindow = () => {
-  const w = gameState.canvas.width / gameState.canvas.height;
-  const h = window.innerHeight;
-  const ratio = h * w;
-  gameState.canvas.style.width = Math.floor(ratio) + 'px';
-  gameState.canvas.style.height = Math.floor(h) + 'px';
+  // const w = gameState.canvas.width / gameState.canvas.height;
+  // const h = window.innerHeight;
+  // const ratio = h * w;
+  // gameState.canvas.style.width = Math.floor(ratio) + 'px';
+  // gameState.canvas.style.height = Math.floor(h) + 'px';
 };
 
 const drawLoadingScreen = () => {
   const ctx = gameState.ctx;
   ctx.fillStyle = 'black';
-  ctx.fillRect(0, 0, 960, 640);
+  ctx.fillRect(0, 0, 960, clientObj.value.width);
   ctx.textAlign = 'center';
-  drawText(ctx, 'Loading...', 640 / 2, 960 / 2, 40);
+  drawText(ctx, 'Loading...', clientObj.value.width / 2, 960 / 2, 40);
   ctx.textAlign = 'left';
 };
 
@@ -617,9 +616,9 @@ const update = (delta) => {
   if (gameState.state === 'play') {
     // // 更新篮球横向移动
     // gameState.ballX += gameState.ballVel * delta;
-    // if (gameState.ballX > 640 - 93) {
+    // if (gameState.ballX > clientObj.value.width - 93) {
     //   gameState.ballVel = -gameState.ballVel;
-    //   gameState.ballX = 640 - 93;
+    //   gameState.ballX = clientObj.value.width - 93;
     // }
     // if (gameState.ballX < 0) {
     //   gameState.ballVel = -gameState.ballVel;
@@ -633,10 +632,10 @@ const update = (delta) => {
     if (gameState.keyRight) {
       gameState.ballX += gameState.ballVel * delta;
     }
-    
+
     // 边界检查
-    if (gameState.ballX > 640 - 93) {
-      gameState.ballX = 640 - 93;
+    if (gameState.ballX > clientObj.value.width - 93) {
+      gameState.ballX = clientObj.value.width - 93;
     }
     if (gameState.ballX < 0) {
       gameState.ballX = 0;
@@ -762,21 +761,44 @@ const draw = () => {
   if (!ctx) return;
 
   // 绘制背景
-  if (gameState.res['/static/images/basketball/background.png']) {
-    ctx.drawImage(gameState.res['/static/images/basketball/background.png'], 0, 0);
+if (gameState.res['/static/images/basketball/background.png']) {
+  const img = gameState.res['/static/images/basketball/background.png'];
+  const canvasWidth = gameState.canvas.width;
+  const canvasHeight = gameState.canvas.height;
+  
+  // 计算图片与画布的比例
+  const imgRatio = img.width / img.height;
+  const canvasRatio = canvasWidth / canvasHeight;
+  
+  let drawWidth, drawHeight, drawX = 0, drawY = 0;
+  
+  // 根据比例计算绘制尺寸
+  if (canvasRatio > imgRatio) {
+    // 画布更宽,按宽度缩放,高度可能超出
+    drawWidth = canvasWidth;
+    drawHeight = canvasWidth / imgRatio;
+    drawY = (canvasHeight - drawHeight) / 2; // 垂直居中
+  } else {
+    // 画布更高,按高度缩放,宽度可能超出
+    drawHeight = canvasHeight;
+    drawWidth = canvasHeight * imgRatio;
+    drawX = (canvasWidth - drawWidth) / 2; // 水平居中
   }
-
+  
+  // 绘制图片(可能裁剪边缘)
+  ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight);
+}
   // 绘制菜单状态
   if (gameState.state === 'menu') {
     if (gameState.res['/static/images/basketball/title.png']) {
       ctx.drawImage(
         gameState.res['/static/images/basketball/title.png'],
-        640 / 2 - (492 / 2),
+        clientObj.value.width / 2 - (492 / 2),
         100
       );
     }
     ctx.textAlign = 'center';
-    drawText(ctx, '请做投篮动作开始游戏', 640 / 2, 520, 40);
+    drawText(ctx, '请做投篮动作开始游戏', clientObj.value.width / 2, 520, 40);
   }
 
   // 绘制游戏状态
@@ -821,9 +843,9 @@ const draw = () => {
   // 绘制游戏结束界面
   if (gameState.state === 'over') {
     ctx.textAlign = 'center';
-    drawText(ctx, 'Game Over', 640 / 2, 200, 80);
-    drawText(ctx, 'Score: ' + gameState.score, 640 / 2, 400, 50);
-    drawText(ctx, 'Click to Continue', 640 / 2, 800, 50);
+    drawText(ctx, 'Game Over', clientObj.value.width / 2, 200, 80);
+    drawText(ctx, 'Score: ' + gameState.score, clientObj.value.width / 2, 400, 50);
+    drawText(ctx, 'Click to Continue', clientObj.value.width / 2, 800, 50);
     ctx.textAlign = 'center';
   }
 };
@@ -843,8 +865,8 @@ const initGame = async () => {
   // 添加篮筐
   gameState.hoops = [
     new Hoop(110, 520),
-    new Hoop(640 - 148 - 110, 520),
-    new Hoop(640 / 2 - (148 / 2), 260)
+    new Hoop(clientObj.value.width - 148 - 110, 520),
+    new Hoop(clientObj.value.width / 2 - (148 / 2), 260)
   ];
 
   // 开始游戏循环

+ 4 - 1
src/views/game/index.vue

@@ -71,7 +71,10 @@ onMounted(() => {
   //停止播报;
   speckCancel();
   //{ name: "方块跳一跳", key: "square" },
-  projectList.value = [{ name: "水果忍者", key: "fruit" }, { name: "投篮", key: "basketball" }, { name: "踢足球", key: "football" }, { name: "17点位", key: "humanBody" }]
+  projectList.value = [{ name: "水果忍者", key: "fruit" }, { name: "投篮", key: "basketball" }, { name: "踢足球", key: "football" }]
+  if (import.meta.env.APP_ENV != 'pro') {
+    projectList.value.push({ name: "17点位", key: "humanBody" })
+  }
 });
 
 onBeforeUnmount(() => {

+ 1 - 1
src/views/home/index.vue

@@ -51,7 +51,7 @@ const getJump = (url: string, name: string) => {
     return false;
   }
   if (url == '/set') {
-    if (import.meta.env.DEV) {
+    if (import.meta.env.APP_ENV != 'pro') {
       proxy?.$modal.msgSuccess('测试环境免密进入');
       router.push({ path: url });
     } else {

+ 1 - 1
src/views/sunshineRun/index.vue

@@ -129,7 +129,7 @@ const getFullScreen = () => {
  * 确定退出
  */
 const confirmExit = async () => {
-  if (import.meta.env.DEV) {
+  if (import.meta.env.APP_ENV != 'pro') {
     getClearTimer();
     proxy?.$modal.msgSuccess('测试环境免密退出');
     await proxy?.$http.common.logout({}).then((res: any) => { });