Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

1

18.04.2012, 23:04

Pixel-Pixel-Collision

N'Abend,
Ich bins mal wieder :D. Und we hätte es gedacht, ich habe ein Problem, bei dem ich irgendwie nicht wieterkomme. Ich möchte mit folgendem Code eine PixelKollisionsabfrage machen. Leider funktioniert diese nicht und ich hab mittlerweile keine Ahnung, woran das liegen mag. Ich hoffe einfach mal, dass jemand Lust hat sich den Code anzugucken und mir zu sagen, an welcher Stelle ich arbeiten sollte :)

Ach ja, Es ist In Visual C# Express 2010 und ist halt offensichtlich XNA4.0.

Und ja, der Code ist nicht komplett kommentiert oder extrem geordnet, sollte ja eigentlich nur ein kleiner Test sein, aber leider ist nur ein Fehler draus geworden :D

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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 XNA_sidescroller_tests
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Texture2D playerTexture;
        Texture2D backgroundTexture;
        Texture2D blockTexture;
            Vector2 speed = Vector2.Zero;
            Vector2 direction = Vector2.Zero;

            Color[] playerTextureData;
            Color[] blockTextureData;
            public bool playerBlockCollide;
        
        //Other classes
            PlayerBlockCollision playerBlockCollision;
        //

        Vector2 blockPosition = new Vector2(100,100);
        //Movements
        int playerSpawnY = 400;
        int playerSpawnX = 400;
        int playerSpeed = 150;
        int playerMoveUp = -1;
        int playerMoveDown = 1;
        int playerMoveLeft = -1;
        int playerMoveRight = 1;
        //
        Vector2 playerPosition = new Vector2(400, 400);


        //the size of the sprite
        public Rectangle size;

        //the amount to increase/decrease the size of the original sprite
        private float mScale = 1.0f;

        public float scale
        {
            get { return mScale; }
            set
            {
                mScale = value;
                //Recalculate the Size of the Sprite with the new scale
                size = new Rectangle(0, 0, (int)(playerTexture.Width * scale), (int)(playerTexture.Height * scale));
            }
        }
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            playerTexture = Content.Load<Texture2D>("circle");
            backgroundTexture = Content.Load<Texture2D>("background");
            blockTexture = Content.Load<Texture2D>("block");

            blockTextureData =
                new Color[blockTexture.Width * blockTexture.Height];
            blockTexture.GetData(blockTextureData);

            playerTextureData =
                new Color[playerTexture.Width * playerTexture.Height];
            playerTexture.GetData(playerTextureData);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            KeyboardState currentState = Keyboard.GetState();
            UpdateMovement(currentState);
            playerPosition += direction * speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
            playerBlockCollision = new PlayerBlockCollision();
            playerBlockCollision.Update(playerPosition, playerTexture, blockPosition, blockTexture, playerTextureData, blockTextureData);

            base.Update(gameTime);
        }


        private void UpdateMovement(KeyboardState theCurrentState)
        {
            speed = Vector2.Zero;
            direction = Vector2.Zero;
            //prüft welche Taste gedrückt wurde und bewegt in die Richtung
            if (theCurrentState.IsKeyDown(Keys.Right) == true)
            {
                speed.X = playerSpeed;
                direction.X = playerMoveRight;
            }
            if (theCurrentState.IsKeyDown(Keys.Left) == true)
            {
                speed.X = playerSpeed;
                direction.X = playerMoveLeft;
            }
            if (theCurrentState.IsKeyDown(Keys.Up) == true)
            {
                speed.Y = playerSpeed;
                direction.Y = playerMoveUp;
            }
            if (theCurrentState.IsKeyDown(Keys.Down) == true)
            {
                speed.Y = playerSpeed;
                direction.Y = playerMoveDown;
            }
        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            

            spriteBatch.Begin();
            if (playerBlockCollide)
            {
                playerPosition = new Vector2(300, 300);
                GraphicsDevice.Clear(Color.Red);
                //spriteBatch.Draw(backgroundTexture, new Vector2(0, 0), Color.Black);
            }
            else
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
                //spriteBatch.Draw(backgroundTexture, new Vector2(0, 0), Color.White);
            }
            spriteBatch.Draw(playerTexture, playerPosition, new Rectangle(0, 0, playerTexture.Width, playerTexture.Height), Color.Tomato, 0.0f, Vector2.Zero, scale, SpriteEffects.None, 0);
            spriteBatch.Draw(blockTexture, blockPosition, Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}



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
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.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;


