POI *Mystery::parsePOINode(xmlNode *node) { POI *poi = new POI(); int x = atoi(xmlGetAttribute(node, "positionX")); int y = atoi(xmlGetAttribute(node, "positionY")); int interest = atoi(xmlGetAttribute(node, "interest")); poi->position = pointMake(x, y); poi->interest = (Interest) interest; poi->description = xmlGetAttribute(node, "description"); poi->shortDescription = poi->description; if (xmlGetAttribute(node, "shortDescription") != NULL) { poi->shortDescription = xmlGetAttribute(node, "shortDescription"); } poi->visualPosition = poi->position; if (xmlGetAttribute(node, "visualPositionX") != NULL) { int vx = atoi(xmlGetAttribute(node, "visualPositionX")); int vy = atoi(xmlGetAttribute(node, "visualPositionY")); poi->visualPosition = pointMake(vx, vy); } poi->contents = NULL; poi->searchedByMurderer = false; return poi; }
void InvestigationScene::questionWhen() { removeQuestionElements(); std::string question; if (currentFilter.strange) { question = "Did anything strange happen"; } else if (currentFilter.where == NULL) { question = "Where "; if (currentFilter.who == activeCharacter) { question.append("were you"); } else { question.append("was "); question.append(currentFilter.who->name); } } else if (currentFilter.who == NULL) { question = "Who was in the "; question.append(currentFilter.where->name); } question.append(" between ... ?"); questionLabel->setText(question.c_str()); Button *button = new Button("<", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(260, 300)); button->setTag(401); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); button = new Button(">", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(540, 300)); button->setTag(402); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); char buff[20]; sprintf(buff, "%s and %s", timeToString(currentFilter.timeStart + START_TIME, false).c_str(), timeToString(currentFilter.timeEnd + START_TIME, false).c_str()); whenLabel->setText(buff); whenLabel->setVisible(true); askQuestionButton->setEnabled(true); askQuestionButton->setVisible(true); }
void Camera::setCenter(Point c) { float cx = c.x; float cy = c.y; float centerX = center.x; float centerY = center.y; if ((cx + (viewportSize.width / 2)) > boundsSize.width) { centerX = boundsSize.width - (viewportSize.width / 2); } else if ((cx - (viewportSize.width / 2)) < 0) { centerX = viewportSize.width / 2; } else { centerX = cx; } if ((cy + (viewportSize.height / 2)) > boundsSize.height) { centerY = boundsSize.height - (viewportSize.height / 2); } else if ((cy - (viewportSize.height / 2)) < 0) { centerY = viewportSize.height / 2; } else { centerY = cy; } center = pointMake(centerX, centerY); }
//Welzl algorithm void minimumCircle(float* radius, Point* position, Point* points,int size){ if(size == 0){ *radius = 0; *position = pointMake(0, 0); return; } size--; Point* evaluationPoint = &points[size]; minimumCircle(radius, position, points, size); if(isPointInsideCircle(*evaluationPoint, *radius, *position)){ return; } Point* P = copyPoints(size, points); Point* R = copyPoints(1, evaluationPoint); minimumDisk(P, R, size, 1, radius, position); free(P); free(R); return; }
Point Camera::getTop() { float cx = center.x - (viewportSize.width / 2); float cy = center.y - (viewportSize.height / 2); return pointMake(cx, cy); }
Camera::Camera(int vw, int vh, int bw, int bh) { viewportSize = sizeMake(vw, vh); boundsSize = sizeMake(bw, bh); center = pointMake(0, 0); }
State physicsResolution(PhysicsObject*a, PhysicsObject*b, CollisionPair pair){ //first we find the impulse in our collision float impulse; Point centerA = worldPosition(a->rotationCenter, *a); Point centerB = worldPosition(b->rotationCenter, *b); Point RA = pointMake(pair.location.x-centerA.x, pair.location.y-centerA.y); Point RB = pointMake(pair.location.x-centerB.x, pair.location.y-centerB.y); Vector VAP = pointMake(a->linearVelocity.x-a->angularVelocity*RA.y, a->linearVelocity.y+a->angularVelocity*RA.x); Vector VBP = pointMake(b->linearVelocity.x-b->angularVelocity*RB.y, b->linearVelocity.y+b->angularVelocity*RB.x); Vector VAB = pointMake(VAP.x - VBP.x, VAP.y - VBP.y); float crossRANsquare = RA.x*pair.normal.y-pair.normal.x*RA.y; crossRANsquare = crossRANsquare*crossRANsquare; float crossRBNsquare = RB.x*pair.normal.y-pair.normal.x*RB.y; crossRBNsquare = crossRBNsquare*crossRBNsquare; impulse = a->inverseMass + b->inverseMass + a->inverseInertia*crossRANsquare + b->inverseInertia*crossRBNsquare; impulse = -(1+RESTITUTION_COEFFCIENT)*(VAB.x*pair.normal.x+VAB.y*pair.normal.y)/impulse; State DeltaState; DeltaState.deltaVel = pointMake(impulse*a->inverseMass*pair.normal.x,impulse*a->inverseMass*pair.normal.y); DeltaState.deltaAngVel = (RA.x*pair.normal.y-RA.y*pair.normal.x)*a->inverseInertia*impulse; float deltaPosModule = a->inverseMass*pair.depth/(a->inverseMass+b->inverseMass); DeltaState.deltaPosition = pointMake(deltaPosModule*pair.normal.x, deltaPosModule*pair.normal.y); return DeltaState; }
//Welzl final recursion - calculates the actual circle void minimumDisk(Point* P, Point* R, int sizeP, int sizeR, float* radius, Point* position){ if(sizeP==0 || sizeR==3){ if(sizeR==1){ *radius = 0; *position = R[0]; return; } if(sizeR==2){ *position = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.); *radius = pointsDistance(R[0], R[1])/2.; return; } if(sizeR==3){ Point P1 = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.); Point AB = pointMake((R[1].x-R[0].x)/2., (R[1].y-R[0].y)/2.); Point BC = pointMake((R[2].x-R[1].x)/2., (R[2].y-R[1].y)/2.); Point AC = pointMake((R[2].x-R[0].x)/2., (R[2].y-R[0].y)/2.); Point PR = pointMake(-AB.y,AB.x); float w = -1./2.*(BC.x*AC.x+BC.y*AC.y)/(BC.x*AB.y-BC.y*AB.x); *position = pointMake(P1.x+w*PR.x, P1.y+w*PR.y); *radius = pointsDistance(*position, R[0]); return; } } Point* P2 = copyPoints(sizeP, P); Point* R2 = copyPoints(sizeR, R); sizeP--; Point point = P[sizeP]; minimumDisk(P2, R2, sizeP, sizeR, radius, position); if(isPointInsideCircle(point, *radius, *position)){ free(R2); free(P2); return; } R2[sizeR] = point; sizeR++; minimumDisk(P2, R2, sizeP, sizeR, radius, position); free(R2); free(P2); return; }
Point worldPosition(Point point, PhysicsObject object){ float c1 = TS8_cos(object.rotation); float s1 = TS9_sin(object.rotation); float offsetx = object.rotationCenter.x*(1-c1)+object.rotationCenter.y*s1+object.position.x; float offsety = object.rotationCenter.y*(1-c1)-object.rotationCenter.x*s1+object.position.y; return pointMake(c1*point.x-s1*point.y+offsetx, s1*point.x+c1*point.y+offsety); }
void InvestigationScene::questionWhere() { removeQuestionElements(); questionLabel->setText("Where was ... ?"); std::vector<Character *> characters = mystery->getCharacters(); std::vector<Character *>::iterator it; int i = 0; int px = 400; int py = 200; for (it = characters.begin(); it < characters.end(); ++it) { Character *character = (Character *) *it; std::string name = character->name; if (character == activeCharacter) { name = "You"; } Button *button = new Button(name.c_str(), font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(px, py)); button->setTag(301 + i); button->data = character; button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); py += 36; i++; } }
void InvestigationScene::questionWho() { removeQuestionElements(); questionLabel->setText("Who was in the ... ?"); std::vector<Room *> rooms = mystery->getRooms(); std::vector<Room *>::iterator it; int i = 0; int px = 300; int py = 200; for (it = rooms.begin(); it < rooms.end(); ++it) { Room *room = (Room *) *it; Button *button = new Button(room->name.c_str(), font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(px, py)); button->setTag(201 + i); button->data = room; button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); py += 36; if (i == 6) { py = 200; px += 192; } i++; } }
bool InvestigationScene::tick(double dt) { if (inputLocked) { return true; } int tx = playerSprite->getPosition().x / collision->getTileSize().width; int ty = playerSprite->getPosition().y / collision->getTileSize().height; std::vector<Room *> rooms = mystery->getRooms(); std::vector<Room *>::iterator itRooms; for (itRooms = rooms.begin(); itRooms < rooms.end(); ++itRooms) { Room *room = (Room *) *itRooms; if (rectContainsPoint(room->bounds, pointMake(tx, ty)) && room != currentRoom) { currentRoom = room; currentRoomLabel->setText(room->name.c_str()); } } float dx = 0; float dy = 0; bool isMoving = !pointEqualsIntegral(moving, pointMake(0, 0)); if (isMoving) { dx = moving.x * 200 * dt; dy = moving.y * 200 * dt; if (dy < 0) { moveDir = 0; } else if (dy > 0) { moveDir = 18; } else if (dx < 0) { moveDir = 9; } else if (dx > 0) { moveDir = 27; } curFrame += dt * 10; if (curFrame > 8) curFrame -= 8; } else { curFrame = 0; } bool collided = false; Rect colRect = rectMake(playerSprite->getPosition().x - 16, playerSprite->getPosition().y - 16, 32, 32); Rect colRectX = rectOffset(colRect, dx, 0); Rect colRectY = rectOffset(colRect, 0, dy); int tw = collision->getTileSize().width; int th = collision->getTileSize().height; int tpx = playerSprite->getPosition().x / collision->getTileSize().width; int tpy = playerSprite->getPosition().y / collision->getTileSize().height; for (int j = tpy - 2; j <= tpy + 2; j++) { for (int i = tpx - 2; i <= tpx + 2; i++) { if (i >= 0 && i < collision->getSize().width && j >= 0 && j < collision->getSize().height) { int gid = collision->getTileAt(i, j); if (gid != 0) { Rect tileRect = rectMake(i * tw, j * th, tw, th); if (rectIntersectsRect(colRectX, tileRect)) { dx = 0; collided = true; } if (rectIntersectsRect(colRectY, tileRect)) { dy = 0; collided = true; } } } } } actionButton->setVisible(false); actionButton->setEnabled(false); activeCharacter = NULL; activePOI = NULL; std::vector<Character *> characters = mystery->getCharacters(); std::vector<Character *>::iterator it; for (it = characters.begin(); it < characters.end(); ++it) { Character *character = (Character *) *it; std::string action; if (character->dead) { action.append("Look at "); } else { action.append("Talk to "); } action.append(character->name); Drawable *sprite = getByTag(character->tag); Rect otherColRect = rectMake(sprite->getPosition().x - 16, sprite->getPosition().y - 16, 32, 32); if (rectIntersectsRect(colRect, otherColRect)) { actionButton->setLabelText(action.c_str()); actionButton->setPosition(pointMake(sprite->getPosition().x, sprite->getPosition().y - 32)); actionButton->setVisible(true); actionButton->setEnabled(true); activeCharacter = character; } } if (currentRoom != NULL) { std::vector<POI *> POIList = currentRoom->pointsOfInterest; std::vector<POI *>::iterator itPOI; for (itPOI = POIList.begin(); itPOI < POIList.end(); ++itPOI) { POI *poi = (POI *) *itPOI; Rect tileRect = collision->getTileRect(poi->position.x, poi->position.y); tileRect = rectExpand(tileRect, 4, 4); if ((poi->interest == InterestContainerVisible || poi->interest == InterestContainerConceiled) && rectIntersectsRect(colRect, tileRect)) { std::string action = "Examine "; action.append(poi->shortDescription); actionButton->setLabelText(action.c_str()); actionButton->setPosition(rectMidPoint(tileRect)); actionButton->setVisible(true); actionButton->setEnabled(true); activePOI = poi; } } } playerSprite->setFrame(moveDir + (int)curFrame + (isMoving ? 1 : 0)); playerSprite->setPosition(pointOffset(playerSprite->getPosition(), dx, dy)); camera->setCenter(playerSprite->getPosition()); return !endScene; }
Mystery::Mystery(const char *file, unsigned int seed, short *collisionData, int mapWidth, int mapHeight) { srand(seed); corpseFound = false; ended = false; this->mapWidth = mapWidth; this->mapHeight = mapHeight; this->mapData = collisionData; Room *firstRoom = NULL; xmlDoc *doc = xmlReadFile(file, NULL, 0); xmlNode *root = xmlDocGetRootElement(doc); std::vector<xmlNode *> roomNodes = xmlGetChildrenForName(root, "room"); std::vector<xmlNode *>::iterator it; for (it = roomNodes.begin(); it < roomNodes.end(); ++it) { xmlNode *roomNode = (xmlNode *) *it; Room *room = new Room(); room->name = xmlGetAttribute(roomNode, "name"); int ox = atoi(xmlGetAttribute(roomNode, "boundsOriginX")); int oy = atoi(xmlGetAttribute(roomNode, "boundsOriginY")); int w = atoi(xmlGetAttribute(roomNode, "boundsWidth")); int h = atoi(xmlGetAttribute(roomNode, "boundsHeight")); room->bounds = rectMake(ox, oy, w, h); if (xmlGetAttribute(roomNode, "firstRoom") != NULL) { firstRoom = room; } std::vector<xmlNode *> POINodes = xmlGetChildrenForName(roomNode, "pointOfInterest"); std::vector<xmlNode *>::iterator itPOI; for (itPOI = POINodes.begin(); itPOI < POINodes.end(); itPOI++) { xmlNode *POInode = (xmlNode *) *itPOI; POI *poi = parsePOINode(POInode); room->pointsOfInterest.push_back(poi); } rooms.push_back(room); } std::vector<xmlNode *> weaponNodes = xmlGetChildrenForName(root, "weapon"); for (it = weaponNodes.begin(); it < weaponNodes.end(); ++it) { xmlNode *weaponNode = (xmlNode *) *it; POI *weapon = parsePOINode(weaponNode); POI *container; Room *room; do { int idx = rand() % rooms.size(); room = rooms[idx]; std::vector<POI *> containers = room->getPointsOfInterest(InterestContainerVisible, false); if (containers.size() > 0) { idx = rand() % containers.size(); container = containers[idx]; } else { container = NULL; } } while (container == NULL || container->contents != NULL); container->contents = weapon; weapon->position = container->visualPosition; if (container->interest == InterestContainerConceiled) { weapon->position = pointMake(-20, -20); } weapons.push_back(weapon); printf("%s is in the %s in the %s\n", weapon->description.c_str(), container->description.c_str(), room->name.c_str()); } crimeWeapon = NULL; std::vector<xmlNode *> charNodes = xmlGetChildrenForName(root, "character"); int i = 1; for (it = charNodes.begin(); it < charNodes.end(); ++it) { xmlNode *charNode = (xmlNode *) *it; Character *character = parseCharacterNode(charNode); character->tag = i; character->interest = (Interest) (rand() % InterestContainerVisible); character->position = pointMake(i + 35, 50); character->currentRoom = firstRoom; character->idle = true; character->currentTarget = NULL; character->murderTarget = NULL; character->carryingWeapon = NULL; character->conversationInterval = CONVERSATION_INTERVAL; character->dead = false; const char *strInt = NULL; switch (character->interest) { case InterestBooks: strInt = "books"; break; case InterestPottery: strInt = "pottery"; break; case InterestPaintings: strInt = "paintings"; break; default: break; } printf("%s interested in %s\n", character->name.c_str(), strInt); characters.push_back(character); i++; } int murderTargetIdx = rand() % characters.size(); victim = characters[murderTargetIdx]; printf("*** %s is the murder target! ***\n", victim->name.c_str()); do { int murdererIdx = rand() % characters.size(); murderer = characters[murdererIdx]; } while (murderer == victim); int weaponInterest = InterestWeaponCutting + rand() % 3; murderer->weaponInterest = (Interest) weaponInterest; murderer->timeBeforeSearchWeapon = rand() % MAX_DURATION_BEFORE_SEARCH_WEAPON + MIN_DURATION_BEFORE_SEARCH_WEAPON; murderer->timeBeforeTryMurder = rand() % MAX_DURATION_BEFORE_TRY_MURDER + MIN_DURATION_BEFORE_TRY_MURDER; printf("*** %s is the murderer! ***\n", murderer->name.c_str()); murderer->murderTarget = victim; time = 0; }
State collideObjects(PhysicsObject* a, PhysicsObject* b){ State state; state.deltaAngVel = 0; state.deltaPosition = pointMake(0, 0); state.deltaVel = pointMake(0, 0); CollisionPair pairs[2*PHYSICS_OBJECT_MAXIMUM_POINTS]; if(!coarseCollision(a, b)){ return state; } //if a coarse collision happened, we will search for a refined one in each of A's edges. //in this step we try to find every point where B has hitted A and A has hitted B int Acurrent, Anext, Abefore, Bcurrent, Bnext, pairCount=0; //first case--------------------------------------------------------------------------- /* PA1 PA3 \ / \ / PB2---------PB1 \/ PA2 V=A --=B */ for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a); Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a); Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a); Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) { /*for each edge of B, we will find if any of the edges are hitted by both edges defined before, if thats the case, then A hitted B on that point If both edges of A hitted more than one edge of B, we will keep the highest depth*/ Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1; Point PB1 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b); Point PB2 = worldPosition(b->format.polygonInfo.points[Bnext], *b); Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y); Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossBI1 = B.x*I1.y-B.y*I1.x; float crossBI2 = B.x*I2.y-B.y*I2.x; float crossAI1 = A1.x*I1.y-A1.y*I1.x; float crossAI2 = A2.x*I2.y-A2.y*I2.x; float crossBA1 = B.x*A1.y-B.y*A1.x; float crossBA2 = B.x*A2.y-B.y*A2.x; crossBA1=crossBA1==0?0.0001:crossBA1; crossBA2=crossBA2==0?0.0001:crossBA2; float t1 = crossAI1/crossBA1; float w1 = crossBI1/crossBA1; float t2 = crossAI2/crossBA2; float w2 = crossBI2/crossBA2; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5); float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y; depth = -depth; if(Fabs(depth)>Fabs(pairs[pairCount].depth)){ pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; } } } if(Fabs(pairs[pairCount].depth)>0){ pairCount++; } } //second case--------------------------------------------------------------------------- /* PA1 PA3 \ / \ / PB2---------PB1 \/ PA2 V=B --=A */ //Although we did not change the names, A variables now refers to B while B variables refer to A for (Acurrent=0; Acurrent<b->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==b->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?b->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(b->format.polygonInfo.points[Abefore],*b); Point PA2 = worldPosition(b->format.polygonInfo.points[Acurrent],*b); Point PA3 = worldPosition(b->format.polygonInfo.points[Anext],*b); Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<a->format.polygonInfo.count; Bcurrent++) { /*for each edge of A, we will find if any of the edges are hitted by both edges defined before, if thats the case, then A hitted B on that point If both edges of B hitted more than one edge of A, we will keep the highest depth*/ Bnext = Bcurrent==a->format.polygonInfo.count-1?0:Bcurrent+1; Point PB1 = worldPosition(a->format.polygonInfo.points[Bcurrent], *a); Point PB2 = worldPosition(a->format.polygonInfo.points[Bnext], *a); Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y); Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossBI1 = B.x*I1.y-B.y*I1.x; float crossBI2 = B.x*I2.y-B.y*I2.x; float crossAI1 = A1.x*I1.y-A1.y*I1.x; float crossAI2 = A2.x*I2.y-A2.y*I2.x; float crossBA1 = B.x*A1.y-B.y*A1.x; float crossBA2 = B.x*A2.y-B.y*A2.x; crossBA1=crossBA1==0?0.0001:crossBA1; crossBA2=crossBA2==0?0.0001:crossBA2; float t1 = crossAI1/crossBA1; float w1 = crossBI1/crossBA1; float t2 = crossAI2/crossBA2; float w2 = crossBI2/crossBA2; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5); float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y; if(Fabs(depth)>Fabs(pairs[pairCount].depth)){ pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; } } } if(Fabs(pairs[pairCount].depth)>0){ pairCount++; } } //third case--------------------------------------------------------------------------- /* PA1 PA3 \ PB2 / \ /\ / X X / \/ \ / PA2 \ PB3 PB1 V=A /\=B */ int Bbefore; for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a); Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a); Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a); Vector A12 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A23 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) { /*for each pair of edge of B, we will find if any of the edges are hitted as shown above*/ Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1; Bbefore = Bcurrent==0?b->format.polygonInfo.count-1:Bcurrent-1; Point PB1 = worldPosition(b->format.polygonInfo.points[Bbefore], *b); Point PB2 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b); Point PB3 = worldPosition(b->format.polygonInfo.points[Bnext], *b); Vector B12 = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector B23 = pointMake(PB3.x-PB2.x, PB3.y-PB2.y); Vector IA12B23 = pointMake(PB2.x-PA1.x, PB2.y-PA1.y); Vector IA23B12 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossB12I = B12.x*IA23B12.y-B12.y*IA23B12.x; float crossB23I = B23.x*IA12B23.y-B23.y*IA12B23.x; float crossA12I = A12.x*IA12B23.y-A12.y*IA12B23.x; float crossA23I = A23.x*IA23B12.y-A23.y*IA23B12.x; float crossB12A23 = B12.x*A23.y-B12.y*A23.x; float crossB23A12 = B23.x*A12.y-B23.y*A12.x; crossB23A12=crossB23A12==0?0.0001:crossB23A12; crossB12A23=crossB12A23==0?0.0001:crossB12A23; float t1 = crossA12I/crossB23A12; float w1 = crossB23I/crossB23A12; float t2 = crossA23I/crossB12A23; float w2 = crossB12I/crossB12A23; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Point collision1 = pointMake((PA1.x+w1*A12.x), (PA1.y+w1*A12.y)); Point collision2 = pointMake((PA2.x+w2*A23.x), (PA2.y+w2*A23.y)); Vector c12 = pointMake(collision2.x-collision1.x, collision2.y-collision1.y); Vector normal = rotateVector(c12, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake((collision1.x+collision2.x)*0.5, (collision1.y+collision2.y)*0.5); float depth = (PA2.x-PB2.x)*normal.x+(PA2.y-PB2.y)*normal.y; depth = -depth; pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; pairCount++; } } } int currentCollision; //solves the physics part ot the collision for each collision that has happened for (currentCollision =0; currentCollision<pairCount; currentCollision++) { State st = physicsResolution(a,b,pairs[currentCollision]); state.deltaAngVel += st.deltaAngVel; state.deltaPosition=pointMake(st.deltaPosition.x+state.deltaPosition.x, st.deltaPosition.y+state.deltaPosition.y); state.deltaVel=pointMake(st.deltaVel.x+state.deltaVel.x, st.deltaVel.y+state.deltaVel.y); } state.deltaAngVel += a->angularVelocity; state.deltaVel = pointMake(a->linearVelocity.x+state.deltaVel.x, a->linearVelocity.y+state.deltaVel.y); state.deltaPosition = pointMake(a->position.x+state.deltaPosition.x, a->position.y+state.deltaPosition.y); return state; }
void Mystery::step() { if (ended) { return; } AStarSearch<MapSearchNode> astarsearch; std::vector<Character *>::iterator itChars; for (itChars = characters.begin(); itChars < characters.end(); ++itChars) { Character *character = (Character *) *itChars; if (character->dead) { continue; } if (character->idle) { int targetX = 0; int targetY = 0; // Any dead people in the same room? Character *corpseInRoom = NULL; std::vector<Character *>::iterator itOthers; for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) { Character *other = (Character *) *itOthers; if (other->currentRoom == character->currentRoom && other->dead) { corpseInRoom = other; } } // Does the character want to chat? bool wantsToTalk = rand() % 2 == 0; if (corpseFound && (character->murderTarget == NULL || (character->murderTarget != NULL && character->carryingWeapon == NULL))) { targetX = victim->position.x; targetY = victim->position.y; character->currentTarget = NULL; } else if (corpseInRoom != NULL && character->murderTarget == NULL) { // Go look at the corpse targetX = corpseInRoom->position.x; targetY = corpseInRoom->position.y; character->currentTarget = NULL; } else if (character->murderTarget != NULL && !character->murderTarget->dead && character->carryingWeapon != NULL && character->timeBeforeTryMurder == 0) { // Murderer goes after its target if he has a weapon and the target is // not dead yet targetX = character->murderTarget->position.x; targetY = character->murderTarget->position.y; character->currentTarget = NULL; } else if (wantsToTalk) { // Goes after another character int idxOption = rand() % characters.size(); Character *option = characters[idxOption]; targetX = option->position.x; targetY = option->position.y; character->currentTarget = NULL; } else { // Looks for a POI matching the characters interest in any room Room *room; std::vector<POI *> points; bool notSearchedOnly = false; Interest interest = character->interest; if (character->murderTarget != NULL && ((character->carryingWeapon == NULL && character->timeBeforeSearchWeapon == 0 && !character->murderTarget->dead) || (character->carryingWeapon != NULL && character->murderTarget->dead))) { // If the character is a murderer and is looking for a weapon, or // if he/she already killed the target, he/she goes to a container // to grab/hide the weapon if (character->carryingWeapon != NULL) { interest = InterestContainerConceiled; } else { interest = InterestContainerVisible; } // If he has no weapon, searches only the containers not // searched yet notSearchedOnly = character->carryingWeapon == NULL; } else { // There's a chance the character wants to see a container int chance = rand() % 100; if (chance < 25) { interest = InterestContainerVisible; } else if (chance < 50) { interest = InterestContainerConceiled; } } do { int roomIdx = rand() % rooms.size(); room = rooms[roomIdx]; points = room->getPointsOfInterest(interest, notSearchedOnly); } while (points.size() == 0); // Goes after an interesting random POI int idx = rand() % points.size(); POI *poi = points[idx]; character->currentTarget = poi; targetX = poi->position.x; targetY = poi->position.y; } character->idle = false; MapSearchNode nodeStart; nodeStart.x = (int) character->position.x; nodeStart.y = (int) character->position.y; nodeStart.mystery = this; MapSearchNode nodeEnd; nodeEnd.x = targetX; nodeEnd.y = targetY; nodeEnd.mystery = this; astarsearch.SetStartAndGoalStates(nodeStart, nodeEnd); unsigned int SearchState; do { SearchState = astarsearch.SearchStep(); } while( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING ); // Found a path to the target if (SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED) { MapSearchNode *node = astarsearch.GetSolutionStart(); while (node) { // Builds the steps for the character to reach its target Step *step = new Step(); step->position = pointMake(node->x, node->y); step->conversationWith = NULL; step->type = StepTypeWalk; step->duration = STEP_DURATION; if (character->currentTarget != NULL && pointEqualsIntegral(step->position, character->currentTarget->position)) { Step *step = new Step(); step->position = pointMake(node->x, node->y); step->conversationWith = NULL; step->type = StepTypeStartInteractPOI; step->duration = 1; character->addStep(step); step = new Step(); step->position = pointMake(node->x, node->y); step->conversationWith = NULL; step->type = StepTypeInteractPOI; step->duration = rand() % MAX_DURATION_POI_INTERACTION + MIN_DURATION_POI_INTERACTION; character->addStep(step); step = new Step(); step->position = pointMake(node->x, node->y); step->conversationWith = NULL; step->type = StepTypeEndInteractPOI; step->duration = 1; character->addStep(step); } else { Step *step = new Step(); step->position = pointMake(node->x, node->y); step->conversationWith = NULL; step->type = StepTypeWalk; step->duration = STEP_DURATION; character->addStep(step); } node = astarsearch.GetSolutionNext(); } astarsearch.FreeSolutionNodes(); } } else { // Updates the character's path by 1 unit of time character->updatePath(); if (!character->isHavingConversation() && character->conversationInterval > 0) { character->conversationInterval--; } if (character->timeBeforeSearchWeapon > 0) { character->timeBeforeSearchWeapon--; } else { if (character->timeBeforeTryMurder > 0 && character->carryingWeapon != NULL) { character->timeBeforeTryMurder--; } } Room *currentRoom = NULL; // Determines if the character entered or left a room std::vector<Room *>::iterator itRooms; for (itRooms = rooms.begin(); itRooms < rooms.end(); ++itRooms) { Room *room = (Room *) *itRooms; if (rectContainsPoint(room->bounds, character->position)) { currentRoom = room; } } if (currentRoom != character->currentRoom) { if (character->currentRoom != NULL) { printf("%s left %s\n", character->name.c_str(), character->currentRoom->name.c_str()); registerEventForAllInRoom(EventLeftRoom, character, NULL, character->currentRoom, NULL, NULL); } character->currentRoom = currentRoom; if (character->currentRoom != NULL) { printf("%s entered %s\n", character->name.c_str(), character->currentRoom->name.c_str()); registerEventForAllInRoom(EventEnteredRoom, character, NULL, character->currentRoom, NULL, NULL); if (character != murderer) { // Register any weapons saw before but missing std::vector<Memory *>::iterator it; std::vector<Memory *> memories = character->getMemories(); std::vector<Memory *> considered; for (it = memories.begin(); it < memories.end(); ++it) { Memory *memory = (Memory *) *it; if (memory->event == EventSawWeapon && memory->where == character->currentRoom && memory->when < time && !pointEqualsIntegral(memory->whatInside->position, memory->what->visualPosition)) { std::vector<Memory *>::iterator itOther; bool found = false; for (itOther = considered.begin(); itOther < considered.end(); ++itOther) { Memory *other = (Memory *) *itOther; if (other->where == memory->where && other->whatInside == memory->whatInside) { found = true; break; } } if (!found) { registerEventFor(character, EventWeaponMissing, NULL, NULL, character->currentRoom, memory->what, memory->whatInside); considered.push_back(memory); } } } } // Register visible weapons the character sees in the room std::vector<POI *>::iterator itPOI; for (itPOI = character->currentRoom->pointsOfInterest.begin(); itPOI < character->currentRoom->pointsOfInterest.end(); ++itPOI) { POI *poi = (POI *) *itPOI; if (poi->interest == InterestContainerVisible && poi->contents != NULL && poi->contents->isWeapon()) { registerEventFor(character, EventSawWeapon, NULL, NULL, character->currentRoom, poi, poi->contents); } } std::vector<Character *>::iterator itOthers; for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) { Character *other = (Character *) *itOthers; if (other != character && other->currentRoom == character->currentRoom) { registerEventFor(character, EventWasInRoom, other, NULL, character->currentRoom, NULL, NULL); // Register others having conversations if (other->isHavingConversation()) { Character *another = other->getCurrentStep()->conversationWith; registerEventFor(character, EventWasHavingConversation, other, another, character->currentRoom, NULL, NULL); } // Register others interacting with POIs if (other->isInteractingWithPOI()) { registerEventFor(character, EventWasInteractingPOI, other, NULL, character->currentRoom, other->currentTarget, NULL); } } } } } if (character->getCurrentStep() != NULL) { Character *another; switch (character->getCurrentStep()->type) { case StepTypeStartInteractPOI: registerEventForAllInRoom(EventStartInteractPOI, character, NULL, character->currentRoom, character->currentTarget, NULL); break; case StepTypeEndInteractPOI: another = character->getCurrentStep()->conversationWith; registerEventForAllInRoom(EventEndInteractPOI, character, another, character->currentRoom, character->currentTarget, NULL); break; case StepTypeEndConversation: another = character->getCurrentStep()->conversationWith; registerEventForAllInRoom(EventEndConversation, character, another, character->currentRoom, NULL, NULL); break; default: break; } } bool aloneInRoom = true; bool aloneInRoomWithVictim = true; bool allNearCorpse = pointEqualsIntegral(character->position, victim->position); std::vector<Character *>::iterator itOthers; for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) { Character *other = (Character *) *itOthers; allNearCorpse = allNearCorpse && pointEqualsIntegral(other->position, victim->position); if (other != character) { if (character->currentRoom == other->currentRoom) { aloneInRoom = false; if (other != character->murderTarget) { aloneInRoomWithVictim = false; } } if (victim->dead && other == victim && pointEqualsIntegral(character->position, other->position) && !corpseFound) { printf("*** %s found %s's body in the %s ***\n", character->name.c_str(), victim->name.c_str(), character->currentRoom->name.c_str()); corpseFound = true; corpseFoundTime = time; corpseFoundRoom = character->currentRoom; character->clearPath(); std::vector<Character *>::iterator itAll; for (itAll = characters.begin(); itAll < characters.end(); ++itAll) { registerEventFor(*itAll, EventFoundBody, character, NULL, corpseFoundRoom, NULL, NULL); } } // Looks for: // - adjacent characters // - one of them without a POI in mind // - both not already in a conversation // - both conversation intervals expired if (pointAdjacentIntegral(character->position, other->position) && (character->currentTarget == NULL || other->currentTarget == NULL) && (!character->isHavingConversation() && !other->isHavingConversation()) && (character->conversationInterval == 0 && other->conversationInterval == 0) && !corpseFound) { int duration = rand() % MAX_DURATION_CONVERSATION + MIN_DURATION_CONVERSATION; // If both characters have matching interests, the talk is longer if (character->interest == other->interest) { duration *= CONVERSATION_INTEREST_FACTOR; } character->clearPath(); other->clearPath(); Step *step = new Step(); step->position = character->position; step->duration = duration; step->conversationWith = other; step->type = StepTypeConversation; character->addStep(step); step = new Step(); step->position = character->position; step->duration = 1; step->conversationWith = other; step->type = StepTypeEndConversation; character->addStep(step); step = new Step(); step->position = other->position; step->duration = duration; step->conversationWith = character; step->type = StepTypeConversation; other->addStep(step); step = new Step(); step->position = other->position; step->duration = 1; step->conversationWith = character; step->type = StepTypeEndConversation; other->addStep(step); character->conversationInterval = CONVERSATION_INTERVAL; other->conversationInterval = CONVERSATION_INTERVAL; registerEventForAllInRoom(EventStartConversation, character, other, character->currentRoom, NULL, NULL); registerEventForAllInRoom(EventStartConversation, other, character, character->currentRoom, NULL, NULL); printf("%s and %s are having a conversation\n", character->name.c_str(), other->name.c_str()); } } } if (allNearCorpse && corpseFound) { ended = true; printf("*** Mystery finished ***\n"); } // Murderer-specific actions if (character->murderTarget != NULL) { // Grabs a weapon if: // - interval elapsed // - not carrying a weapon already // - murder target is not dead // - has a target POI // - reached the target POI // - POI has contents // - POI's content is a weapon matching interest // - alone in the room if (character->timeBeforeSearchWeapon == 0 && character->carryingWeapon == NULL && !victim->dead && character->currentTarget != NULL && pointEqualsIntegral(character->position, character->currentTarget->position) && character->currentTarget->contents != NULL && character->currentTarget->contents->interest == character->weaponInterest && aloneInRoom) { character->carryingWeapon = character->currentTarget->contents; character->carryingWeapon->position = pointMake(-20, -20); character->currentTarget->contents = NULL; printf("*** %s got a %s! ***\n", character->name.c_str(), character->carryingWeapon->description.c_str()); } // Kills the victim if: // - interval elapsed // - already got a weapon // - near the victim // - murder target is not dead // - alone in the room with victim if (character->timeBeforeTryMurder == 0 && character->carryingWeapon != NULL && pointAdjacentIntegral(character->position, victim->position) && !victim->dead && aloneInRoomWithVictim) { printf("*** %s murdered %s! ***\n", character->name.c_str(), victim->name.c_str()); victim->dead = true; crimeWeapon = character->carryingWeapon; character->clearPath(); // Murderer will lie int idx = rand() % character->currentRoom->pointsOfInterest.size(); POI *poi = character->currentRoom->pointsOfInterest[idx]; registerEventFor(character, EventStartInteractPOI, character, NULL, character->currentRoom, poi, NULL); registerEventFor(character, EventEndInteractPOI, character, NULL, character->currentRoom, poi, NULL); } // Hides the weapon if: // - carrying a weapon // - murder target is dead // - has a target POI // - reached the target POI // - POI has no contents // - alone in the room if (character->carryingWeapon != NULL && victim->dead && character->currentTarget != NULL && pointEqualsIntegral(character->position, character->currentTarget->position) && character->currentTarget->contents == NULL && aloneInRoom) { character->carryingWeapon->position = character->currentTarget->visualPosition; if (character->currentTarget->interest == InterestContainerConceiled) { character->carryingWeapon->position = pointMake(-20, -20); } character->currentTarget->contents = character->carryingWeapon; character->carryingWeapon = NULL; printf("*** %s hid the %s in the %s, in the %s! ***\n", character->name.c_str(), character->currentTarget->contents->description.c_str(), character->currentTarget->description.c_str(), currentRoom->name.c_str()); } } } } astarsearch.EnsureMemoryFreed(); time++; }
void InvestigationScene::questionStart() { inputLocked = true; currentFilter.where = NULL; currentFilter.who = NULL; actionButton->setEnabled(false); actionButton->setVisible(false); cancelQuestionButton->setEnabled(true); cancelQuestionButton->setVisible(true); removeQuestionElements(); std::string question = "Select a question to ask "; question.append(activeCharacter->name); questionLabel->setText(question.c_str()); questionLabel->setVisible(true); bkgQuestion->setVisible(true); Button *button = new Button("Who was in the...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(400, 200)); button->setTag(101); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); button = new Button("Where was...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(400, 260)); button->setTag(102); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); button = new Button("Anything strange...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(400, 320)); button->setTag(103); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); button = new Button("You are the murderer!", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); button->setZOrder(504); button->setAnchorPoint(pointMake(0.5, 0.5)); button->setPosition(pointMake(400, 380)); button->setTag(104); button->setHandler(this); addToDisplayList(button); questionElements.push_back(button); }
void InvestigationScene::setupScene() { std::vector<Point> positions; positions.push_back(pointMake(32, 48)); positions.push_back(pointMake(34, 48)); positions.push_back(pointMake(36, 48)); positions.push_back(pointMake(38, 48)); positions.push_back(pointMake(40, 49)); positions.push_back(pointMake(40, 51)); positions.push_back(pointMake(40, 53)); positions.push_back(pointMake(30, 49)); positions.push_back(pointMake(30, 51)); positions.push_back(pointMake(32, 52)); const char *fontFile = "res/AveriaSerif-Regular.ttf"; font = al_load_font(fontFile, 18, 0); if (!font) { Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile); } fontBig = al_load_font(fontFile, 26, 0); if (!fontBig) { Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile); } searchSound = al_load_sample("res/search.wav"); if (!searchSound) { Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/search.wav"); } clickSound = al_load_sample("res/click.wav"); if (!clickSound) { Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/click.wav"); } std::vector<TilemapLayer *> layers = TilemapLayer::parseTMXFile("res/mansion.tmx"); std::vector<TilemapLayer *>::iterator it; TilemapLayer *firstLayer = layers[0]; camera = new Camera(800, 600, firstLayer->getBoundsSize().width, firstLayer->getBoundsSize().height); for (it = layers.begin(); it < layers.end(); ++it) { TilemapLayer *layer = (TilemapLayer *) *it; layer->setCamera(camera); addToDisplayList(layer); if (layer->isCollision()) { collision = layer; } } playerSprite = new Spritesheet("res/professor_walk_cycle_no_hat.png", 64, 64); playerSprite->setTag(PLAYER_SPRITE_TAG); playerSprite->setCamera(camera); playerSprite->setPosition(pointMake(35 * 32, 50 * 32)); playerSprite->setAnchorPoint(pointMake(0.5, 0.9)); playerSprite->setAutoZOrder(true); addToDisplayList(playerSprite); mysterySeed = 0; do { mysteryTime = 0; mysterySeed = time(0); mystery = new Mystery("res/mansion.xml", mysterySeed, collision->getData(), collision->getSize().width, collision->getSize().height); while (!mystery->ended && mysteryTime < MAX_MYSTERY_DURATION) { mystery->step(); mysteryTime++; } if (!mystery->ended) { delete mystery; mystery = NULL; } } while (mystery == NULL); printf("Case seed: %d Total duration: %ld %s\n", mysterySeed, mysteryTime, timeToString(mysteryTime, true).c_str()); std::vector<Character *> characters = mystery->getCharacters(); std::vector<Character *>::iterator itChars; int i = 0; for (itChars = characters.begin(); itChars < characters.end(); ++itChars) { Character *character = (Character *) *itChars; int frame = i * 2; if (!character->dead) { int idx = rand() % positions.size(); Point pos = positions[idx]; character->position = pos; positions.erase(positions.begin() + idx); } else { frame++; } Spritesheet *sprite = new Spritesheet("res/characters.png", 64, 64); sprite->setTag(character->tag); sprite->setCamera(camera); sprite->setAnchorPoint(pointMake(0.5, 0.9)); sprite->setAutoZOrder(true); sprite->setFrame(frame); Rect tileRect = collision->getTileRect(character->position.x, character->position.y); sprite->setPosition(rectMidPoint(tileRect)); addToDisplayList(sprite); i++; } std::vector<POI *>::iterator itWeapons; i = 0; for (itWeapons = mystery->weapons.begin(); itWeapons < mystery->weapons.end(); ++itWeapons) { POI *weapon = (POI *) *itWeapons; Spritesheet *sprite = new Spritesheet("res/weapons.png", 32, 32); sprite->setTag(i + 20); sprite->setFrame(i); sprite->setCamera(camera); sprite->setAnchorPoint(pointMake(0.5, 0.5)); sprite->setZOrder(400); Rect tileRect = collision->getTileRect(weapon->position.x, weapon->position.y); sprite->setPosition(rectMidPoint(tileRect)); addToDisplayList(sprite); i++; } actionButton = new Button("action", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png"); actionButton->setZOrder(500); actionButton->setAnchorPoint(pointMake(0.5, 1)); actionButton->setPosition(pointMake(400, 400)); actionButton->setCamera(camera); actionButton->setHandler(this); addToDisplayList(actionButton); Spritesheet *bkgRoomLabel = new Spritesheet("res/bkg_room_name.png"); bkgRoomLabel->setAnchorPoint(pointMake(0.5, 0.5)); bkgRoomLabel->setPosition(pointMake(400, 40)); bkgRoomLabel->setZOrder(501); addToDisplayList(bkgRoomLabel); currentRoomLabel = new Label("room", font, al_map_rgb(0, 0, 0)); currentRoomLabel->setAnchorPoint(pointMake(0.5, 0.5)); currentRoomLabel->setPosition(bkgRoomLabel->getPosition()); currentRoomLabel->setZOrder(502); addToDisplayList(currentRoomLabel); Spritesheet *bkgWeaponLabel = new Spritesheet("res/bkg_room_name.png"); bkgWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5)); bkgWeaponLabel->setPosition(pointMake(720, 40)); bkgWeaponLabel->setZOrder(501); addToDisplayList(bkgWeaponLabel); crimeWeaponLabel = new Label("No weapon", font, al_map_rgb(0, 0, 0)); crimeWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5)); crimeWeaponLabel->setPosition(bkgWeaponLabel->getPosition()); crimeWeaponLabel->setZOrder(502); addToDisplayList(crimeWeaponLabel); Spritesheet *bkgAccusationLabel = new Spritesheet("res/bkg_room_name.png"); bkgAccusationLabel->setAnchorPoint(pointMake(0.5, 0.5)); bkgAccusationLabel->setPosition(pointMake(80, 40)); bkgAccusationLabel->setZOrder(501); addToDisplayList(bkgAccusationLabel); char buf[100]; sprintf(buf, "%d accusations left", MAX_ACCUSATIONS); accusationsLabel = new Label(buf, font, al_map_rgb(0, 0, 0), 120); accusationsLabel->setAnchorPoint(pointMake(0.5, 0.5)); accusationsLabel->setPosition(bkgAccusationLabel->getPosition()); accusationsLabel->setZOrder(502); addToDisplayList(accusationsLabel); bkgQuestion = new Spritesheet("res/bkg_question.png"); bkgQuestion->setAnchorPoint(pointMake(0.5, 0.5)); bkgQuestion->setPosition(pointMake(400, 300)); bkgQuestion->setZOrder(503); bkgQuestion->setVisible(false); addToDisplayList(bkgQuestion); questionLabel = new Label("question", font, al_map_rgb(0, 0, 0), 350); questionLabel->setAnchorPoint(pointMake(0.5, 0.5)); questionLabel->setPosition(pointMake(400, 120)); questionLabel->setZOrder(504); questionLabel->setVisible(false); addToDisplayList(questionLabel); whenLabel = new Label("00:00 and 00:15", fontBig, al_map_rgb(0, 0, 0)); whenLabel->setAnchorPoint(pointMake(0.5, 0.5)); whenLabel->setPosition(pointMake(400, 300)); whenLabel->setZOrder(504); whenLabel->setVisible(false); addToDisplayList(whenLabel); askQuestionButton = new Button("Ask", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png"); askQuestionButton->setZOrder(504); askQuestionButton->setAnchorPoint(pointMake(0.5, 0.5)); askQuestionButton->setPosition(pointMake(480, 490)); askQuestionButton->setHandler(this); askQuestionButton->setVisible(false); askQuestionButton->setEnabled(false); addToDisplayList(askQuestionButton); cancelQuestionButton = new Button("Cancel", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png"); cancelQuestionButton->setZOrder(504); cancelQuestionButton->setAnchorPoint(pointMake(0.5, 0.5)); cancelQuestionButton->setPosition(pointMake(300, 490)); cancelQuestionButton->setHandler(this); cancelQuestionButton->setVisible(false); cancelQuestionButton->setEnabled(false); addToDisplayList(cancelQuestionButton); bkgSpeech = new Spritesheet("res/speech.png"); bkgSpeech->setAnchorPoint(pointMake(0.35, 1)); bkgSpeech->setCamera(camera); bkgSpeech->setZOrder(503); bkgSpeech->setVisible(false); addToDisplayList(bkgSpeech); speechLabel = new Label("speech", font, al_map_rgb(0, 0, 0), 280); speechLabel->setAnchorPoint(pointMake(0.5, 0.5)); speechLabel->setCamera(camera); speechLabel->setZOrder(504); speechLabel->setVisible(false); addToDisplayList(speechLabel); speechCountLabel = new Label("1/1", font, al_map_rgb(0, 0, 0)); speechCountLabel->setAnchorPoint(pointMake(1, 0.5)); speechCountLabel->setCamera(camera); speechCountLabel->setZOrder(504); speechCountLabel->setVisible(false); addToDisplayList(speechCountLabel); speechButton = new Button(bkgSpeech->getFrameSize()); speechButton->setAnchorPoint(bkgSpeech->getAnchorPoint()); speechButton->setCamera(camera); speechButton->setZOrder(504); speechButton->setEnabled(false); speechButton->setHandler(this); addToDisplayList(speechButton); camera->setCenter(playerSprite->getPosition()); activeCharacter = NULL; activePOI = NULL; currentRoom = NULL; crimeWeapon = NULL; accusationsLeft = MAX_ACCUSATIONS; questionsAsked = 0; moving = pointMake(0, 0); moveDir = 0; curFrame = 0; endScene = false; debug = false; currentFilter.timeStart = 0; currentFilter.timeEnd = QUESTION_INTERVAL; std::string msg; msg.append(mystery->victim->name); msg.append("'s body was found around "); msg.append(timeToString(mystery->corpseFoundTime + START_TIME, false)); msg.append(" in the "); msg.append(mystery->corpseFoundRoom->name); msg.append("."); ModalDialog *dialog = new ModalDialog(msg.c_str(), font, "OK", NULL); dialog->setHandler(this); dialog->showInScene(this, 1000); music = al_load_audio_stream("res/mystery.ogg", 4, 2048); al_set_audio_stream_playmode(music, ALLEGRO_PLAYMODE_LOOP); al_attach_audio_stream_to_mixer(music, al_get_default_mixer()); inDialogue = false; inputLocked = true; investigationStartTime = time(0); }
int main(){ //EPIPHANY VARIABLES e_platform_t platform; e_epiphany_t dev; //DEBUG VARIABLES unsigned read_buffer[RAM_SIZE/4]; unsigned read_data; unsigned addr; int i,j,k; char filename[9] = "logs.txt"; FILE* file = fopen(filename,"w"); //TIME VARIABLEs struct timeval initTime, endTime; long int timediff; //initialize the cores e_init(NULL); e_get_platform_info(&platform); clearMemory(); e_open(&dev, 0,0,4,4); e_reset_group(&dev); //initialize physics objects and Physics Engine PhysicsEngine engine; engine.count = 0; PhysicsObject obj; obj.type = OBJECT_TYPE_POLYGON; addPointToObject(&obj,pointMake(0,0)); addPointToObject(&obj,pointMake(2,-2)); addPointToObject(&obj,pointMake(4,0)); addPointToObject(&obj,pointMake(2,2)); obj.rotationCenter = pointMake(2,0); obj.position = pointMake(0.5,0.99); obj.rotation = 0; obj.inverseInertia = 1; obj.inverseMass = 1; obj.linearVelocity = pointMake(0,-1); obj.angularVelocity = 0; addObject(&engine,obj); //------- PhysicsObject obj2; obj2.type = OBJECT_TYPE_POLYGON; addPointToObject(&obj2,pointMake(0,-1)); addPointToObject(&obj2,pointMake(2,-4)); addPointToObject(&obj2,pointMake(4,-1)); obj2.rotationCenter = pointMake(2,-2); obj2.position = pointMake(0,0); obj2.rotation = 0; obj2.inverseInertia = 1; obj2.inverseMass = 1; obj2.linearVelocity = pointMake(0,0); obj2.angularVelocity = 0; addObject(&engine,obj2); //calculate minimun circles minimunCircles(&engine); printf("%x\n",sizeof(PhysicsObject)); distributeObjectsToCores(&engine,&dev); printf("frame->%x\n",sizeof(Frame)); char start = 1; for(i=0;i<4;i++){ for(j=0;j<4;j++){ e_load("epiphanyProgram.srec",&dev,i,j,E_TRUE); e_write(&dev,i,j,COMMADDRESS_READY, &start,sizeof(char)); //usleep(20000); } } //usleep(3000000); long long int TotalTime; gettimeofday(&initTime,NULL); Frame frm1, frm2; while(1){ e_read(&dev,0,0,COMMADDRESS_FRAMES,&frm1,sizeof(Frame)); e_read(&dev,0,1,COMMADDRESS_FRAMES,&frm2,sizeof(Frame)); printf("Frame---%d\nvelocity(%g,%g)\nposition(%g,%g)\nangVel%g\n",frm1.frameNumber,frm1.velocity.x,frm1.velocity.y,frm1.position.x,frm1.position.y,frm1.angVelocity); printf("Frame---%d\nvelocity(%g,%g)\nposition(%g,%g)\nangVel%g\n",frm1.frameNumber,frm2.velocity.x,frm2.velocity.y,frm2.position.x,frm2.position.y,frm2.angVelocity); gettimeofday(&endTime, NULL); TotalTime =endTime.tv_sec*1000+endTime.tv_usec/1000-initTime.tv_usec/1000-initTime.tv_sec*1000; float fps= frm1.frameNumber; fps = fps*1000/(float)TotalTime; printf("FPS=%g\n",fps); if(frm1.frameNumber >=20 && frm2.frameNumber >= 20){ break; } } gettimeofday(&endTime, NULL); TotalTime =endTime.tv_sec*1000+endTime.tv_usec/1000-initTime.tv_usec/1000-initTime.tv_sec*1000; printf("TotalTime = %lld\n", TotalTime); //-------------------------DUMP MEMORY ----------------------------- //read all memory e_open(&dev, 0, 0, platform.rows, platform.cols); fprintf(file,"(ROW,COL) ADDRESS DATA\n"); fprintf(file,"-----------------------------\n"); for (i=0; i<(platform.rows); i++) { for (j=0; j<(platform.cols); j++) { for(k=0;k<RAM_SIZE/4;k++){ addr=4*k; e_read(&dev, i, j, addr, &read_data, sizeof(int)); read_buffer[k]=read_data; } for(k=0;k<RAM_SIZE/4;k++){ fprintf(file,"(%2d,%2d) 0x%08x 0x%08x\n",i,j,k*4,read_buffer[k]); } } } fclose(file); e_close(&dev); e_finalize(); return EXIT_SUCCESS; }
void InvestigationScene::dialogueStart() { inDialogue = true; questionsAsked++; speechLines.clear(); std::vector<std::string> memories = activeCharacter->getFormattedMemories(currentFilter); if (memories.size() > 0) { speechLines.insert(speechLines.end(), memories.begin(), memories.end()); } else { if (currentFilter.who == NULL) { if (currentFilter.strange) { speechLines.push_back(std::string("I don't remember anything strange happening there around that time.")); } else { speechLines.push_back(std::string("I don't remember seeing anyone there around that time.")); } } else if (currentFilter.where == NULL) { std::string res = "I don't remember seeing "; if (currentFilter.who->male) { res.append("him "); } else { res.append("her "); } res.append("around that time."); speechLines.push_back(res); } } speechIdx = 0; Drawable *sprite = getByTag(activeCharacter->tag); bkgSpeech->setVisible(true); bkgSpeech->setPosition(pointMake(sprite->getPosition().x, sprite->getPosition().y - 20)); speechLabel->setText(speechLines[speechIdx].c_str()); speechLabel->setVisible(true); speechLabel->setPosition(pointOffset(bkgSpeech->getPosition(), 54, -175)); char buff[10]; sprintf(buff, "%d/%lu", speechIdx + 1, speechLines.size()); speechCountLabel->setText(buff); speechCountLabel->setVisible(true); speechCountLabel->setPosition(pointOffset(bkgSpeech->getPosition(), 188, -68)); speechButton->setEnabled(true); speechButton->setPosition(bkgSpeech->getPosition()); speechIdx++; }