Historique des modifications - Message

Message #3060

Sujet: Monstres


Type Date Auteur Contenu
Création du message 20-10-2007 20:31:54 shell
Bonjour !
Je voudrais savoir s'il vous plait comment je peux créer "massivement" des ennemis et gérer leur IA globale, sans traiter au cas par cas (évidemment!) ?
Je m'explique : je ne veux pas de code d'IA ni de code de monstres, juste un code qui me permet de créer plusieurs nodes et de leur faire executer des fonctions à tous...
Par exemple je veux pouvoir créer quelques golems, et je voudrais que dès que je suis à proximité de l'un d'eux, ce dernier se dirige vers moi et m'attaque.
Problème, je ne sais ni comment créer plusieurs nodes comme dans un tableau, de leur affecter un mesh, ni comment gérer leur IA de façon globale...
Question qui peut vous sembler être comme "comment on fait un mmorpg trop bien, pliz ?" mais détrompez vous ma question est juste pour savoir, comment ca fonctionne au niveau classe et code...
Merci d'avance !

Voilà mon code en ce moment ! =>

/*
This tutorial will show how to implement a camera and character display which is a copy of the
one used in World of Warcraft.
Its purpose is to offer the Community an example for a camera and movement system for rpg or 
as a base to develop theyr own movement/camera system.

It is based on the irrlicht Tutorial 12 and 
NightBirds NWN Camera example http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=3245

Atm its all a bitt messy and very unclean but its still work in progress , althought comments 
or suggestions are always welcome.
You can contact me in the Irrlicht Forums
Username: Jonchaos
or per Email
Antharon@Hotmail.com
*/
#include <irrlicht.h>
#include <iostream>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

#define CAMERASPEED 0.1f
#define PI 3.14159265f
#define WIDTH 1024

class Golem
{
public:
    Golem(){       
       this->gIsRunning = false;
       this->gIsAttacking = 0;
       this->gIsAttacked = 0;
       life = 100;
       }
void Pain()
{
       if (this->gIsAttacked == 1)
       {
       this->gIsAttacked++;
       }
}    
private:
        bool gIsRunning;
        int gIsAttacking;
        int gIsAttacked;
        int life;
};
       
class MyEventReceiver : public IEventReceiver
{
public:

	MyEventReceiver(scene::ISceneNode* terrain ,
					scene::IAnimatedMeshSceneNode* ptrCharacter,
					IrrlichtDevice* ptrDevice,
					scene::ICameraSceneNode* ptrCamera)
	{
		// store pointer to terrain so we can change its drawing mode
		this->Terrain = terrain;
		this->Character = ptrCharacter;
		this->device = ptrDevice;
		this->pCamera = ptrCamera;
		this->m_yRotationAngle = 3.14159265*0.5f;
		this->distance = 130;
		this->bIsRunning = false;
		this->bIsAttacking = 0;
		
	}


	
	void Update() 
	{ 
		if (!pCamera || !Character) return;


		if (m_lastTargetPos != Character->getPosition()) 
		{
			m_updated = true;
			m_lastTargetPos = Character->getPosition();
		}
		
		if (m_updated) 
		{
			m_updated = false;
			irr::core::vector3df m_Camerapos = m_lastTargetPos;
			m_Camerapos.X += distance*sin(m_yRotationAngle);
			m_Camerapos.Z += distance*cos(m_yRotationAngle);
			m_Camerapos.Y += distance;
			pCamera->setPosition(m_Camerapos);
			pCamera->setTarget(m_lastTargetPos);
		}
}

void attack()
{
                if (this->bIsAttacking != 0){
                this->bIsAttacking ++;
                }
                if (this->bIsAttacking >= 105)
                {
                this->bIsAttacking = 0;
                if(!this->bIsRunning){
                Character->setMD2Animation(scene::EMAT_STAND);
                }else{
                Character->setMD2Animation(scene::EMAT_RUN);
                }
                }
                if (this->bIsAttacking == 1)
                {
                  
                }
                
}
void Zoom(float amount) 
{
	distance *= amount;
	if (distance == 0) distance = 2; //there should be more elaborate capping of things here..
	m_updated = true;
}

