关于#javascript#的问题:

vue简易上下移动案例,遇到墙不能走,怎么判断在多个墙的上下左右不能移动,只会写一个墙的情况


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .content {
            height: 800px;
            width: 800px;
            margin: 0 auto;
            background-image: url(./img/bg.png);
            border: 1px solid black;
        }

        .xz {
            height: 100px;
            width: 100px;
            background-image: url(./img/箱子.png);
            position: relative;
            background-size: 100px 100px;
        }

        .qb {
            height: 100px;
            width: 100px;
            background-image: url(./img/物理图_防火墙.png);
            position: relative;
            background-size: 100px 100px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="content">
            <div class="xz" :style="{left:leftVal + 'px',top:topVal + 'px'}">

            </div>
            <div class="qb" :style="{left:leftValue + 'px',top:topValue + 'px'}">

            </div>
            
        </div>
        <div>
            <h1>leftVal:{{leftVal}}</h1>
            <h1>topVal:{{topVal}}</h1>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                leftVal: 0,
                topVal: 0,
                leftValue: 300,
                topValue: 200,
            },
            methods: {
                move(event) {
                    switch (event.keyCode) {
                        case 37:
                            if (this.leftVal < 100 || (this.leftVal == this.leftValue+100 && this.topVal == this.topValue+100)) {
                                this.leftVal = this.leftVal
                                alert('左边有墙');
                                console.log(this.leftValue[0]);
                            } else {
                                this.leftVal -= 100;
                            }
                            break;
                        case 38:
                            if (this.topVal < 100 || (this.leftVal == this.leftValue && this.topVal == this.topValue+200)) {
                                this.topVal = this.topVal
                                alert('上边有墙')
                            } else {
                                this.topVal -= 100;
                            }
                            break;
                        case 39:
                            if (this.leftVal >= 700 || (this.leftVal == this.leftValue-100 && this.topVal == this.topValue+100)) {
                                this.leftVal = this.leftVal
                                alert('右边有墙')
                            } else {
                                this.leftVal += 100;
                            }
                            break;
                        case 40:
                            if (this.topVal >= 700 || (this.leftVal == this.leftValue    && this.topVal == this.topValue)) {
                                alert('下边有墙')
                                this.topVal = this.topVal
                            } else {
                                this.topVal += 100;
                            }
                            break;
                        default:
                            break;
                    }
                }
            },
            mounted() {
                document.addEventListener('keydown', this.move)
            },
        })
    </script>
</body>

</html>

img

img

这样能懂吗,没理解我写一个出来,记得点采纳


<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>

    <style>
        .content {
            height: 800px;
            width: 800px;
            position: relative;
            margin: 0 auto;
            background-image: url(./23.jpg);
            border: 1px solid black;
        }
 
        .xz {
            height: 100px;
            width: 100px;
            background-image: url(./23.jpg);
            position: absolute;
            background-size: 100px 100px;
        }
 
        .qb {
            height: 100px;
            width: 100px;
            background-image: url(./23.jpg);
            position: absolute;
            background-size: 100px 100px;
        }
    </style>
</head>
 
<body>
    <div id="app">
        <div class="content">
            <div class="xz" :style="{left: leftVal*100 + 'px',top:topVal*100 + 'px'}">
 
            </div>
            <div class="qb" :style="{left:400 + 'px',top:0 + 'px'}">
 
            </div>
            <div class="qb" :style="{left:200 + 'px',top:200 + 'px'}">
 
            </div>
            <div class="qb" :style="{left:300 + 'px',top:400 + 'px'}">
 
            </div>
            
        </div>
        <div>
            <h1>leftVal:{{leftVal}}</h1>
            <h1>topVal:{{topVal}}</h1>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                leftVal: 0,
                topVal: 0,
                listWall:['4-0','2-2','3-4']  //墙坐标
            },
            methods: {
                move(event) {
        
                    switch (event.keyCode) {
                        case 37:
                            // 左边
                            if(this.listWall.includes(this.leftVal-1+'-'+this.topVal)|| this.leftVal== 0){
                                alert("撞墙了左边")
                            }else{
                                this.leftVal--;
                            }
                            
                            break;
                        case 38:
                            // 上边  
                            if(this.listWall.includes(this.leftVal+'-'+(this.topVal-1))|| this.topVal== 0){
                                alert("撞墙了上边")
                            }else{
                                this.topVal--;
                            }
                            
                            break;
                        case 39:
                            // 右边
                            if(this.listWall.includes(this.leftVal+1+'-'+this.topVal)|| this.leftVal== 7){
                                alert("撞墙了右边")
                            }else{
                                this.leftVal++;
                            }
                            
                            break;
                        case 40:
                            //   下边
                            if(this.listWall.includes(this.leftVal+'-'+(this.topVal+1))|| this.topVal== 7){
                                alert("撞墙了下边")
                            }else{
                                this.topVal++;
                            }                            
                            break;
                        default:
                            break;
                    }
                }
            },
            mounted() {
                document.addEventListener('keydown', this.move)
            }
        })
    </script>
</body>
 