namespace XNA_sidescroller_tests
{
    class PlayerBlockCollision
    {

        //Other classes
        Game1 game1;

        public void Update(Vector2 thePlayerPosition, Texture2D thePlayerTexture, Vector2 theBlockPosition, Texture2D theBlockTexture, Color[] thePlayerTextureData,Color[] theBlockTextureData)
        {

            Rectangle playerRectangle = 
                new Rectangle((int)thePlayerPosition.X, (int)thePlayerPosition.Y,
                    thePlayerTexture.Width, thePlayerTexture.Height);

            Rectangle blockRectangle = 
                new Rectangle((int)theBlockPosition.X,(int)theBlockPosition.Y,
                    theBlockTexture.Width, theBlockTexture.Height);

            //Check collision
            if(IntersectPixels(playerRectangle,thePlayerTextureData,blockRectangle,theBlockTextureData))
            {
                game1 = new Game1();
                game1.playerBlockCollide = true;
            }
        }
        static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
                                    Rectangle rectangleB, Color[] dataB)
        {
            // Find the bounds of the rectangle intersection
            int top = Math.Max(rectangleA.Top, rectangleB.Top);
            int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
            int left = Math.Max(rectangleA.Left, rectangleB.Left);
            int right = Math.Min(rectangleA.Right, rectangleB.Right);

            // Check every point within the intersection bounds
            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    // Get the color of both pixels at this point
                    Color colorA = dataA[(x - rectangleA.Left) +
                                        (y - rectangleA.Top) * rectangleA.Width];
                    Color colorB = dataB[(x - rectangleB.Left) +
                                        (y - rectangleB.Top) * rectangleB.Width];
                    
                    // If both pixels are not completely transparent,
                    if (colorA.A != 0 && colorB.A != 0)
                    {
                        // then an intersection has been found
                        return true;
                    }
                }
            }

            // No intersection found
            return false;
        }
    }
}

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

18.04.2012, 23:13

Hallo ich bins mal wieder. Ich würde gern meinen Dr der Physik machen, blicke durch den ganzen Kram aber nicht ganz durch. Vielleicht hat ja jemand lust meine Arbeit zu schreiben.
Wenn du da einfach Code hin klatschst sieht das so aus, als wenn du selbst keine Ahnung davon hättest und einfach irgendwoher kopiert hättest. Es gibt gute Tutorials zu diesem Thema. Auch mit XNA. Bei Riemers war zum Beispiel was darüber wenn ich mich recht erinnere. So viel Google-benutzen solltest du nun noch selbst schaffen. Wenn du dann konkrete fragen hast kannst du diese gerne stellen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

3

18.04.2012, 23:42

Zum Ersten habe ich mich gewiss nicht an das Forum gewandt um mich grundlos anmeckern zu lassen. Und da ich nichts auf mir sitzen lasse, frage ich mich mal öffentlich ob du nachts nichts besseres Zutun hast als dir unbekannte grundlos anzumeckern. Ich wüsste nicht warum ich mich mit einer solchen Frage nicht an eben dieses Forum wenden dürfte.

Nun gut nochmal eine genauere Beschreibung :

Nach erfolgreicher kollisionsabfrage wird die Variable zwar auf True gesetzt, aber trotzdem macht die draw Methode nicht das, was sie tun soll. Der Hintergrund bleibt Blau anstatt von rot.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

18.04.2012, 23:55

