为什么一个事件没有被另一个元素识别?
Why is an event not being recognized by another element?
我在使用 A 型框架逻辑门类型组件时遇到问题。我正在为一个 7 年级的学校项目做这个(我可能选择了一些非常高级的东西,但我几乎完成了它),但是我在这里找不到错误。
我遇到的问题是连接的组件(在本例中是一扇门,它的子门是门)似乎应该响应来自门的信号。目前,无论按钮的状态如何,门都卡在“关闭”位置,但是应该发生的是当激活的按钮(红色)满足门属性中指定的逻辑条件时,门应该发出指定的事件。门控制的门我之前测试过并且可以使用按钮,这让我认为问题出在逻辑门本身。我已经检查了所有的语法,它似乎是正确的,调试控制台也没有给出任何错误,这使得调试变得更加困难。
<script>
AFRAME.registerComponent('logic', {
schema: {
type: {
type: 'string',
default: 'and'
},
input1: {
type: 'string'
},
input2: {
type: 'string'
},
event: {
type: 'string'
}
},
init: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
this.activeOut = false;
this.active1 = false;
this.active2 = false;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Toggle each input
entity.addEventListener(input1, function (event) {
if(!this.active1) {
this.active1 = true;
}
else {
this.active1 = false;
}
});
entity.addEventListener(input2, function (event) {
if(!this.active2) {
this.active2 = true;
}
else {
this.active2 = false;
}
});
},
tick: function (time, timeD) {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Detect the gate type and check for the corresponding condition
switch (type) {
case 'and' :
if((this.active1 && this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !(this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'or' :
if((this.active1 || this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !(this.active1 || this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'xor' :
if(((this.active1 || this.active2) && !(this.active1 && this.active2)) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !((this.active1 || this.active2) && !(this.active1 && this.active2))) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'nand' :
if(!(this.active1 && this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && (this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'nor' :
if(!(this.active1 || this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && (this.active1 || this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'xnor' :
if(!((this.active1 || this.active2) && !(this.active1 && this.active2)) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && ((this.active1 || this.active2) && !(this.active1 && this.active2))) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
}
}
});
</script>
这是 HTML 的门(包括重要的门和按钮):
<a-box
color="blue"
door="to: 5 3 -5; toggleEvent: open;"
position="0 3 -5"
width="5"
height="6"
depth="0.06"
>
<a-box
logic="type: and; input1: button; input2: button2; event: open;"
position="0 0 0"
width="0.0001"
height="0.0001"
depth="0.0001"
>
<a-box
color="blue"
position="4 1 -2"
button="eventOn: button; eventOff: button;"
></a-box>
<a-box
color="blue"
button="eventOn: button2; eventOff: button2;"
position="4 3 -2"
></a-box>
</a-box>
</a-box>
代码中的格式取决于它在此处的粘贴方式。
event listener functions have this
set to the element on which the listener is placed:
this.active1 = false; // "this" refers to the component
entity.addEventListener(input1, function (event) {
if(!this.active1) {
this.active1 = true; // "this" refers to "entity"
} else {
this.active1 = false; // "this" refers to entity"
}
});
所以你认为它是相同的 'variable',而实际上你正在设置 entity
的新 属性。
解决此问题的两种常见方法是:
// assing `this` to another variable, which is used in the listener
const self = this;
entity.addEventListener(input1, function (event) {
self.active1 = false; // this is the components active1 property
})
// use an arrow function, which does not have it's own scope
entity.addEventListener(input1, event => {
this.active1 = false; // this is the components active1 property
})
一些备注:
- 如果您确定状态仅在单击按钮时发生变化,则无需每秒检查逻辑 60 次。侦听器可以触发检查当前门状态的功能。
- 在尝试查找错误时尽可能简化代码。将日志放在具有 one/two 执行路径的代码中会更容易。
- 记录、记录并再次记录您认为相关的任何内容。条件看起来不错?
console.log("and")
里面。不触发? console.log(this.active1, this.active2)
在条件之前。总是 false
? console.log(this.active1)
在事件侦听器中。
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component@4.2.1/dist/aframe-event-set-component.min.js"></script>
<script>
AFRAME.registerComponent('logic', {
schema: {
type: { type: 'string', default: 'and' },
input1: { type: 'string' },
input2: { type: 'string' },
event: { type: 'string' }
},
init: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
this.activeOut = false;
this.active1 = false;
this.active2 = false;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Toggle each input
entity.addEventListener(input1, (event) => {
// toggle betweeen true / false
this.active1 = !this.active1 ? true : false
console.log(input1, "triggered. active1: ", this.active1)
this.checkState() // check if the gate is open or closed
});
entity.addEventListener(input2, (event) => {
// toggle betweeen true / false
this.active2 = !this.active2 ? true : false
console.log(input2, "triggered. active1: ", this.active2)
this.checkState() // check if the gate is open or closed
});
},
checkState: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Detect the gate type and check for the corresponding condition
console.log("checkState: active1/2", this.active1, this.active2)
switch (type) {
case 'and':
if ((this.active1 && this.active2) && !this.activeOut) {
console.log("and fullfiled")
entity.emit(event, {}, true);
this.activeOut = true;
} else if (this.activeOut && !(this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
}
}
});
// set text open/closed depending on the 'open' events from the entity with the logic
AFRAME.registerComponent("door", {
init: function () {
const gate = document.querySelector("[logic]")
var toggle = false;
gate.addEventListener("open", evt => {
toggle = !toggle
this.el.setAttribute("text", "value", toggle ? "open" : "closed")
})
}
})
// not sure where this came from, simple toggle between to events on click
AFRAME.registerComponent("button", {
schema: {
eventOn: { type: "string" },
eventOff: { type: "string" }
},
init: function () {
var toggle = false;
this.el.addEventListener("click", evt => {
if (!toggle) {
this.el.emit(this.data.eventOn)
this.el.setAttribute("color", "red")
} else {
this.el.emit(this.data.eventOff)
this.el.setAttribute("color", "blue")
}
toggle = !toggle
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-box">
<a-box logic="type: and; input1: button; input2: button2; event: open;" width="0.0001"
height="0.0001" depth="0.0001">
<a-box color="blue" position="1 2 -2" button="eventOn: button; eventOff: button;"></a-box>
<a-box color="blue" button="eventOn: button2; eventOff: button2;" position="-1 2 -2"></a-box>
</a-box>
<a-entity door position="0.45 1.8 -0.275" text="color:black; value: closed"></a-entity>
<a-sky color="#ECECEC"></a-sky>
<a-entity position="0 1.6 0" camera>
</a-scene>
我在使用 A 型框架逻辑门类型组件时遇到问题。我正在为一个 7 年级的学校项目做这个(我可能选择了一些非常高级的东西,但我几乎完成了它),但是我在这里找不到错误。
我遇到的问题是连接的组件(在本例中是一扇门,它的子门是门)似乎应该响应来自门的信号。目前,无论按钮的状态如何,门都卡在“关闭”位置,但是应该发生的是当激活的按钮(红色)满足门属性中指定的逻辑条件时,门应该发出指定的事件。门控制的门我之前测试过并且可以使用按钮,这让我认为问题出在逻辑门本身。我已经检查了所有的语法,它似乎是正确的,调试控制台也没有给出任何错误,这使得调试变得更加困难。
<script>
AFRAME.registerComponent('logic', {
schema: {
type: {
type: 'string',
default: 'and'
},
input1: {
type: 'string'
},
input2: {
type: 'string'
},
event: {
type: 'string'
}
},
init: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
this.activeOut = false;
this.active1 = false;
this.active2 = false;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Toggle each input
entity.addEventListener(input1, function (event) {
if(!this.active1) {
this.active1 = true;
}
else {
this.active1 = false;
}
});
entity.addEventListener(input2, function (event) {
if(!this.active2) {
this.active2 = true;
}
else {
this.active2 = false;
}
});
},
tick: function (time, timeD) {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Detect the gate type and check for the corresponding condition
switch (type) {
case 'and' :
if((this.active1 && this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !(this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'or' :
if((this.active1 || this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !(this.active1 || this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'xor' :
if(((this.active1 || this.active2) && !(this.active1 && this.active2)) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && !((this.active1 || this.active2) && !(this.active1 && this.active2))) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'nand' :
if(!(this.active1 && this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && (this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'nor' :
if(!(this.active1 || this.active2) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && (this.active1 || this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
case 'xnor' :
if(!((this.active1 || this.active2) && !(this.active1 && this.active2)) && !this.activeOut) {
entity.emit(event, {}, true);
this.activeOut = true;
}
else if(this.activeOut && ((this.active1 || this.active2) && !(this.active1 && this.active2))) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
}
}
});
</script>
这是 HTML 的门(包括重要的门和按钮):
<a-box
color="blue"
door="to: 5 3 -5; toggleEvent: open;"
position="0 3 -5"
width="5"
height="6"
depth="0.06"
>
<a-box
logic="type: and; input1: button; input2: button2; event: open;"
position="0 0 0"
width="0.0001"
height="0.0001"
depth="0.0001"
>
<a-box
color="blue"
position="4 1 -2"
button="eventOn: button; eventOff: button;"
></a-box>
<a-box
color="blue"
button="eventOn: button2; eventOff: button2;"
position="4 3 -2"
></a-box>
</a-box>
</a-box>
代码中的格式取决于它在此处的粘贴方式。
event listener functions have this
set to the element on which the listener is placed:
this.active1 = false; // "this" refers to the component
entity.addEventListener(input1, function (event) {
if(!this.active1) {
this.active1 = true; // "this" refers to "entity"
} else {
this.active1 = false; // "this" refers to entity"
}
});
所以你认为它是相同的 'variable',而实际上你正在设置 entity
的新 属性。
解决此问题的两种常见方法是:
// assing `this` to another variable, which is used in the listener
const self = this;
entity.addEventListener(input1, function (event) {
self.active1 = false; // this is the components active1 property
})
// use an arrow function, which does not have it's own scope
entity.addEventListener(input1, event => {
this.active1 = false; // this is the components active1 property
})
一些备注:
- 如果您确定状态仅在单击按钮时发生变化,则无需每秒检查逻辑 60 次。侦听器可以触发检查当前门状态的功能。
- 在尝试查找错误时尽可能简化代码。将日志放在具有 one/two 执行路径的代码中会更容易。
- 记录、记录并再次记录您认为相关的任何内容。条件看起来不错?
console.log("and")
里面。不触发?console.log(this.active1, this.active2)
在条件之前。总是false
?console.log(this.active1)
在事件侦听器中。
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component@4.2.1/dist/aframe-event-set-component.min.js"></script>
<script>
AFRAME.registerComponent('logic', {
schema: {
type: { type: 'string', default: 'and' },
input1: { type: 'string' },
input2: { type: 'string' },
event: { type: 'string' }
},
init: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
this.activeOut = false;
this.active1 = false;
this.active2 = false;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Toggle each input
entity.addEventListener(input1, (event) => {
// toggle betweeen true / false
this.active1 = !this.active1 ? true : false
console.log(input1, "triggered. active1: ", this.active1)
this.checkState() // check if the gate is open or closed
});
entity.addEventListener(input2, (event) => {
// toggle betweeen true / false
this.active2 = !this.active2 ? true : false
console.log(input2, "triggered. active1: ", this.active2)
this.checkState() // check if the gate is open or closed
});
},
checkState: function () {
var entity = this.el;
var scene = entity.sceneEl;
var event = this.data.event;
var type = this.data.type;
var input1 = this.data.input1;
var input2 = this.data.input2;
// Detect the gate type and check for the corresponding condition
console.log("checkState: active1/2", this.active1, this.active2)
switch (type) {
case 'and':
if ((this.active1 && this.active2) && !this.activeOut) {
console.log("and fullfiled")
entity.emit(event, {}, true);
this.activeOut = true;
} else if (this.activeOut && !(this.active1 && this.active2)) {
entity.emit(event, {}, true);
this.activeOut = false;
}
break;
}
}
});
// set text open/closed depending on the 'open' events from the entity with the logic
AFRAME.registerComponent("door", {
init: function () {
const gate = document.querySelector("[logic]")
var toggle = false;
gate.addEventListener("open", evt => {
toggle = !toggle
this.el.setAttribute("text", "value", toggle ? "open" : "closed")
})
}
})
// not sure where this came from, simple toggle between to events on click
AFRAME.registerComponent("button", {
schema: {
eventOn: { type: "string" },
eventOff: { type: "string" }
},
init: function () {
var toggle = false;
this.el.addEventListener("click", evt => {
if (!toggle) {
this.el.emit(this.data.eventOn)
this.el.setAttribute("color", "red")
} else {
this.el.emit(this.data.eventOff)
this.el.setAttribute("color", "blue")
}
toggle = !toggle
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-box">
<a-box logic="type: and; input1: button; input2: button2; event: open;" width="0.0001"
height="0.0001" depth="0.0001">
<a-box color="blue" position="1 2 -2" button="eventOn: button; eventOff: button;"></a-box>
<a-box color="blue" button="eventOn: button2; eventOff: button2;" position="-1 2 -2"></a-box>
</a-box>
<a-entity door position="0.45 1.8 -0.275" text="color:black; value: closed"></a-entity>
<a-sky color="#ECECEC"></a-sky>
<a-entity position="0 1.6 0" camera>
</a-scene>