// // Boxer.js // // Make yourself into a boxer, with your hands having spheres that strike others // var GLOVE_SIZE = 0.20; var GLOVE_COLOR = { red: 128, green: 128, blue: 126 }; var HIT_COLOR = { red: 255, green: 0, blue: 0 }; var BLOCK_COLOR = { red: 0, green: 255, blue: 0 }; var HIT_SOUND = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/philip/boxing_hit.wav"); var leftHand = { position: { x: 0, y: 0, z: 0 }, lastPosition: { x: 0, y: 0, z: 0 }, velocity: { x: 0, y: 0, z: 0 }, hitting: false, blocked: false, waitingToClear: false, entity: null }; var rightHand = { position: { x: 0, y: 0, z: 0 }, lastPosition: { x: 0, y: 0, z: 0 }, velocity: { x: 0, y: 0, z: 0 }, hitting: false, blocked: false, waitingToClear: false, entity: null }; // Start: Rez some spheres on your hands leftHand.entity = Entities.addEntity({ type: "Sphere", localPosition: { x: 0, y: 0, z: 0 }, collidesWith: "static", dimensions: { x: GLOVE_SIZE, y: GLOVE_SIZE, z: GLOVE_SIZE }, parentID: MyAvatar.sessionUUID, parentJointIndex: MyAvatar.getJointIndex("LeftHandMiddle2"), color: GLOVE_COLOR }); rightHand.entity = Entities.addEntity({ type: "Sphere", localPosition: { x: 0, y: 0, z: 0 }, collidesWith: "static", dimensions: { x: GLOVE_SIZE, y: GLOVE_SIZE, z: GLOVE_SIZE }, parentID: MyAvatar.sessionUUID, parentJointIndex: MyAvatar.getJointIndex("RightHandMiddle2"), color: GLOVE_COLOR }); function getClosestAvatar() { var workQueue = AvatarList.getAvatarIdentifiers(); var closestDistance = 100; var whichAvatar = -1; for (var i = 0; i < workQueue.length; i++) { var avatar = AvatarList.getAvatar(workQueue[i]), avatarPosition = avatar && avatar.position; if (avatarPosition) { var distance = Vec3.length(Vec3.subtract(avatar.position, MyAvatar.position)); if (distance < closestDistance && (distance > 0)) { closestDistance = distance; whichAvatar = i; } } } if (whichAvatar >= 0) { return AvatarList.getAvatar(workQueue[whichAvatar]); } else { return null; } } function updateHand(hand, deltaTime, enemy) { props = Entities.getEntityProperties(hand.entity); hand.position = props.position; hand.velocity = Vec3.length(hand.position, hand.lastPosition) / deltaTime; if (enemy) { // Check for hit to hand var head = enemy.getJointPosition("Head"); if (!hand.hitting && (Vec3.distance(head, hand.position) < GLOVE_SIZE / 2)) { print("startHit"); Entities.editEntity(hand.entity, { color: HIT_COLOR }); hand.hitting = true; Audio.playSound(HIT_SOUND, { position: hand.position, volume: 1.0, loop: false } ); } else if (hand.hitting && (Vec3.distance(head, hand.position) > GLOVE_SIZE)) { print("endHit"); Entities.editEntity(hand.entity, { color: GLOVE_COLOR }); hand.hitting = false; } // Check for successful block enemyHands = [enemy.getJointPosition("LeftHandMiddle2"), enemy.getJointPosition("RightHandMiddle2")]; for (var i = 0; i < 2; i++) { var distanceToHand = Vec3.distance(hand.position, enemyHands[i]); if (!hand.blocked && (distanceToHand < GLOVE_SIZE / 2)) { Entities.editEntity(hand.entity, { color: BLOCK_COLOR }); print("Start Blocked"); hand.blocked = true; } else if (hand.blocked && (distanceToHand > GLOVE_SIZE)) { if (!hand.waitingToClear) { hand.waitingToClear = true; Script.setTimeout(clearBlock, 500); } } } } hand.lastPosition = props.position; } function clearBlock() { Entities.editEntity(leftHand.entity, { color: GLOVE_COLOR }); Entities.editEntity(rightHand.entity, { color: GLOVE_COLOR }); leftHand.blocked = false; rightHand.blocked = false; leftHand.waitingToClear = false; rightHand.waitingToClear = false; print("End Blocked"); } // Update: Check for collisions and update colors accordingly function update(deltaTime) { var enemy = getClosestAvatar(); updateHand(leftHand, deltaTime, enemy); updateHand(rightHand, deltaTime, enemy); } // Finish: Cleanup spheres function cleanup() { Entities.deleteEntity(leftHand.entity); Entities.deleteEntity(rightHand.entity); } Script.update.connect(update); Script.scriptEnding.connect(cleanup);