	bool OnEvent(SEvent event)
	{		
		Update();

		if (event.EventType == EET_MOUSE_INPUT_EVENT) 
			{
				switch (event.MouseInput.Event) 
				{
					case EMIE_MOUSE_WHEEL:
						Zoom(((-event.MouseInput.Wheel)+1)/2+.5f); //make it be from .5 to 1.5
						return true;
						break;

				} ;
		}
		
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
		{
			switch (event.KeyInput.Key)
			{
			case irr::KEY_ESCAPE:
				this->device->closeDevice(); 
				return true;
			}
		}		
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown  )
		{
			switch (event.KeyInput.Key)
			{		
			case irr::KEY_UP:
				Charpos	= Character->getPosition();
				Charpos.X = Charpos.X - 10.0f ;
				Character->setPosition(Charpos); 
				Character->setRotation(core::vector3df(0,180,0));
				if (!this->bIsRunning)
				{
					Character->setMD2Animation(scene::EMAT_RUN); 
					this->bIsRunning = true;
				}
				return true;			
			case irr::KEY_DOWN: 
				Charpos	= Character->getPosition(); 
				Charpos.X = Charpos.X + 10.0f ;
				Character->setPosition(Charpos); 
				Character->setRotation(core::vector3df(0,0,0));
				if (!this->bIsRunning)
				{
					Character->setMD2Animation(scene::EMAT_RUN); 
					this->bIsRunning = true;
				}
				return true;
			case irr::KEY_LEFT:  
				Charpos	= Character->getPosition(); 
				Charpos.Z = Charpos.Z - 10.0f ;
				Character->setPosition(Charpos); 
				Character->setRotation(core::vector3df(0,90,0));
				if (!this->bIsRunning)
				{
					Character->setMD2Animation(scene::EMAT_RUN); 
					this->bIsRunning = true;
				}
				return true;
			case irr::KEY_RIGHT: 
				Charpos	= Character->getPosition(); 
				Charpos.Z = Charpos.Z + 10.0f ;
				Character->setPosition(Charpos); 
				Character->setRotation(core::vector3df(0,-90,0));
				if (!this->bIsRunning)
				{
					Character->setMD2Animation(scene::EMAT_RUN); 
					this->bIsRunning = true;
				}				
				return true;
            case irr::KEY_SPACE:
                if (this->bIsAttacking == 0)
                {
				    Character->setMD2Animation(scene::EMAT_ATTACK); 
					this->bIsAttacking = 1;    
                }
                return true;
                
         			
			}
		}		
		
		// if one of the walk keys is lifted -> stop run animation
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
		{
			switch (event.KeyInput.Key)
			{		
			case irr::KEY_UP:
				this->bIsRunning = false;
				Character->setMD2Animation(scene::EMAT_STAND);
				return true;			
			case irr::KEY_DOWN: 
				this->bIsRunning = false;
				Character->setMD2Animation(scene::EMAT_STAND);
				return true;
			case irr::KEY_LEFT:  
				this->bIsRunning = false;
				Character->setMD2Animation(scene::EMAT_STAND);
				return true;
			case irr::KEY_RIGHT: 
				this->bIsRunning = false;
				Character->setMD2Animation(scene::EMAT_STAND);			
				return true;
			case irr::KEY_SPACE:

                return true;
			}
		}
		return false;
	}
private:
	bool bIsRunning;
	int bIsAttacking;
	scene::ISceneNode* Terrain;
	scene::IAnimatedMeshSceneNode* Character;
	IrrlichtDevice* device;


	scene::ICameraSceneNode* pCamera;

	irr::core::vector3df m_lastTargetPos;
	
	irr::core::vector3df Charpos;

	bool m_updated;
	int MouseX;
	float distance;

	float m_yRotationAngle; //the angle about the Y axis 
};


