Permalänk
Medlem

C# Problem med bugg

Hej

Nu ligger det till så i mitt spel när man skjuter så ökas fiendens hastighet hela tiden, med varje skott.

Detta är väldigt störande då fienderna nästintill flyger fram efter man skjutit några skott. Fiendens hastighet är konstant och borde enligt mig inte ändras heller eller ökas om den nu gör det.

Kod för fiender:

using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Stickman { // Facing directions of the enemies. enum FaceDirection { Left = -1, Right = 1, } class Enemy { #region variables private Level level; private Vector2 position; private Rectangle localBounds; public int health; // Animations private Animation runAnimation; private Animation idleAnimation; private AnimationPlayer sprite; // The direction this enemy is facing and moving along the X-axis private FaceDirection direction = FaceDirection.Left; // The time the enemy has been waiting before turning around private float waitTime; // How long to wait before turning around private const float MaxWaitTime = 0.5f; // The speed at which the enemy moves along the X-axis private const float MoveSpeed = 64.0f; #endregion #region properties public Level Level { get { return level; } } // Position in the level public Vector2 Position { get { return position; } } // The health of the enemy public int Health { get { return health; } set { health = value; } } // Gets a rectangle which bounds this enemy in the level public Rectangle BoundingRectangle { get { int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X; int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y; return new Rectangle(left, top, localBounds.Width, localBounds.Height); } } #endregion #region Constructors public Enemy(Level level, Vector2 position, string spriteSet, int _health) { this.level = level; this.position = position; this.health = _health; LoadContent(spriteSet); } #endregion #region Methods // Loads the enemies content and calculate bounds within texture size public void LoadContent(string spriteSet) { // Load Animation spriteSet = "Sprites/" + spriteSet + "/"; idleAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "idle"), 0.1f, true); runAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "run"), 0.1f, true); sprite.PlayAnimation(idleAnimation); // Calculate bounds within texture size int width = (int)(idleAnimation.FrameWidth * 0.35); int left = (idleAnimation.FrameWidth - width) / 2; int height = (int)(idleAnimation.FrameWidth * 0.7); int top = idleAnimation.FrameHeight - height; localBounds = new Rectangle(left, top, width, height); } // Updates the enemies so the wait at each end of the platform public void Update(GameTime gameTime) { float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; // Calculate tile position based on the side we are walking towards float posX = Position.X + localBounds.Width / 2 * (int)direction; int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction; int tileY = (int)Math.Floor(Position.Y / Tile.Height); if (waitTime > 0) { // Wait for some amount of time. waitTime = Math.Max(0.0f, waitTime - (float)gameTime.ElapsedGameTime.TotalSeconds); if (waitTime <= 0.0f) { // Then turn around direction = (FaceDirection)(-(int)direction); } } else { // If we are about to run into a wall or off a cliff, start waiting if (Level.GetCollision(tileX + (int)direction, tileY - 1) == TileCollision.Impassable || Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Passable) { waitTime = MaxWaitTime; } else { // Move in the current direction Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f); position = position + velocity; } } } // Draws the animated enemy public void Draw(GameTime gameTime, SpriteBatch spriteBatch) { // Stop running when the game is paused or before turning around if (!Level.Player.IsAlive || Level.ReachedExit || Level.TimeRemaining == TimeSpan.Zero || waitTime > 0) { sprite.PlayAnimation(idleAnimation); } else { sprite.PlayAnimation(runAnimation); } // Draw facing the way the enemy is moving SpriteEffects flip = direction > 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; sprite.Draw(gameTime, spriteBatch, Position, flip); } #endregion } }

Kod för projectiles:

using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Stickman { /// <summary> /// This class is a class for different kinds of projectiles. /// Each projectile will have a weapon which uses the projectiles. /// </summary> class Projectile { #region variables private AnimationPlayer sprite; private Texture2D texture; private Vector2 position; float projectileMoveSpeed; private Player player; private Rectangle localBounds; public int damage; public int Direction; private bool active; #endregion #region properties public int Damage { get { return damage; } set { damage = value; } } // Returns the texture of the projectile public Texture2D Texture { get { return texture; } } // Returns the position of the projectile public Vector2 Position { get { return position; } set { position = value; } } public int Width { get { return Texture.Width; } } public int Height { get { return Texture.Height; } } public Player Player { get { return player; } } public bool Active { get { return active; } set { active = value; } } public Rectangle BoundingRectangle { get { int left = (int)Math.Round(Position.X - Texture.Width / 2) + localBounds.X; int top = (int)Math.Round(Position.Y - Texture.Height / 2) + localBounds.Y; return new Rectangle(left, top, localBounds.Width, localBounds.Height); } } #endregion public Projectile(Texture2D texture, Vector2 position, int dmg) { this.texture = texture; this.position = position; Active = true; Damage = dmg; projectileMoveSpeed = 10f; } #region Methods public void Update(GameTime gameTime) { position.X += projectileMoveSpeed; // Set active to false if bullet goes out of bounds if ((position.X + texture.Width / 2 > 850) || position.X + texture.Width / 2 < 0) Active = false; } public void Draw(GameTime gameTime, SpriteBatch spriteBatch) { //SpriteEffects flip = player.Velocity.X > 0 ? SpriteEffects.FlipHorizontally : // SpriteEffects.None; SpriteEffects flip = SpriteEffects.None; //sprite.Draw(gameTime, spriteBatch, Position, flip); spriteBatch.Draw(texture, position, null, Color.White, 0f, new Vector2(Width / 2, Height / 2), 1f, flip, 0f); } #endregion } }

Sen kanske om någon skulle behöva följande kod
Update för bullets och enemies:

public void UpdateEnemies(GameTime gameTime) { for (int i = 0; i < enemies.Count; i++) { enemies[i].Update(gameTime); // Touching an enemy lowers the players health and kills the enemy if (enemies[i].BoundingRectangle.Intersects(Player.BoundingRectangle)) { // If a player has 0 lives after the life has been // subtracted. if (Player.Lives == 1) { // Kill Player OnPlayerKilled(enemies[i]); } else { // Else lower players lives with 1 enemies.RemoveAt(i--); --Player.Lives; } } } } public void AddBullet(Vector2 position, Texture2D texture, int dmg) { Projectile projectile = new Projectile(texture, position, dmg); bullets.Add(projectile); } public void UpdateBullets(GameTime gameTime) { for (int i = 0; i < bullets.Count; i++) { // Updates all bullets bullets[i].Update(gameTime); for (int e = 0; e < enemies.Count; e++) { // Updates all enemies enemies[e].Update(gameTime); // If a bullet collides with an enemy // lower the enemys health and if // the enemy dies - add 100 to score. if (bullets[i].BoundingRectangle.Intersects(enemies[e].BoundingRectangle)) { //enemies[e].Health -= bullets[i].damage; if (enemies[e].Health <= 0) { score += 100; enemies.RemoveAt(e--); bullets.RemoveAt(i--); } else { enemies[e].Health -= bullets[i].damage; bullets.RemoveAt(i--); if (enemies[e].Health == 0) { score += 100; enemies.RemoveAt(e--); } } } }// end enemies for-loop }// end bullets for-loop }// end UpdateBullets

Hoppas något ser var felet ligger för jag har tittat efter men lyckas inte lokalisera det

Permalänk
Medlem

Var kommer din gameTime ifrån? Den ser ut som en misstänkt kandidat i mina ögon. Din kod:

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);
position = position + velocity;

...om elapsed hela tiden ökar kommer vektorn varje gång att bli större, och positionen därmed ändras mer (== "högre hastighet").
Du visar inte koden som anropar de här metoderna med parametern gameTime, så det går inte att säga säkert om det är den. Men jag skulle kolla lite noggrannare där om jag var du, eftersom MoveSpeed är en konstant och direction ser ut att bara kunna anta värdena 1 eller -1.

Permalänk
Medlem

Skummat igenom lite fort, inte så mkt erfarenhet av XNA/C#/Spelprogrammering lr så men enda jag kunde se som verkade lite lurt var väl

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; ... Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f); position = position + velocity;

Borde inte detta göra att gubben flyttar snabbare ju längre tid spelet vart igång?
Kanske missat nån hantering lr tänkt fel men det är det jag kunde se utan att grotta ner mig i koden

Lycka till annars^^

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Medlem
Skrivet av veggie_d:

Var kommer din gameTime ifrån? Den ser ut som en misstänkt kandidat i mina ögon. Din kod:

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);
position = position + velocity;

...om elapsed hela tiden ökar kommer vektorn varje gång att bli större, och positionen därmed ändras mer (== "högre hastighet").
Du visar inte koden som anropar de här metoderna med parametern gameTime, så det går inte att säga säkert om det är den. Men jag skulle kolla lite noggrannare där om jag var du, eftersom MoveSpeed är en konstant och direction ser ut att bara kunna anta värdena 1 eller -1.

Nja GameTime kommer från update metoden som kör igenom allas objects Update osv.
Den i sin tur kommer ifrån huvudklassen Game.

Koden :

public void Update(GameTime gameTime, GamePadState gamePadState, KeyboardState keyboardState) { // Pauses while the player is dead or time has expired. if (!Player.IsAlive || TimeRemaining == TimeSpan.Zero) { // Still want to perform physics on the player. Player.ApplyPhysics(gameTime); } else if (ReachedExit) { // Animate the time being converted into points. int seconds = (int)Math.Round(gameTime.ElapsedGameTime.TotalSeconds * 100.0f); seconds = Math.Min(seconds, (int)Math.Ceiling(TimeRemaining.TotalSeconds)); timeRemaining -= TimeSpan.FromSeconds(seconds); score += seconds * PointsPerSeconds; } else { timeRemaining -= gameTime.ElapsedGameTime; Player.Update(gameTime, keyboardState, gamePadState); UpdateCoins(gameTime); UpdateBullets(gameTime); UpdateEnemies(gameTime); // Check if the player has reached the exit. if (Player.IsAlive && Player.IsOnGround && Player.BoundingRectangle.Contains(exit)) { OnExitReached(); } } // Clamp the time remaining at zero. if (timeRemaining < TimeSpan.Zero) timeRemaining = TimeSpan.Zero; }

och

protected override void Update(GameTime gameTime) { HandleInput(); level.Update(gameTime, gamePadState, keyboardState); base.Update(gameTime); }

Permalänk
Medlem
Skrivet av Gnejs:

Skummat igenom lite fort, inte så mkt erfarenhet av XNA/C#/Spelprogrammering lr så men enda jag kunde se som verkade lite lurt var väl

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; ... Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f); position = position + velocity;

Borde inte detta göra att gubben flyttar snabbare ju längre tid spelet vart igång?
Kanske missat nån hantering lr tänkt fel men det är det jag kunde se utan att grotta ner mig i koden

Lycka till annars^^

Tackar, men nä det händer endast när jag avfyrar ett skott som fienden ökar hastighet, om vi säger att jag har fler fiender så ökar varje fiendes hastighet

Permalänk
Medlem

Lägg in breakpoints vid de områden som manipulerar hastighet/position och kolla vilka värden de inblandade variablerna har via debuggern?

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Medlem
Skrivet av Sandric:

Nja GameTime kommer från update metoden som kör igenom allas objects Update osv.
Den i sin tur kommer ifrån huvudklassen Game.

gameTime är ju en parameter in till Update. Man kan fortfarande inte se var den kommer ifrån, och vad den sätts till. Men tipset ovan angående breakpoints är ett bra ett, alt. spotta ut lite variabelvärden till konsolen här och där. Brukar vara ett bra sätt att få en uppfattning om huruvida du har knasiga värden någonstans.

Permalänk
Medlem

okej, men när jag kollar med breakpoints så verkar hastigheten fungera utmärkt, står som 64.0.
Vet inte hur jag ska visa vart den kommer från =/
GameTime fungerar också, samt positionen verkar såklart inte vara något knas på.

Permalänk
Medlem
Skrivet av Sandric:

okej, men när jag kollar med breakpoints så verkar hastigheten fungera utmärkt, står som 64.0.
Vet inte hur jag ska visa vart den kommer från =/
GameTime fungerar också, samt positionen verkar såklart inte vara något knas på.

Ok. Farten (inte hastigheten) är 64.0, det är inte så konstigt eftersom den är const-deklarerad. Hastigheten är sedan en produkt av riktningen (som verkar kunna anta värdena 1 eller -1), farten och "elapsed time", oklart vad det innebär. Det var det jag undrade, vad innebär elapsed time? Är det tiden sedan du senast uppdaterade positionen, eller tiden sedan spelet startade, eller vad?
Om du säger att det inte verkar vara något fel med positionen, så är visualiseringen av den det enda jag kan tänka mig. Alltså: det kan ju vara helt OK värden på alla hastigheter och positioner, men om rutinerna som ska rita upp fienderna gör fel så att de ritas på fel ställen så kommer det naturligtvis se ut som att positionerna faktiskt ÄR fel. De rutinerna är nästa ställe jag hade satt brytpunkter på

Permalänk
Medlem

Problemet är att du uppdaterar alla enemies en gång för alla bullets i UpdateBullets()... Prova kommentera bort enemies[e].update(...) i den funktionen så får du se

Skickades från m.sweclockers.com

Permalänk
Medlem

Tackar så hemskt mycket Alex, det var där problemet låg. Tänkte bara höra om något visste ang. ett annat problem jag har när jag skjuter vissa fiender på nästkommande banor.

Jag får ett ArgumentOutOfRangeException fel.
Står följande: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

Koden som debuggen gnäller på:

if (bullets[i].BoundingRectangle.Intersects(enemies[e].BoundingRectangle))

Finns under UpdateBullets vid översta posten

har även provat att sätta removeAt(i) respektive (e) istället för i--, e--.

verkar inte heller få rätt på detta.

Vore jättetacksam om någon vänlig själ unde hjälpa mig med det problemet.

Permalänk
Medlem

Vad har i och e för värde när det craschar?

Permalänk
Medlem

Värdet är följande:
e = 1
i = -1

Permalänk

Ja, och i kan som minst vara 0 (första positionen i listan)

Permalänk
Medlem

jo de förstod jag, men vet inte varför den blir - hela tiden oberoende av om jag tar removeAt(i) eller removeAt(i--)

Permalänk
Medlem

Så som du har skrivit nu: Om den första kulan (kula 0) träffar en fiende, så tas kulan bort från listan, och i som tidigare varit 0 blir då -1, och i kommer inte att ökas till 0 igen förens efter alla fiender blivit testade. Du lär helt enkelt tänka om i din uppdate

Permalänk
Medlem

men om man har removeAt(i) händer väl inte det ?

Eller är det bara jag som inte ser de ^^

För om vi säger följande scenarie:

Level 1: 1 fiende - inget problem
Level 2: 2 fiende - inget problem, vad jag kommer ihåg kan testa om jag skjuter annorlunda
Level 3: 2 fiende - problem om man skjuter fienden som är placerad på övre halvan först, men inte om man dödar dem omvänt.

Permalänk
Medlem

Jo det blir så, eftersom att du använder i-- mitt i den andra for-loopen utan att säkerställa att den är 0 eller mer. Gör såhär: i slutet på den andra for-loopen, kolla om i är mer, eller lika med 0, och är den inte det så sätter du den till 0.

if (i <= 0)
i = 0;

Skickades från m.sweclockers.com

Permalänk
Medlem

Ber om ursäkt för att jag svarade för fort.. Mitt svar förklarar bara det ena scenariot. Det andra (om du inte använder i--) så kommer koden testa kollision mellan fienderna och en kula som du redan tagit bort.

Såhär menar jag: du har 2 fiender och skjuter iväg en kula som träffar den första fienden. Kulan tas bort från listan, och sen försöker koden testa om samma kula träffar fiende nummer 2, men eftersom att den kulan redan är borttagen så kommer spelet att krascha.

Skickades från m.sweclockers.com

Permalänk
Medlem

aha men då förstår jag, men hur ska man skriva för att det inte ska krascha då ? :/

Permalänk
Medlem

Ett sätt att skriva på kan vara att du lägger till en bool i både bullet och enemy-klassen som skulle kunna heta isAlive och har värdet true. Sen istället för att du tar bort saker från sina listor, så sätter du bara isAlive till false.

När du sen är färdig med att testa alla kollisioner så loopar du igenom listorna igen och plockar bort allt som har dött (där isAlive är false)

Skickades från m.sweclockers.com

Permalänk
Medlem

okej det skal genast testas tackar

Edit: Jodå det fungerade utmärkt, att jag inte tänkte på det, tackar så hemskt mycket

Permalänk
Medlem

Det var så lite :). Rapportera gärna tillbaka så vi får veta hur det gick

Skickades från m.sweclockers.com