大量CPU利用率 - XNA游戏循环

时间:2013-06-14 16:20:18

标签: c# performance profiling lag frame-rate

我和ANTS探测器一起浏览了我的游戏,看看是什么导致了我的极端FPS下降,我发现它与玩家的动作有关。请注意,每当我的播放器移动时,名为Microsoft.Win32.SafeNativeMethods.QueryPerformanceCounter的内容占用了我的CPU的75%左右。根据ANTS,它与System.Diagnostics.Stopwatch.GetTimestamp相关联。以下是分析器结果的屏幕截图:

enter image description here

这是我的所有代码:

Player.cs

namespace Innovationally
{
public class Player
{
    public Texture2D PlayerTexture;
    public Vector2 Position;
    public bool Active;
    public float angle;
    public int coins { get; set; }
    public int bombs { get; set; }
    public int normalaelever { get; set; }
    public int health { get; set; }
    public int damage { get; set; }
    public int maximumhealth { get; set; }
    public int problemelever { get; set; }
    public int mvgelever { get; set; }
    public int elever { get; set; }
    public int nyckel { get; set; }
    public int Width
    {
        get { return PlayerTexture.Width; }
    }
    public int Height
    {
        get { return PlayerTexture.Height; }
    }
    public void Initialize(Texture2D texture, Vector2 position)
    {
        PlayerTexture = texture;
        Position = position;
        Active = true;
        elever = 0;
        mvgelever = 0;
        normalaelever = 0;
        coins = 0;
        bombs = 0;
        health = 100;
        maximumhealth = 100;
        damage = 20;
        nyckel = 99;
        angle = (float)Math.PI * 2;
    }
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(PlayerTexture, Position, null, Color.White, angle, new Vector2(PlayerTexture.Width / 2, PlayerTexture.Height / 2), 1f, SpriteEffects.None, 0f);
    }
}
}

Game1.cs

namespace Innovationally
{
enum GameState
{
    TITLESCREEN,
    HELPSCREEN,
    PLAYING,
    WON,
    CONTROLS,
    LOST
}
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    GameState gameState = GameState.TITLESCREEN;

    //PLAYER STATS
    public static Player player;
    KeyboardState currentKeyboardState;
    KeyboardState previousKeyboardState;
    float playerMoveSpeed;
    int bHit;

    //LEVEL STATS
    Dictionary<Texture2D, uint[]> pixelMaps = new Dictionary<Texture2D,uint[]>();
    int level_number = 0;
    int loadlevel = 0;
    Texture2D hud, level0, level1, level2, level3, level4, level5;
    Vector2 levelPos;

    //ROOM STATS
    List<int> tile_life = new List<int>();
    Texture2D tile_gfx, stairsUp, stairsDown;
    List<Vector2> tile_position = new List<Vector2>();
    List<int> tile_type = new List<int>();
    List<int> tile_elev = new List<int>();
    int antlabb = 0;
    int antvapen = 0;
    int antpolis = 0;
    int antwavers = 0;
    TimeSpan researchSpan;
    int researchTime;

    //MISC
    SpriteFont font;
    Loot loot;