</html>

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7574139
  • 这篇博客也不错, 你可以看下【JavaScript系列】vue项目中实现滚动条(具体视窗口的滚动条)操作:(1)置底,(2)置于上次停留的位置
  • 除此之外, 这篇博客: vue2响应式原理中的 Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接,不过理解其工作原理同样重要,这样你可以避开一些常见的问题。在这里,我们将研究一下 Vue 响应式系统的底层的细节。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • vue2.x是利用Object.defineProperty劫持对象或对象的属性(指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果)的访问器,在属性值发生变化时获取属性值变化, 从而进行后续操作。

    数据代理的的demo(通过一个对象代理对另一个对象属性的操作)
     

    var a = {age:20}
    			var b = {height:30}
    			Object.defineProperty(b,'age',{
    				get(){
    					return a.age
    				},
    				set(newvalue){
    				   a.age = newvalue	
    				}
    			})

    1、Object.defineProperty在js中的描述:

    Object.defineProperty(obj, prop, descriptor) 直接在一个对象上定义一个属性,或者修改一个对象的现有 属性,并返回这个对象。

     参数:obj 要在其上定义属性的对象;prop 要定义或修改的属性的名称;descriptor 将被定义或修改的属性描述符

    返回值: 传递给函数的对象obj 

    
    //利用Object.defineProperty劫持对象的访问器,在属性值发生变化时我们可以获取变化,然后根据变化进行后续响应,在vue3.0中通过Proxy代理对象进行类似的操作。
    		// 这是将要被劫持的对象
    			const data = {
    				name: '',
    			};
     
    			function say(name) {
    				if (name === '古天乐') {
    					console.log('给大家推荐一款超好玩的游戏');
    				} else if (name === '渣渣辉') {
    					console.log('戏我演过很多, 可游戏我只玩贪玩懒月');
    				} else {
    					console.log('来做我的兄弟');
    				}
    			}
     
    			// 遍历对象,对其属性值进行劫持
    			Object.keys(data).forEach(function(key) {
    				Object.defineProperty(data, key, {
    					enumerable: true,
    					configurable: true,
    					get: function() {
    						console.log('get');
    					},
    					set: function(newVal) {
    						// 当属性值发生变化时我们可以进行额外操作
    						console.log(`大家好, 我系${newVal}`);
    						say(newVal);
    					},
    				});
    			});
    			data.name = '渣渣辉';
    

     

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>数据响应式原理</title>
    	</head>
    	<body>
    		<div id="app">
    		    Hello Vue
    		</div>
    	</body>
    	<script>
    		// 模拟Vue实例中的data选项
    		let data={
    		    msg:'Hello Vue'
    		}
    		//模拟Vue的实例
    		let vm={};
    		
    		//数据劫持,当访问或者设置vm中的成员的时候,做一些干预操作
    		Object.defineProperty(vm,'msg',{
    		    //可枚举(即可被遍历)
    		    enumerable:true,
    		    //可配置(可以使用delete删除,可以通过defineProperty重新定义)
    		    configurable:true,
    		 
    		    //当获取值时执行
    		    get(){
    		        console.log('getter:',data.msg);
    		        return data.msg;
    		    },
    		    //当设置、更新msg变量时执行
    		    set(newValue){
    		        console.log("setter:",newValue);
    		        if(data.msg===newValue){
    		            return;//前后数据相同,则不用做操作DOM的多余操作
    		        }
    		        data.msg=newValue;
    		        document.querySelector("#app").textContent=newValue;
    		    }
    		})
    		//测试setter
    		vm.msg="Hello 响应式原理";
    		 
    		//测试getter
    		console.log(vm.msg);
    	</script>
    </html>
  • 以下回答由chatgpt基于相关博客总结生成:

    对于问题中的具体情况,需要判断在多个墙的情况下,如何实现不能移动的问题。

    首先,在进行判断时需要遍历所有的墙,而不只是一个墙。可以用循环语句来实现遍历。

    接下来,将所有的墙及其位置信息储存在一个数组中,以便于进行比对判断。数组的结构可以是类似于以下格式:

    const walls = [
      {
        position: 'top',
        x: 1,
        y: 1
      },
      {
        position: 'bottom',
        x: 1,
        y: 3
      },
      {
        position: 'left',
        x: 1,
        y: 2
      },
      {
        position: 'right',
        x: 2,
        y: 2
      }
    ];
    

    其中,position 表示墙的位置,x 和 y 表示墙所在的坐标。

    然后,在移动的时候,先判断移动方向,然后判断是否与墙相撞。如果有墙,就不能继续移动。

    具体实现可以是先判断移动的方向,比如向左移动,那么判断当前坐标左侧是否有墙,如果有,就不能移动。如果没有,就可以移动,同时更新自己的坐标。

    以下是一个简单的示例代码:

    const walls = [
      {
        position: 'top',
        x: 1,
        y: 1
      },
      {
        position: 'bottom',
        x: 1,
        y: 3
      },
      {
        position: 'left',
        x: 1,
        y: 2
      },
      {
        position: 'right',
        x: 2,
        y: 2
      }
    ];
    
    // 玩家的坐标
    let playerX = 2;
    let playerY = 2;
    
    // 移动方法
    function move(direction) {
      switch (direction) {
        case 'left':
          if (isWall(playerX - 1, playerY)) {
            console.log('不能向左移动');
          } else {
            playerX -= 1;
            console.log('向左移动成功');
          }
          break;
        case 'right':
          if (isWall(playerX + 1, playerY)) {
            console.log('不能向右移动');
          } else {
            playerX += 1;
            console.log('向右移动成功');
          }
          break;
        case 'up':
          if (isWall(playerX, playerY - 1)) {
            console.log('不能向上移动');
          } else {
            playerY -= 1;
            console.log('向上移动成功');
          }
          break;
        case 'down':
          if (isWall(playerX, playerY + 1)) {
            console.log('不能向下移动');
          } else {
            playerY += 1;
            console.log('向下移动成功');
          }
          break;
        default:
          console.log('无效的方向');
      }
    }
    
    // 判断是否为墙
    function isWall(x, y) {
      return walls.some(wall => wall.x === x && wall.y === y);
    }
    

    以上代码只是示例,具体实现应根据实际情况来编写。