/*
The start of the main function starts like in most other example. We ask the user
for the desired renderer and start it up.
*/
int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
	// create device

	IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(1040, 780));

	if (device == 0)
		return 1; // could not create selected driver.

	
	/*
	First, we add standard stuff to the scene: A nice irrlicht engine
	logo, a small help text, a user controlled camera, and we disable
	the mouse cursor.
	*/   

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	gui::IGUIEnvironment* env = device->getGUIEnvironment();

	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);

	//set other font
	env->getSkin()->setFont(env->getFont("../../media/fontlucida.png"));

	// add some help text
	gui::IGUIStaticText* text = env->addStaticText(
		L"Vie : 100/100",
		core::rect<s32>(10,740,250,775), true, true, 0, -1, true);

	// add camera
	scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();

		
	camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
	camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
	camera->setFarValue(12000.0f);

	//mouse cursor
	device->getCursorControl()->setVisible(false);
	smgr->setAmbientLight ( video::SColorf ( 0x00c0c0c0 ) );

	// add terrain scene node
	scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( 
		"../../media/terrain-heightmap2.bmp",
		0,										// parent node
		-1,										// node id
		core::vector3df(0.f, 0.f, 0.f),			// position
		core::vector3df(0.f, 0.f, 0.f),			// rotation
		core::vector3df(40.f, 4.4f, 40.f),		// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor,
		5,										// maxLOD
		scene::ETPS_17,							// patchSize
		4										// smoothFactor
		);

	terrain->setMaterialFlag(video::EMF_LIGHTING, true);

	terrain->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
	terrain->setMaterialTexture(1, driver->getTexture("../../media/Floor09.jpg"));
	
	terrain->setMaterialType(video::EMT_DETAIL_MAP);

	terrain->scaleTexture(1.0f, 40.0f);
	//terrain->setDebugDataVisible ( true );


	/*
	To be able to do collision with the terrain, we create a triangle selector.
	If you want to know what triangle selectors do, just take a look into the 
	collision tutorial. The terrain triangle selector works together with the
	terrain. To demonstrate this, we create a collision response animator 
	and attach it to the camera, so that the camera will not be able to fly 
	through the terrain.
	*/

	// create triangle selector for the terrain	
	scene::ITriangleSelector* selector
		= smgr->createTerrainTriangleSelector(terrain, 0);
	terrain->setTriangleSelector(selector);
	selector->drop();




	// create event receiver


// create skybox
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

	smgr->addSkyBoxSceneNode(
		driver->getTexture("../../media/irrlicht2_up.jpg"),
		driver->getTexture("../../media/irrlicht2_dn.jpg"),
		driver->getTexture("../../media/irrlicht2_lf.jpg"),
		driver->getTexture("../../media/irrlicht2_rt.jpg"),
		driver->getTexture("../../media/irrlicht2_ft.jpg"),
		driver->getTexture("../../media/irrlicht2_bk.jpg"));

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

		smgr->setShadowColor(video::SColor(150,0,255,0));
	    scene::IAnimatedMeshSceneNode* Character = smgr->addAnimatedMeshSceneNode(smgr->getMesh("knight.md2"));
	    Character->setMaterialFlag(video::EMF_LIGHTING, true);
		Character->setFrameLoop(160, 183);
		Character->setAnimationSpeed(40);
		Character->setMD2Animation(scene::EMAT_STAND);
		Character->setRotation(core::vector3df(0,180.0f,0));
		Character->setMaterialTexture(0, driver->getTexture("knight.bmp"));
		Character->addShadowVolumeSceneNode();
		Character->setPosition(core::vector3df(1900*2,255*2,3700*2));
        scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector, Character, core::vector3df(60,10,60),
		core::vector3df(0,-100,0), 
		core::vector3df(0,50,0));
	    Character->addAnimator(anim); 	
	    anim->drop();
        
		
        //Iron Golem
        scene::IAnimatedMesh* mesh = smgr->getMesh("Iron_Golem_X.x");
        scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
        node->setMaterialFlag(video::EMF_LIGHTING, true);
        node->setMaterialTexture(0,driver->getTexture("c_golem_iron.tga"));
        node->setPosition(core::vector3df(1900*2, 255*2, 3650*2));
        node->setRotation(core::vector3df(-90,-90,0));
        node->setScale(core::vector3df(0.3,0.3,0.3));
        node->setFrameLoop(200, 260);
        node->setAnimationSpeed(20);
        node->setLoopMode(true);
        node->addShadowVolumeSceneNode();
	    scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
		selector, node, core::vector3df(60,10,60),
		core::vector3df(0,-100,0), 
		core::vector3df(0,10,0));
	    node->addAnimator(anim2); 	
        anim2->drop();
        

	MyEventReceiver receiver(terrain,Character,device,camera);
	device->setEventReceiver(&receiver);

	int lastFPS = -1;

		

	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0 );

        receiver.attack();
		smgr->drawAll();
		env->drawAll();

		driver->endScene();

		// display frames per second in window title
		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = L"Messiah for all lights - OpenGL [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;
			// Also print terrain height of current camera position
			// We can use camera position because terrain is located at coordinate origin
			str += " Height: ";
			str += terrain->getHeight(camera->getAbsolutePosition().X, camera->getAbsolutePosition().Z);

			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}

Merci beaucoup !

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
518 invités en ligne
membre en ligne: -
RSS Feed