void Animal::handleStimulus(Environment *environment, double dt) { voiceInterval -= dt; if (this == environment->getPlayer()) { Vector2D movement = environment->getMovement(); movement = movement.mult(dt); translate(movement); handleCollisions(environment); environment->updateObjectScreen(this); if (movement.distanceTo(Vector2D()) > 1.0e-5) { addEnergy(-dt); } for (int i = 0; i < sensors.size(); i++) { sensors[i]->handleStimulus(this, environment, dt); } } else { RandomNumberGenerator *rng = RandomNumberGenerator::getInstance(); if (curAIStateDuration > 0.0) { curAIStateDuration -= dt; } else { curAIStateDuration = ((double) rng->getInt(500, 3000)) / 1000.0; curAIDirection = Vector2D(rng->getInt(-1, 1), rng->getInt(-1, 1)); curAIDirection = curAIDirection.mult(speed); } Vector2D movement = curAIDirection; movement = movement.mult(dt); translate(movement); handleCollisions(environment); environment->updateObjectScreen(this); } }
void Animal::handleCollisions(Environment *environment) { Vector2D boundsCorrection; if (getBounds().getMinX() < environment->getBounds().getMinX()) { boundsCorrection.setX(environment->getBounds().getMinX() - getBounds().getMinX()); } if (getBounds().getMinY() < environment->getBounds().getMinY()) { boundsCorrection.setY(environment->getBounds().getMinY() - getBounds().getMinY()); } if (getBounds().getMaxX() > environment->getBounds().getMaxX()) { boundsCorrection.setX(environment->getBounds().getMaxX() - getBounds().getMaxX()); } if (getBounds().getMaxY() > environment->getBounds().getMaxY()) { boundsCorrection.setY(environment->getBounds().getMaxY() - getBounds().getMaxY()); } translate(boundsCorrection); std::vector<Object *> nearestObjects = environment->getNearestObjects(this); for (int k = 0; k < nearestObjects.size(); k++) { Object *nearestObject = nearestObjects[k]; double distance = getPosition().distanceTo(nearestObject->getPosition()); double radius = (OBJECT_WIDTH / 2); if (distance < 2.0 * radius) { Vector2D overlapVector = Vector2D(nearestObject->getPosition(), getPosition()); overlapVector = overlapVector.normalize(); double overlapLength = 2.0 * radius - distance; overlapVector = overlapVector.mult(overlapLength); translate(overlapVector); handleCollision(environment, nearestObject); } } }
Vector2D Vector2D::proj(Vector2D s, Vector2D t) { t.normalise(); Vector2D proj = t; float multiple = proj.dot(s, t) / proj.dot(t, t); proj.mult(multiple); return proj; }
void MultiDirectionalEar::renderFeedback(Object *object, Environment *environment) { if (object == environment->getPlayer()) { Vector2D windowPos = environment->getWindowPos(object->getPosition()); for (int i = 0; i < nearestObjects.size(); i++) { Object *nearestObject = nearestObjects[i]; if (nearestObject->getVoice() && nearestObject->getVoiceInterval() <= 0.0) { nearestObject->resetVoiceInterval(); Vector2D objectWindowPos = environment->getWindowPos(nearestObject->getPosition()); Vector2D relativePos = objectWindowPos.add(windowPos.mult(-1.0)); relativePos = relativePos.normalize(); double pan = relativePos.getX(); double nearestObjectDistance = windowPos.distanceTo(objectWindowPos); double gain = 1.0 - (nearestObjectDistance / 1000.0); if (gain < 0.0) { gain = 0.0; } al_play_sample(nearestObject->getVoice(), gain, pan, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); } } } }