Aide Xna scrolling

Madaraa Messages postés 22 Date d'inscription mardi 11 août 2009 Statut Membre Dernière intervention 7 février 2013 - 23 déc. 2009 à 10:59
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 - 24 déc. 2009 à 23:56
Bien le bonjour amis programmeur j'ai un problème avec un projet de scrolling, l'erreur concerne le SourceRectangle sa me met "Un objet qui autorise la valeur Null doit posséder une valeur." quand j'essaye de bouger à droite ou à gauche merci à vous si vous trouver la solution bonne journée. voici ma classe game1.cs ainsi que ma classe Sprite:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Scrolling
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Sprite sprite;
Rectangle sourceRectangle;




public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
ServiceHelper.Game= this;
Components.Add(new ClavierManager(this));
graphics.PreferredBackBufferWidth = 200;// change la taille de la fiche en largeur
graphics.PreferredBackBufferHeight = 300;// change la taille de la fiche en hauteur
}

protected override void Initialize()
{
sourceRectangle = new Rectangle(100, 100, 100, 10);
base.Initialize();
}

protected override void LoadContent()
{
sprite = new Sprite(new Vector2(0,0));
spriteBatch = new SpriteBatch(GraphicsDevice);
sprite.LoadContent(Content, "Fond");

}

protected override void UnloadContent()
{

}

protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

if (ServiceHelper.Get().IsKeyDown(Keys.Right))
sprite.SourceRectangle = new Rectangle(sprite.SourceRectangle.Value.X + gameTime.ElapsedGameTime.Milliseconds / 10,0,200,300);
if (ServiceHelper.Get().IsKeyDown(Keys.Left))
sprite.SourceRectangle = new Rectangle(sprite.SourceRectangle.Value.X - gameTime.ElapsedGameTime.Milliseconds / 10,0,200,300);

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
sprite.Draw(spriteBatch);
spriteBatch.End();

base.Draw(gameTime);

}
}
}

voici aussi la classe ou SourceRectangle est utilisée:

class Sprite
{
Vector2 position;
Texture2D texture;
Rectangle destinationRectangle;
Rectangle? sourceRectangle;


public Vector2 Position
{
get { return position; }
set { position = value; }
}

public Rectangle? SourceRectangle
{
get { return sourceRectangle; }
set { sourceRectangle = value; }
}
public Sprite(Vector2 position)
{
this.position = position;
}

public Sprite(Vector2 position, Rectangle? sourceRectangle)
{
this.position = position;
this.sourceRectangle = sourceRectangle;

}
public Sprite(float x, float y, Texture2D texture, Rectangle? sourceRectangle)
{
this.position = new Vector2(x,y);
this.texture = texture;
this.sourceRectangle = sourceRectangle;
}
public void LoadContent(ContentManager content, string assetName)
{
texture = content.Load<Texture2D>(assetName);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, sourceRectangle, Color.White);
}
public Sprite(Rectangle destinationRectangle, Rectangle? sourcerectangle)
{
this.destinationRectangle = destinationRectangle;
this.sourceRectangle = sourcerectangle;
}



}
}

9 réponses

krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
23 déc. 2009 à 12:01
Salut

Merci d'encadrer ton code par des balises
 ... 
