Browse Source

1、blocklyGame背景地图渲染

liyanbo 6 months ago
parent
commit
f8b1f2b94c
2 changed files with 56 additions and 62 deletions
  1. BIN
      src/assets/images/blockly/mapGame.png
  2. 56 62
      src/views/block/MapGame.vue

BIN
src/assets/images/blockly/mapGame.png


+ 56 - 62
src/views/block/MapGame.vue

@@ -58,9 +58,9 @@
 
       <!-- Blockly工作区 -->
       <div class="blockly-section">
-        <div class="toolbox-section">
+        <div class="toolbox-section" style="display: none;">
           <h2>工具箱</h2>
-          <div id="toolbox" style="display: none;">
+          <div id="toolbox">
             <!-- 移动控制积木 -->
             <category name="移动控制" colour="%{BKY_MOTION_HUE}">
               <block type="move_forward"></block>
@@ -84,7 +84,7 @@
               <block type="controls_repeat_ext">
                 <value name="TIMES">
                   <shadow type="math_number">
-                    <field name="NUM">5</field>
+                    <field name="NUM"></field>
                   </shadow>
                 </value>
               </block>
@@ -95,34 +95,19 @@
             <category name="数学" colour="%{BKY_MATH_HUE}">
               <block type="math_number"></block>
               <block type="math_arithmetic"></block>
-              <block type="math_single"></block>
-            </category>
-
-            <!-- 文本输出积木 -->
-            <category name="文本" colour="%{BKY_TEXTS_HUE}">
-              <block type="text"></block>
-              <block type="text_length"></block>
-              <block type="text_print"></block>
             </category>
           </div>
         </div>
 
         <div class="workspace-section">
           <h2>工作区</h2>
-          <div id="blocklyDiv"></div>
           <div class="controls">
             <button id="runCode" @click="runCode">运行代码</button>
             <button @click="clearWorkspace">清空工作区</button>
             <button @click="resetPlayer">重置玩家</button>
           </div>
-        </div>
 
-        <div class="output-section">
-          <h2>输出</h2>
-          <div class="controls">
-            <button @click="clearOutput">清空输出</button>
-          </div>
-          <pre id="output">{{ output }}</pre>
+          <div id="blocklyDiv"></div>
         </div>
       </div>
     </div>
@@ -136,6 +121,7 @@ import { ArrowLeftBold } from '@element-plus/icons-vue';
 import * as Blockly from "blockly";
 import 'blockly/msg/zh-hans';
 import { javascriptGenerator } from "blockly/javascript";
+import mapBackgroundImage from '@/assets/images/blockly/mapGame.png';
 
 const router = useRouter();
 
