我不能让XNA让我在MAIN类之外使用texture2D对象

时间:2014-06-09 01:57:14

标签: c# xna

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace TileEngine
{   
    class Renderer
    {
        GraphicsDevice mydevice;

        void doit()
        {
            int width = 400;
            int height = 400;
            Texture2D TEX = new Texture2D(mydevice, 400, 400);
            RenderTarget2D Mine = new RenderTarget2D(mydevice, width, height);
            GraphicsDevice.SetRenderTarget(Mine);

        }
    }
}

我得到的问题如下:

  

错误2当前上下文中不存在名称“我的”C:\ Users \ Programming \ Desktop \ Tengine \ TileEngine \ TileEngine \ Game1.cs 149 30 TileEngine

     

错误1非静态字段,方法或属性'Microsoft.Xna.Framework.Graphics.GraphicsDevice.SetRenderTarget(Microsoft.Xna.Framework.Graphics.RenderTarget2D)'C:\ Users \需要对象引用编程\桌面\ Tengine \ TileEngine \ TileEngine \ Renderer.cs 18 13 TileEngine

我理解面向对象编程的方式。这应该在技术上有效。也许我根本不懂XNA。我还在学习,所以是的。

我想要一个在主类之外渲染的类的原因是因为我将会有一些函数来为我做繁重的工作并且裁剪会根据我正在获得的参考框架而改变。我想基于这些大小的设置抛出Texture2D对象的新实例,每次我做渲染(每个帧)或者每次都有变化。还将对2D图像进行缩放和扭曲,以及缩放和照明效果。这是我想通过SEPARATE类处理的所有内容。

如果你无法为我提供解决方案,解决我的错误以及如何解决问题,请教我或向我展示正确的方法。

我现在已经解决了这个问题。嗯..

似乎我必须包含Microsoft.xna.Framework中的所有内容 即使我在命名空间TileEngine中也是如此..它不应该只是它的全部吗? 也出于某种原因...起初它不喜欢我在底部的那些线条中使用“mydevice” 然后..错误又开始消失了? 也许改变Game1.cs里面的错误,btw是我删除的东西的引用,修复了 渲染器里面的错误? 这没有任何意义但是......如果在Game1.cs内部存在关于完全不同的对象引用的错误,则渲染器不应该说我的设备在当前上下文中不存在

也许我不明白口译员的工作方式,但我的诚实意见应该永远不会发生。

以下是具有类似问题(需要清理)的任何人的固定代码

因为我尚未分离功能。 LOL。

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace TileEngine
{   
    class Renderer
    {
        GraphicsDevice mydevice;
        SpriteBatch spriteBatch;



        void doit()
        {
            int width = 400;
            int height = 400;
            Texture2D TEX = new Texture2D(mydevice, 400, 400);
            RenderTarget2D Mine = new RenderTarget2D(mydevice, width, height);
            mydevice.SetRenderTarget(Mine);

            mydevice.SetRenderTarget(null);
            Rectangle drawrect = new Rectangle(0, 0, 400, 400);
            spriteBatch.Begin();
            spriteBatch.Draw(Mine, drawrect, Color.White);
            spriteBatch.End();

        }


    }
}

也许我的编译器或ide只是愚蠢。它确实有一些重新编译故障与我的高清我认为它的Windows权限。嗯..感谢所有读过这篇文章的人。

================= NEW ISSUE相同的代码来源在这里开始===================== ================= 好的,现在我有一个新问题沿着同样的路线。 Microsoft xna试图在函数生命周期的开始实例化这些对象。 我似乎无法创建此类的实例将设备对象传递回主类。 这个解决方案不起作用,我想基本上说 嘿,给我一个目标渲染对象。哦,你走了。 抓住感谢好友。 在第二个函数中使用render

以上是他们上次工作时的两个功能...... 上次工作巨大的陈述。

唯一的问题是Game.Run()函数崩溃或我的主类绘图中的代码由于图形设备的问题为空而崩溃?

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace TileEngine
{
    class Renderer
    {
        GraphicsDevice mydevice;
        public SpriteBatch spriteBatch;



        public RenderTarget2D new_texture(int width, int height)
        {
            RenderTarget2D Mine = new RenderTarget2D(mydevice, width, height);
            Texture2D TEX = new Texture2D(mydevice, width, height);   //create the texture to render to
            mydevice.SetRenderTarget(Mine); //set the render device to the reference provided
            //maybe base.draw can be used with spritebatch. Idk. We'll see if the order of operation
            //works out. Wish I could call base.draw here.
            return Mine;    //I'm hoping that this returns the same instance and not a copy.

        }

        public void draw_texture(int width, int height, RenderTarget2D Mine)
        {
            mydevice.SetRenderTarget(null); //Set the renderer to render to the backbuffer again
            Rectangle drawrect = new Rectangle(0, 0, width, height); //Set the rendering size to what we want
            spriteBatch.Begin();                        //This uses spritebatch to draw the texture directly to the screen  
            spriteBatch.Draw(Mine, drawrect, Color.White); //This uses the color white
            spriteBatch.End();      //ends the spritebatch
            //Call base.draw after this since it doesn't seem to recognize inside the function
            //maybe base.draw can be used with spritebatch. Idk. We'll see if the order of operation
            //works out. Wish I could call base.draw here.
        }


    }
}

