Kollisioner med pixlar

Diskutera artiklarna

Kollisioner med pixlar

Inläggav Jonas Nilsson » 2 november 2011, 11:40

Här kan du kommentera/diskutera artikelns innehåll.
Användarvisningsbild
Jonas Nilsson
Administratör
 
Inlägg: 289
Blev medlem: 2 november 2011, 09:47

Re: Kollisioner med pixlar

Inläggav ape_doodle » 26 december 2011, 21:57

Jag får felet
System.ArgumentException was unhandled
Message=The rectangle is too large or too small for this resource.
Parameter name: rect
Source=Microsoft.Xna.Framework.Graphics
ParamName=rect
StackTrace:
at Microsoft.Xna.Framework.Graphics.Texture.GetAndValidateRect(_D3DSURFACE_DESC* __unnamed000, UInt32* pdwLockWidth, UInt32* pdwLockHeight, Nullable`1 rect)
at Microsoft.Xna.Framework.Graphics.Texture2D.CopyData[T](Int32 level, Nullable`1 rect, T[] data, Int32 startIndex, Int32 elementCount, UInt32 options, Boolean isSetting)
at Microsoft.Xna.Framework.Graphics.Texture2D.GetData[T](Int32 level, Nullable`1 rect, T[] data, Int32 startIndex, Int32 elementCount)
at Asteroids_01.Game1.TestCollision(Texture2D t1, Rectangle r1, Texture2D t2, Rectangle r2) in c:\users\uiz3x\documents\visual studio 2010\Projects\Asteroids_01\Asteroids_01\Asteroids_01\Game1.cs:line 276
at Asteroids_01.Game1.Update(GameTime gameTime) in c:\users\uiz3x\documents\visual studio 2010\Projects\Asteroids_01\Asteroids_01\Asteroids_01\Game1.cs:line 199
at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
at Microsoft.Xna.Framework.Game.Run()
at Asteroids_01.Program.Main(String[] args) in c:\users\uiz3x\documents\visual studio 2010\Projects\Asteroids_01\Asteroids_01\Asteroids_01\Program.cs:line 15
InnerException:


när jag försöker köra programmet... felet uppstår här:
Kod: Markera allt
public static bool TestCollision(Texture2D t1, Rectangle r1, Texture2D t2, Rectangle r2)
        {
            //Beräkna hur många pixlar som finns i området som ska undersökas
            int pixelCount = r1.Width * r1.Height;
            uint[] texture1Pixels = new uint[pixelCount];
            uint[] texture2Pixels = new uint[pixelCount];

            //Kopiera ut pixlarna från båda områdena
------->  t1.GetData(0, r1, texture1Pixels, 0, pixelCount); <------------
            t2.GetData(0, r2, texture2Pixels, 0, pixelCount);

            //Jämför om vi har några pixlar som överlappar varandra i områdena
            for (int i = 0; i < pixelCount; i++)
            {
                if (((texture1Pixels[i] & 0xff000000) > 0) && ((texture2Pixels[i] & 0xff000000) > 0))
                {
                    return true;
                }
            }
            return false;
        }


Hjälp gärna snabbt :D // mvh daniel (koden ser finurligt konstig ut men hoppas ni/du ser :P)
ape_doodle
 
Inlägg: 4
Blev medlem: 26 december 2011, 17:45

Re: Kollisioner med pixlar

Inläggav ape_doodle » 26 december 2011, 22:03

snälla... fullfölj asteroids tutorial'n med kollision osv :)
Senast redigerad av ape_doodle 27 december 2011, 19:14, redigerad totalt 1 gång.
ape_doodle
 
Inlägg: 4
Blev medlem: 26 december 2011, 17:45

Re: Kollisioner med pixlar

Inläggav ape_doodle » 26 december 2011, 23:19

Förstog nu det där med overlap och reference men har fortfarande inte löst mitt första problem! :S
ape_doodle
 
Inlägg: 4
Blev medlem: 26 december 2011, 17:45

Re: Kollisioner med pixlar

Inläggav Jonas Nilsson » 30 december 2011, 13:12

Hej, vi ska fortsätta serien om Asteriods det är många som vill det.

Angående ditt problem så verkar det som om du glömmer att testa om rektanglarna överlappar. Dvs början av artikeln om pixel-kollision.

Kod: Markera allt
//Överlappar vi?
kollision = Intersection(playerBox, meteorBox);
 
if (kollision.Width > 0 && kollision.Height > 0)
{
    Rectangle r1 = Normalize(playerBox, kollision);
    Rectangle r2 = Normalize(meteorBox, kollision);
    bHit = TestCollision(ship, r1, meteor, r2);
}
else
    bHit = false;


Vilket problem har du kvar?
Användarvisningsbild
Jonas Nilsson
Administratör
 
Inlägg: 289
Blev medlem: 2 november 2011, 09:47

Re: Kollisioner med pixlar

Inläggav Tjoblesk » 20 januari 2012, 01:08

Tänkte jag skulle få koden att returnera true om pixlarna som överlappade varandra var grön och någon annan färg.
Enligt mig tycker jag att
Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && ((texture2Pixels[i] & 0xff00ff00) > 0))
                {
                    return true;
                }

borde fungera.
Jag vill att om spelarens sprite(texture1) överlappar ett grönt fält på markspriten(texture2) så skall den returnera true. Den returnerar dock alltid true vid kollision, oavsett färg. Vad kan vara felet? (Jag har även prövat massa olika kombinationer på ((texture2Pixels[i] & 0xff00ff00) > 0)). Men inget verkar fungera.)
Tjoblesk
 
Inlägg: 4
Blev medlem: 18 januari 2012, 12:57

Re: Kollisioner med pixlar

Inläggav Jonas Nilsson » 20 januari 2012, 08:16

Hej så som din kod ser ut så returnerar den true vid kollision om pixeln innehåller minsta lilla grönt. Du behöver skriva:

Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && (texture2Pixels[i] == 0xff00ff00))
{
 return true;
}


För exakt grön färg. alt:


Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && ((texture2Pixels[i] & 0xff00ff00) == 0xff00ff00))
{
 return true;
}


För att se om pixeln har "full" grön färg. Obs ger alltså true om pixeln är helt vit.
Användarvisningsbild
Jonas Nilsson
Administratör
 
Inlägg: 289
Blev medlem: 2 november 2011, 09:47

Re: Kollisioner med pixlar

Inläggav Tjoblesk » 20 januari 2012, 19:30

Det fungerade! Tack! :D
Få se om jag fattat allt rätt nu:
0xff000000
ff beskriver alpha-nivån. De andra talparen beskriver RGB i respektive ordning. Har jag rätt?
Är då 0xffff0000 röd? Försökte ändra så att koden kollar efter röd också. Dock fungerar det inte riktigt.
Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && texture2Pixels[i] == 0xffff0000)
     {
       //Look for red target. Win. More points.
       return 3;
     }

Har även försökt med
Kod: Markera allt
((texture2Pixels[i] & 0xffff0000) == 0xffff0000))


Tack på förhand :)
Tjoblesk
 
Inlägg: 4
Blev medlem: 18 januari 2012, 12:57

Re: Kollisioner med pixlar

Inläggav Jonas Nilsson » 20 januari 2012, 21:05

Det stämmer att formatet är AARRGGBB (alpha, R, G , B). Om du testar mot 0xffffff00 så testar du bara mot en färg full R + G. Du måste skriva:

Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && (texture2Pixels[i] == 0xffff0000 || texture2Pixels[i] == 0xff00ff00))
{
}


För att testa mot både röd och grön färg.
Användarvisningsbild
Jonas Nilsson
Administratör
 
Inlägg: 289
Blev medlem: 2 november 2011, 09:47

Re: Kollisioner med pixlar

Inläggav Tjoblesk » 21 januari 2012, 00:07

Så långt är jag med. Jag skrev om if-satsen;
När den får ett värde på svart (0xff010101, i detta fall.) så returnerar den 1.
Är det grönt (0xff00ff00) så returnerar den 2.
Är det rött (0xffff0000) så returnerar den 3.
Jag borde egentligen skrivit med hela koden från början.
Kod: Markera allt
if (((texture1Pixels[i] & 0xff000000) > 0) && texture2Pixels[i] == 0xff010101)
                {
                    //Looking for black color. Ground = loose.
                    return 1;
                }
                if (((texture1Pixels[i] & 0xff000000) > 0) && texture2Pixels[i] == 0xff00ff00 /*& 0xff000000) > 0*/)
                {
                    //Look for green color. Win, less points.
                    return 2;
                }
                if (((texture1Pixels[i] & 0xff000000) > 0) && texture2Pixels[i] == 0xffff0000)
                {
                    //Look for red target. Win, more points.
                    return 3;
                }

När den stöter på svart och grönt så lyckas jag returnera värden. Stöter jag dock på rött så händer inget. Jag har testat att ändra ordningen på if-satserna, samt prövat med blå färg. Inget av detta fungerade, jag lyckas ändå bara returnera värden vid grön och svart av någon anledning :o .
Tjoblesk
 
Inlägg: 4
Blev medlem: 18 januari 2012, 12:57

Nästa

Återgå till Artiklar

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 1 gäst

cron