@@ -144,15 +130,15 @@ const gameState = reactive({
   // 地图配置信息
   mapConfig: {
     // 地图背景图片路径
-    background: '@/assets/images/room.png',
+    background: mapBackgroundImage,
     // 每个瓦片的尺寸(像素)
-    tileSize: 50,
+    tileSize: 167,
   },
 
   // 玩家相关状态
   player: {
     // 玩家当前位置坐标
-    position: { x: 1, y: 1 },
+    position: { x: 2, y: 2 },
     // 玩家当前朝向:0=上, 1=右, 2=下, 3=左
     direction: 1,
     // 是否正在发生碰撞
@@ -172,19 +158,14 @@ const gameState = reactive({
   // 地图数据信息
   mapData: {
     // 游戏起点位置
-    startPoint: { x: 1, y: 1 },
+    startPoint: { x: 2, y: 2 },
     // 游戏终点位置
-    endPoint: { x: 3, y: 1 },
+    endPoint: { x: 3, y: 3 },
     // 地图上所有可行走的点坐标集合
     walkablePoints: [
-      { x: 1, y: 1 }, { x: 2, y: 1 }, { x: 3, y: 1 }, { x: 4, y: 1 }, { x: 5, y: 1 },
-      { x: 1, y: 2 }, { x: 5, y: 2 },
-      { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 3 }, { x: 4, y: 3 }, { x: 5, y: 3 },
-      { x: 1, y: 4 }, { x: 3, y: 4 }, { x: 5, y: 4 },
-      { x: 1, y: 5 }, { x: 2, y: 5 }, { x: 3, y: 5 }, { x: 4, y: 5 }, { x: 5, y: 5 },
-      { x: 1, y: 6 }, { x: 5, y: 6 },
-      { x: 1, y: 7 }, { x: 2, y: 7 }, { x: 3, y: 7 }, { x: 4, y: 7 }, { x: 5, y: 7 },
-      { x: 6, y: 7 }, { x: 7, y: 7 }, { x: 8, y: 7 }
+      { x: 1, y: 1 }, { x: 2, y: 1 }, { x: 3, y: 1 },
+      { x: 2, y: 2 }, { x: 3, y: 2 },
+      { x: 1, y: 3 }, { x: 3, y: 3 },
     ]
   }
 });
@@ -225,8 +206,8 @@ function isWalkable(x, y) {
 // 计算点的样式
 function getPointStyle(point) {
   return {
-    left: point.x * tileSize.value + 'px',
-    top: point.y * tileSize.value + 'px',
+    left: point.x * tileSize.value - tileSize.value + 'px',
+    top: point.y * tileSize.value - tileSize.value + 'px',
     width: tileSize.value + 'px',
     height: tileSize.value + 'px'
   };
@@ -234,8 +215,8 @@ function getPointStyle(point) {
 
 // 计算玩家样式
 const playerStyle = computed(() => ({
-  left: playerPosition.value.x * tileSize.value + 'px',
-  top: playerPosition.value.y * tileSize.value + 'px',
+  left: playerPosition.value.x * tileSize.value - tileSize.value + 'px',
+  top: playerPosition.value.y * tileSize.value - tileSize.value + 'px',
   transform: `rotate(${playerDirection.value * 90}deg)`,
   '--player-rotation': `${playerDirection.value * 90}deg`,
   width: (tileSize.value * 0.8) + 'px',
@@ -419,12 +400,32 @@ function initBlockly() {
   const toolbox = document.getElementById('toolbox');
   workspace = Blockly.inject('blocklyDiv', {
     toolbox: toolbox,
-    theme: Blockly.Themes.Classic,
+    collapse: true,
+    comments: true,
+    disable: false, // 设为false以允许编辑
+    maxBlocks: Infinity,
+    trashcan: true,
+    horizontalLayout: false,
+    toolboxPosition: 'start',
+    css: true,
+    media: 'https://unpkg.com/blockly/media/',
+    rtl: false,
+    scrollbars: true,
+    sounds: false, // 禁用声音以提高性能
+    oneBasedIndex: true,
     grid: {
       spacing: 20,
       length: 3,
-      colour: '#ccc',
+      colour: "#ccc",
       snap: true
+    },
+    zoom: {
+      controls: true,
+      wheel: true,
+      startScale: 1.0,
+      maxScale: 3,
+      minScale: 0.3,
+      scaleSpeed: 1.2
     }
   });
 }
@@ -508,8 +509,7 @@ async function move(direction) {
   if (isWalkable(newX, newY)) {
     // 使用平滑移动动画
     await smoothMoveTo(newX, newY);
-    output.value += `${moveType}到: (${newX}, ${newY})
-`;
+    output.value += `${moveType}到: (${newX}, ${newY})\n`;
 
     // 检查是否到达终点
     if (newX === endPoint.value.x && newY === endPoint.value.y) {
@@ -591,14 +591,12 @@ window.turnAround = async function() {
   await new Promise(resolve => setTimeout(resolve, 500));
 };
 
-
 // 添加一个变量来跟踪当前执行的代码
 let currentExecutionPromise = null;
 let executionAbortController = null;
 // 运行代码
 const runCode = async () => {
   try {
-
     await resetPlayer();
 
     // 创建新的AbortController用于取消执行
@@ -679,11 +677,6 @@ const clearWorkspace = () => {
   showGameMessage('工作区已清空', 'info');
 };
 
-// 清空输出
-const clearOutput = () => {
-  output.value = '// 输出将显示在这里\n';
-};
-
 // 重置玩家位置和状态
 const resetPlayer = () => {
   // 取消任何正在执行的代码
@@ -829,7 +822,7 @@ onUnmounted(() => {
 .map-background {
   position: relative;
   width: 500px;
-  height: 400px;
+  height: 500px;
   margin: 0 auto;
   border: 2px solid #ddd;
   border-radius: 8px;
@@ -841,28 +834,28 @@ onUnmounted(() => {
   width: 100%;
   height: 100%;
   object-fit: cover;
-  opacity: 0.7;
+  //opacity: 0.7;
 }
 
 /* 可行走区域样式 */
 .walkable-point {
-  position: absolute;
-  background-color: rgba(52, 152, 219, 0.2);
-  border: 1px solid rgba(52, 152, 219, 0.5);
-  box-sizing: border-box;
+  //position: absolute;
+  //background-color: rgba(52, 152, 219, 0.2);
+  //border: 1px solid rgba(52, 152, 219, 0.5);
+  //box-sizing: border-box;
 }
 
 /* 起点和终点样式 */
 .start-point,
 .end-point {
-  position: absolute;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  font-weight: bold;
-  color: white;
-  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.7);
-  border-radius: 5px;
+  //position: absolute;
+  //display: flex;
+  //justify-content: center;
+  //align-items: center;
+  //font-weight: bold;
+  //color: white;
+  //text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.7);
+  //border-radius: 5px;
 }
 
 .start-point {
@@ -982,6 +975,7 @@ onUnmounted(() => {
   background: rgba(248, 249, 250, 0.82);
   padding: 15px;
   border-radius: 15px;
+  height: 100%;
 }
 
 .workspace-section h2 {
@@ -1002,7 +996,7 @@ onUnmounted(() => {
 .controls {
   display: flex;
   gap: 10px;
-  margin-top: 15px;
+  margin: 15px 0px;
   flex-wrap: wrap;
 }