Historique des modifications - Message

Message #4545

Sujet: Petit moteur "tilemap" en C# avec Irrlicht.


Type Date Auteur Contenu
Dernière modification 10-09-2008 20:16:50 Krankmann
J'ai essayé de compiler le tuto sous Mono (linux), et, une flopée d'erreurs apparait, parmi lesquelles certaines me semblent assez bizarres...

Enfin bref, j'ai "corrigé" (essayé de corriger serait plus juste) le code, et voilà ce que ça donne (étant donné que j'ai fait à moitié des copier-collers, et que j'ai repris une bonne partie afin de me familiariser, tous les commentaires ne sont pas là...)

Si ça peut intéresser quelqu'un...

using System;

using System.Collections.Generic;

using System.Windows.Forms;

using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;

namespace TileTutorial

{
	public class TileEngine

    {
		// La taille de la carte

        const int Mapsize_X = 32;

        const int Mapsize_Y = 32;



        // La taille de la fenêtre d'affichage

        const int Windowsize_X = 800;

        const int Windowsize_Y = 600;



        // Le device Irrlicht et ses petits.

        public static IrrlichtDevice device;

        public static SceneManager smgr;

        public static VideoDriver driver;



        // La camera

        public static CameraSceneNode camera;



        // Les tiles

        public static SceneNode[,] FloorTile = new SceneNode[Mapsize_X, Mapsize_Y];



        // Le joueur

        public static AnimatedMeshSceneNode Player;



        // La position où le joueur doit aller.

        public static Vector3D playertargetpos;



        // Une source de lumière

        public static LightSceneNode light;
		
		public static bool Running;
		
		static double pi =3.1415926535;
		
		static void Main()

        {
			// Création du device Irrlicht
			device = new IrrlichtDevice(DriverType.OpenGL, new Dimension2D(640, 480), 32, false, true, true, true);
            device.FileSystem.WorkingDirectory = "./media";
			device.OnEvent += new OnEventDelegate(device_OnEvent);
			smgr = device.SceneManager;
			driver = device.VideoDriver;
			//Initialisation du gestionnaire d'évènement
			

			// On charge le mesh utilisé pour le sol.
			Mesh TileMesh = smgr.GetMesh("floor.x").GetMesh(0);
			TileMesh = smgr.MeshManipulator.CreateMeshWithTangents(TileMesh);
			
			Texture TileTex = driver.GetTexture("floor.jpg");
			
			// Et la normal map.

            Texture TileTexNormal = driver.GetTexture("floor_normal.jpg");
			
			for (int i = 0; i < Mapsize_X; i++)

                for (int j = 0; j < Mapsize_Y; j++)

                {

                    // Très important : les nodes des tiles ont une ID de 1! Cela servira lors de la détection

                    // des clics.

                    FloorTile[i, j] = smgr.AddMeshSceneNode(TileMesh, null, 1);

//                    FloorTile[i, j].SetMaterialFlag(MaterialFlag.LIGHTING, false);

                    FloorTile[i, j].SetMaterialTexture(0, TileTex);

                    FloorTile[i, j].Position = new Vector3D(i * 5, 0, j * 5);





                        FloorTile[i, j].SetMaterialTexture(1, TileTexNormal);

                        FloorTile[i, j].SetMaterialType(MaterialType.NormalMapSolid);



                }
			
			Player = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("sydney.md2"));

            Player.SetMaterialTexture(0, driver.GetTexture("sydney.bmp"));

            Player.Position = new Vector3D(2.5f, 2.5f, 2.5f);

            // Syndey est un peu grosse, alors on va la réduire.

            Player.Scale = new Vector3D(0.15f, 0.15f, 0.15f);

            Player.SetFrameLoop(0,159);
			
			playertargetpos = Player.Position;
			
			// On ajoute la caméra...

            camera = smgr.AddCameraSceneNode(null);
			camera.Position=new Vector3D(0, 0, 0);                              
			camera.Target=new Vector3D(0, 25, 25);                                 


            // Et une petite source de lumière, histoire qu'on y voit quelque chose.

            light = smgr.AddLightSceneNode(null, new Vector3D(25, 25, 25), new Colorf(1.0f,1.0f, 0.95f, 0.9f), 100, 0);
			