Du schreibst dass dein Code nicht das macht was er soll. Zeigst dann über 250 Zeilen Code. Wir wissen dass der Code irgendwie eine PerPixelkollision umsetzen soll. Das ist nun mal einfach nur faul von dir. Zeig den Codeabschnitt der nicht richtig funktioniert. Wenn du nicht weißt in welchem Codeabschnitt das Problem ist, dann guck dir den Code selbst noch mal an. Geh mit dem Debugger drüber und guck dir ein paar Werte an. Überleg dir wie sie eigentlich aussehen sollten. Dann weißt du vermutlich schon selbst was falsch läuft. Ich habe dir mit Riemers wenigstens eine Anlaufstelle für dein Problem gegeben. Und ich finde dafür dass du doch recht wenig Eigeninitiative bei der Fehlersuche zeigst bist du ganz schön Frech. Wie gesagt ich habe dir gesagt was du machen kannst. Löse es damit selbst oder stell bitte eine vernünftige Frage mit dem relevanten Codeabschnitt. Hört sich jetzt vermutlich alles mehr aggro an als es gedacht ist aber ok. Stell halt einfach die Frage vernünftig und dir wird vernünftig geholfen. Vor allem geht es dann schneller weil die Helfer sich nicht erst durch den ganzen Code wühlen müssen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

5

19.04.2012, 00:14

Ganz im ernst wenn du nicht helfen möchtest Hör doch bitte einfach auf hier rumzutrollen.
Wenn ich wissen würde woran das Problem genau liegt, hätte ich es wohl gesagt. Ich habe bereits gegoogelt und versucht das Problem zu lösen, habe bereits viel zeit im Debugger verbracht, aber kann mir wie gesagt keinen Reim darauf machen, warum es nicht funktioniert.

Ich möchte dich auch nicht persönlich angreifen, aber ich find so ein rumgetrolle einfach schade. Jemand mit noch nicht so guten Kenntnissen kommt mit einer frage, an dessen Lösung er Grade scheitert und wird dann noch angemeckert und auf Suchmaschinen verwiesen.

Ich bitte um konstruktive Hilfe.

Gruß
Error

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

6

19.04.2012, 00:34

Also ich muss Schorsch auf jeden Fall zustimmen.
Ein großer Teil des gezeigten Codes ist für das Problem gar nicht relevant.

Des weiteren scheinst du das Prinzip der OO überhaupt nicht verstanden zu haben.

Um nicht nur zu meckern:
Ich bin eben über den Code der unteren Klasse drübergeflogen und funktionale Fehler habe ich jetzt nicht entdeckt.
(Wobei es schon ein wenig seltsam ist bei jedem Updatezyklus ein neues Game zu erstellen und auch so von der Codestruktur(Parameter,...), eher nicht so der Mustercode. :rolleyes: )

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

19.04.2012, 00:39

Ich gebe Schorsch recht.
ERROR, auf diese Weise machst du dir hier keine Freunde.
Wenn du willst, dass dir geholfen wird, dann solltest du es den potenziellen Helfern so einfach wie möglich machen und zu erkennen geben, dass du dich auch selbst um die Lösung bemüht hast.
Du hast hier einfach ein Stück Code reingeklatscht, das ganz offensichtlich zum größten Teil von irgendwo kopiert ist, mit der Fehlerbeschreibung "Geht nicht". Die genaue Fehlerbeschreibung musste man dir erst aus der Nase ziehen, worauf du schon gereizt reagiert hast. Dabei bist du doch derjenige, der Hilfe will.

Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

8

19.04.2012, 00:41

Nun gut nochmal eine genauere Beschreibung :

Nach erfolgreicher kollisionsabfrage wird die Variable zwar auf True gesetzt, aber trotzdem macht die draw Methode nicht das, was sie tun soll. Der Hintergrund bleibt Blau anstatt von rot.
Damit kann man schon deutlich mehr anfangen, als mit deiner ersten Fehlerbeschreibung. Dann hättest du dir auch wie bereits gesagt wurde 90% des Codes sparen können.

