Pixelová grafika

V niektorých aplikáciách, hlavne hrách je často potrebné vykresľovať grafickú scénu na úrovni pixelov. Niekedy je to dobrá alternatíva k animácii. Pre grafiku na úrovni pixelov sa najlepšie hodí objekt Writeable Bitmap.

Ukážem procedúry využité v aplikácii Chcicken Adventure http://apps.microsoft.com/windows/app/chicken-adventure/45ddf192-274b-408f-9c73-8db3fe5f470e

(dal som ju do store pôvodne pod názvom FLAPPY, ale story hry z týmto názvom dávajú preč)

Do XAM kódu stačí vložiť objekt Image o rozmeroch budúceho obrazu.

<Image Name=”gameimage” Stretch=”Fill” Grid.Column=”0″
HorizontalAlignment=”Center” VerticalAlignment=”top” Width=”864″ Height=”540″
Loaded=”gameimage_Loaded” PointerPressed=”gameimage_PointerPressed” PointerReleased=”gameimage_PointerReleased”/>

Prvok gameimage je v metóde Loaded priradený prvku

public static Image imgGame = null;

private void gameimage_Loaded(object sender, RoutedEventArgs e)
{
imgGame = (Image)sender;
}

Pri hre portovanej z osembitovej platformy som využil rozlíšenie obrázku scény hry 320 x 200 resp 640 x 400.

this.img = new WriteableBitmap(320, 200);
pixely = new byte[4 * img.PixelWidth * img.PixelHeight];
pixelStream = img.PixelBuffer.AsStream();
MainPage.imgGame.Source = img;

Každý pixel je v pamäťovej štruktúre WriteableBitmap reprezentovaný štyrmi bitmi. Jednotlivé pixely sa preto nastavujú priamym zápisom do bajtového pola takto

protected void SetPixel(int x, int y, Color clr)
{
  int index = 4 * (y * img.PixelWidth + x);
pixely[index + 0] = clr.B;
pixely[index + 1] = clr.G;
pixely[index + 2] = clr.R;
pixely[index + 3] = clr.A;
}

Užitočné môžu byť aj procedúry na vykreslenie prázdneho a vyplneného obdĺžnika

protected void fillRect(int x0, int y0, int width, int height) //vykresli vyplneny obdlznik nastavenej farby
{
for (int yy = y0; yy < y0 + height; yy++)
{
for (int xx = x0; xx < x0+width; xx++) SetPixel(xx, yy, cFarba);
}
UpdateBitmap();
}

void drawRect(int x0, int y0, int width, int height) //vykresli obrysy obdlznika nastavenej farby
{
for (int xx = x0; xx < x0 + width; xx++) SetPixel(xx, y0, cFarba); //horna ciara
for (int yy = y0; yy < y0 + height; yy++) //zvisle ciary vlavo a vpravo
{
SetPixel(x0, yy, cFarba); //v1avo
SetPixel(x0 + width, yy, cFarba); //vpravo
}
for (int xx = x0; xx < x0 + width; xx++) SetPixel(xx, y0 + height, cFarba); //dolna ciara
UpdateBitmap();
}

Aktualizácia obrázka sa robí v procedúre

protected void UpdateBitmap()
{
pixelStream.Seek(0, SeekOrigin.Begin);
pixelStream.Write(pixely, 0, pixely.Length);
img.Invalidate();
}

Ak chcete do WriteableBitmap vložiť obrázok využijete procedúru

//vlozi obrazok do bitmapy bitmap

public void PixelovyObrazok(WriteableBitmap image, int x, int y)
{
//rozmery vkladaneho obrazka
int nSirka = image.PixelWidth;
 int nVyska = image.PixelHeight;
 IBuffer ib = image.PixelBuffer;
byte[] pixely_obr = ib.ToArray();
int nZdrojIndex = 0; //index v cielovej bitmape
//po jednotlivych riadkoch vlozim binarnu reprezentaciu vkladaneho obrazka
for (int yy = y; yy < (y + nVyska); yy++)
{
for (int xx = x; xx < (x + nSirka); xx++)
  {
int nCielIndex = 4 * (yy * img.PixelWidth + xx); //index v cielovej bitmape
pixely[nCielIndex + 0] = pixely_obr[nZdrojIndex]; nZdrojIndex++;
pixely[nCielIndex + 1] = pixely_obr[nZdrojIndex]; nZdrojIndex++;
pixely[nCielIndex + 2] = pixely_obr[nZdrojIndex]; nZdrojIndex++;
pixely[nCielIndex + 3] = pixely_obr[nZdrojIndex]; nZdrojIndex++;
}
}
UpdateBitmap();
}

Reklamy

Pridaj komentár

Zadajte svoje údaje, alebo kliknite na ikonu pre prihlásenie:

WordPress.com Logo

Na komentovanie používate váš WordPress.com účet. Odhlásiť sa / Zmeniť )

Twitter picture

Na komentovanie používate váš Twitter účet. Odhlásiť sa / Zmeniť )

Facebook photo

Na komentovanie používate váš Facebook účet. Odhlásiť sa / Zmeniť )

Google+ photo

Na komentovanie používate váš Google+ účet. Odhlásiť sa / Zmeniť )

Connecting to %s


%d bloggers like this: