制作A-Frame堆叠游戏:如何设置盒子变量位置或x,y-10,z位置?
问题描述
我想制作一款类似Stacker街机的A-Frame游戏,尽量避免使用重力(必要时也可接受)。目前找不到让盒子位置下移的方法,可能需要用到Three.js,但我整体不太擅长JavaScript。我尝试编写了如下代码,想通过动画实现点击后将盒子位置设置为x,y-10,z,但未成功,也不知道如何用JavaScript将盒子位置设为变量:
<!DOCTYPE html> <html> <head> <title>Drop the Box</title> <script src="https://aframe.io/releases/1.0.0/aframe.min.js"></script> <script src="https://cdn.rawgit.com/donmccurdy/aframe-physics-system/v4.0.1/dist/aframe-physics-system.min.js"></script> <script src="index.js"></script> </head> <body> <a-scene physics="gravity:-4.5"> <a-sky color="lightblue"></a-sky> <a-plane position="0 -10 -10" width="20" height="20" rotation="-90 0 0"></a-plane> <!-- Camera --> <a-entity camera look-controls wasd-controls position="0 1.6 0" constraint="collideConnected:true" static-body ></a-entity> <a-camera> <a-cursor></a-cursor> </a-camera> <a-box position="-10 0 -10" width="2" height="2" depth="2" color="red" animation__1=" property:position; from: -10 0 -10; to: 10 0 -10; loop: true; dur: 2000; dir: alternate; pauseEvents: click; " animation__2=" property:position; from: position; to: position.x y-10 z; startEvents:click; "></a-box> </a-scene> </body> </html>
问题分析与解决方案
1. 动画组件语法问题
你在animation__2中的to值写法不符合A-Frame规则,动画组件不支持position.x这类动态表达式,必须用具体数值或通过JavaScript动态计算。
2. 实现盒子下移的两种方式
方式一:带动画的下移(自定义组件)
通过注册A-Frame自定义组件,点击时获取盒子当前位置,计算下移后的坐标并启动动画:
AFRAME.registerComponent('drop-on-click', { init: function () { const box = this.el; box.addEventListener('click', () => { // 暂停左右移动的动画 box.components['animation__1'].pause(); // 获取当前位置 const currentPos = box.getAttribute('position'); // 设置下移动画参数 box.setAttribute('animation__drop', { property: 'position', from: currentPos, to: {x: currentPos.x, y: currentPos.y - 10, z: currentPos.z}, dur: 600 // 动画时长,可按需调整 }); // 启动下移动画 box.components['animation__drop'].play(); }); } });
然后修改盒子标签,添加自定义组件:
<a-box position="-10 0 -10" width="2" height="2" depth="2" color="red" animation__1=" property:position; from: -10 0 -10; to: 10 0 -10; loop: true; dur: 2000; dir: alternate; " drop-on-click> </a-box>
方式二:直接修改位置(无动画)
如果不需要动画效果,点击时直接更新盒子位置即可:
AFRAME.registerComponent('drop-on-click', { init: function () { const box = this.el; box.addEventListener('click', () => { box.components['animation__1'].pause(); const currentPos = box.getAttribute('position'); box.setAttribute('position', { x: currentPos.x, y: currentPos.y - 10, z: currentPos.z }); }); } });
3. 额外优化点
- 代码中存在两个相机实体(
<a-entity camera>和<a-camera>),保留一个即可避免冲突,建议合并为:
<a-entity camera look-controls wasd-controls position="0 1.6 0" constraint="collideConnected:true" static-body> <a-cursor></a-cursor> </a-entity>
- 如果完全不需要重力,可以移除
<a-scene>上的physics属性,因为当前需求是手动控制下移,物理引擎并非必需。
内容的提问来源于stack exchange,提问作者Iskandar Williams
相关产品推荐
相关产品推荐

