MonoGame – Old school demo

Inledning

Förr i tiden när datorerna var långsamma och kallades för hemdatorer så satt det ungdomar runt om i världen och programmerade s.k. "demos". Ett demo var helt enkelt en cool uppvisning i vad man kunde. Det anordnades regelbundet tävlingar inom detta. Den s.k. demoscenen lever kvar än idag men är kanske inte lika känd som förr.

Går det at göra demos i MonoGame?

Visst gör det det! Men datorerna fungerar inte likadant som förr givetvis. Numera har man ett grafikkort som jobbar främst med 3D och texturer. Alla gamla demo-effekter var oftast anpassade för dåtidens 2D-hårdvara.

Cirklar

Vi tänker använda oss av ett visuellt trick med cirklar. Tricket kallas interferens och är något som du kanske hört på fysiklektionen. För att få ut cirklar på skärmen så kan vi: a) rita dem i ett program och ladda dem via Content eller b) Generera cirklarna i programmet. Alternativ b är krångligare så det kör vi på utan tvekan!

För att generera cirklar behöver vi en algoritm. Det är ingen tillfällighet att vi precis diskuterat cirklar i klassiska programmeringsproblem #4.

Vi har modifierat algoritmen till att rita linjer istället för enskilda punkter längs x-axeln. På så vis kan vi rita ut fyllda cirklar.

Fylld cirkel

private void DrawFilledCircle(int x, int y, int radius, Color color, int width, int height, Color[] data)
{
    int sx = -radius;
    int sy = 0;
    int error = 2 - 2 * radius;

    while (sx <= 0)
    {
        for (int i = sy; i >= 0; i--)
        {
            data[(x - sx) + (y - i) * width] = color;
            data[(x - sx) + (y + i) * width] = color;
            data[(x + sx) + (y + i) * width] = color;
            data[(x + sx) + (y - i) * width] = color;
        }

        int r = error;
        if (r <= sy)
            error += ++sy * 2 + 1;
        if (r > sx || error > y)
            error += ++sx * 2 + 1;
    }
}

Modifiera en Texture2D

Det händer rätt ofta att vi måste modifiera en Texture2D av olika anledningar. Vi vill generera cirklar. Det enda sätt vi kan göra detta är genom att be om "rådata" från texturen. Vi måste be om datan, modifiera den och sist skriva tillbaka den i texturen. Detta då Texture2D objekt lever i grafikkortet, därför kan vi inte direkt modifiera dem.

Hämtning sker med metoden GetData och skrivning med SetData. I vår Initialize genererar vi en textur med varannan vit, varannan genomskinlig, cirkel. Sist så sätter vi datan på vår textur via SetData.

Initialize

protected override void Initialize()
{
	int size = 1024;
	overlay = new Texture2D(graphics.GraphicsDevice, size, size);

	Color[] data = new Color[size * size];

	for (int i = 0; i <= 12; i++)
	{
		DrawFilledCircle(size / 2, size / 2, size / 2 - 1 -(i*40), 
			Color.White, size, size, data);
		DrawFilledCircle(size / 2, size / 2, size / 2 - 21 - (i * 40), 
			Color.TransparentBlack, size, size, data);
	}
	overlay.SetData<Color>(data);

	base.Initialize();
}

Den datastruktur vi använder för pixeldata är Color. Den är enkel att arbeta med.

Update och Draw

Update

protected override void Update(GameTime gameTime)
{
	offset1 = new Vector2((float)Math.Sin(counter + MathHelper.PiOver4), 
		(float)Math.Cos(counter + MathHelper.PiOver4))* 120;
	offset2 = new Vector2((float)Math.Sin(-counter), (float)Math.Cos(-counter)) * 120;

	counter += 0.03;
	base.Update(gameTime);
}

I vår update använder vi en counter av typen double som vinkel. Vi använder också två Vector2 som beräknas som cirkelrörelse med hjälp av Sin och Cos.

Draw

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

	spriteBatch.Begin();
	spriteBatch.Draw(overlay, offset1 - new Vector2(240, 240), new Color(255, 0, 0, 100));
	spriteBatch.Draw(overlay, offset2 - new Vector2(120, 120), new Color(0, 255, 0, 100));
	spriteBatch.Draw(overlay, -offset2 - new Vector2(120, 120), new Color(0, 0, 255, 100));
	spriteBatch.End();

	base.Draw(gameTime);
}

Vi ritar ut tre varianter av samma textur, overlay. Men vi ritar ut med olika avstånd och förskjutningar så att det blir en cirkelrörelse för vadera uppritning men med förskjutningar i både vinkel och avstånd.

Röd, grön och blå används som "blandfärg" vid uppritningen så att cirklarna får olika färger. När cirklarna sedan korsas så uppstår en blandning av färgerna. Målet med det hela är att få en visuell effekt!

bild

Videogenomgång

Övningar

Övning 1

Testa att göra cirklarna "tunnare" och fler för att få bättre effekt.

Övning 1

Få cirklarna att skifta färg. Se om du kan använda en vågrörelse (Sin eller Cos) när du bestämmer blending color i uppritningen.

Här nedan kan du se ett klipp som visar hur både övninga 1 och 2 kan se ut.

Vill du veta mer?

Tyckte du det här verkade skoj och intressant så rekommenderar vi att du kollar på youtube efter "c64 demo" eller "amiga demo". Det görs, och har gjorts, fantastiska demos till PC också såklart. Det är bara att googl'a på!

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Scroll to top