|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>Finite State Machine Demo with 3D Bird Swarm</title> |
|
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> |
|
</head> |
|
<body> |
|
<a-scene> |
|
<a-assets> |
|
<img id="groundTexture" src="https://cdn.aframe.io/a-painter/images/floor.jpg"> |
|
<img id="skyTexture" src="https://cdn.aframe.io/a-painter/images/sky.jpg"> |
|
</a-assets> |
|
<a-sky src="#skyTexture"></a-sky> |
|
<a-plane src="#groundTexture" rotation="-90 0 0" height="100" width="100"></a-plane> |
|
<a-entity id="player" position="0 1.5 -5" movement></a-entity> |
|
<a-entity id="bird-swarm"> |
|
<a-sphere color="#F44336" position="0 1.5 -10" radius="0.5"></a-sphere> |
|
<a-sphere color="#E91E63" position="0 1.5 -11" radius="0.5"></a-sphere> |
|
<a-sphere color="#9C27B0" position="0 1.5 -12" radius="0.5"></a-sphere> |
|
<a-sphere color="#2196F3" position="0 1.5 -13" radius="0.5"></a-sphere> |
|
<a-sphere color="#4CAF50" position="0 1.5 -14" radius="0.5"></a-sphere> |
|
</a-entity> |
|
</a-scene> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/javascript-state-machine/3.0.0/state-machine.min.js"></script> |
|
<script> |
|
AFRAME.registerComponent('movement', { |
|
init: function () { |
|
var el = this.el; |
|
var playerState = 'idle'; |
|
|
|
var stateMachine = new StateMachine({ |
|
init: 'idle', |
|
transitions: [ |
|
{ name: 'moveForward', from: ['idle', 'moveBackward'], to: 'moveForward' }, |
|
{ name: 'moveBackward', from: ['idle', 'moveForward'], to: 'moveBackward' }, |
|
{ name: 'stop', from: ['moveForward', 'moveBackward'], to: 'idle' } |
|
], |
|
methods: { |
|
onEnterMoveForward: function () { |
|
el.setAttribute('animation', 'property: position; to: 0 1.5 -2; dur: 2000'); |
|
}, |
|
onEnterMoveBackward: function () { |
|
el.setAttribute('animation', 'property: position; to: 0 1.5 -8; dur: 2000'); |
|
}, |
|
onLeaveMoveForward: function () { |
|
el.setAttribute('animation', ''); |
|
}, |
|
onLeaveMoveBackward: function () { |
|
el.setAttribute('animation', ''); |
|
} |
|
} |
|
}); |
|
|
|
document.addEventListener('keydown', function (event) { |
|
switch (event.key) { |
|
case 'ArrowUp': |
|
stateMachine.moveForward(); |
|
break; |
|
case 'ArrowDown': |
|
stateMachine.moveBackward(); |
|
break; |
|
} |
|
}); |
|
|
|
document.addEventListener('keyup', function (event) { |
|
switch (event.key) { |
|
case 'ArrowUp': |
|
case 'ArrowDown': |
|
stateMachine.stop(); |
|
break; |
|
} |
|
}); |
|
|
|
var birdSwarm = document.querySelector('#bird-swarm'); |
|
var birdState = 'idle'; |
|
|
|
var birdStateMachine = new StateMachine({ |
|
init: 'follow', |
|
transitions: [ |
|
{ name: 'follow', from: 'idle', to: 'follow' }, |
|
{ name: 'stop', from: 'follow', to: 'idle' } |
|
], |
|
methods: { |
|
onEnterFollow: function () { |
|
birdSwarm.setAttribute('animation', 'property: position; to: 0 1.5 -6; dur: 2000'); |
|
}, |
|
onLeaveFollow: function () { |
|
birdSwarm.setAttribute('animation', ''); |
|
} |
|
} |
|
}); |
|
|
|
function updateBirdPosition () { |
|
var playerPosition = el.getAttribute('position'); |
|
birdSwarm.setAttribute('position', playerPosition.x + ' ' + playerPosition.y + ' ' + (playerPosition.z - 5)); |
|
} |
|
|
|
setInterval(function () { |
|
updateBirdPosition(); |
|
}, 100); |
|
|
|
document.addEventListener('keydown', function (event) { |
|
switch (event.key) { |
|
case 'ArrowUp': |
|
case 'ArrowDown': |
|
birdStateMachine.follow(); |
|
break; |
|
} |
|
}); |
|
|
|
document.addEventListener('keyup', function (event) { |
|
switch (event.key) { |
|
case 'ArrowUp': |
|
case 'ArrowDown': |
|
birdStateMachine.stop(); |
|
break; |
|
} |
|
}); |
|
} |
|
}); |
|
</script> |
|
</body> |
|
</html> |
|
|