Avatar billede mcgoat Nybegynder
09. august 2009 - 22:47 Der er 14 kommentarer og
1 løsning

List of List.RemoveAt()

void DrawSmoke()
        {
            foreach (Vector2 smokePos in smokeList)
            {
                spriteBatch.Draw(smokeTexture, smokePos, null, Color.White, 0, new Vector2(40, 35), 0.2f, SpriteEffects.None, 1);
            }
            if (smokeList.Count > 10000)
            {
                smokeList.RemoveAt(0);
            }
        }


Den fjerner godt nok object som ligger på pos 0, men count tæller hele tiden op når jeg sætter nye i. Burde denne kode ikke gøre at count ikke kan blive højere end 10.000?
Avatar billede arne_v Ekspert
09. august 2009 - 22:52 #1
Kun hvis den her metode bliver kaldt i forbindelse med indsæt i listen.
Avatar billede mcgoat Nybegynder
09. august 2009 - 23:03 #2
hmm.. måske jeg har bidt over for meget på en gang.. hvorfor kan overstående ikke lade sig gøre.

"hele" min kode:

public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D myTexture;
        Texture2D stickTexture;
        Texture2D smokeTexture;
        Texture2D gifTexture;
        Vector2 gifPosition = new Vector2(335.0f, 140.0f);
        Vector2 spritePosition = Vector2.Zero;
        Vector2 spriteSpeed = new Vector2(400.0f, 400.0f);
        Vector2 stickPosition = Vector2.Zero;
        Vector2 stickSpeed = new Vector2(0.0f, 0.0f);
        Vector2 textPosition = new Vector2(375.0f, 250.0f);
        SpriteFont myFont;
        List<Vector2> smokeList = new List<Vector2>();
        Random randomizer = new Random();

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

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            myTexture = Content.Load<Texture2D>("ball");
            stickTexture = Content.Load<Texture2D>("stick");
            myFont = Content.Load<SpriteFont>("SpriteFont1");
            smokeTexture = Content.Load<Texture2D>("smoke");
        }

        protected override void UnloadContent()
        {

        }

        protected override void Update(GameTime gameTime)
        {
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape)) this.Exit(); // ESC = Exit Game
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Up)) MoveStick(true, "Up",gameTime);
            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(Keys.Up)) MoveStick(false, "Up", gameTime);
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Down)) MoveStick(true, "Down", gameTime);
            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(Keys.Down)) MoveStick(false, "Down", gameTime);
            UpdateSprite(gameTime);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(myTexture, spritePosition, Color.White);
            spriteBatch.Draw(stickTexture, stickPosition, Color.White);
            DrawSmoke();
            DrawText(smokeList.Count.ToString());
            spriteBatch.End();
            base.Draw(gameTime);
        }

        void UpdateSprite(GameTime gameTime)
        {
            spritePosition += spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
            int MinX = 0;
            int MinY = 0;
            int MaxX = graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
            int MaxY = graphics.GraphicsDevice.Viewport.Height - myTexture.Height;

            if (spritePosition.X > MaxX)
            {
                spriteSpeed.X *= -1;
                spritePosition.X = MaxX;
            }

            else if (spritePosition.X < MinX)
            {
                spriteSpeed.X *= -1;
                spritePosition.X = MinX;
            }

            else if (spritePosition.Y > MaxY)
            {
                spriteSpeed.Y *= -1;
                spritePosition.Y = MaxY;
            }

            else if (spritePosition.Y < MinY)
            {
                spriteSpeed.Y *= -1;
                spritePosition.Y = MinY;
            }
            for (int i = 0; i < 5; i++)
            {
                Vector2 smokePos = spritePosition;
                smokePos.X += randomizer.Next(10);
                smokePos.Y += randomizer.Next(10);
                smokeList.Add(smokePos);
            }
        }

        void MoveStick(bool keyPressed, string stickDirection, GameTime gameTime)
        {
            int MinYY = 0;
            int MaxYY = graphics.GraphicsDevice.Viewport.Height - stickTexture.Height;
            stickPosition += stickSpeed;
            switch (stickDirection)
            {
                case "Up":
                    if (keyPressed) stickSpeed.Y -= 5;
                    if (!keyPressed) stickSpeed.Y = 0;
                break;
               
                case "Down":
                    if (keyPressed) stickSpeed.Y += 5;
                    if (!keyPressed) stickSpeed.Y = 0;
                break;
            }
            if (stickPosition.Y < MinYY) stickPosition.Y = 0;
            if (stickPosition.Y > MaxYY) stickPosition.Y = MaxYY;
        }

        void DrawText(string strText)
        {
            spriteBatch.DrawString(myFont, strText, textPosition, Color.Red);
        }

        void DrawSmoke()
        {
            foreach (Vector2 smokePos in smokeList)
            {
                spriteBatch.Draw(smokeTexture, smokePos, null, Color.White, 0, new Vector2(40, 35), 0.2f, SpriteEffects.None, 1);
            }
            if (smokeList.Count > 10000)
            {
                smokeList.RemoveAt(0);
            }
        }
    }
