Autor Beitrag
Terrenay
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Sa 12.04.14 21:49 
Hallo, ich hab schon wieder ein Problem... Ich programmiere gerade ein Role-Play-Game oder Adventure und habe vor einer Woche den ersten Gegner implementiert. (danach gingen wir in den Urlaub aber das ist eigentlich irrelevant ^^) Als ich vorher wieder nach Hause kam, hab ich erstmal die Funktion, mit der der Gegner den Spieler anpeilt optimiert. (Es hat aber vorher schon nicht richtig funktioniert, aber auf eine andere Weise)

Das Problem ist jetzt, dass der Gegner sich seltsam verhält. Das heisst, er kommt auf mich zu, bleibt aber ca. 25 Pixel (DAS wäre die Hälfte seiner Grösse) links und 25 Pixel über mir stehen. Die Bälle, die er auf den Spieler feuert, spawnt er dann in der rechten unteren Ecke der Gegnertextur, statt in der Mitte, wie es sein sollte. Nach einigem Überlegen bin ich dann auf die vermeintliche Lösung gestossen, dass der Gegner nämlich einfach zu weit links und zu weit oben gezeichnet wird (wobei ich mir nicht erklären kann, wieso..) Also hab ich bei der Draw-Methode einfach
ausblenden C#-Quelltext
1:
spriteBatch.Draw(Texture, new Vector2(Position.X+25, Position.Y+25null, Color.Red, 0new Vector2(Texture.Width / 2, Texture.Height / 2), 1, SpriteEffects.None, 0);					

geschrieben. AAAAAABER: Erstens Mal sollte das ja nicht sein, dass man des noch dazuaddieren muss. Zweitens stimmte es danach trotzdem noch nicht genau, der Gegner lappte nämlich in alle Richtungen einen Pixel über den Spieler aus (wobei das ja nicht ganz so schlimm ist).

Kann mir jemand helfen? :( Bin schon sicher 3 Stunden daran, aber ich weiss nichtmal, wo der Fehler sein könnte...

Hier sind alle Klassen (ich denke aber, der Fehler liegt in der Enemy- oder in der Player-Klasse)
[Evt. wichtig damit niemand nen Schock bekommt: Die Texturen von Player und Enemy stimmen nicht, sind nur so um die ganze Textur zu sehen. Ebenso bewegt sich der Bullet nicht, um zu sehen, wo er gespawnt wird...]


Enemy
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace AncientMagic
{
    public class Enemy
    {
        public string Name { get; private set; }
        public int Level { get; private set; }
        public Texture2D Texture { get; private set; }

        public Vector2 Position { get; private set; }
        public Rectangle PositionRectangle { get; private set; }
        public Vector2 Center { get; private set; }
        public double Velocity { get; private set; }
        public int ReactionTime { get; private set; }
        public float Rotation { get; private set; }
        public int Radius { get; private set; }
        public Vector2 MoveDirection { get; private set; }

        public float Hp { get; private set; }
        public float Damage { get; private set; }
        public int AttackSpeed { get; private set; }


        public Texture2D Bullet_Texture { get; private set; }
        public int Bullet_Speed { get; private set; }
        public int Bullet_MaxAge { get; private set; }

        private int _attackCounter = 2000;

        public Enemy(Vector2 position, int tileIndex)
        {
            Position = position;

            switch (tileIndex)
            {
                case 4// Pila, Level 1
                    Name = "Pila";
                    Level = 1;
                    Velocity = 1;
                    Rotation = 0;
                    Hp = 50;
                    Damage = 3;
                    Radius = 300;
                    AttackSpeed = 2000;
                    Bullet_Texture = Graphics.Bullet_Pila;
                    Bullet_Speed = 3;
                    Bullet_MaxAge = 100;
                    Texture = Graphics.Tile_Grass;
                    break;
            }
        }

        public void Update(GameTime gameTime)
        {
            PositionRectangle = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);
            Center = new Vector2(Position.X + Texture.Width / 2, Position.Y + Texture.Height / 2);
            if(IsInRange())
            {
                FaceTarget();
                Move();
                Attack(gameTime);
            }
        }

        private bool IsInRange()
        {
            return Vector2.Distance(Center, Player.Center) <= Radius;
        }

        private void Move()
        {
            MoveDirection = Vector2.Transform(new Vector2(0, (float)-Velocity), Matrix.CreateRotationZ(Rotation));
            Vector2 positionAfterMove = Position + MoveDirection;
            Rectangle sourceRectAfterMove = new Rectangle((int)positionAfterMove.X, (int)positionAfterMove.Y, Texture.Width, Texture.Height);
            bool intersected = false;
            foreach (var item in World.TileList.Where(c => sourceRectAfterMove.Intersects(c.CollisionRectangle) && !c.Walkable))
                intersected = true;
            if (!intersected && !PositionRectangle.Intersects(Player.PositionRectangle))
                Position += MoveDirection;
        }

        private void FaceTarget()
        {
            Vector2 dir = Center - Player.Center;
            dir.Normalize();
            Rotation = (float) Math.Atan2(-dir.X, dir.Y);
        }

        private void Attack(GameTime gameTime)
        {
            _attackCounter += gameTime.ElapsedGameTime.Milliseconds;
            if (_attackCounter >= AttackSpeed)
            {
                World.BulletList.Add(new Bullet(new Vector2(Center.X-Bullet_Texture.Width/2, Center.Y-Bullet_Texture.Height/2), Player.Center, Bullet_Speed, Damage, Bullet_MaxAge, Bullet_Texture, Rotation));
                _attackCounter = 0;
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Texture, Position, null, Color.Red, 0new Vector2(Texture.Width / 2, Texture.Height / 2), 1, SpriteEffects.None, 0);
        }
    }
}



Player
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace AncientMagic
{
    public static class Player
    {
        public static Vector2 Position { get; set; }
        public static Rectangle PositionRectangle { get; private set; }
        public static Vector2 Center { get; private set; }
        public static Vector2 MoveDirection { get; private set; }
        public static KeyboardState keyboardState { get; private set; }
        public static MouseState mouseState { get; private set; }
        public static Vector2 LoadedWorld { get; private set; }

        public static void Update(GameTime gameTime)
        {
            keyboardState = Keyboard.GetState();
            mouseState = Mouse.GetState();

            PositionRectangle = new Rectangle((int)Position.X, (int)Position.Y, 5050); //Seltsame Zahlen weil es sonst falsch gespeichert wird o.o
            Center = new Vector2(Position.X + 25, Position.Y + 25);

            #region Move the player and check for collisions

            MoveDirection = Vector2.Zero;

            if (keyboardState.IsKeyDown(Keys.W) || keyboardState.IsKeyDown(Keys.Up))
            {
                bool collision = false;
                foreach (var item in World.TileList.Where(c => c.CollisionRectangle.Intersects(new Rectangle((int)Position.X, (int)Position.Y - 24949)) && !c.Walkable))
                    collision = true;
                if (!collision)
                    MoveDirection += new Vector2(0,-2);
            }
            if (keyboardState.IsKeyDown(Keys.S) || keyboardState.IsKeyDown(Keys.Down))
            {
                bool collision = false;
                foreach (var item in World.TileList.Where(c => c.CollisionRectangle.Intersects(new Rectangle((int)Position.X, (int)Position.Y + 24949)) && !c.Walkable))
                    collision = true;
                if (!collision)
                    MoveDirection += new Vector2(02);
            }
            if (keyboardState.IsKeyDown(Keys.D) || keyboardState.IsKeyDown(Keys.Right))
            {
                bool collision = false;
                foreach (var item in World.TileList.Where(c => c.CollisionRectangle.Intersects(new Rectangle((int)Position.X + 2, (int)Position.Y, 4949)) && !c.Walkable))
                    collision = true;
                if (!collision)
                    MoveDirection += new Vector2(20);
            }
            if (keyboardState.IsKeyDown(Keys.A) || keyboardState.IsKeyDown(Keys.Left))
            {
                bool collision = false;
                foreach (var item in World.TileList.Where(c => c.CollisionRectangle.Intersects(new Rectangle((int)Position.X - 2, (int)Position.Y, 4949)) && !c.Walkable))
                    collision = true;
                if (!collision)
                    MoveDirection += new Vector2(-20);
            }
            if (MoveDirection != Vector2.Zero)
                MoveDirection.Normalize();

            Position += MoveDirection;

            #endregion

            #region Load new Maps if necessary

            if (Position.X >= 1000)
            {
                LoadedWorld = new Vector2(LoadedWorld.X + 1, LoadedWorld.Y);
                World.Load();
                Position = new Vector2(50, Position.Y);
            }

            if (Position.X <= -50)
            {
                LoadedWorld = new Vector2(LoadedWorld.X -1, LoadedWorld.Y);
                World.Load();
                Position = new Vector2(900,Position.Y);
            }

            if (Position.Y >= 1000)
            {
                LoadedWorld = new Vector2(LoadedWorld.X, LoadedWorld.Y+1);
                World.Load();
                Position = new Vector2(Position.X, 50);
            }
            
            if (Position.Y <= -50)
            {
                LoadedWorld = new Vector2(LoadedWorld.X, LoadedWorld.Y-1);
                World.Load();
                Position = new Vector2(Position.X, 900);
            }
            
            #endregion

        }

        public static void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Graphics.Tile_Grass, Position, Color.Blue); //ÄNDERN
        }
    }
}



