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
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)
Problème avec SetWindowsHookEx, Vista et UAC [ par Dugnouf ]
Bonjour, j'ai écrit un programme avec Visual C# 2008 qui entre autre utilise des interceptions clavier à l'aide de la fonction SetWindowsHookEx(). Le
Livres en rapport
|
Derniers Blogs
TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE !MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE ! par Vko
Hier durant une session dédiée aux Techdays 2012, j'ai eu le plaisir d'annoncer la sortie de la Béta 2 de Mishra Reader. C'est quoi ? Pour les utilisateurs, c'est une vraie expérience de lecture de flux RSS sur Windows. Rien à voir avec les produit...
Cliquez pour lire la suite de l'article par Vko [FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui m'ont suivi. Je profite de ce poste, pour faire le re...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|