MMLCollisionMoveEvent extendsRemoteEvent
Received when a user moves the collision point they are colliding at on an element.
<m-label y="5" z="-3" width="10" height="5" color="red" font-size="150">
</m-label>
<m-cube id="my-cube" y="0.1" z="5" width="4" depth="2" height="0.3" collision-interval="100"></m-cube>
<script>
const labelElement = document.querySelector("m-label")
const collidingCube = document.querySelector("#my-cube");
collidingCube.addEventListener("collisionmove", ({ detail }) => {
const text = `User at
x: ${detail.position.x.toString().substring(0, 6)},
y: ${detail.position.y.toString().substring(0, 6)},
z: ${detail.position.z.toString().substring(0, 6)}`
labelElement.setAttribute("content", text)
})
</script>
detailisReadonly
detail: {
position: Position
connectionId: number
}
Type declaration
- position:
{
x: number
y: number
z: number
}
The position of the collision relative to the element's origin
- connectionId:
number
The unique numeric id of the connection that sent the event.
typeisReadonly
The **
type
** read-only property of the Event interface returns a string containing the event's type.
Literal: collisionmove
Examples
Move check
<!--Basic example of element collision-->
<m-cube
id="collision-ground"
y="0.2"
height="0.1"
width="3"
depth="3"
color="green"
collision-interval="200"
></m-cube>
<script>
const collisionGround = document.getElementById("collision-ground");
function getShortenedPosition(position) {
return {
x: position.x.toString().substring(0, 6),
y: position.y.toString().substring(0, 6),
z: position.z.toString().substring(0, 6),
};
}
let lastKnownPosition = { x: 0, y: 0, z: 0 };
collisionGround.addEventListener("collisionmove", ({ detail }) => {
// This is because of javascript floating point precision
const shortenedPosition = getShortenedPosition(detail.position);
// This is to prevent the label from updating every frame if the position is the same
if (JSON.stringify(lastKnownPosition) === JSON.stringify(shortenedPosition)) return;
lastKnownPosition = shortenedPosition;
const colors = ["black", "blue", "green", "white", "red", "purple"];
let selectedColor = Math.floor(Math.random() * colors.length);
// We don't want the color to be the same as the ground
while (colors[selectedColor] === collisionGround.getAttribute("color")) {
selectedColor = Math.floor(Math.random() * colors.length);
}
collisionGround.setAttribute("color", colors[selectedColor]);
});
</script>Moving object
<!-- Define a larger cube where the user cubes will appear -->
<m-cube id="users-panel" height="6" width="12" depth="0.1" y="4" z="-2">
<!-- This group will contain all the users cubes -->
<m-group rx="90" id="user-presence-holder"></m-group>
</m-cube>
<!-- Define a platform that detects collisions -->
<m-cube
id="platform"
y="0.05"
height="0.1"
width="6"
depth="3"
color="green"
collision-interval="100"
></m-cube>
<script>
const platform = document.getElementById("platform");
const userPresenceHolder = document.getElementById("user-presence-holder");
// A map that will hold the user's connectionId and
// their associated cube on the users panel.
let standingUsers = new Map();
// A function to either fetch the existing cube representation
// for a user or create one.
function getOrCreateUser(connectionId, position) {
const user = standingUsers.get(connectionId);
if (user) {
user.position = position;
return user;
}
// Create a new cube to represent the user.
const userCube = document.createElement("m-cube");
userCube.setAttribute("collide", false);
userCube.setAttribute("width", 0.25);
userCube.setAttribute("height", 0.25);
userCube.setAttribute("depth", 0.25);
userCube.setAttribute("color", `#${Math.floor(Math.random() * 0xffffff).toString(16)}`);
userPresenceHolder.append(userCube);
const newUser = {
cube: userCube,
position,
};
standingUsers.set(connectionId, newUser);
return newUser;
}
// Function to set the cube's position based on the user's position
// on the platform.
function setCubePosition(connectionId, position) {
const user = getOrCreateUser(connectionId, position);
user.cube.setAttribute("x", position.x * 2);
user.cube.setAttribute("y", 0.2);
user.cube.setAttribute("z", position.z * 2);
}
// Remove user representation when they disconnect or stop colliding.
function clearUser(connectionId) {
const user = standingUsers.get(connectionId);
if (!user) return;
user.cube.remove();
standingUsers.delete(connectionId);
}
// When a user disconnects, their representation is cleared.
window.addEventListener("disconnected", (event) => {
const { connectionId } = event.detail;
clearUser(connectionId);
});
// When a collision starts, set the position of the cube representation.
function handleCollisionstart(e) {
const { connectionId, position } = event.detail;
setCubePosition(connectionId, position);
}
// Update cube position when the user moves while colliding.
function handleCollisionmove(e) {
const { connectionId, position } = event.detail;
setCubePosition(connectionId, position);
}
// Clear user representation when collision ends.
function handleCollisionend(e) {
const { connectionId } = event.detail;
clearUser(connectionId);
}
// Add the necessary event listeners to the platform.
platform.addEventListener("collisionstart", handleCollisionstart);
platform.addEventListener("collisionmove", handleCollisionmove);
platform.addEventListener("collisionend", handleCollisionend);
</script>