Tile
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace AncientMagic
{
    public class Tile
    {
        public Vector2 Position { get; private set; }
        public Rectangle CollisionRectangle { get; private set; }
        public Texture2D Texture { get; private set; }
        public int TileIndex { get; private set; }
        public bool Walkable { get; private set; }
        public int Layer { get; private set; }
        
        public Tile(Vector2 position, int tileIndex)
        {
            Position = position;
            TileIndex = tileIndex;
            CollisionRectangle = new Rectangle((int)Position.X, (int)Position.Y, 5050);

            if (TileIndex == 0)
                Texture = Graphics.Tile_Grass;
            if (TileIndex == 1)
                Texture = Graphics.Tile_Wall;
            if (TileIndex == 2)
                Texture = Graphics.Tile_Path;
            if (TileIndex == 3)
                Texture = Graphics.Image_Home;

            //----
            //Layer zuweisen
            //----

            if (TileIndex == 0 || TileIndex == 1 || TileIndex == 2)
                Layer = 0;
            else
                Layer = 2;

            //----
            //Überprüfen, ob das Tile begehbar ist oder nicht
            //----

            if (TileIndex == 0 || TileIndex == 2)
                Walkable = true;

            //----
            //Einige Tiles haben eine grössere Textur
            //----

            if (TileIndex == 3)
            {
                CollisionRectangle = new Rectangle((int) Position.X, (int) Position.Y + 50150100);
                World.TileList.Add(new Tile(Position, 0));
            }
        }
    }
}


