1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LovyanGFXAdvent Calendar 2022

Day 5

LovyanGFX で画面描画(3):スプライト描画

Last updated at Posted at 2022-12-12

スプライト

古のホビーPCやレトロゲーム機などでおなじみだったスプライト機能。
本来はハードウェアで高速描画をするものでしたが、扱いやすさから同様の機能をソフトウェアで実現したものも多くあります。

LovyanGFX もドライバでスプライト機能が実現されています。ゲーム機のスプライトとは異なり、スプライト描画命令でスプライトに指定された画像をオブジェクト内に上書き描画するという概念です。これを活用することで、簡単に楽しい描画をすることができます。

サンプルコード

    
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <LGFX_AUTODETECT.hpp>

LGFX display ( 128, 64 , 5 );
static LGFX_Sprite sprite(&display);

void setup()
{
  display.init();
  sprite.createSprite( 16,16);
  sprite.fillRect(0,0,15,15,TFT_WHITE);
  sprite.pushSprite(0, 0);
}

void loop()
{
}


image.png

16x16 のスプライトを表示してみました。一番簡単に、白い豆腐が表示されています。うーん、もうちょっと楽しくしたい・・・

アニメーション

プログラムを以下のように変更します。

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <LGFX_AUTODETECT.hpp>

LGFX display ( 128,64,5 );
static LGFX_Sprite sprite(&display);

void setup()
{
  display.init();
  sprite.createSprite(17,17);
  sprite.fillCircle(8,8,8,TFT_RED);
  sprite.fillRect(2,6,13,5,TFT_WHITE);
}

void loop()
{
  for(int i=0; i<128; i++){
    display.clear();
    display.fillRect(5,5,25,25,display.color888(127,127,127));
    sprite.pushSprite(i,0,0);
    SDL_Delay(50);
  }
}


image.png

標識マークが移動していきます。

pushSprite(i,0,0); のように、第3引数があるとそのパレット色を抜いて描画します。

スプライトの回転、拡大縮小

以下で r 角度に回転、 xscale,yscale で拡縮したものを x, y 座標に描画するようになります。

  sprite.pushRotateZoom(x,y,r,xscale,yscale);

回転軸は以下のように指定します。

  sprite.setPivot(sprite.width()/2.0, sprite.height()/2.0);

複雑なスプライト

LGFX display ( 128,64,5 );
static LGFX_Sprite sprite(&display);
static LGFX_Sprite sprite2(&sprite);
void setup()
{
  display.init();
  sprite.createSprite(65, 65);
  sprite2.createSprite(16, 3);
  sprite.fillCircle(32,32,32,TFT_WHITE);
  sprite2.fillRect(0,0,16,2,TFT_RED);
  sprite2.pushSprite(24,31,0);
  sprite.pushSprite(0,0,0);
}

のようにすると、sprite 中に sprite2 を使って描画できます。

image.png

もちろん、sprite3,sprite4 なども親子関係でどんどん建て増しできます。

sprite2 を回転して複数回 sprite に描画してみました。

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <LGFX_AUTODETECT.hpp>

LGFX display ( 320,200,2 );
static LGFX_Sprite sprite(&display);
static LGFX_Sprite sprite2(&sprite);
void setup()
{
  display.init();
  sprite.createSprite(256, 256);
  sprite2.createSprite(30, 5);
  sprite.fillCircle(128,128,128,TFT_WHITE);
  sprite2.drawGradientLine(0,0,30,0,sprite.color888(227,227,164),sprite.color888(227,227,227));
  sprite2.drawGradientLine(0,1,30,1,sprite.color888(220,220,164),sprite.color888(220,220,220));
  sprite2.drawGradientLine(0,2,30,2,sprite.color888(210,210,164),sprite.color888(210,210,210));
  sprite2.drawGradientLine(0,2,30,3,sprite.color888(200,200,164),sprite.color888(200,200,200));
  sprite2.drawGradientLine(0,2,30,4,sprite.color888(190,190,164),sprite.color888(190,190,190));
  sprite2.setPivot(128, 2);
  for ( int i=0; i < 12; i++){
    sprite2.pushRotateZoom(128,128,360/12*i,1.0,1.0,0);
  }
}
void loop()
{
  for(int i=0; i<320; i++){
    display.clear();
    display.fillRect(50,50,250,250,display.color888(127,127,127));
    sprite.pushRotateZoom(i,128,i,0.5,0.5,0);
    SDL_Delay(50);
  }
}

image.png

時計なんかが簡単に描けそうですね!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?