			            // Et voici donc cette boucle de dessin principale.
			
			Running=true;

           // DrawLoop();
			int lastFPS = -1;
			while (device.Run())
			{
				if (device.WindowActive)
				{
                    device.VideoDriver.BeginScene(true, true, new Color(255, 100, 101, 140));

					device.SceneManager.DrawAll();
					 driver.EndScene();
					if ((playertargetpos.X != Player.Position.X) ||(playertargetpos.Z != Player.Position.Z))

                {

                    float speedx = 0.0f;

                    float speedz = 0.0f;
					
					// On vérifie l'axe X

                    if (Player.Position.X < playertargetpos.X) speedx = 0.1f;

                    else if (Player.Position.X > playertargetpos.X) speedx = -0.1f;



                    // On vérifie l'axe Z

                    if (Player.Position.Z < playertargetpos.Z) speedz = 0.1f;

                    else if (Player.Position.Z > playertargetpos.Z) speedz = -0.1f;
					
								// On fait bouger tout ça...

                    Player.Position = new Vector3D(Player.Position.X + speedx, 2.5f, Player.Position.Z + speedz);
						
						//Pour éviter un effet de "sautillement", si le joueur est suffisemment près de sa position

                    //cible, on l'y place directement.

                    if (Math.Abs(Player.Position.X - playertargetpos.X) < 0.15f)

                        Player.Position = new Vector3D(playertargetpos.X, 2.5f, Player.Position.Z);



                    if (Math.Abs(Player.Position.Z - playertargetpos.Z) < 0.15f)

                        Player.Position = new Vector3D(Player.Position.X, 2.5f, playertargetpos.Z);
				}
				                // La lumière suit le joueur, puisqu'il a un "ring of light +1"

                // Je ne vous l'avait pas dit? Maintenant, c'est fait.

                light.Position = new Vector3D(Player.Position.X +10, 5, Player.Position.Z +10);
				
				                // La caméra suit le perso

                camera.Position = new Vector3D(Player.Position.X + 10, 15, Player.Position.Z + 10);

                camera.Target = Player.Position;

					int fps = device.VideoDriver.FPS;

				}
			}



            // On est sorti de la boucle principale car la fenêtre n'est plus active.

            // Il ne reste plus...



            // 1- Qu'à détruire le device

            device.Dispose();



            // 2- Et à faire un peu le ménage dans la mémoire.

            GC.Collect();
			
		}
		static bool device_OnEvent(Event e)

        {

            if (e.KeyCode == KeyCode.Escape)

                TileEngine.Running = false;
			
			
				 // Si c'est pas la souris, poubelle. Il n'y a que la souris qui nous intéresse.

            if (e.Type != EventType.MouseInputEvent) return false;



            // Un clic gauche... Ah, ah! Ca veut dire que le joueur veut bouger.

            if (e.MouseInputEvent == MouseInputEvent.LMousePressedDown)

            {

                // On doit trouver sur quel tile le joueur a cliqué.

                // Ca se fait avec le SceneCollisionManager.

                // Notez que le paramètre "idbitmask" permet de ne prendre en compte que certains nodes.

                // (Ici, ceux avec l'ID 1, donc les tiles. Cliquer sur Sydney ne fait donc rien).

                SceneNode ClickedNode =

                    TileEngine.smgr.CollisionManager.GetSceneNodeFromScreenCoordinates(e.MousePosition, 1, true);



                // Si le joueur n'a pas cliqué sur une tile, on oublie tout ça...

                if (ClickedNode == null) return false;



                // Sinon, le joueur doit maintenant aller sur cette tile.

                // On ajoute 2,5 aux coordonnées X et Z pour que le joueur aille au centre de la tile, pas

                // dans un coin.

                TileEngine.playertargetpos =

                    new Vector3D(ClickedNode.Position.X + 2.5f, 0, ClickedNode.Position.Z + 2.5f);

            }



            return false;
			}
				
					
	}
}

PS : vu la date du dernier message, il se pourrait fortement que ces erreurs soient dues à un (voir plusieurs) changements de syntaxe dans irrlicht.

