Cannot modify the return value of

馋奶兔 提交于 2019-12-11 01:26:37

问题


I'm new at C# so, sorry in advance if this question is a bit silly, I get a error when i try to run the program. From visual Studio 2012 I got this error message "Cannot modify the return value of 'GameName1.Cartman.Position' because it is not a variable" 2 times, on line 30 and 31. I hope some one can help me with this.

here is the code:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameName1
{
    class Cartman
    {
        public Vector2 Position { get; set; }
        public float Scale { get; set; }
        public int Direction { get; set; }
        public float Rotation { get; set; }
        public Texture2D Texture { get; set; }

    public Vector2 Origin {
        get
        {
            return new Vector2(Texture.Width / 2, Texture.Height / 2);
        } 
    }

    public Rectangle BoundingBox
    { 
        get 
        {
            return new Rectangle(
                (int)(Position.X = Texture.Width / 2 * Scale), // line 30
                (int)(Position.Y = Texture.Width / 2 * Scale), // line 31
                (int)(Texture.Width * Scale),
                (int)(Texture.Height * Scale)
                );
        }
    }
    public Cartman()
    {
        Direction = 1; //standaard naar rechts
    }
    }
}

and here is my other class:

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
#endregion

namespace GameName1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        private Cartman _cartman;

        public Game1()
            : base()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            _cartman = new Cartman();
            _cartman.Position = new Vector2(100, 100);
            _cartman.Scale = 0.3f;

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            _cartman.Texture = Content.Load<Texture2D>("cartman");

        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here
            _cartman.Position = new Vector2(_cartman.Position.X + 1 *_cartman.Direction, _cartman.Position.Y);

            _cartman.Rotation += 0.3f * _cartman.Direction;

            if(!GraphicsDevice.Viewport.Bounds.Contains(_cartman.BoundingBox))
            {
                _cartman.Direction *= -1;
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Orange);

            // TODO: Add your drawing code here
            spriteBatch.Begin();

            spriteBatch.Draw(   _cartman.Texture,
                                _cartman.Position,
                                null,
                                Color.White,
                                _cartman.Rotation,
                                new Vector2 (0,0),
                                _cartman.Scale,
                                SpriteEffects.None,
                                0);

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

回答1:


The return value from a property is not considered a variable when the type is a struct.

So this:

(int)(Position.X = Texture.Width / 2 * Scale),

Attempts to assign a new value to the X property of the result of calling the Position property, but the Vector2 type is a struct, not a class.

This is basically telling you that you're attempting to shoot yourself in the foot, because returning a struct returns a copy. You would, if this error didn't pop up, modify the copy.

In other words, the above code is similar to this:

var temp = Position;
(int)(temp.X = Texture.Width / 2 * Scale),

But, since the variable is considered a copy of a struct, the "temp" variable in this case does not really exist as such, and thus the compiler prevents you from doing it this way.

So you need to read out the position vector to a variable, modify that, and then assign the whole variable back to the property.

Somewhat like this:

Position = new Vector2(Texture.Width / 2 * Scale, Texture.Width / 2 * Scale);
return new Rectangle(
    (int)Position.X,
    (int)Position.Y,
    (int)(Texture.Width * Scale),
    (int)(Texture.Height * Scale)
    );



回答2:


You aren't allowed to modify Vector2s like that (as the error indicates). Here's what would work:

Position = new Vector2(Texture.Width / 2 * Scale, Texture.Width / 2 * Scale);
return new Rectangle(
            (int)(Position.X),
            (int)(Position.Y),
            (int)(Texture.Width * Scale),
            (int)(Texture.Height * Scale)
            );

Note that instead of trying to modify the Vector2's components, I just create a new one, then use it in the rectangle constructor. Lasse V. Karlsen's answer contains a great explanation of why you aren't allowed to do this.



来源:https://stackoverflow.com/questions/23549720/cannot-modify-the-return-value-of

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!