(avec [ et ] à la place de < et >

A quelle ligne ton exception est-elle générée exactement ?

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé ! -
0
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 12
23 déc. 2009 à 13:03
Houlàlà, tu n'as pas compris à quoi servait sourcerectangle dans la méthode draw du spritebatch.

Le paramètre source rectangle permet de récupérer une portion d'une image.
Imagine que tu as une image de 40x40 pixels et que ton source rectangle fait 20x20 pixels, alors la partie de l'image affichée à l'écran est de (0,0) à (19, 19).

Donc toi en appuyant sur les touches fléchées tu modifies ton source rectangle si bien qu'à un moment donnée ton rectangle source sort de la texture d'où l'erreur...

Lorsque je dis sort de la texture c'est que ta texture aura toujours 40x40 pixels mais ton source rectangle lui sera de ce style : 21 (X), 0 (Y), 20 (W), 20 (H)

d'où X + W 21 + 20 41 > 40 (taille texture) => erreur. La carte graphique ne peut pas savoir ce qu'il y'a au delà de 40 px...

Ici tu veux faire du scrolling alors la seule chose à changer est la position de l'image qui est affichée à l'écran et qui est représenté par la variable position (Vector2) de la méthode Draw.

Donc ici tu dois modifier ton code comme ceci :

classe Sprite :

public float PositionX
{
    get { return position.X; }
    set { position.X = value; }
}

public float PositionY
{
   get { return position.Y; }
   set { position.Y = value; }
}


et dans ta methode update de la classe générale :

if (ServiceHelper.Get().IsKeyDown(Keys.Right)) 
    sprite.PositionX += gameTime.ElapsedGameTime.Milliseconds / 10; 
if (ServiceHelper.Get().IsKeyDown(Keys.Left)) 
    sprite.PositionX -= gameTime.ElapsedGameTime.Milliseconds / 10; 


Voili voilou...
0
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 12
24 déc. 2009 à 09:59
Oups, j'ai dit n'imp Ce que je viens de te donner permet de déplacer l'image à l'écran.
Pour le scrolling de ton image (car je suppose que ton image à une taille supérieure à la taille du jeu) tu dois détecter que ton rectangle source ne dépasse pas la texture donc dans le setter SourceRectangle de ta classe sprite tu écris :

set
{
   sourceRectangle = value;
   int X = sourceRectangle.X;
   int Y = sourceRectangle.Y;
   int width = sourceRectangle.Width;
   int height = sourceRectangle.Height;
   int texWidth = texture.Width;
   int texHeight = texture.Height;

   if(X + width > texWidth)
     sourceRectangle.X = texWidth - width;

   if(Y + height > texHeight)
     sourceRectangle.Y = texHeight - height;
}
0
Madaraa Messages postés 22 Date d'inscription mardi 11 août 2009 Statut Membre Dernière intervention 7 février 2013
24 déc. 2009 à 10:49
Bonjour et merci de m'avoir répondu aussi rapidement , j'ai mis le bout de code que Master m'a mis sauf que Height .x .y Width ne sont pas reconnue dans ma classe Sprite auriez-vous une idée ?

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;



namespace Scrolling
{
    public class Sprite
    {
        Vector2 position;
        Texture2D texture;
        Rectangle destinationRectangle;
        Rectangle? sourceRectangle;



        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }

        public Rectangle? SourceRectangle
        {
            get
            {
                return sourceRectangle = new Rectangle(0, 0, 200, 300);
            }
            set
            {

                sourceRectangle = value;
                int X = sourceRectangle.X;// ici le x n'est pas reconnue
                int Y = sourceRectangle.Y;// ici le y
                int width = sourceRectangle.Width;//ici le width
                int height = sourceRectangle.Height;//et ici le height
                int texWidth = texture.Width;
                int texHeight = texture.Height;

                if (X + width > texWidth)
                    sourceRectangle.X = texWidth - width;

                if (Y + height > texHeight)
                    sourceRectangle.Y = texHeight - height;
            }
        }
        
        public Sprite(Vector2 position)
        {
            this.position = position;
        }

        public Sprite(Vector2 position, Rectangle? sourceRectangle)
        {
            this.position = position;
            this.sourceRectangle = sourceRectangle;
        }
        public Sprite(float x, float y, Texture2D texture, Rectangle? sourceRectangle)
        {
            this.position = new Vector2(x, y);
            this.texture = texture;
            this.sourceRectangle = sourceRectangle;
        }
        public void LoadContent(ContentManager content, string assetName)
        {
            texture = content.Load<Texture2D>(assetName);
        }
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, sourceRectangle, Color.White);
        }
        public Sprite(Rectangle destinationRectangle, Rectangle? sourcerectangle)
        {
            this.destinationRectangle = destinationRectangle;
            this.sourceRectangle = sourcerectangle;

        }
        public float PositionX
        {
            get { return position.X; }
            set { position.X = value; }
        }

        public float PositionY
        {
            get { return position.Y; }
            set { position.Y = value; }
        }




    }
}

mais quand je tape sourceRectangle dans game1.cs le x,y,height,width apparait.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 12
24 déc. 2009 à 17:16
Normal, j'ai pas pris en compte le ? de la propriété, cela devrait aller mieux :

set
{
     sourceRectangle = value;

     if(sourceRectangle.HasValue)
     {
          int X = sourceRectangle.X;// ici le x n'est pas reconnue
          int Y = sourceRectangle.Y;// ici le y
          int width = sourceRectangle.Width;//ici le width
          int height = sourceRectangle.Height;//et ici le height
          int texWidth = texture.Width;
          int texHeight = texture.Height;

          if (X + width > texWidth)
              sourceRectangle = new Rectangle(texWidth - width,
                                              sourceRectangle.Value.Y,
                                              sourceRectangle.Value.Width,
                                              sourceRectangle.Value.Height);

          if (Y + height > texHeight)
              sourceRectangle = new Rectangle(sourceRectangle.Value.X,
                                              texHeight - height,
                                              sourceRectangle.Value.Width,
                                              sourceRectangle.Value.Height); 
    }
}
0
Madaraa Messages postés 22 Date d'inscription mardi 11 août 2009 Statut Membre Dernière intervention 7 février 2013
24 déc. 2009 à 23:11
Bonsoir, j'ai toujours le même problème aux mêmes lignes même en ayant mis les modification de Master merci de m'aider
0
Madaraa Messages postés 22 Date d'inscription mardi 11 août 2009 Statut Membre Dernière intervention 7 février 2013
24 déc. 2009 à 23:19
bonsoir j'ai trouvé mon erreur je mettais sourceRectangle.X au lieu de sourceRecangle.Value.X mais j'ai toujours un petit problème quand je bouge avec mes touches flécher j'arrive à sortir de mon image je voudrais que sa bloque pouvez-vous m'aidez svp .
0
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 12
24 déc. 2009 à 23:22
Envoie moi par MP ton mail, je t'enverrais le mien et tu m'enverras ton projet complet, parce que normalement avec ce que j'ai écris tu ne devrais plus avoir de problème...
0
MasterShadows Messages postés 268 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 19 avril 2012 12
24 déc. 2009 à 23:56
Après réflexion change les opérateur > en >=
0
Rejoignez-nous