    //GAMEPLAY STATS
    TimeSpan timeElapsed;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        graphics.PreferredBackBufferHeight = 800;
        graphics.PreferredBackBufferWidth = 900;
    } 
    protected override void Initialize()
    {
        player = new Player();
        playerMoveSpeed = 4.0f;
        tile_elev.Add(1);
        levelPos.X = 0;
        levelPos.Y = 0;
        loot = new Loot();
        researchTime = 160 - (antlabb * 40);
        base.Initialize();
    }
    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);

        Vector2 playerPosition = new Vector2(430, 450);
        //LEVEL STATS
        LaddaLevel(level_number);
        level0 = Content.Load<Texture2D>("level0");
        level1 = Content.Load<Texture2D>("level1");
        level2 = Content.Load<Texture2D>("level2");
        level3 = Content.Load<Texture2D>("level3");
        level4 = Content.Load<Texture2D>("level4");
        level5 = Content.Load<Texture2D>("level5");
        player.Initialize(Content.Load<Texture2D>("Leftplayer"), playerPosition);
        //As you can see I'm using the new PixelMaps function here... 
        pixelMaps = PixelMaps(new[] { level0, level1, level2, level3, level4, level5, player.PlayerTexture });
        hud = Content.Load<Texture2D>("hud");

        //ROOM STATS
        tile_gfx = Content.Load<Texture2D>("tile");
        stairsUp = Content.Load<Texture2D>("stairsUp");
        stairsDown = Content.Load<Texture2D>("stairsDown");

        font = Content.Load<SpriteFont>("SpriteFont1");

        //SOMEONE STOP THE MUSIC, MUSIC.
        MediaPlayer.Volume = 0.5f;
        MediaPlayer.IsRepeating = true;
        MediaPlayer.Play(Content.Load<Song>("barn-beat"));
    }
    public void LaddaLevel(int nummer)
    {
        StreamReader SR = new StreamReader(nummer.ToString());

        string bana = SR.ReadToEnd();
        SR.Close();
        int temp_positionY = 0;
        int temp_positionX = 0;

        tile_position.Clear(); 
        tile_type.Clear();    
        tile_life.Clear();
        tile_elev.Clear();

        for (int i = 0; i < bana.Length; i++)
        {
            switch (bana[i])
            {
                case ' ':
                    temp_positionX++;
                    break;
                case '0':
                    tile_life.Add(loot.myRnd.Next(8));
                    tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
                    temp_positionX++;
                    tile_type.Add(int.Parse(bana[i].ToString()));
                    break;
                case '8': 
                    tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
                    temp_positionX++;
                    tile_type.Add(int.Parse(bana[i].ToString()));
                    tile_life.Add(8);
                    break;
                case '9': 
                    tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
                    temp_positionX++;
                    tile_type.Add(int.Parse(bana[i].ToString()));
                    tile_life.Add(9);
                    break;
                case '\n':
                    temp_positionY++;
                    temp_positionX = 0;
                    break;
            }
        }
    }
    protected override void UnloadContent()
    {
    }
    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();
        previousKeyboardState = currentKeyboardState;
        currentKeyboardState = Keyboard.GetState();
        if (currentKeyboardState.IsKeyDown(Keys.Escape) && previousKeyboardState.IsKeyUp(Keys.Escape))
            this.Exit();

        switch (gameState)
        {
            case GameState.TITLESCREEN:
                UpdatePlayer(gameTime);
                if (currentKeyboardState.IsKeyDown(Keys.S) && previousKeyboardState.IsKeyUp(Keys.S))
                    gameState = GameState.PLAYING;
                if (currentKeyboardState.IsKeyDown(Keys.H) && previousKeyboardState.IsKeyUp(Keys.H))
                    gameState = GameState.HELPSCREEN;
                break;
            case GameState.HELPSCREEN:
                if (currentKeyboardState.IsKeyDown(Keys.B) && previousKeyboardState.IsKeyUp(Keys.B))
                    gameState = GameState.TITLESCREEN;
                break;
            case GameState.PLAYING:
                timeElapsed += gameTime.ElapsedGameTime;
                UpdatePlayer(gameTime);
                UpdateResearchCenters(gameTime);
                UpdateCollisions(gameTime);
                break;
            case GameState.LOST:
                if (currentKeyboardState.IsKeyDown(Keys.S) && previousKeyboardState.IsKeyUp(Keys.S))
                {
                    loadlevel = 0;
                    gameState = GameState.PLAYING;
                }
                break;
        }
        base.Update(gameTime);
    }
    private void UpdatePlayer(GameTime gameTime)
    {
        if (currentKeyboardState.IsKeyDown(Keys.Left))
        {
            player.angle = (float)Math.PI * 1.5f;
            player.Position.X -= playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Right))
        {
            player.angle = (float)Math.PI / 2;
            player.Position.X += playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Up))
        {
            player.angle = (float)Math.PI * 2;
            player.Position.Y -= playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Down))
        {
            player.angle = (float)Math.PI;
            player.Position.Y += playerMoveSpeed;
        }
        if (player.health <= 0)
            gameState = GameState.LOST;

        switch (gameState)
        {
            case GameState.TITLESCREEN:
                if (player.Position.X > 800)
                    this.Exit();
                if (player.Position.X < 0)
                    gameState = GameState.PLAYING;
                if (player.Position.Y > 900)
                    gameState = GameState.HELPSCREEN;
                if (player.Position.Y < 0)
                    gameState = GameState.CONTROLS;
                break;
        }
    }
    public void UpdateResearchCenters(GameTime gameTime)
    {
        researchSpan -= (gameTime.ElapsedGameTime);
        researchTime = (int)researchSpan.Seconds;
        if (researchTime <= 0)
        {
            loot.RandomResearch();
            researchTime = 160 - (antlabb*40);
        }
    }
    public static uint[] Pixels(Texture2D texture)
    {
        uint[] data = new uint[texture.Width * texture.Height];
        texture.GetData(data);
        return data;
    }
    public static Dictionary<Texture2D, uint[]> PixelMaps(IEnumerable<Texture2D> textures)
    {
        return textures.ToDictionary(t => t, Pixels);
    }
    public static int TestCollision(uint[] t1, int t1Width, Rectangle r, uint[] t2)
    {
        for (var x = r.X; x < r.X + r.Width; x++)
            for (var y = r.Y; y < r.Y + r.Height; y++)
            {
                var i = x + (y * t1Width);
                /*if (((t1[i] & 0xff000000) > 0) && (t2[i] == 0xffC3C3C3))
                {
                    return 1;
                }
                if (((t1[i] & 0xff000000) > 0) && (t2[i] == 0xff000000))
                {
                    return 2;
                }*/
            }
        return 0;
    }
    public void UpdateCollisions(GameTime gameTime)
    {
        Rectangle playerBox = new Rectangle((int)player.Position.X - 20, (int)player.Position.Y - 20, 40, 37);
        Rectangle levelBox = new Rectangle(0, 0, 900, 800);

        for (int i = 0; i < tile_position.Count; i++)
        {
            Rectangle tileBox = new Rectangle((int)tile_position[i].X, (int)tile_position[i].Y, 100, 100);
            if (playerBox.Intersects(tileBox))
            {
                if (tile_life[i] <= 9)
                {
                    if (tile_life[i] == 9 && currentKeyboardState.IsKeyDown(Keys.Space)) 
                    {
                        loadlevel += 1;
                        LaddaLevel(loadlevel);
                    }
                    else if (tile_life[i] == 8 && currentKeyboardState.IsKeyDown(Keys.Space))
                    {
                        loadlevel -= 1;
                        LaddaLevel(loadlevel);
                    }
                    else if (tile_life[i] == 7 && currentKeyboardState.IsKeyDown(Keys.Space) && player.nyckel >= 1)
                    {
                        loot.RandomLoot();
                        player.nyckel -= 1;
                        tile_life[i] = 70; 
                    }
                    else if (tile_life[i] == 6 && currentKeyboardState.IsKeyDown(Keys.Space) && (player.mvgelever >=  1 || player.normalaelever >= 1 || player.problemelever >= 1))
                    {
                        tile_life[i] = 60;
                        if (player.mvgelever != 0)
                            player.mvgelever -= 1;
                        else if (player.normalaelever != 0)
                            player.normalaelever -= 1;
                        else if (player.problemelever != 0)
                            player.problemelever -= 1;
                        antlabb += 1;
                    }
                }
            }
        }
        var playerMap = pixelMaps[player.PlayerTexture];
        var level0Map = pixelMaps[level0];
        if (loadlevel == 0)
            bHit = TestCollision(playerMap, 15, playerBox, level0Map);

        if (bHit == 2)
            this.Exit();
    }
    private void DrawHud()
    {
        string timeString = "TIME: " + timeElapsed.Minutes.ToString("00") + ":" + timeElapsed.Seconds.ToString("00");

        spriteBatch.Draw(hud, new Vector2(0, 0), Color.White);
        spriteBatch.DrawString(font, timeString, new Vector2(15, 35), Color.White);
        spriteBatch.DrawString(font, "Level " + (loadlevel + 1), new Vector2(15, 10), Color.White);
        spriteBatch.DrawString(font, "" + player.mvgelever, new Vector2(739, 55), Color.White);
        spriteBatch.DrawString(font, "" + player.problemelever, new Vector2(799, 55), Color.White);
        spriteBatch.DrawString(font, "" + player.normalaelever, new Vector2(859, 55), Color.White);
        spriteBatch.DrawString(font, "" + antwavers, new Vector2(454, 55), Color.White);
        spriteBatch.DrawString(font, "" + antpolis, new Vector2(514, 55), Color.White);
        spriteBatch.DrawString(font, "" + antvapen, new Vector2(574, 55), Color.White);
        spriteBatch.DrawString(font, "" + antlabb, new Vector2(633, 55), Color.White);
        spriteBatch.DrawString(font, "" + player.coins, new Vector2(359, 55), Color.White);
        spriteBatch.DrawString(font, "" + player.nyckel, new Vector2(328, 55), Color.White);
        spriteBatch.DrawString(font, "" + player.bombs, new Vector2(296, 55), Color.White);
        spriteBatch.DrawString(font, "RESEARCH IN: " + researchTime, new Vector2(15, 55), Color.White);
    }
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();
        switch (gameState)
        {
            case GameState.TITLESCREEN:
                break;
            case GameState.PLAYING:
                if (loadlevel == 0)
                    spriteBatch.Draw(level0, new Vector2(0, 0), Color.White);
                if (loadlevel == 1)
                    spriteBatch.Draw(level1, new Vector2(0, 0), Color.White);
                if (loadlevel == 2)
                    spriteBatch.Draw(level2, new Vector2(0, 0), Color.White);
                if (loadlevel == 3)
                    spriteBatch.Draw(level3, new Vector2(0, 0), Color.White);
                if (loadlevel == 4)
                    spriteBatch.Draw(level4, new Vector2(0, 0), Color.White);
                if (loadlevel == 5)
                    spriteBatch.Draw(level5, new Vector2(0, 0), Color.White);
                for (int i = 0; i < tile_position.Count; i++)
                {
                    switch (tile_life[i])
                    {
                        case 0: spriteBatch.Draw(tile_gfx, tile_position[i], Color.White);
                            break;
                        case 1: spriteBatch.Draw(tile_gfx, tile_position[i], Color.HotPink);
                            break;
                        case 2: spriteBatch.Draw(tile_gfx, tile_position[i], Color.YellowGreen);
                            break;
                        case 3: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Purple);
                            break;
                        case 4: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Yellow);
                            break;
                        case 5: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Silver);
                            break;
                        case 6: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Gold);
                            break;
                        case 60: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Gold);
                            spriteBatch.Draw(player.PlayerTexture, new Vector2(tile_position[i].X + 35, tile_position[i].Y + 40), Color.White);
                            break;
                        case 7: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Orange);
                            break;
                        case 70: spriteBatch.Draw(tile_gfx, tile_position[i], Color.DarkOrange);
                            break;
                        case 8: spriteBatch.Draw(stairsDown, tile_position[i], Color.White);
                            break;
                        case 9: spriteBatch.Draw(stairsUp, tile_position[i], Color.White);
                            break;
                    }
                }
                DrawHud();
                player.Draw(spriteBatch);
                break;
        }
        spriteBatch.End();
        base.Draw(gameTime);
    }
}
}

有人能帮我识别这个内存泄漏吗?

0 个答案:

没有答案