Guten Abend Leute,
ich stehe gerade vor einem Problem, dass ich nach stundenlangem Versuchen immer noch nicht bewältigen konnte.
Undzwar arbeite z.Z. an einer Art Partikel-Anwendung, jedenfalls werden sehr sehr viele Objekte erzeugt (je mehr desto besser eben :D).
Das Problem dabei liegt an der derzeit möglichen Menge, die etwa bei 1000 liegt und schon einen Kern voll auslastet.
Danach sinken die FPS enorm schnell.
Es handelt sich dabei um eine MonoGame/ OpenGL C# Anwendung.
Das Komische: Eine ähnliche Anwendung habe ich zuvor mit XNA erstellt und dort hatte ich noch 60 FPS bei über 20 000 Objekten.
Leider sehe ich keinen Unterschied, zu mal die XNA Anwendung sogar mehr Abfragen besitzt.
Der Code: (kann man hier im Forum auch C#-Code highlighten?)
Main-Klasse
Spoiler anzeigen
Ball-Klasse
Spoiler anzeigen
Das "Auskommentierte" sind Ansätze für eine Array-Variante, jedoch komme ich auch da nicht weiter, weils glücklichweise keine dynamischen Arrays in C# gibt
Ich hoffe ihr könnt mir weiterhelfen
ich stehe gerade vor einem Problem, dass ich nach stundenlangem Versuchen immer noch nicht bewältigen konnte.
Undzwar arbeite z.Z. an einer Art Partikel-Anwendung, jedenfalls werden sehr sehr viele Objekte erzeugt (je mehr desto besser eben :D).
Das Problem dabei liegt an der derzeit möglichen Menge, die etwa bei 1000 liegt und schon einen Kern voll auslastet.
Danach sinken die FPS enorm schnell.
Es handelt sich dabei um eine MonoGame/ OpenGL C# Anwendung.
Das Komische: Eine ähnliche Anwendung habe ich zuvor mit XNA erstellt und dort hatte ich noch 60 FPS bei über 20 000 Objekten.
Leider sehe ich keinen Unterschied, zu mal die XNA Anwendung sogar mehr Abfragen besitzt.
Der Code: (kann man hier im Forum auch C#-Code highlighten?)
Main-Klasse
Quellcode
- #region Using Statements
- using System;
- using System.IO;
- 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;
- using System.Collections;
- #endregion
- namespace Vorlage
- {
- public class Game1 : Game
- {
- GraphicsDeviceManager graphics;
- SpriteBatch spriteBatch;
- Texture2D ballText;
- SpriteFont font;
- MouseState mouseState;
- MouseState oldMouseState;
- KeyboardState keyboardState;
- KeyboardState oldKeyboardState;
- Double Elapsed = 0;
- int apm;
- bool isElapsed = false;
- String Key = "";
- int i = 0;
- Vector2 position = new Vector2(10,20);
- Vector2 velocity = new Vector2(3,0);
- //private Ball[] balls = new Ball[0];
- List<Ball> balls = new List<Ball>();
- public Game1()
- : base()
- {
- graphics = new GraphicsDeviceManager(this);
- Content.RootDirectory = "Content";
- }
- protected override void Initialize()
- {
- graphics.PreferredBackBufferWidth = 1280;
- graphics.PreferredBackBufferHeight = 720;
- graphics.IsFullScreen = false;
- graphics.PreferMultiSampling = true;
- // IsFixedTimeStep = false;
- graphics.ApplyChanges();
- apm = 30;
- base.Initialize();
- }
- protected override void LoadContent()
- {
- spriteBatch = new SpriteBatch(GraphicsDevice);
- ballText = Content.Load<Texture2D>("white");
- font = Content.Load<SpriteFont>("Font");
- }
- protected override void UnloadContent()
- {
- //Content.Unload();
- }
- protected override void Update(GameTime gameTime)
- {
- // EXIT
- if (Keyboard.GetState().IsKeyDown(Keys.Escape))
- Exit();
- // INPUT REFRESH
- Elapsed += gameTime.ElapsedGameTime.TotalMilliseconds;
- if (Elapsed >= (1000/apm))
- {
- Elapsed = 0;
- mouseState = Mouse.GetState();
- keyboardState = Keyboard.GetState();
- isElapsed = true;
- }
- // EINSTELLUNGEN
- Key = PressedLetter(keyboardState, oldKeyboardState, Key);
- // ERSTER PLATZ FÜR NEUEN PARTIKEL
- // i = FindIndex(ref balls);
- switch (Key)
- {
- case "mouse" :
- if (( mouseState.LeftButton == ButtonState.Pressed))
- {
- Vector2 mousePos = new Vector2(mouseState.X, mouseState.Y);
- //balls[i]= new Ball(ballText, mousePos);
- balls.Add(new Ball(ballText, mousePos));
- }
- break;
- case "auto":
- if (this.velocity.X > 0 && position.X >= graphics.PreferredBackBufferWidth - ballText.Width - 20) { velocity.X = -velocity.X; }
- if (this.velocity.X < 0 && position.X <= 0 + 20) { velocity.X = -velocity.X; }
- position += velocity;
- balls[i] = new Ball(ballText, position);
- break;
- case "manual":
- if (keyboardState.IsKeyDown(Keys.Right))
- {
- position.X += 3;
- }
- else if (keyboardState.IsKeyDown(Keys.Left))
- {
- position.X -= 3;
- }
- // balls[i] = new Ball(ballText, position);
- balls.Add(new Ball(ballText, position));
- break;
- case "random":
- Random rnd = new Random();
- if (velocity.X < 0)
- {
- velocity.X = -rnd.Next(0, 5);
- }
- else { velocity.X = rnd.Next(0, 5); }
- position += velocity;
- // balls[i] = new Ball(ballText, position);
- balls.Add(new Ball(ballText, position));
- break;
- default:
- break;
- }
- // UPDATE
- foreach (Ball b in balls)
- {
- if (!( b == null))
- {
- b.Update(graphics.PreferredBackBufferHeight, graphics.PreferredBackBufferWidth, mouseState, isElapsed);
- }
- }
- // DELETE OLD ONES
- for (int j = 0; j < balls.Count; j++)
- {
- // if ((!(balls[j] == null)) && balls[j].exist == false) { balls[j] = null; }
- if (balls[j].exist == false) { balls.RemoveAt(j); }
- }
- // OLD INPUT SAVE
- if (isElapsed)
- {
- isElapsed = false;
- oldMouseState = mouseState;
- oldKeyboardState = keyboardState;
- }
- base.Update(gameTime);
- }
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(Color.Black);
- spriteBatch.Begin();
- foreach (Ball b in balls)
- {
- if (!(b == null))
- {
- b.Draw(this.spriteBatch, font, balls.Count - 1);
- }
- }
- spriteBatch.End();
- base.Draw(gameTime);
- }
- private string PressedLetter(KeyboardState State,KeyboardState oldState,String oldKey)
- {
- if (State.IsKeyDown(Keys.F1) && oldState.IsKeyDown(Keys.F1))
- {
- return "mouse";
- }
- else if (State.IsKeyDown(Keys.F2) && oldState.IsKeyDown(Keys.F2))
- {
- return "auto";
- }
- else if (State.IsKeyDown(Keys.F3) && oldState.IsKeyDown(Keys.F3))
- {
- return "manual";
- }
- else if (State.IsKeyDown(Keys.F4) && oldState.IsKeyDown(Keys.F4))
- {
- return "random";
- }
- else
- {
- String key = oldKey;
- return key;
- }
- }
- }
Ball-Klasse
Quellcode
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- 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;
- namespace Vorlage
- {
- class Ball
- {
- private Texture2D texture;
- private Vector2 velocity;
- private Vector2 position;
- public Boolean exist = true;
- private Byte r = 255;
- private Byte g, b;
- private Color color;
- Random rnd = new Random();
- public Ball(Texture2D texture, Vector2 position)
- {
- this.texture = texture;
- this.position = position;
- this.velocity.Y = 0.1f;
- }
- private void Fall(int height)
- {
- //Falling and Bouncing
- velocity.Y += 0.1f;
- // REFRESH POSITION
- // this.position += this.velocity;
- if (this.position.Y + this.velocity.Y + this.texture.Height >= height)
- {
- this.position.Y = height - this.texture.Height;
- this.velocity.Y = -this.velocity.Y + 0.2f * this.velocity.Y;
- }
- if ((Math.Abs(this.velocity.Y) <= 0.05f) && (this.position.Y + this.texture.Height >= height*0.95))
- { this.exist = false; }
- }
- private void Swarm(MouseState mouseState,int height)
- {
- float fak = 20f;
- if (this.position.Y > mouseState.Y)
- {
- this.velocity.Y -= (rnd.Next(1,10)/fak);
- }
- else
- {
- this.velocity.Y += (rnd.Next(1, 10) / fak);
- }
- if (this.position.X > mouseState.X)
- {
- this.velocity.X -= (rnd.Next(1, 10) / fak);
- }
- else
- {
- this.velocity.X += (rnd.Next(1, 10) / fak);
- }
- // SO SCREAM AND SHOUT AND (DON'T) LET IT ALL OUT
- if (this.position.Y + this.velocity.Y + this.texture.Height >= height)
- {
- this.position.Y = height - this.texture.Height;
- this.velocity.Y = -this.velocity.Y*0.3f;
- }
- }
- public void Update(int height,int width,MouseState mouseState,bool isElapsed)
- {
- if (mouseState.RightButton == ButtonState.Pressed)
- { // NORMAL PHYSICS
- Swarm(mouseState,height);
- }
- else
- { // SWARM TO MOUSE
- Fall(height);
- }
- // Color UPDATE
- Update_Colors();
- // RIGHT SIDE
- if (this.position.X + this.velocity.X + this.texture.Width >= width)
- {
- this.position.X = width - this.texture.Width;
- this.velocity.X = -this.velocity.X*0.3f;
- }
- // LEFT SIDE
- if (this.position.X + this.velocity.X <= 0)
- {
- this.position.X = 0;
- this.velocity.X = -this.velocity.X*0.3f;
- }
- // TOP
- if (this.position.Y + this.velocity.Y <= 0)
- {
- this.position.Y = 0;
- this.velocity.Y = -this.velocity.Y*0.3f;
- }
- this.position += this.velocity;
- }
- // COLOR
- public void Update_Colors()
- {
- if (r == 255 & g < 255 & g >= 0 & b == 0)
- {
- g += 1;
- }
- else if (g == 255 & b == 0 & r <= 255 & r > 0)
- {
- r -= 1;
- }
- else if (r == 0 & g == 255 & b < 255 & b >= 0)
- {
- b += 1;
- }
- else if (r == 0 & b == 255 & g > 0 & g <= 255)
- {
- g -= 1;
- }
- else if (g == 0 & b == 255 & r >= 0 & r < 255)
- {
- r += 1;
- }
- else
- {
- b -= 1;
- }
- color = new Color(r, g, b);
- }
- public void Draw(SpriteBatch spriteBatch,SpriteFont font,Int32 number)
- {
- spriteBatch.Draw(this.texture, this.position, color);
- spriteBatch.DrawString(font, Convert.ToString(number), new Vector2(2, 2), Color.White);
- }
- }
- }
Das "Auskommentierte" sind Ansätze für eine Array-Variante, jedoch komme ich auch da nicht weiter, weils glücklichweise keine dynamischen Arrays in C# gibt
Ich hoffe ihr könnt mir weiterhelfen