World
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 AncientMagic
{
    public static class World
    {
        public static int[,] WorldArray;
        public static List<Tile> TileList = new List<Tile>(); 
        public static List<Enemy> EnemyList = new List<Enemy>();
        public static List<Bullet> BulletList = new List<Bullet>(); 

        public static void Load()
        {
            bool saveData = false;
            TileList.RemoveAll(c => c.Position.X > int.MinValue);
            EnemyList.RemoveAll(c => c.Position.X > int.MinValue);
            BulletList.RemoveAll(c => c.Position.X > int.MinValue);
            if (Player.LoadedWorld == new Vector2(0,0))
            {
                WorldArray = new int[,]
                    {
                        {11111111222211111111}, //20
                        {10000000222200000001},
                        {10000000222200000001},
                        {10000000222200000001},
                        {10300000222200030001},
                        {10000000222200000001},
                        {10000000222200000001},
                        {10020000222200002001},
                        {10022222222222222001},
                        {10000000222200000001},
                        {10000000222200000001},
                        {10000400222200000001},
                        {10000000222200300001},
                        {10003000222200000001},
                        {10000000222200000001},
                        {10000000222200020001},
                        {10000200222222220001},
                        {10000222222200000001},
                        {10000000222200000001},
                        {11111111111111111111}
                    };
                saveData = true;
            }

            if (saveData)
            {
                for (int y = 0; y < 20; y++)
                {
                    for (int x = 0; x < 20; x++)
                    {
                        if (WorldArray[x,y] == 4)
                        {
                            EnemyList.Add(new Enemy(new Vector2(y*50, x*50), 4));
                            TileList.Add(new Tile(new Vector2(y * 50, x * 50), 0)); //Um das leere Feld zu füllen
                        }
                        else
                            TileList.Add(new Tile(new Vector2(y*50,x*50), WorldArray[x,y])); //x und y vertauscht weil das Array anders herum eingelesen wird...
                    }
                }
            }
        }

        public static void Update(GameTime gameTime)
        {
            foreach(var item in EnemyList)
            {
                item.Update(gameTime);
            }

            try
            {
                foreach (var item in BulletList)
                    item.Update(gameTime);
            }
            catch { }
        }

        public static void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < 3; i++ )
            {
                foreach (var item in TileList.Where(c => c.Layer == i))
                    spriteBatch.Draw(item.Texture, item.Position, Color.White);
                
                if (i == 1)
                {
                    Player.Draw(spriteBatch);

                    foreach (var item in EnemyList)
                    {
                        item.Draw(spriteBatch);
                    }

                    foreach (var item in BulletList)
                    {
                        item.Draw(spriteBatch);
                    }

                }
            }

            
        }
    }
}