Dein Fehler ist einfach, dass du das true an deine neu erstellte game1 Variable gibst, die aber gar nichts mit deinem Drawloop zu tun hat sondern einfach ein neuer Drawloop ist. Du musst sie natürlich an deine game-Klasse zurückgeben.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

9

19.04.2012, 00:50

Es geht darum dass du da ne Menge Code hinklatschst und sagst es geht nicht. Wenn du schon mit dem Debugger geguckt hast, dann kannst du sowas ja dazu schreiben. Am besten schreibt man dann noch Ergebnisse dazu, welche Werte sich in welchen Situationen wie verhalten etc. Vom Code musst du dann nicht alles posten, sondern vielleicht nur die relevanten Funktionen. Solche Threads gibt es in letzter Zeit viele und bei vielen merkt man, dass sie sich selbst keine Gedanken gemacht haben. Wenn das auf dich zutrifft tut mir das in dem Fall leid, aber achte dann doch bitte beim nächsten mal drauf dein Problem genauer zu beschreiben.
Habe deinen Code jetzt mal überflogen. Für mich sieht es so aus, als wenn du noch nicht sonderlich viel Erfahrung hättest. Sicher dass du weißt was ich mit debuggen gemeint habe? Mir ging es nicht darum, dass du oben auf den grünen Pfeil in Visual Studio klicken kannst. Das glaube ich dir. Guck doch vielleicht mal hier.
Du hast einige Probleme und solltest dringend noch mal ein Tutorial oder Buch angucken. Du erstellst in Update dein Kollisionsobjekt jedes mal neu. Das ist zwar langsam, aber an sich funktioniert es damit noch. Dann prüfst du in der Updatemethode des Kollisionsobjektes auf Kollision. Die Benennung ist etwas irreführend. Da solltest du dir möglichst praktische Namen angewöhnen. Das erleichtert dir selbst die Arbeit ungemein. Dein Kollisionsobjekt hat nun ein Game1 Objekt als Member. Wenn eine Kollision in Update auftritt wird diese Variable initialisiert. Dabei wird einfach ein neues Gameobjekt erzeugt. Außer einem Konstruktoraufruf und dem bool-Wert den du setzt passiert da aber nichts. Das Game1 Objekt ist jetzt aber ein völlig anderes als dein hauptspiel. Und jedes mal wenn eine Kollision auftritt wird wieder so eine Gameinstanz erstellt. Sowas solltest du auf jeden Fall vermeiden, vor allem da es in diesem Fall nicht das macht was du möchtest.
Was du vermutlich möchtest und was dir weiterhelfen würde, bau die Kollisionsabfrage erst mal in deine Game1-Klasse ein. Mache eine Funktion "bool Kollidiert(Texture2d objekt1, Vector2 position1, Textur2D objekt2, Vector2 position2);". Diese liefert dann true zurück wenn die Texturen überlappen. Benennen kannst du das ganze wie du möchtest. Wenn du anstatt der Texturen deine Colorarrays übergeben möchtest darfst du das natürlich auch gerne.
Weiterhin musst du nicht Color-Arrays speichern, sondern kannst Bool-Arrays speichern. Dann musst du nicht jedes mal Alphawerte von Pixeln abfragen, sondern machst das alles ein mal am Anfang und speicherst einfach ob der Pixel für Kollision sorgen soll oder nicht.

Aber dafür dass ich mir anhören muss ich würde rumtrollen und was weiß ich was alles zeigt dein Code doch eigentlich ganz gut was ich gemeint habe.
Vielleicht einfach mal noch ein Buch lesen oder ein paar Tutorials angucken. Vor allem zum Thema XNA gabs hier grad nen Thread. Du hast ja wenigstens selbst was versucht, was ja auch löblich ist, aber tu dir selbst den Gefallen und guck dir die Grundlagen noch mal an.

edit: F5 ist mein Freund;)
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige

Ähnliche Themen