Accueil > Forum > > > > Programme 2D très lent (gros débutant)
Programme 2D très lent (gros débutant)
samedi 7 juillet 2007 à 08:36:56 |
Programme 2D très lent (gros débutant)

meuh_ou_jeje
|
Bonjour, Tout d'abord, je tiens à dire que je suis très fortement débutant en programmation, surtout en c#. Ayant depuis peu plusieurs heures à perdre, j'ai voulu faire un petit jeu en 2D (du style rpg). Je n'utilise ni directx ni quoi que ce soit d'autre (je n'y connais absolument rien) et je me suis donc lancé en touriste avec pour seuls outils ceux de l'API de Visual Studio. Mon problème se situe dans la redéfinition de la méthode onPaint du formulaire affichant le jeu. protected override void OnPaint(PaintEventArgs e) { carte.dessiner(e); } Allons voir la méthode dessiner :
public void dessiner(PaintEventArgs e) { dessinerDecor(e); // On dessine le décor dessinerUnités(e); // puis les unités }Rien de bien palpitant, mais le problème est que à chaque déplacement d'une unité sur la carte, la méthode onPaint est appelée via la fonction invalidate(). Donc ça redessine tout à chaque fois que mon unité bouge, décor y compris (de plus, je redessine toutes les 100ms). Le problème vient du décor qui prend un temps fou à se redessiner (1 seconde !!), car si je désactive le décor, tout se fait très fluidement. C'est franchement pas génial de redessiner tout à chaque mouvement d'unité, mais je n'arrive pas à trouver une autre solution... J'ai essayé de faire des invalidate avec un rectangle comme argument pour ne redessiner que la zone où mon unité est en train de bouger, mais celà ne marche pas, ou du moins, je n'y arrive pas. :-( Que faire? Je bloque sur ce point depuis des heures, et ce n'est franchement pas celui qui m'intéresse le plus. Le problème est que je ne peux pas avancer plus loin dans la programmation car la lenteur du programme empêche tout autre test. PS: je stocke le décor dans une grilleDécor qui contient des objets Décor. Lors du dessin du décor, pour chaque élément Décor de grilleDécor, je dessine une image correspondant au type de décor (herbe, eau...). Ces images élémentaires sont en .gif de dimension 20x20 et pèsent moins de 100 octets. Merci d'avance pour d'éventuelles réponses.
|
|
samedi 7 juillet 2007 à 09:54:53 |
Re : Programme 2D très lent (gros débutant)

Julien237
|
Réponse acceptée !
Salut, Il y a plusieurs précautions à prendre, d'abord ne dessine pas ta map directement sur le graphics donné par PaintEventArgs. Au chargement de ton jeu dessine la map statique sur un bitmap, puis utilise graphics.DrawImageUnscaledClipped lors du dessin en clippant le bon morceau. Tu devras utiliser graphics.TranslateTransform pour la placer au bon endroit. Rien qu'en faisant ça tu y gagneras déjà beaucoup.
Ensuite pour les autres éléments du décors, qui pourraient ne pas être statiques, appliquent la même technique à une différence près. Tu ajoute un flag booléen disant si le bitmap a besoin d'être redessiné ou pas. Lorsqu'une propriété affectant l'apparence de ton élément de décors change, tu lève le flag. Lors du dessin, si le flag est levé, tu l'abaisse et tu redessine ton bitmap, puis tu fais le rendu de la même manière qu'au point précédant.
Tu gagneras beaucoup à utiliser DrawImageUnscaled plutot que DrawImage. A toi de leur donner directment la bonne taille.
Essaye de voir ce qui prend vraiment du temps dans ton dessin, c'est pas toujours évident, utilise System.Diagnostic.Stopwatch pour mesurer les temps dans ton code.
Sinon la vraie solution ce serait quand même du directx, mais je pense que y'a quand même moyen de faire de chouettes choses avec GDI+...
Julien.
|
|
samedi 7 juillet 2007 à 10:10:24 |
Re : Programme 2D très lent (gros débutant)

Bidou
|
Moi je connais un gros wrapper directX qui s'appelle WPF 
- Blog-
|
|
samedi 7 juillet 2007 à 10:36:43 |
Re : Programme 2D très lent (gros débutant)
|
samedi 7 juillet 2007 à 12:54:31 |
Re : Programme 2D très lent (gros débutant)

Lutinore
|
Salut, 1 seconde pour dessiner le background, c'est pas normal.. GDI+ n'est pas super performant mais avec un double buffer et en limitant les zones à dessiner on peut faire des choses sympas.
public partial class Form1 : Form { private const int WIDTH = 800; // client size width. private const int HEIGHT = 600; // client size height. private const int W = 20; // tile width. private const int H = 20; // tile height; private const int X = WIDTH / W; // tile x count. private const int Y = HEIGHT / H; // tile y count;
private Bitmap[ ] tiles = null; private byte[ , ] map = null;
public Form1( ) { InitializeComponent( );
this.ClientSize = new Size( WIDTH, HEIGHT ); this.BackColor = Color.Black; this.FormBorderStyle = FormBorderStyle.FixedSingle; this.StartPosition = FormStartPosition.CenterScreen; this.SetStyle // Double buffer. ( ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true );
// Les tiles font 20x20 pour eviter d'être redimensionnés. tiles = new Bitmap[ 4 ] { new Bitmap( "tile1.bmp" ), new Bitmap( "tile2.bmp" ), new Bitmap( "tile3.bmp" ), new Bitmap( "tile4.bmp" ) };
map = new byte[ X, Y ];
Random r = new Random( ( int )DateTime.Now.Ticks );
for( int x = 0; x < X; x++ ) { for ( int y = 0; y < Y; y++ ) { map[ x, y ] = ( byte )r.Next( 0, 4 ); // Aléatoire pour l'exemple. } }
// Une boucle avec DoEvent peut être mieux qu'un timer, // ou invalider seulement dans un OnMouseDown ou KeyDown .. Timer t = new Timer( ); t.Interval = 100; t.Tick += delegate { Invalidate( this.ClientRectangle ); }; t.Start( ); }
protected override void OnPaint( PaintEventArgs args ) { //base.OnPaint( args );
Graphics g = args.Graphics;
for( int x = 0; x < X; x++ ) { for ( int y = 0; y < Y; y++ ) { g.DrawImage( tiles[ map[ x, y ] ], x * W, y * H ); } } } }
|
|
samedi 7 juillet 2007 à 21:09:49 |
Re : Programme 2D très lent (gros débutant)

yann_lo_san
|
Il y a un moyen simple de ne redessiner que la partie qui est derriere le sprite qui vient de bouger :
1 - on dessine le fond (qui est presque toujours statique) Image imgFond = new Bitmap("leFond.bmp"); g.Draw ect...
2 - dans la méthode qui deplace les sprites on récupère les coordonnées des sprites avant qu'ils ne bougent int xOld = X_EN_COURS; int yOld = Y_EN_COURS; int w = sprite.Width; int h = sprite.Height;
3 - On bouge le sprite
4 - On ne redessine du fond, que l'ancienne position du sprite de dimention de celui-ci
BitmapData bmpData = imgFond.LockBits(new Rectangle(xOld, yOld, w, h), ImageLockMode.ReadWrite, imgFond.PixelFormat); int stride = bmpData.Stride; System.IntPtr scan0 = bmpData.Scan0;
// morceau de l'image de fond a dessiner
Bitmap morceauBmp = new Bitmap( w, h, stride, imgFond.PixelFormat, scan0)
// dessine le morceau g.Draw ect...
// on peut travailler au niveau pixel directement avec les pointeurs C# // pour faire des effet de couleurs
unsafe { byte* p = (byte*)(void*)scan0; int offset = stride - w * 3; p[offset] = 0x00ffff; }
// UnlockBits(...)
Mais le mieux n'étant pas toujours l'ennemis du bien, DIRECTX en dotnet est très agréable à utiliser....
|
|
samedi 7 juillet 2007 à 21:41:02 |
Re : Programme 2D très lent (gros débutant)

Julien237
|
Bon je recommence avec firefox vu qu'apparemment IE est allergique à ce forum (ou le contraire ?)
Je disais, Si tu clippe la partie où ça a bougé, puis que tu demande de redessiner tout, normalement GDI ne redessine que la partie clippée non ? Ce serait quelque peu plus simple non ?
Julien.
|
|
dimanche 8 juillet 2007 à 02:42:56 |
Re : Programme 2D très lent (gros débutant)

meuh_ou_jeje
|
Problème résolu facilement ! Merci beaucoup pour toutes vos réponses, c'est très sympa.
J'ai suivi vos conseils et crée un bitmap qui sert pour le décor statique, et j'ai mis des flags pour redessiner éventuellement le décor modifiable. À vrai dire cette idée me trottait en tête avant de vous poser ma question mais je ne savais pas à l'époque comment déclarer une image.
class Carte { /* Attributs */ private static const int LARGEUR_CARTE = 460, LONGUEUR_CARTE=300; private Bitmap decor = new Bitmap(LARGEUR_CARTE, LONGUEUR_CARTE);
... /* Fonction permettant de dessiner tous les décors de la grille */ private void dessinerDecor(PaintEventArgs e) { Graphics g = Graphics.FromImage(decor); Pour chaque élément de la grille de décor, si son flag est à true { elem.dessiner(g); mettre le flag à faux; } e.Graphics.DrawImageUnscaled(decor, 0, 0, LARGEUR_CARTE, LONGUEUR_CARTE); // Puis finalement on dessine le décor }
Voilà, c'est tout bête, tout simple et ça marche, il fallait donc créer une image fixe ! A chaque fois que le formulaire se rafraîchit, aucun problème, ça s'affiche direct. Je m'occuperai du clipping plus tard, quand j'aurai des maps plus grandes :-)
Merci à vous tous et bonne journée.
|
|
Cette discussion est classée dans : problème, programme, unité, 2d, décor
Répondre à ce message
Sujets en rapport avec ce message
Limiter les ressources utilisé par un programme [ par kezyr ]
BonjourVoila, j'expose mon problème : j'ai un programme avec une fonction qui comporte 14 boucle for imbriqué (oui je sais, c'est beaucoup, mais oblig
Problème avec Windows Installer [ par DevilYann ]
Salut G un petit problème urgent à résoudre car je bosse en informatique et je dois corriger ce bug le plus rapidement possible pour envoyer le corre
TextBox + Problème [ par emmanuel9 ]
Bonjour à tous, J'ai un textbox que j'ai dérivé et je l'ais appliqué à tout les textbox de mon programme, le problème est que mon textbox n'est pas
Problème de sécurité.net [ par avildark ]
Bonjour,actuellement je modifie un programme en c# que je n'ai pas concu, qui passea la compilation , a l'éxecution, mais des que je le met sur un lec
Problème de mémoire [ par chandler8692 ]
Salut, après 2 semaines acharnées, j'ai enfin fini le programme que j'avais entrepri defaire dans le cadre de mes TIPE. Je l'ai fini aujourd'hui mais
problème avec une erreur [ par choukri175 ]
Bonjour à tous et à toutes,J'ai un petit programme qui a bien marché dans une forme, alors je l'ai copié dans une autre form.lorsque j'exécute mon pro
Form affiché l'écran [ par taoetc ]
Bonjour,je vous explique mon problème :j'ai une form principale qui appelle une autre form ( mais pas en MDI). Je lance la seconde form en pricisant q
Problème de compilation d'une Application C# sur SmartPhone [ par Mohammad000 ]
SalamJ'ai un problème lors de la compilation d'un programme écris en Visual Studio 2008 (C#), Mon programme doit tourner dans un SmartPhone, il doit p
Openfiledialog, problème bouton annuler [ par yabiyou ]
Bonjour,J'ai dans mon programme une openfiledialog qui me perrmet de selectionner des fichiers pour la suite du code. Tout se passe bien lorsque je sé
problème avec un fichier XML [ par suethi75 ]
BonsoirJe développe un petite application en C# orienté Objet. Cependant, j'ai un soucis. private void button1_Click(object sender, EventArgs e)
Livres en rapport
|
Derniers Blogs
UNE JOLIE-HORLOGE ET PAS QU'UN PEU !UNE JOLIE-HORLOGE ET PAS QU'UN PEU ! par neodante
Pour les possesseurs d'iPhone, ça y est Bijin Tokei - qui se traduit littéralement en Français par " Jolie Horloge " - est arrivé et GRATUITEMENT s'il vous plaît ! Après la version Tokyo, Hokkaido, night club, racing, Gal, "pour les mademoiselles'", . voi...
Cliquez pour lire la suite de l'article par neodante TECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICESTECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICES par ROMELARD Fabrice
Animé par: Gaetan Bouveret et Julien Chomarat Business Connectivity Services (BCS) est dans SharePoint 2010 la version 2 de Business Data Catalog (BDC dans SharePoint 2007). Il s'agit de la solution permettant de visualiser des données provenan...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE[DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE par orion
Comme de nombreux geek, je suis un grand amateur de série TV et je rate régulièrement des épisodes de mes séries préférés. Une solution s'offre à vous avec ce merveilleux site : Tv Gorge - www.tvgorge.com Moteur de recherche à l'appui, vous pouvez ...
Cliquez pour lire la suite de l'article par orion TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Vincent Bellet et Baptiste Giraudier La BI dans SharePoint 2010, Les nouveaux services d'application dans SP2010 et SQL Server Reporting services 2008 R2. La BI dans SharePoint est généralisée pour tous afin de permettre à tous les coll...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|