Bullet
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace AncientMagic
{
    public class Bullet
    {
        public Vector2 Position { get; private set; } //Center = +Texture.Width/2 etc.
        public Rectangle PositionRectangle { get; private set; }
        public Vector2 Center { get; private set; }
        public Vector2 TargetPosition { get; private set; } //IST BEREITS ZENTRIERT, ALSO GENAU DIE POSITION AUF DIE GESCHOSSEN WIRD!
        public int Velocity { get; private set; }
        public float Rotation { get; private set; }
        public Vector2 MoveDirection { get; private set; }
        public float Damage { get; private set; }
        public int Age { get; private set; }
        public int MaxAge { get; private set; }
        public Texture2D Texture { get; private set; }

        public Bullet(Vector2 position, Vector2 targetPosition, int velocity, float damage, int maxAge, Texture2D texture, float rotation)
        {
            Position = position;
            TargetPosition = targetPosition;
            Velocity = velocity;
            Damage = damage;
            MaxAge = maxAge;
            Texture = texture;
            Rotation = rotation;
            MoveDirection = Vector2.Transform(new Vector2(0, -Velocity), Matrix.CreateRotationZ(Rotation));
        }

        public void Update(GameTime gameTime)
        {
            PositionRectangle = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);
            Center = new Vector2(Position.X + Texture.Width / 2, Position.Y + Texture.Height / 2);

            Age++;

            foreach (var item in World.TileList.Where(c => c.CollisionRectangle.Intersects(new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height)) && !c.Walkable))
                Age = MaxAge + 1;

            

            if (Age > MaxAge)
                World.BulletList.Remove(this);

            //Move();
        }

        private void Move()
        {
            Position += MoveDirection;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, new Vector2(Texture.Width/2, Texture.Height/2), 1, SpriteEffects.None, 1);
        }
    }
}


Game1
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
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 AncientMagic
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

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

            graphics.PreferredBackBufferHeight = 1000;
            graphics.PreferredBackBufferWidth = 1000;
            IsMouseVisible = true;
        }


        protected override void Initialize()
        {

            base.Initialize();
        }


        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Graphics.Tile_Grass = Content.Load<Texture2D>("GrassTile");
            Graphics.Tile_Wall = Content.Load<Texture2D>("WallTile");
            Graphics.Tile_Player = Content.Load<Texture2D>("Player");
            Graphics.Tile_Path = Content.Load<Texture2D>("PathTile");
            Graphics.Image_Home = Content.Load<Texture2D>("Home");

            Graphics.Tile_Pila_Level1 = Content.Load<Texture2D>("Pila_Level1");
            Graphics.Bullet_Pila = Content.Load<Texture2D>("Pila_Bullet");

            Player.Position = new Vector2(474474);
            World.Load();
        }


        protected override void UnloadContent()
        {
        }


        protected override void Update(GameTime gameTime)
        {
            Player.Update(gameTime);
            World.Update(gameTime);

            base.Update(gameTime);
        }


        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            World.Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

    public static class Graphics
    {
        public static Texture2D Tile_Grass { get; set; }
        public static Texture2D Tile_Wall { get; set; }
        public static Texture2D Tile_Player { get; set; }
        public static Texture2D Tile_Path { get; set; }
        public static Texture2D Image_Home { get; set; }

        public static Texture2D Tile_Pila_Level1 { get; set; }

        public static Texture2D Bullet_Pila { get; set; }
    }
}


Ich werde den Post gleich editieren und die gesamte Datei hinzufügen, damit ihr es euch in Ruhe anschauen könnt :)

Ich weiss echt nicht, was da nicht stimmen sollte....
Einloggen, um Attachments anzusehen!
Terrenay Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Sa 12.04.14 22:42 
Ja ganz toll, es ist immer so was kleines... Ich hab iwie den Origin falsch berechnet und dadurch hat es das Bild somehow falsch gezeichnet xD

Naja, trotzdem Danke an alle, die sich die Mühe gemacht haben, den Thread durchzulesen...