void CameraControl(CHARACTERid targetid) { FnCamera camera; camera.ID(cID); FnCharacter actor; actor.ID(targetid); float targetPos[3]; actor.GetPosition(targetPos); float negativeDistance[3]; negativeDistance[0] = -distance; negativeDistance[1] = 0; negativeDistance[2] = 0; float* rotation = EulerToQuarternion(0, degToRad(rot_y), degToRad(rot_x)); float* forwardDir = QuaternionMultiVector(rotation, negativeDistance); float camPos[3], GlobalRight[3]; GlobalRight[0] = 0; GlobalRight[1] = 1; GlobalRight[2] = 0; camPos[0] = targetPos[0] - forwardDir[0]; camPos[1] = targetPos[1] - forwardDir[1]; camPos[2] = targetPos[2] - forwardDir[2]; float* upDir = VectorCross(GlobalRight, forwardDir); //camera.Quaternion(rotation[0], rotation[1], rotation[2], rotation[3], GLOBAL); camera.SetPosition(camPos); camera.SetDirection(forwardDir, upDir); }
/*------------------ the main program C.Wang 1010, 2014 -------------------*/ void FyMain(int argc, char **argv) { // create a new world BOOL4 beOK = FyStartFlyWin32("NTU@2015 Homework #02 - Use Fly2", 0, 0, 1024, 768, FALSE); // setup the data searching paths FySetShaderPath("Data\\NTU6\\Shaders"); FySetModelPath("Data\\NTU6\\Scenes"); FySetTexturePath("Data\\NTU6\\Scenes\\Textures"); FySetScenePath("Data\\NTU6\\Scenes"); //Tang: FX FySetGameFXPath("Data\\NTU6\\FX"); //Tang // create a viewport vID = FyCreateViewport(0, 0, 1024, 768); FnViewport vp; vp.ID(vID); // create a 3D scene sID = FyCreateScene(10); FnScene scene; scene.ID(sID); // load the scene scene.Load("gameScene02"); scene.SetAmbientLights(1.0f, 1.0f, 1.0f, 0.6f, 0.6f, 0.6f); // load the terrain tID = scene.CreateObject(OBJECT); FnObject terrain; terrain.ID(tID); BOOL beOK1 = terrain.Load("terrain"); terrain.Show(FALSE); // set terrain environment terrainRoomID = scene.CreateRoom(SIMPLE_ROOM, 10); FnRoom room; room.ID(terrainRoomID); room.AddObject(tID); // load the character FySetModelPath("Data\\NTU6\\Characters"); FySetTexturePath("Data\\NTU6\\Characters"); FySetCharacterPath("Data\\NTU6\\Characters"); actorID = scene.LoadCharacter("Lyubu2"); // put the character on terrain float pos[3], fDir[3], uDir[3]; SetValues(pos, 3569.0f, -3208.0f, 1000.0f); SetValues(fDir, 1.0f, 1.0f, 0.0f); SetValues(uDir, 0.0f, 0.0f, 1.0f); ActorGen(scene, terrainRoomID, LyubuID, "Lyubu2", "Idle", pos, fDir, uDir); actorID = LyubuID.actorID; FnCharacter actor; actor.ID(actorID); // Get two character actions pre-defined at Lyubu2 idleID = actor.GetBodyAction(NULL, "Idle"); runID = actor.GetBodyAction(NULL, "Run"); NormalAttack1ID = actor.GetBodyAction(NULL, "NormalAttack1"); NormalAttack2ID = actor.GetBodyAction(NULL, "NormalAttack2"); HeavyAttack1ID = actor.GetBodyAction(NULL, "HeavyAttack1"); // translate the camera cID = scene.CreateObject(CAMERA); FnCamera camera; camera.ID(cID); camera.SetNearPlane(5.0f); camera.SetFarPlane(100000.0f); //hw3 : Donzo and Robber02 initialization float temp_pos[3]; float temp_fDir[3]; /* for (int i = 0; i < NUM_OF_BADGUYS; i++) { temp_pos[0] = pos[0] + 30 * (rand()%8); temp_pos[1] = pos[1] + 30 * (rand()%8); temp_pos[2] = pos[2] + 30 * (rand()%8); temp_fDir[0] = -1.0f; temp_fDir[1] = -1.0f; temp_fDir[2] = 1.0f; ActorGen(scene, terrainRoomID, badguyID[i], "Robber02", "CombatIdle", temp_pos, temp_fDir, uDir); } */ for (int i = 0; i < NUM_OF_BOSS; i++) { temp_pos[0] = pos[0] + 30 * (rand() % 8); temp_pos[1] = pos[1] + 30 * (rand() % 8); temp_pos[2] = pos[2] + 30 * (rand() % 8); SetValues(temp_fDir, -1.0f, -1.0f, 1.0f); ActorGen(scene, terrainRoomID, BossID[i], "Donzo2", "CombatIdle", temp_pos, temp_fDir, uDir); } // hw2 initial : set camera position actor.GetPosition(pos); pos[0] = pos[0] - SHORTDIST * fDir[0]; pos[1] = pos[1] - SHORTDIST * fDir[1]; pos[2] = pos[2] + HEIGHTOFFSET; SetValues(fDir, 1.0f, 1.0f, 0.0f); SetValues(uDir, 0.0f, 0.0f, 1.0f); camera.SetPosition(pos); camera.SetDirection(fDir, uDir); // the same as actor float mainLightPos[3] = { -4579.0, -714.0, 15530.0 }; float mainLightFDir[3] = { 0.276, 0.0, -0.961 }; float mainLightUDir[3] = { 0.961, 0.026, 0.276 }; FnLight lgt; lgt.ID(scene.CreateObject(LIGHT)); lgt.Translate(mainLightPos[0], mainLightPos[1], mainLightPos[2], REPLACE); lgt.SetDirection(mainLightFDir, mainLightUDir); lgt.SetLightType(PARALLEL_LIGHT); lgt.SetColor(1.0f, 1.0f, 1.0f); lgt.SetName("MainLight"); lgt.SetIntensity(0.4f); // create a text object for displaying messages on screen textID = FyCreateText("Trebuchet MS", 18, FALSE, FALSE); // create a 2D scene for sprite rendering which will be rendered on the top of 3D sID2 = FyCreateScene(1); scene.ID(sID2); scene.SetSpriteWorldSize(800, 600); // 2D scene size in pixels spID0 = scene.CreateObject(SPRITE); sp.ID(spID0); //showPicture(sp, "talk_mission.jpg", 780, 200 , 10, 10); //showPicture parameter : FnSprite ,imageName, size, position // set Hotkeys FyDefineHotKey(FY_ESCAPE, QuitGame, FALSE); // escape for quiting the game FyDefineHotKey(FY_UP, Movement, FALSE); // Up for moving forward FyDefineHotKey(FY_RIGHT, Movement, FALSE); // Right for turning right FyDefineHotKey(FY_LEFT, Movement, FALSE); // Left for turning left FyDefineHotKey(FY_DOWN, Movement, FALSE); FyDefineHotKey(FY_Q, Movement, FALSE); FyDefineHotKey(FY_W, Movement, FALSE); FyDefineHotKey(FY_E, Movement, FALSE); FyDefineHotKey(FY_A, Movement, FALSE); // Turn left with camera rotation FyDefineHotKey(FY_D, Movement, FALSE); // Turn right with camera rotation FyDefineHotKey(FY_S, Movement, FALSE); // define some mouse functions FyBindMouseFunction(LEFT_MOUSE, InitPivot, PivotCam, NULL, NULL); FyBindMouseFunction(MIDDLE_MOUSE, InitZoom, ZoomCam, NULL, NULL); FyBindMouseFunction(RIGHT_MOUSE, InitMove, MoveCam, NULL, NULL); // bind timers, frame rate = 30 fps FyBindTimer(0, 30.0f, GameAI, TRUE); FyBindTimer(1, 30.0f, RenderIt, TRUE); // invoke the system FyInvokeFly(TRUE); }
/*---------------------- perform the rendering C.Wang 0720, 2006 -----------------------*/ void RenderIt(int skip) { FnViewport vp; // render the whole scene vp.ID(vID); vp.Render3D(cID, TRUE, TRUE); // render the sprites vp.RenderSprites(sID2, FALSE, TRUE); // no clear the background but clear the z buffer FySwapBuffers(); // get camera's data FnCamera camera; camera.ID(cID); FnObject terrain; terrain.ID(tID); float pos[3], fDir[3], uDir[3]; //-----------------HW2 added-----------------------// float actorPos[3], actorfDir[3], actoruDir[3]; FnCharacter actor; actor.ID(actorID); actor.GetPosition(actorPos); actor.GetDirection(actorfDir, actoruDir); camera.GetPosition(pos); camera.GetDirection(fDir, uDir); // Initialze probing ray direction float dir[3], charDir[3]; dir[0] = -fDir[0] / CAMERAPROBE; dir[1] = -fDir[1] / CAMERAPROBE; dir[2] = -1; charDir[0] = actorfDir[0] / ACTORPROBE; charDir[1] = actorfDir[1] / ACTORPROBE; charDir[2] = -1; if ((FyCheckHotKeyStatus(FY_A) || FyCheckHotKeyStatus(FY_D)) && dirCount % SMOOTHINESS == 0) { int tempHeight = pos[2]; pos[2] = actorPos[2]; int theDistance = FyDistance(pos, actorPos); pos[0] = actorPos[0] - theDistance * actorfDir[0]; pos[1] = actorPos[1] - theDistance * actorfDir[1]; pos[2] = tempHeight; fDir[0] = actorfDir[0]; fDir[1] = actorfDir[1]; uDir[0] = fDir[0] / abs(fDir[0] * fDir[1]); uDir[1] = fDir[1] / abs(fDir[0] * fDir[1]); uDir[2] = -abs(uDir[0] * fDir[0] + uDir[1] * fDir[1]) / fDir[2]; } if ((FyCheckHotKeyStatus(FY_UP) || FyCheckHotKeyStatus(FY_S)) && dirCount % SMOOTHINESS == 0) { if (pos[2] > actorPos[2] + HEIGHTOFFSET) { pos[2] = actorPos[2]; pos[2] = actorPos[2] + HEIGHTBOUND + HEIGHTOFFSET - FyDistance(pos, actorPos); fDir[0] = actorPos[0] - pos[0]; fDir[1] = actorPos[1] - pos[1]; fDir[2] = -pos[2]; uDir[0] = fDir[0] / abs(fDir[0] * fDir[1]); uDir[1] = fDir[1] / abs(fDir[0] * fDir[1]); uDir[2] = -abs(uDir[0] * fDir[0] + uDir[1] * fDir[1]) / fDir[2]; } else // Reset the up direction { pos[2] = actorPos[2] + HEIGHTOFFSET; fDir[0] = actorfDir[0]; fDir[1] = actorfDir[1]; fDir[2] = 0; uDir[0] = 0; uDir[1] = 0; uDir[2] = 1; } if (FyDistance(pos, actorPos) > LONGDIST) { pos[0] = actorPos[0] - LONGDIST * actorfDir[0]; pos[1] = actorPos[1] - LONGDIST * actorfDir[1]; pos[2] = actorPos[2] + HEIGHTOFFSET; fDir[0] = actorfDir[0]; fDir[1] = actorfDir[1]; fDir[2] = -0.0f; uDir[0] = actoruDir[0]; uDir[1] = actoruDir[1]; uDir[2] = actoruDir[2]; } } if (FyCheckHotKeyStatus(FY_RIGHT) && dirCount % SMOOTHINESS == 0) { actorPos[2] += HEIGHTOFFSET; if (terrain.HitTest(actorPos, charDir) <= 0) { camera.MoveRight(-CAMERASPEED, FALSE, FALSE, 0, FALSE); camera.GetPosition(pos); } fDir[0] = actorPos[0] - pos[0]; fDir[1] = actorPos[1] - pos[1]; fDir[2] = 0.0f; } if (FyCheckHotKeyStatus(FY_LEFT) && dirCount % SMOOTHINESS == 0) { actorPos[2] += HEIGHTOFFSET; if (terrain.HitTest(actorPos, charDir) <= 0) { camera.MoveRight(CAMERASPEED, FALSE, FALSE, 0, FALSE); camera.GetPosition(pos); } fDir[0] = actorPos[0] - pos[0]; fDir[1] = actorPos[1] - pos[1]; fDir[2] = 0.0f; } if (FyCheckHotKeyStatus(FY_DOWN) && dirCount % SMOOTHINESS == 0) { if (FyDistance(pos, actorPos) < SHORTDIST) { if (terrain.HitTest(pos, dir) > 0) { pos[0] = actorPos[0] + SHORTDIST * actorfDir[0]; pos[1] = actorPos[1] + SHORTDIST * actorfDir[1]; pos[2] = actorPos[2] + HEIGHTOFFSET; fDir[0] = -actorfDir[0]; fDir[1] = -actorfDir[1]; fDir[2] = 0.0f; uDir[0] = actoruDir[0]; uDir[1] = actoruDir[1]; uDir[2] = actoruDir[2]; } else { // go back and hit Obstacle : camera look down at the actor pos[2] = actorPos[2]; pos[2] = actorPos[2] + HEIGHTBOUND + HEIGHTOFFSET - FyDistance(pos, actorPos); fDir[0] = actorPos[0] - pos[0]; fDir[1] = actorPos[1] - pos[1]; fDir[2] = -pos[2]; uDir[0] = fDir[0] / abs(fDir[0] * fDir[1]); uDir[1] = fDir[1] / abs(fDir[0] * fDir[1]); uDir[2] = -abs(uDir[0] * fDir[0] + uDir[1] * fDir[1]) / fDir[2]; } } } //-----------------HW2 end-------------------------// if (dirCount % SMOOTHINESS == 0) { camera.SetPosition(pos); camera.SetDirection(fDir, uDir); } // show frame rate static char string[128]; if (frame == 0) { FyTimerReset(0); } if (frame / 10 * 10 == frame) { float curTime; curTime = FyTimerCheckTime(0); sprintf(string, "Fps: %6.2f", frame / curTime); } frame += skip; if (frame >= 1000) { frame = 0; } FnText text; text.ID(textID); text.Begin(vID); text.Write(string, 20, 20, 255, 0, 0); char posS[256], fDirS[256], uDirS[256], debug[256]; sprintf(posS, "pos: %8.3f %8.3f %8.3f", pos[0], pos[1], pos[2]); sprintf(fDirS, "facing: %8.3f %8.3f %8.3f", fDir[0], fDir[1], fDir[2]); sprintf(uDirS, "up: %8.3f %8.3f %8.3f", uDir[0], uDir[1], uDir[2]); sprintf(debug, "debug: %d %d %d", LyubuID.level, LyubuID.exp_cur, LyubuID.blood_remain); text.Write(posS, 20, 35, 255, 255, 0); text.Write(fDirS, 20, 50, 255, 255, 0); text.Write(uDirS, 20, 65, 255, 255, 0); text.Write(debug, 20, 90, 255, 255, 0); text.End(); // swap buffer FySwapBuffers(); }
/* ------------------ the main program C.Wang 1010, 2014 -------------------*/ void FyMain(int argc, char **argv) { // create a new world BOOL4 beOK = FyStartFlyWin32("NTU@2014 Homework #02 - Use Fly2", 0, 0, 1024, 768, FALSE); // setup the data searching paths FySetShaderPath("Data\\NTU6\\Shaders"); FySetModelPath("Data\\NTU6\\Scenes"); FySetTexturePath("Data\\NTU6\\Scenes\\Textures"); FySetScenePath("Data\\NTU6\\Scenes"); // create a viewport vID = FyCreateViewport(0, 0, 1024, 768); FnViewport vp; vp.ID(vID); // create a 3D scene sID = FyCreateScene(10); FnScene scene; scene.ID(sID); // load the scene scene.Load("gameScene02"); scene.SetAmbientLights(1.0f, 1.0f, 1.0f, 0.6f, 0.6f, 0.6f); // load the terrain tID = scene.CreateObject(OBJECT); FnObject terrain; terrain.ID(tID); BOOL beOK1 = terrain.Load("terrain"); terrain.Show(FALSE); // set terrain environment terrainRoomID = scene.CreateRoom(SIMPLE_ROOM, 10); FnRoom room; room.ID(terrainRoomID); room.AddObject(tID); // load the character FySetModelPath("Data\\NTU6\\Characters"); FySetTexturePath("Data\\NTU6\\Characters"); FySetCharacterPath("Data\\NTU6\\Characters"); actorID = scene.LoadCharacter("Lyubu2"); npc1ID = scene.LoadCharacter("Donzo2"); npc2ID = scene.LoadCharacter("Robber02"); // put the character on terrain float apos[3], cpos[3], fDir[3], uDir[3]; FnCharacter actor, npc1, npc2; actor.ID(actorID); npc1.ID(npc1ID); npc2.ID(npc2ID); apos[0] = 3569.0f; apos[1] = -3208.0f; apos[2] = 1000.0f; fDir[0] = 1.0f; fDir[1] = 0.0f; fDir[2] = 0.0f; uDir[0] = 0.0f; uDir[1] = 0.0f; uDir[2] = 1.0f; actor.SetDirection(fDir, uDir); fDir[0] = -1.0f; fDir[1] = -1.0f; npc1.SetDirection(fDir, uDir); fDir[0] = 1.0f; npc2.SetDirection(fDir, uDir); actor.SetTerrainRoom(terrainRoomID, 10.0f); npc1.SetTerrainRoom(terrainRoomID, 10.0f); npc2.SetTerrainRoom(terrainRoomID, 10.0f); beOK = actor.PutOnTerrain(apos); apos[1] -= 150.0f; beOK = npc1.PutOnTerrain(apos); apos[1] -= 50.0f; beOK = npc2.PutOnTerrain(apos); // Get two character actions pre-defined at Lyubu2 idleID = actor.GetBodyAction(NULL, "Idle"); runID = actor.GetBodyAction(NULL, "Run"); attackID = actor.GetBodyAction(NULL, "NormalAttack1"); idle1ID = npc1.GetBodyAction(NULL, "Idle"); damage1ID = npc1.GetBodyAction(NULL, "DamageL"); die1ID = npc1.GetBodyAction(NULL, "Die"); idle2ID = npc2.GetBodyAction(NULL, "CombatIdle"); damage2ID = npc2.GetBodyAction(NULL, "Damage1"); die2ID = npc2.GetBodyAction(NULL, "DEAD"); // set the character to idle action curPoseID = idleID; actor.SetCurrentAction(NULL, 0, curPoseID); actor.Play(START, 0.0f, FALSE, TRUE); actor.TurnRight(90.0f); npc1.SetCurrentAction(NULL, 0, idle1ID); npc1.Play(START, 0.0f, FALSE, TRUE); npc2.SetCurrentAction(NULL, 0, idle2ID); npc2.Play(START, 0.0f, FALSE, TRUE); // translate the camera cID = scene.CreateObject(CAMERA); FnCamera camera; camera.ID(cID); camera.SetNearPlane(5.0f); camera.SetFarPlane(100000.0f); // set camera initial position and orientation actor.GetPosition(apos); //cpos[0] = 4315.783f; cpos[1] = -3199.686f; cpos[2] = 93.046f; fDir[0] = DIST; fDir[1] = 0.0f; fDir[2] = -HEIGHT; cpos[0] = apos[0] - fDir[0]; cpos[1] = apos[1] - fDir[1]; cpos[2] = apos[2] - fDir[2]; float distance = sqrt(double((fDir[0])*(fDir[0]) + (fDir[1])*(fDir[1]))); uDir[0] = -fDir[2] * fDir[0] / distance; uDir[1] = -fDir[2] * fDir[1] / distance; uDir[2] = distance; //fDir[0] = -0.983f; fDir[1] = -0.143f; fDir[2] = -0.119f; //uDir[0] = -0.116f; uDir[1] = -0.031f; uDir[2] = 0.993f; camera.SetPosition(cpos); camera.SetDirection(fDir, uDir); float mainLightPos[3] = { -4579.0, -714.0, 15530.0 }; float mainLightFDir[3] = { 0.276, 0.0, -0.961 }; float mainLightUDir[3] = { 0.961, 0.026, 0.276 }; FnLight lgt; lgt.ID(scene.CreateObject(LIGHT)); lgt.Translate(mainLightPos[0], mainLightPos[1], mainLightPos[2], REPLACE); lgt.SetDirection(mainLightFDir, mainLightUDir); lgt.SetLightType(PARALLEL_LIGHT); lgt.SetColor(1.0f, 1.0f, 1.0f); lgt.SetName("MainLight"); lgt.SetIntensity(0.4f); // create a text object for displaying messages on screen textID = FyCreateText("Trebuchet MS", 18, FALSE, FALSE); // set Hotkeys FyDefineHotKey(FY_ESCAPE, QuitGame, FALSE); // escape for quiting the game FyDefineHotKey(FY_UP, Movement, FALSE); // Up for moving forward FyDefineHotKey(FY_DOWN, Movement, FALSE); // Down for turning right FyDefineHotKey(FY_RIGHT, Movement, FALSE); // Right for turning right FyDefineHotKey(FY_LEFT, Movement, FALSE); // Left for turning left FyDefineHotKey('W', Movement, FALSE); // Up for moving forward FyDefineHotKey('S', Movement, FALSE); // Down for turning right FyDefineHotKey('D', Movement, FALSE); // Right for turning right FyDefineHotKey('A', Movement, FALSE); // Left for turning left FyDefineHotKey('J', Movement, FALSE); // define some mouse functions FyBindMouseFunction(LEFT_MOUSE, InitPivot, PivotCam, NULL, NULL); FyBindMouseFunction(MIDDLE_MOUSE, InitZoom, ZoomCam, NULL, NULL); FyBindMouseFunction(RIGHT_MOUSE, InitMove, MoveCam, NULL, NULL); // bind timers, frame rate = 30 fps FyBindTimer(0, 30.0f, GameAI, TRUE); FyBindTimer(1, 30.0f, RenderIt, TRUE); // invoke the system FyInvokeFly(TRUE); }
/* ------------------------------------------------------------ - 30fps timer callback in fixed frame rate for major game loop -------------------------------------------------------------- */ void GameAI(int skip) { FnCharacter actor, npc1, npc2; // play character pose actor.ID(actorID); actor.Play(LOOP, (float)skip, FALSE, TRUE); npc1.ID(npc1ID); if (HP1>0 || (frame - framedamage1 + 1000) % 1000 < dietime1) npc1.Play(LOOP, (float)skip, FALSE, TRUE); npc2.ID(npc2ID); if (HP2>0 || (frame - framedamage2 + 1000) % 1000 < dietime2) npc2.Play(LOOP, (float)skip, FALSE, TRUE); if ((frame - frameattack + 1000) % 1000 == attacktime) actor.SetCurrentAction(NULL, 0, curPoseID, 5.0f); if (HP1 > 0) { if ((frame - framedamage1 + 1000) % 1000 == damagetime1) npc1.SetCurrentAction(NULL, 0, idle1ID, 0.0f); else if (frame == framedamage1) npc1.SetCurrentAction(NULL, 0, damage1ID, 0.0f); } else if (frame == framedamage1) { npc1.SetCurrentAction(NULL, 0, die1ID, 0.0f); } if (HP2 > 0) { if ((frame - framedamage2 + 1000) % 1000 == damagetime2) npc2.SetCurrentAction(NULL, 0, idle2ID, 0.0f); else if (frame == framedamage2) npc2.SetCurrentAction(NULL, 0, damage2ID, 0.0f); } else if (frame == framedamage2) { npc2.SetCurrentAction(NULL, 0, die2ID, 0.0f); } FnCamera camera; camera.ID(cID); FnObject terrain; terrain.ID(tID); float fDir[3], uDir[3] = { 0, 0, 1 }, cpos[3], apos[3], distance, height, length; camera.GetPosition(cpos); actor.GetPosition(apos); fDir[0] = apos[0] - cpos[0]; fDir[1] = apos[1] - cpos[1]; fDir[2] = apos[2] - cpos[2]; distance = sqrt(double((fDir[0])*(fDir[0]) + (fDir[1])*(fDir[1]))); height = -fDir[2]; length = sqrt(double(distance*distance + height*height)); uDir[0] = -fDir[2] * fDir[0] / distance; uDir[1] = -fDir[2] * fDir[1] / distance; uDir[2] = distance; camera.SetDirection(fDir, uDir); uDir[0] = 0; uDir[1] = 0; uDir[2] = 1; bool up = FyCheckHotKeyStatus(FY_UP) || FyCheckHotKeyStatus('W'), down = FyCheckHotKeyStatus(FY_DOWN) || FyCheckHotKeyStatus('S'), left = FyCheckHotKeyStatus(FY_LEFT) || FyCheckHotKeyStatus('A'), right = FyCheckHotKeyStatus(FY_RIGHT) || FyCheckHotKeyStatus('D'), act = (frame - frameattack + 1000) % 1000 >= attacktime; if (act) { if (up&&!down) { actor.SetDirection(fDir, uDir); float norm = sqrt(double((fDir[0])*(fDir[0]) + (fDir[1])*(fDir[1]))); actor.MoveForward(speed, TRUE); actor.GetPosition(apos); cpos[0] = apos[0] - LENGTH*fDir[0] / norm; cpos[1] = apos[1] - LENGTH*fDir[1] / norm; cpos[2] = apos[2] + HEIGHT; float dir[3] = { cpos[0] - apos[0], cpos[1] - apos[1], 0 }, result[3]; if (terrain.HitTest(apos, dir, result) > 0) { float line[3] = { result[0] - apos[0], result[1] - apos[1], result[2] - apos[2] }; if (line[0] * line[0] + line[1] * line[1]<LENGTH*LENGTH) { cpos[0] = result[0]; cpos[1] = result[1]; cpos[2] = apos[2] + sqrt(double(LENGTH*LENGTH + HEIGHT*HEIGHT - (line[0] * line[0] + line[1] * line[1]))); } } camera.SetPosition(cpos); } if (down&&!up) { float bDir[3] = { -fDir[0], -fDir[1], -fDir[2] }; actor.SetDirection(bDir, uDir); float norm = sqrt(double((bDir[0])*(bDir[0]) + (bDir[1])*(bDir[1]))); actor.MoveForward(speed, TRUE); actor.GetPosition(apos); cpos[0] = apos[0] - LENGTH*fDir[0] / norm; cpos[1] = apos[1] - LENGTH*fDir[1] / norm; cpos[2] = apos[2] + HEIGHT; float dir[3] = { cpos[0] - apos[0], cpos[1] - apos[1], 0 }, result[3]; if (terrain.HitTest(apos, dir, result) > 0) { float line[3] = { result[0] - apos[0], result[1] - apos[1], result[2] - apos[2] }; if (line[0] * line[0] + line[1] * line[1]<LENGTH*LENGTH) { cpos[0] = result[0]; cpos[1] = result[1]; cpos[2] = apos[2] + sqrt(double(LENGTH*LENGTH + HEIGHT*HEIGHT - (line[0] * line[0] + line[1] * line[1]))); } } camera.SetPosition(cpos); } if (left&&!right) { float lDir[3] = { -fDir[1], fDir[0], fDir[2] }, apos2[3]; actor.SetDirection(lDir, uDir); actor.TurnRight(-asin(speed / 2 / distance) * 180 / pi); actor.MoveForward(speed, TRUE); actor.GetPosition(apos2); if ((apos[0] - apos2[0])*(apos[0] - apos2[0]) + (apos[1] - apos2[1])*(apos[1] - apos2[1]) == 0) { camera.TurnRight(-asin(2 * speed / 2 / distance) * 180 / pi); camera.MoveRight(2 * speed); } } if (right&&!left) { float rDir[3] = { fDir[1], -fDir[0], fDir[2] }, apos2[3]; actor.SetDirection(rDir, uDir); actor.TurnRight(asin(speed / 2 / distance) * 180 / pi); actor.MoveForward(speed, TRUE); actor.GetPosition(apos2); if ((apos[0] - apos2[0])*(apos[0] - apos2[0]) + (apos[1] - apos2[1])*(apos[1] - apos2[1]) == 0) { camera.TurnRight(asin(2 * speed / 2 / distance) * 180 / pi); camera.MoveRight(-2 * speed); } } } }
/*------------------ the main program C.Wang 1010, 2014 -------------------*/ void FyMain(int argc, char **argv) { // create a new world BOOL4 beOK = FyStartFlyWin32("NTU@2014 Homework #01 - Use Fly2", 0, 0, 1024, 768, FALSE); // setup the data searching paths FySetShaderPath("Data\\NTU6\\Shaders"); FySetModelPath("Data\\NTU6\\Scenes"); FySetTexturePath("Data\\NTU6\\Scenes\\Textures"); FySetScenePath("Data\\NTU6\\Scenes"); // create a viewport vID = FyCreateViewport(0, 0, 1024, 768); FnViewport vp; vp.ID(vID); // create a 3D scene sID = FyCreateScene(10); FnScene scene; scene.ID(sID); // load the scene scene.Load("gameScene02"); scene.SetAmbientLights(1.0f, 1.0f, 1.0f, 0.6f, 0.6f, 0.6f); // load the terrain tID = scene.CreateObject(OBJECT); FnObject terrain; terrain.ID(tID); BOOL beOK1 = terrain.Load("terrain"); terrain.Show(FALSE); // set terrain environment terrainRoomID = scene.CreateRoom(SIMPLE_ROOM, 10); FnRoom room; room.ID(terrainRoomID); room.AddObject(tID); // load the character FySetModelPath("Data\\NTU6\\Characters"); FySetTexturePath("Data\\NTU6\\Characters"); FySetCharacterPath("Data\\NTU6\\Characters"); actorID = scene.LoadCharacter("Lyubu2"); // put the character on terrain float pos[3], fDir[3], uDir[3]; FnCharacter actor; actor.ID(actorID); pos[0] = 3569.0f; pos[1] = -3208.0f; pos[2] = 1000.0f; fDir[0] = 1.0f; fDir[1] = -1.0f; fDir[2] = 0.0f; uDir[0] = 0.0f; uDir[1] = 0.0f; uDir[2] = 1.0f; actor.SetDirection(fDir, uDir); actor.SetTerrainRoom(terrainRoomID, 10.0f); beOK = actor.PutOnTerrain(pos); // Get two character actions pre-defined at Lyubu2 idleID = actor.GetBodyAction(NULL, "Idle"); runID = actor.GetBodyAction(NULL, "Run"); // set the character to idle action curPoseID = idleID; actor.SetCurrentAction(NULL, 0, curPoseID); actor.Play(START, 0.0f, FALSE, TRUE); actor.TurnRight(90.0f); // translate the camera cID = scene.CreateObject(CAMERA); FnCamera camera; camera.ID(cID); camera.SetNearPlane(5.0f); camera.SetFarPlane(100000.0f); // set camera initial position and orientation pos[0] = 4069.0f; pos[1] = -3208.0f; pos[2] = 93.046f; fDir[0] = -500.0f; fDir[1] = -0.0f; fDir[2] = -0.0f; uDir[0] = -0.116f; uDir[1] = -0.031f; uDir[2] = 0.993f; camera.SetPosition(pos); camera.SetDirection(fDir, uDir); float mainLightPos[3] = { -4579.0, -714.0, 15530.0 }; float mainLightFDir[3] = { 0.276, 0.0, -0.961 }; float mainLightUDir[3] = { 0.961, 0.026, 0.276 }; FnLight lgt; lgt.ID(scene.CreateObject(LIGHT)); lgt.Translate(mainLightPos[0], mainLightPos[1], mainLightPos[2], REPLACE); lgt.SetDirection(mainLightFDir, mainLightUDir); lgt.SetLightType(PARALLEL_LIGHT); lgt.SetColor(1.0f, 1.0f, 1.0f); lgt.SetName("MainLight"); lgt.SetIntensity(0.4f); // create a text object for displaying messages on screen textID = FyCreateText("Trebuchet MS", 18, FALSE, FALSE); // set Hotkeys FyDefineHotKey(FY_ESCAPE, QuitGame, FALSE); // escape for quiting the game FyDefineHotKey(FY_UP, Movement, FALSE); // Up for moving forward FyDefineHotKey(FY_RIGHT, Movement, FALSE); // Right for turning right FyDefineHotKey(FY_LEFT, Movement, FALSE); // Left for turning left // define some mouse functions if (!IsCameraFollow) { FyBindMouseFunction(LEFT_MOUSE, InitPivot, PivotCam, NULL, NULL); FyBindMouseFunction(MIDDLE_MOUSE, InitZoom, ZoomCam, NULL, NULL); FyBindMouseFunction(RIGHT_MOUSE, InitMove, MoveCam, NULL, NULL); } else { FyBindMouseFunction(LEFT_MOUSE, InitZoom2, ZoomCam2, NULL, NULL); FyBindMouseFunction(RIGHT_MOUSE, NULL, RotateCam, NULL, NULL); } // bind timers, frame rate = 30 fps FyBindTimer(0, 30.0f, GameAI, TRUE); FyBindTimer(1, 30.0f, RenderIt, TRUE); // invoke the system FyInvokeFly(TRUE); }