这是代码工作时的代码。 这是该类使用此代码时的代码:

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;

namespace TileEngine
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {

        public GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Renderer tileclipping = new Renderer();








        TileMap myMap = new TileMap();
        int squaresAcross = 12;
        int squaresDown = 12;

        public Game1()
        {
             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

            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);

            Tile.TileSetTexture = Content.Load<Texture2D>(@"Textures\TileSets\part1_tileset");

            // TODO: use this.Content to load your game content here
        }

        /// <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)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            KeyboardState ks = Keyboard.GetState();
            if (ks.IsKeyDown(Keys.Left))
            {
                Camera.Location.X = MathHelper.Clamp(Camera.Location.X - 8, 0, (myMap.MapWidth - squaresAcross) * 32);
            }

            if (ks.IsKeyDown(Keys.Right))
            {
                Camera.Location.X = MathHelper.Clamp(Camera.Location.X + 8, 0, (myMap.MapWidth - squaresAcross) * 32);
            }

            if (ks.IsKeyDown(Keys.Up))
            {
                Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y - 8, 0, (myMap.MapHeight - squaresDown) * 32);
            }

            if (ks.IsKeyDown(Keys.Down))
            {
                Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y + 8, 0, (myMap.MapHeight - squaresDown) * 32);
            }
            // TODO: Add your update logic here

            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.CornflowerBlue);
            //use the instance of renderer called tileclipping to generate a new texture of a specified size for tiles
            //this surface is 200 pixels by 200 pixels for the reason that it's the same as the clipping i'll choose



            Texture2D mytexture = new Texture2D(GraphicsDevice, 200, 200);
            RenderTarget2D Mine = new RenderTarget2D(graphics.GraphicsDevice, 200, 200);
            Mine = tileclipping.new_texture(200, 200);
            spriteBatch.Begin();

            Vector2 firstSquare = new Vector2(Camera.Location.X / 32, Camera.Location.Y / 32);
            int firstX = (int)firstSquare.X;
            int firstY = (int)firstSquare.Y;

            Vector2 squareOffset = new Vector2(Camera.Location.X % 32, Camera.Location.Y % 32);            
            int offsetX = (int)squareOffset.X;
            int offsetY = (int)squareOffset.Y;

            for (int y = 0; y < squaresDown; y++)
            {
                for (int x = 0; x < squaresAcross; x++)
                {
                    spriteBatch.Draw(
                        Tile.TileSetTexture,
                        new Rectangle((x * 32) - offsetX, (y * 32) - offsetY, 32, 32),
                        Tile.GetSourceRectangle(myMap.Rows[y + firstY].Columns[x + firstX].TileID),
                        Color.White);
                }
            }

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

            //There are two instances of mine
                //A new one is made each time tileclipping.new_texture is called
                    //This function can re use the copy created by new texture
                        //hopefully this saves on memory

                        tileclipping.draw_texture(200, 200, Mine);





            base.Draw(gameTime);
        }

        public CubeMapFace Tex2d { get; set; }
    }
}

请注意:我没有包含其他类,因为它们的功能没有引起任何问题。 如果这个问题太混乱,我可以通过pastebin给出导致问题的来源链接。 但基本上这件事就是说

以下是我遇到的这个问题的两个错误:

警告2字段'TileEngine.Renderer.device'永远不会被赋值,并且将始终具有其默认值null C:\ Users \ Programming \ Desktop \ Tengine \ TileEngine \ TileEngine \ Renderer.cs 11 24 TileEngine

警告1字段'TileEngine.Renderer.spriteBatch'永远不会被赋值,并且将始终具有其默认值null C:\ Users \ Programming \ Desktop \ Tengine \ TileEngine \ TileEngine \ Renderer.cs 10 28 TileEngine

崩溃信息是: 创建新资源时,GraphicsDevice不能为null。 参数名称:graphicsDevice

我将把我的工作留在这个状态,因为它是正确编译的最后一个状态。 现在等待帮助谢谢。 :3

2 个答案:

答案 0 :(得分:0)

您已经创建了Tesxture2D的实例,但没有给它任何数据。如果要从中绘制,则必须在其中设置数据,或者从硬盘驱动器上的文件加载数据,或者通过内容管道将其拉出(在这种情况下,必须在运行之前使用内容管道进行编译)该程序)。最后一个选项是推荐的方法(对于XNA和Monogame)。

此外,你走在正确的轨道上。渲染的典型设计是将其卸载到负责该对象其余部分的类中。我建议你将SpriteBatch传递给绘图方法,而不是让它成为类的成员。在加载内容时,这样做更容易。

答案 1 :(得分:0)

在渲染器中,尚未设置图形设备和精灵批处理。 您可以为渲染器类创建构造函数。像这样:

public Renderer(GraphicsDevice device, SpriteBatch spriteBatch)
{
   this.myDevice = device;
   this.spriteBatch = spriteBatch;
}

然后,在initialze()中:

tileClipping = new Renderer(graphics.GraphicsDevice, spriteBatch);