PPS : En fait, il s'agit d'une convertion vers Irrlicht.Net CP ^^
Création du message 10-09-2008 20:12:04 Krankmann
J'ai essayé de compiler le tuto sous Mono (linux), et, une flopée d'erreurs apparait, parmi lesquelles certaines me semblent assez bizarres...

Enfin bref, j'ai "corrigé" (essayé de corriger serait plus juste) le code, et voilà ce que ça donne (étant donné que j'ai fait à moitié des copier-collers, et que j'ai repris une bonne partie afin de me familiariser, tous les commentaires ne sont pas là...)

Si ça peut intéresser quelqu'un...

using System;

using System.Collections.Generic;

using System.Windows.Forms;

using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;

namespace TileTutorial

{
	public class TileEngine

    {
		// La taille de la carte

        const int Mapsize_X = 32;

        const int Mapsize_Y = 32;



        // La taille de la fenêtre d'affichage

        const int Windowsize_X = 800;

        const int Windowsize_Y = 600;



        // Le device Irrlicht et ses petits.

        public static IrrlichtDevice device;

        public static SceneManager smgr;

        public static VideoDriver driver;



        // La camera

        public static CameraSceneNode camera;



        // Les tiles

        public static SceneNode[,] FloorTile = new SceneNode[Mapsize_X, Mapsize_Y];



        // Le joueur

        public static AnimatedMeshSceneNode Player;



        // La position où le joueur doit aller.

        public static Vector3D playertargetpos;



        // Une source de lumière

        public static LightSceneNode light;
		
		public static bool Running;
		
		static double pi =3.1415926535;
		
		static void Main()

        {
			// Création du device Irrlicht
			device = new IrrlichtDevice(DriverType.OpenGL, new Dimension2D(640, 480), 32, false, true, true, true);
            device.FileSystem.WorkingDirectory = "./media";
			device.OnEvent += new OnEventDelegate(device_OnEvent);
			smgr = device.SceneManager;
			driver = device.VideoDriver;
			//Initialisation du gestionnaire d'évènement
			

			// On charge le mesh utilisé pour le sol.
			Mesh TileMesh = smgr.GetMesh("floor.x").GetMesh(0);
			TileMesh = smgr.MeshManipulator.CreateMeshWithTangents(TileMesh);
			
			Texture TileTex = driver.GetTexture("floor.jpg");
			
			// Et la normal map.

            Texture TileTexNormal = driver.GetTexture("floor_normal.jpg");
			
			for (int i = 0; i < Mapsize_X; i++)

                for (int j = 0; j < Mapsize_Y; j++)

                {

                    // Très important : les nodes des tiles ont une ID de 1! Cela servira lors de la détection

                    // des clics.

                    FloorTile[i, j] = smgr.AddMeshSceneNode(TileMesh, null, 1);

//                    FloorTile[i, j].SetMaterialFlag(MaterialFlag.LIGHTING, false);

                    FloorTile[i, j].SetMaterialTexture(0, TileTex);

                    FloorTile[i, j].Position = new Vector3D(i * 5, 0, j * 5);





                        FloorTile[i, j].SetMaterialTexture(1, TileTexNormal);

                        FloorTile[i, j].SetMaterialType(MaterialType.NormalMapSolid);



                }
			
			Player = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("sydney.md2"));

            Player.SetMaterialTexture(0, driver.GetTexture("sydney.bmp"));

            Player.Position = new Vector3D(2.5f, 2.5f, 2.5f);

            // Syndey est un peu grosse, alors on va la réduire.

            Player.Scale = new Vector3D(0.15f, 0.15f, 0.15f);

            Player.SetFrameLoop(0,159);
			
			playertargetpos = Player.Position;
			
			// On ajoute la caméra...

            camera = smgr.AddCameraSceneNode(null);
			camera.Position=new Vector3D(0, 0, 0);                              
			camera.Target=new Vector3D(0, 25, 25);                                 


            // Et une petite source de lumière, histoire qu'on y voit quelque chose.

            light = smgr.AddLightSceneNode(null, new Vector3D(25, 25, 25), new Colorf(1.0f,1.0f, 0.95f, 0.9f), 100, 0);
			
			            // Et voici donc cette boucle de dessin principale.
			