Avatar billede mcgoat Nybegynder
09. august 2009 - 23:05 #3
Er en bold der flyver rundt (ping-pong), og med et smoketrail efter den.
Men for ikke at det trail skal blive "for langt", må jeg jo cutte noget af.. Men kan ikke lide at det fylder op i min liste selvom det ikke bliver vist på skærmen
Avatar billede arne_v Ekspert
09. august 2009 - 23:18 #4
Hvorfor ikke lave dit test & remove lige efter:

smokeList.Add(smokePos);

?
Avatar billede arne_v Ekspert
09. august 2009 - 23:19 #5
Med din brug, så var LinkedList nok bedre end List.
Avatar billede mcgoat Nybegynder
09. august 2009 - 23:29 #6
Du er sørme en klog mand Arne.. har jeg sku altid syntes. Du er god til at give folk et puf i den rigtige retning.

                Vector2 smokePos = spritePosition;
                smokePos.X += randomizer.Next(10);
                smokePos.Y += randomizer.Next(10);
                if (smokeList.Count >= 1000) smokeList.RemoveAt(0);
                smokeList.Add(smokePos);


Og så virkede det ski.

Hvad ville fordelen ved en LinkedList være frem for List?
PS: Smid et svar :-)

Kan dog stadig ikke forstå hvorfor det ikke kan være ligemeget hvor i koden jeg laver mit tjek og fjerner noget... suk
Avatar billede arne_v Ekspert
09. august 2009 - 23:33 #7
svar
Avatar billede arne_v Ekspert
09. august 2009 - 23:33 #8
Det er dyrt at fjerne første element i en List men billigt at fjerne første element i en LinkedList.
Avatar billede arne_v Ekspert
09. august 2009 - 23:36 #9
Der er to forskelle:
- de overflødige bliver fjernet lige efter at de er blevet overflødige ved at nye er tilføjet
- de overflødige når ikke at blive udskrevet inden de bliver fjernet
Avatar billede mcgoat Nybegynder
09. august 2009 - 23:47 #10
ændret til

if (smokeList.Count >= 100) smokeList.RemoveFirst();
smokeList.AddLast(smokePos);


Eller kan man sætte LinkedList til kun at have 100 positioner, g så sørger den selv for at fjerne gamle?
Avatar billede arne_v Ekspert
09. august 2009 - 23:57 #11
Nej - jeg mener at du selv skal gøre det.
Avatar billede windcape Praktikant
10. august 2009 - 14:23 #12
Ville en Stack<T> ikke være bedre, fra et rent performance synspunkt?
Avatar billede arne_v Ekspert
10. august 2009 - 14:55 #13
Saa vidt jeg kan se er det en Queue d.v.s. FIFO ikke en Stack LIFO han bruger.

Stack kan implementeres effektivt med array backing.

Queue boer implementeres med linked list backing.
Avatar billede windcape Praktikant
11. august 2009 - 23:14 #14
I så fald, ville Queue<T> ikke være ligeså korrekt som LinkedList.

Jeg mener at Queue<T> har et lidt mere venligt interface.
Avatar billede arne_v Ekspert
12. august 2009 - 01:39 #15
Tjo. Det illusterer måske tydeligere FIFO princippet.

Jeg ved dog ikke om Enqueue/Dequeue er venligere end AddLast/RemoveFirst.

Jeg kiggede iøvrigt lidt på Queue<T> - den er faktisk ikke implementeret som linked list backing men med et cirkulær buffer array.

Men det er bare en ekstra bonus for spørger da det formentligt er hurtigere at iterere gennem den.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester