void Player::Init(UnitObject* pUnit,ITriangleSelector* pTerrain) { Irrdevice* pDevice = Irrdevice::GetInstance(); m_pUnitObject = pUnit; ISceneManager* pSmgr = pDevice->GetSceneManager(); SKeyMap aKeyMap[5]; aKeyMap[0].Action = EKA_MOVE_FORWARD; aKeyMap[0].KeyCode = KEY_KEY_W; aKeyMap[1].Action = EKA_MOVE_BACKWARD; aKeyMap[1].KeyCode = KEY_KEY_S; aKeyMap[2].Action = EKA_STRAFE_LEFT; aKeyMap[2].KeyCode = KEY_KEY_A; aKeyMap[3].Action = EKA_STRAFE_RIGHT; aKeyMap[3].KeyCode = KEY_KEY_D; aKeyMap[4].Action = EKA_JUMP_UP; aKeyMap[4].KeyCode = KEY_SPACE; //각 유닛마다 카메라 생성 m_pCamera = pSmgr->addCameraSceneNodeFPS(0,100.0f,0.5f,-1,aKeyMap,9,false,0,false,false); m_pCollisionAnimator = static_cast<ISceneNodeAnimatorCameraFPS*>(*(m_pCamera->getAnimators().begin())); //카메라가 가지고 있는 FPS 카메라 애니메이션 을 가지온다. 이것은 줌 확대 기능 등!! //카메라 따라댕기는 유닉 오브젝트... 방향에 대한것도 설정해줘야함... 이것은 일단 나중에 테스트를 위하여 m_pUnitObject->GetAnimatedNode()->setParent(m_pCamera); IMeshSceneNode* pNode = pSmgr->addCubeSceneNode(10,m_pCamera); m_pCamera->addChild(pUnit->GetAnimatedNode()); pNode->setVisible(true); m_pMyTriangle = pSmgr->createTriangleSelector(pNode->getMesh(),pNode); m_pMetaTriangle = pSmgr->createMetaTriangleSelector(); m_pMetaTriangle->addTriangleSelector(pTerrain); //역시 스크립트 적용 안할 수가 없다... 파일을 읽어와서 적용하던지.... 아우 ISceneNodeAnimatorCollisionResponse * pani = pSmgr->createCollisionResponseAnimator(m_pMetaTriangle,m_pCamera); m_pCamera->addAnimator(pani); pani->drop(); }
int main() { Input input; IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<u32>(800, 600), 16, false, true, false, &input); device->setWindowCaption(L"Seas of Gold"); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); IGUIEnvironment* guienv = device->getGUIEnvironment(); E_DRIVER_TYPE driverType = driverChoiceConsole(); EffectHandler *effect = new EffectHandler(device, driver->getScreenSize(), false, true); E_FILTER_TYPE filterType = (E_FILTER_TYPE)core::clamp<u32>((u32)3 - '1', 0, 4); MapID currentMap; int skyR = 30, skyG = 30, skyB = 70; int timer = 0; SColor sky = SColor(255, skyR, skyG, skyB); float plPos_x = 0.0f, plPos_y = 0.0f, plPos_z = 0.0f; bool updateCam = true; bool menu1 = false; int state = Main; int frameCount = 0; LoadMap loadMap; Player player; Interface playerInterface(driver); ITriangleSelector* selector = 0; ISceneNodeAnimator* anim = 0; Vendor southVendor; Vendor eastVendor; Vendor northVendor; //InitializeVendors(northVendor, southVendor, eastVendor, itemD); //ItemDatabase* itemD = new ItemDatabase; ItemDatabase itemD; itemD.Initialize(); //initialize player's inventory player.AddGold(1000); player.getInventory()->addItem(itemD.getItem(bronzeOre), 50); player.getInventory()->addItem(itemD.getItem(ironOre), 50); player.getInventory()->addItem(itemD.getItem(goldOre), 50); //initialize south vendor's inventory southVendor.getInventory()->addItem(itemD.getItem(bronzeOre), 100); southVendor.getInventory()->addItem(itemD.getItem(coalOre), 100); southVendor.getInventory()->addItem(itemD.getItem(supplies), 1000); //initialize north vendor's inventory northVendor.getInventory()->addItem(itemD.getItem(obsidianOre), 50); northVendor.getInventory()->addItem(itemD.getItem(supplies), 1000); //initialize south vendor's inventory eastVendor.getInventory()->addItem(itemD.getItem(goldOre), 100); eastVendor.getInventory()->addItem(itemD.getItem(ironOre), 100); eastVendor.getInventory()->addItem(itemD.getItem(supplies), 1000); //Item item(0, "bronzeOre", "Sprites/ore_Bronze.png"); //Item item2 = item; //Item* item2 = itemD.getItem(3); //inventory.addItem(&item, 2); //inventory.addItem(&item, 2); //inventory.addItem(item2, 2); //int test = 0; // Load the map scene //loadMap.Load(smgr, device, Map_Africa); //loadMap.Load(smgr, device, Map_India); //loadMap.Load(smgr, device, selector, plyrNode, anim, Map_England); IAnimatedMeshSceneNode* plyrNode = player.loadPlayerNode(device, smgr); //plyrNode->setDebugDataVisible((scene::E_DEBUG_SCENE_TYPE)(plyrNode->isDebugDataVisible() ^ scene::EDS_BBOX)); ICameraSceneNode* camera = smgr->addCameraSceneNode(0, plyrNode->getPosition() + vector3df(0, 2, 2), vector3df(0, 0, 100)); loadMap.Load(smgr, device, selector, plyrNode, anim, driver, Map_Africa); currentMap = Map_Africa; //loadMap.setCollisions(smgr, selector, plyrNode, anim); if (loadMap.CollNode) { selector = smgr->createOctreeTriangleSelector(loadMap.CollNode->getMesh(), loadMap.CollNode, 32); for (int i = 0; i < loadMap.CollNode->getMaterialCount(); i++) { loadMap.CollNode->getMaterial(i).NormalizeNormals = true; } loadMap.CollNode->setTriangleSelector(selector); } if (selector) { anim = smgr->createCollisionResponseAnimator(selector, plyrNode, vector3df(0.6f, 0.75f, 0.4f), core::vector3df(0.0f, -0.05f, 0.0f), core::vector3df(0.0f, -0.725f, 0.0f)); plyrNode->addAnimator(anim); } ISceneCollisionManager* collMan = smgr->getSceneCollisionManager(); ////////////// The Sun //////////// ILightSceneNode *sun_node; SLight sun_data; ISceneNode *sun_billboard; float sun_angle = 0; video::SColorf Diffuse_Night = video::SColorf(0.0f, 0.0f, 0.0f, 1.0f); video::SColorf Diffuse_Day = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); sun_node = smgr->addLightSceneNode(); sun_data.Direction = vector3df(0, 0, 0); sun_data.Type = video::ELT_DIRECTIONAL; sun_data.AmbientColor = video::SColorf(0.1f, 0.1f, 0.1f, 1); sun_data.SpecularColor = video::SColorf(0, 0, 0, 0); sun_data.DiffuseColor = Diffuse_Day; sun_data.CastShadows = true; sun_node->setLightData(sun_data); sun_node->setPosition(vector3df(0, 0, 0)); sun_node->setRotation(vector3df(0, 0, 0)); sun_billboard = smgr->addBillboardSceneNode(sun_node, core::dimension2d<f32>(60, 60)); if (sun_billboard) { sun_billboard->setPosition(vector3df(0, 0, -100)); sun_billboard->setMaterialFlag(video::EMF_LIGHTING, false); sun_billboard->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); sun_billboard->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); sun_billboard->setMaterialTexture(0, driver->getTexture("Assets/particlewhite.bmp")); } /////////// End //////////// //------- candleLight -----// ILightSceneNode *candleLight = smgr->addLightSceneNode(); SLight candleLight_data; candleLight_data.Type = video::ELT_POINT; candleLight_data.DiffuseColor = SColorf(1.0f, 0.546f, 0.016f, 1.0f); candleLight_data.SpecularColor = video::SColorf(0, 0, 0, 0); candleLight->setPosition(vector3df(2.43467f, 1.55795f, -3.94657)); candleLight_data.Radius = 1.5f; candleLight->setLightData(candleLight_data); //------- end -----// //// Make the player //player.AddGold(1000); //player.SetCurrentPort(eMapDest::South); //Item* itemCi = new Item("Iron Ore", 1); //player.getItems()->addItem(itemCi); //Item* itemCb = new Item("Bronze Ore", 1); //player.getItems()->addItem(itemCb); //Vendor vN; //Item* itemG = new Item("Gold Ore", 1000); //vN.getItems()->addItem(itemG); //Vendor vS; //Item* itemI = new Item("Iron Ore", 1000); //vS.getItems()->addItem(itemI); //Vendor vE; //Item* itemB = new Item("Bronze Ore", 1000); //vE.getItems()->addItem(itemB); //Vendor northVendor //delete &itemD; int test99 = 0; // Make the menus MainMenu mainMenu(device, driver); MapMenu mapMenu(device, driver); mapMenu.SetPlayer(&player); TradeMenu tradeMenu; tradeMenu.Initialize(device, driver, &player, &southVendor); //TradeMenu tradeMenu(device, driver); //tradeMenu.SetPlayer(&player); //tradeMenu.SetVendor(&vS); // CraftingMenu craftMenu(device, driver, &player, itemD); //craftMenu.SetPlayer(&player); ////////////////////////////////////////////////////////////////////////// // Initialize timer to compute elapsed time between frames ////////////////////////////////////////////////////////////////////////// __int64 cntsPerSec = 0; QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec); float secsPerCnt = 1.0f / (float)cntsPerSec; __int64 prevTimeStamp = 0; QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp); while (device->run()) { //for scaling animation by time, not by frame __int64 currTimeStamp = 0; QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp); float dt = (currTimeStamp - prevTimeStamp) * secsPerCnt; sun_node->setRotation(vector3df(sun_angle, 0.0f, 0.0f)); sun_angle += dt; frameCount += 1; if ((sun_angle > 0 && sun_angle < 109) || (sun_angle>350)) { timer++; if (timer > 10) { if (skyR < 100) skyR += 1; if (skyG < 100) skyG += 1; if (skyB < 140) skyB += 1; timer = 0; } } if (sun_angle > 170 && sun_angle < 330) { timer++; if (timer > 10) { if (skyR > 0) skyR -= 1; if (skyG > 0) skyG -= 1; if (skyB > 40) skyB -= 1; timer = 0; } } player.updatePlayer(plyrNode, dt, collMan, selector); playerInterface.update(plyrNode, loadMap, driver, device, input, updateCam, state); switch (state) { case Map: { int out = mapMenu.Update(&input, frameCount); switch (out) { case eMapDest::Exit: { state = None; break; } case eMapDest::East: { state = None; //Item* itemB = new Item("Bronze Ore", 1000); //vE.getItems()->addItem(itemB); tradeMenu.SetVendor(&eastVendor); loadMap.Load(smgr, device, selector, plyrNode, anim, driver, Map_India); currentMap = Map_India; if (loadMap.CollNode) { selector = smgr->createOctreeTriangleSelector(loadMap.CollNode->getMesh(), loadMap.CollNode, 32); for (int i = 0; i < loadMap.CollNode->getMaterialCount(); i++) { loadMap.CollNode->getMaterial(i).NormalizeNormals = true; } loadMap.CollNode->setTriangleSelector(selector); } if (selector) { anim = smgr->createCollisionResponseAnimator(selector, plyrNode, vector3df(0.6f, 0.75f, 0.4f), core::vector3df(0.0f, -0.05f, 0.0f), core::vector3df(0.0f, -0.725f, 0.0f)); plyrNode->addAnimator(anim); } collMan = smgr->getSceneCollisionManager(); break; } case eMapDest::North: { state = None; //Item *itemG = new Item("Gold Ore", 1000); //vN.getItems()->addItem(itemG); //tradeMenu.SetVendor(&vN); tradeMenu.SetVendor(&northVendor); loadMap.Load(smgr, device, selector, plyrNode, anim, driver, Map_England); currentMap = Map_England; if (loadMap.CollNode) { selector = smgr->createOctreeTriangleSelector(loadMap.CollNode->getMesh(), loadMap.CollNode, 32); for (int i = 0; i < loadMap.CollNode->getMaterialCount(); i++) { loadMap.CollNode->getMaterial(i).NormalizeNormals = true; } loadMap.CollNode->setTriangleSelector(selector); } if (selector) { anim = smgr->createCollisionResponseAnimator(selector, plyrNode, vector3df(0.6f, 0.75f, 0.4f), core::vector3df(0.0f, -0.05f, 0.0f), core::vector3df(0.0f, -0.725f, 0.0f)); plyrNode->addAnimator(anim); } collMan = smgr->getSceneCollisionManager(); break; } case eMapDest::South: { state = None; //Item *itemI = new Item("Iron Ore", 1000); //vS.getItems()->addItem(itemI); //tradeMenu.SetVendor(&vS); tradeMenu.SetVendor(&southVendor); loadMap.Load(smgr, device, selector, plyrNode, anim, driver, Map_Africa); currentMap = Map_Africa; if (loadMap.CollNode) { selector = smgr->createOctreeTriangleSelector(loadMap.CollNode->getMesh(), loadMap.CollNode, 32); for (int i = 0; i < loadMap.CollNode->getMaterialCount(); i++) { loadMap.CollNode->getMaterial(i).NormalizeNormals = true; } loadMap.CollNode->setTriangleSelector(selector); } if (selector) { anim = smgr->createCollisionResponseAnimator(selector, plyrNode, vector3df(0.6f, 0.75f, 0.4f), core::vector3df(0.0f, -0.05f, 0.0f), core::vector3df(0.0f, -0.725f, 0.0f)); plyrNode->addAnimator(anim); } collMan = smgr->getSceneCollisionManager(); break; } default: break; } break; } case Trade: { bool out = false; out = tradeMenu.Update(&input, frameCount, device, currentMap); if (out) state = None; break; } case Main: { int out = mainMenu.Update(&input, frameCount); switch (out) { case MSstart: { state = None; break; } case MSexit: { device->closeDevice(); //return 0; break; } default: break; } break; } case Craft: { bool out = craftMenu.Update(&input, frameCount, device); if (out) state = None; break; } default: // Do nothing break; } if (updateCam) moveCameraControl(plyrNode, device, camera); //////////////////////////////////////////////////////// if (sun_angle > 360) sun_angle = 0; if (sun_angle < 180) sun_data.DiffuseColor = Diffuse_Day; else sun_data.DiffuseColor = Diffuse_Night; sun_node->setLightData(sun_data); sky.setRed(skyR); sky.setGreen(skyG); sky.setBlue(skyB); driver->beginScene(true, true, sky); smgr->drawAll(); playerInterface.render(driver, state); // Draw the menu switch (state) { case Map: { mapMenu.Draw(driver, device); break; } case Trade: { tradeMenu.Render(driver, device); break; } case Main: { mainMenu.Draw(driver); break; } case Craft: { craftMenu.Draw(driver); break; } default: // Do nothing break; } driver->endScene(); // Update the prev time stamp to current prevTimeStamp = currTimeStamp; } device->drop(); return 0; }
/** Test that collision response animator will reset itself when removed from a scene node, so that the scene node can then be moved without the animator jumping it back again. */ bool collisionResponseAnimator(void) { IrrlichtDevice * device = irr::createDevice(video::EDT_NULL); assert(device); if(!device) return false; ISceneManager * smgr = device->getSceneManager(); // Create 2 nodes to the left of a "wall" ISceneNode * testNode1 = smgr->addEmptySceneNode(); ISceneNode * testNode2 = smgr->addEmptySceneNode(); testNode1->setPosition(vector3df(-50, 0,0)); testNode2->setPosition(vector3df(-50, 0,0)); // Create a "wall" node, and collision response animators for each test node. IMeshSceneNode * wallNode = smgr->addCubeSceneNode(10.f); ITriangleSelector * wallSelector = smgr->createTriangleSelectorFromBoundingBox(wallNode); ISceneNodeAnimatorCollisionResponse * collisionAnimator1 = smgr->createCollisionResponseAnimator(wallSelector, testNode1, vector3df(10,10,10), vector3df(0, 0, 0)); testNode1->addAnimator(collisionAnimator1); CMyCollisionCallback collisionCallback; collisionAnimator1->setCollisionCallback(&collisionCallback); collisionAnimator1->drop(); collisionAnimator1 = 0; ISceneNodeAnimatorCollisionResponse * collisionAnimator2 = smgr->createCollisionResponseAnimator(wallSelector, testNode2, vector3df(10,10,10), vector3df(0, 0, 0)); testNode2->addAnimator(collisionAnimator2); collisionAnimator2->setCollisionCallback(&collisionCallback); wallSelector->drop(); // Don't drop() collisionAnimator2 since we're going to use it. // Get the system in a good state device->run(); smgr->drawAll(); // Try to move both nodes to the right of the wall. // This one should be stopped by its animator. testNode1->setPosition(vector3df(50, 0,0)); collisionCallback.setNextExpectedCollision(testNode1, vector3df(-5.005f, 0, 0), vector3df(-15.005f, 0, 0), false); // Whereas this one, by forcing the animator to update its target node, should be // able to pass through the wall. (In <=1.6 it was stopped by the wall even if // the animator was removed and later re-added); testNode2->setPosition(vector3df(50, 0,0)); collisionAnimator2->setTargetNode(testNode2); collisionAnimator2->drop(); // We're done using this now. device->run(); smgr->drawAll(); bool result = true; if(testNode1->getAbsolutePosition().X > -15.f) { logTestString("collisionResponseAnimator test node 1 wasn't stopped from moving.\n"); assert(false); result = false; } if(testNode2->getAbsolutePosition().X < 50.f) { logTestString("collisionResponseAnimator test node 2 was stopped from moving.\n"); assert(false); result = false; } // Now try to move the second node back through the wall again. Now it should be // stopped by the wall. testNode2->setPosition(vector3df(-50, 0, 0)); // We'll consume this collision, so the node will actually move all the way through. collisionCallback.setNextExpectedCollision(testNode2, vector3df(5.005f, 0, 0), vector3df(15.005f, 0, 0), true); device->run(); smgr->drawAll(); if(testNode2->getAbsolutePosition().X != -50.f) { logTestString("collisionResponseAnimator test node 2 was stopped from moving.\n"); assert(false); result = false; } // Now we'll try to move it back to the right and allow it to be stopped. collisionCallback.setNextExpectedCollision(testNode2, vector3df(-5.005f, 0, 0), vector3df(-15.005f, 0, 0), false); testNode2->setPosition(vector3df(50, 0, 0)); device->run(); smgr->drawAll(); if(testNode2->getAbsolutePosition().X > -15.f) { logTestString("collisionResponseAnimator test node 2 moved too far.\n"); assert(false); result = false; } device->drop(); result &= expectedCollisionCallbackPositions; return result; }
/** Test functionality of the ISceneNodeAnimator implementations. */ bool sceneNodeAnimator(void) { IrrlichtDevice * device = irr::createDevice(video::EDT_NULL, dimension2d<u32>(160, 120)); assert_log(device); if(!device) return false; ISceneManager * smgr = device->getSceneManager(); // Test the hasFinished() method. ISceneNodeAnimatorCollisionResponse* collisionResponseAnimator = smgr->createCollisionResponseAnimator(0, 0); ISceneNodeAnimator* deleteAnimator = smgr->createDeleteAnimator(1); ISceneNodeAnimator* flyCircleAnimator = smgr->createFlyCircleAnimator(); ISceneNodeAnimator* flyStraightAnimator = smgr->createFlyStraightAnimator(vector3df(0, 0, 0), vector3df(0, 0, 0), 1, false); ISceneNodeAnimator* flyStraightAnimatorLooping = smgr->createFlyStraightAnimator(vector3df(0, 0, 0), vector3df(0, 0, 0), 1, true); ISceneNodeAnimator* rotationAnimator = smgr->createRotationAnimator(vector3df(0, 0, 0)); array<vector3df> points; points.push_back(vector3df(0, 0, 0)); points.push_back(vector3df(0, 0, 0)); ISceneNodeAnimator* followSplineAnimator = smgr->createFollowSplineAnimator(0, points, 1000.f); array<video::ITexture*> textures; textures.push_back(0); textures.push_back(0); ISceneNodeAnimator* textureAnimator = smgr->createTextureAnimator(textures, 1, false); ISceneNodeAnimator* textureAnimatorLooping = smgr->createTextureAnimator(textures, 1, true); bool result = true; ISceneNode * deletedNode = smgr->addEmptySceneNode(); deletedNode->addAnimator(deleteAnimator); ISceneNode * testNode = smgr->addEmptySceneNode(); testNode->addAnimator(collisionResponseAnimator); testNode->addAnimator(deleteAnimator); testNode->addAnimator(flyCircleAnimator); testNode->addAnimator(flyStraightAnimator); testNode->addAnimator(flyStraightAnimatorLooping); testNode->addAnimator(rotationAnimator); testNode->addAnimator(followSplineAnimator); testNode->addAnimator(textureAnimator); testNode->addAnimator(textureAnimatorLooping); result &= !collisionResponseAnimator->hasFinished(); result &= !deleteAnimator->hasFinished(); result &= !flyCircleAnimator->hasFinished(); result &= !flyStraightAnimator->hasFinished(); result &= !flyStraightAnimatorLooping->hasFinished(); result &= !rotationAnimator->hasFinished(); result &= !followSplineAnimator->hasFinished(); result &= !textureAnimator->hasFinished(); result &= !textureAnimatorLooping->hasFinished(); device->run(); device->sleep(10); device->run(); smgr->drawAll(); // These animators don't have an endpoint. result &= !collisionResponseAnimator->hasFinished(); result &= !flyCircleAnimator->hasFinished(); result &= !rotationAnimator->hasFinished(); result &= !followSplineAnimator->hasFinished(); // These animators are looping and so can't finish. result &= !flyStraightAnimatorLooping->hasFinished(); result &= !textureAnimatorLooping->hasFinished(); // These have an endpoint and have reached it. result &= deleteAnimator->hasFinished(); result &= flyStraightAnimator->hasFinished(); result &= textureAnimator->hasFinished(); collisionResponseAnimator->drop(); deleteAnimator->drop(); flyCircleAnimator->drop(); flyStraightAnimator->drop(); flyStraightAnimatorLooping->drop(); rotationAnimator->drop(); followSplineAnimator->drop(); textureAnimator->drop(); textureAnimatorLooping->drop(); device->closeDevice(); device->run(); device->drop(); if(!result) { logTestString("One or more animators has a bad hasFinished() state\n."); assert_log(false); } return result; }