			Running=true;

           // DrawLoop();
			int lastFPS = -1;
			while (device.Run())
			{
				if (device.WindowActive)
				{
                    device.VideoDriver.BeginScene(true, true, new Color(255, 100, 101, 140));

					device.SceneManager.DrawAll();
					 driver.EndScene();
					if ((playertargetpos.X != Player.Position.X) ||(playertargetpos.Z != Player.Position.Z))

                {

                    float speedx = 0.0f;

                    float speedz = 0.0f;
					
					// On vérifie l'axe X

                    if (Player.Position.X < playertargetpos.X) speedx = 0.1f;

                    else if (Player.Position.X > playertargetpos.X) speedx = -0.1f;



                    // On vérifie l'axe Z

                    if (Player.Position.Z < playertargetpos.Z) speedz = 0.1f;

                    else if (Player.Position.Z > playertargetpos.Z) speedz = -0.1f;
					
								// On fait bouger tout ça...

                    Player.Position = new Vector3D(Player.Position.X + speedx, 2.5f, Player.Position.Z + speedz);
						
						//Pour éviter un effet de "sautillement", si le joueur est suffisemment près de sa position

                    //cible, on l'y place directement.

                    if (Math.Abs(Player.Position.X - playertargetpos.X) < 0.15f)

                        Player.Position = new Vector3D(playertargetpos.X, 2.5f, Player.Position.Z);



                    if (Math.Abs(Player.Position.Z - playertargetpos.Z) < 0.15f)

                        Player.Position = new Vector3D(Player.Position.X, 2.5f, playertargetpos.Z);
				}
				                // La lumière suit le joueur, puisqu'il a un "ring of light +1"

                // Je ne vous l'avait pas dit? Maintenant, c'est fait.

                light.Position = new Vector3D(Player.Position.X +10, 5, Player.Position.Z +10);
				
				                // La caméra suit le perso

                camera.Position = new Vector3D(Player.Position.X + 10, 15, Player.Position.Z + 10);

                camera.Target = Player.Position;

					int fps = device.VideoDriver.FPS;

				}
			}



            // On est sorti de la boucle principale car la fenêtre n'est plus active.

            // Il ne reste plus...



            // 1- Qu'à détruire le device

            device.Dispose();



            // 2- Et à faire un peu le ménage dans la mémoire.

            GC.Collect();
			
		}
		static bool device_OnEvent(Event e)

        {

            if (e.KeyCode == KeyCode.Escape)

                TileEngine.Running = false;
			
			
				 // Si c'est pas la souris, poubelle. Il n'y a que la souris qui nous intéresse.

            if (e.Type != EventType.MouseInputEvent) return false;



            // Un clic gauche... Ah, ah! Ca veut dire que le joueur veut bouger.

            if (e.MouseInputEvent == MouseInputEvent.LMousePressedDown)

            {

                // On doit trouver sur quel tile le joueur a cliqué.

                // Ca se fait avec le SceneCollisionManager.

                // Notez que le paramètre "idbitmask" permet de ne prendre en compte que certains nodes.

                // (Ici, ceux avec l'ID 1, donc les tiles. Cliquer sur Sydney ne fait donc rien).

                SceneNode ClickedNode =

                    TileEngine.smgr.CollisionManager.GetSceneNodeFromScreenCoordinates(e.MousePosition, 1, true);



                // Si le joueur n'a pas cliqué sur une tile, on oublie tout ça...

                if (ClickedNode == null) return false;



                // Sinon, le joueur doit maintenant aller sur cette tile.

                // On ajoute 2,5 aux coordonnées X et Z pour que le joueur aille au centre de la tile, pas

                // dans un coin.

                TileEngine.playertargetpos =

                    new Vector3D(ClickedNode.Position.X + 2.5f, 0, ClickedNode.Position.Z + 2.5f);

            }



            return false;
			}
				
					
	}
}

PS : vu la date du dernier message, il se pourrait fortement que ces erreurs soient dues à un (voir plusieurs) changements de syntaxe dans irrlicht.

PPS : En fait, il s'agit d'une convertion vers Irrlicht.Net CP ^^

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
527 invités en ligne
membre en ligne: -
RSS Feed