Skip to content

Commit

Permalink
Merge pull request #20 from lovyan03/unstable
Browse files Browse the repository at this point in the history
v0.1.12
  • Loading branch information
lovyan03 committed Jun 22, 2020
2 parents c66b798 + 62c26ed commit 105ae24
Show file tree
Hide file tree
Showing 12 changed files with 724 additions and 74 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# LovyanGFX

SPI LCD graphics library (for ESP32 / SAMD51).
M5Stack / M5StickC / TTG T-Watch / ODROID-GO / ESP-WROVER-KIT / WioTerminal
M5Stack / M5StickC / TTGO T-Watch / ODROID-GO / ESP-WROVER-KIT / WioTerminal / and more...

[![examples](http://img.youtube.com/vi/ClR-75mbyU4/0.jpg)](http://www.youtube.com/watch?v=ClR-75mbyU4 "MovingIcons")
[![examples](http://img.youtube.com/vi/vzQ6La0HgCg/0.jpg)](http://www.youtube.com/watch?v=vzQ6La0HgCg "MeterSample")
Expand Down Expand Up @@ -308,8 +308,12 @@ void loop(void)
# 注意・制限事項
## M5Stack.h(M5StickC.h)と共存させたい場合は、
ESP32-Chimera-Core のlgfxブランチを利用してください。
## M5Stack.h(M5StickC.h)と共存させる方法
### 方法1
include <M5Stack.h> より後に include <LovyanGFX.hpp> を書いてください。
M5.Lcdは使わずに、別途LGFXのインスタンスを用意して使用してください。
### 方法2
[ESP32-Chimera-Core](https://github.com/tobozo/ESP32-Chimera-Core) を利用すると、M5.Lcd が LovyanGFX になります。
作成動機 Motivation behind this library
Expand Down
278 changes: 278 additions & 0 deletions examples/Game/BallMaze/BallMaze.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@

#include <LovyanGFX.hpp>


#if defined( LGFX_M5STACK ) || defined( ARDUINO_M5Stack_Core_ESP32 ) || defined( ARDUINO_M5STACK_FIRE ) // M5Stack

#define BUTTON_A_PIN 39
#define BUTTON_B_PIN 38

static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;

#elif defined ( LGFX_M5STICKC ) || defined ( ARDUINO_M5Stick_C )

#include <AXP192.h>
#define BUTTON_A_PIN 37
#define BUTTON_B_PIN 39

static constexpr std::uint32_t draw_cycle = 1;
static constexpr float zoom_min = 1.4;
static constexpr float zoom_max = 16;

#elif defined( LGFX_ODROID_GO ) || defined( ARDUINO_ODROID_ESP32 ) // ODROID-GO

#define BUTTON_A_PIN 32
#define BUTTON_B_PIN 33

static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;

#elif defined( LGFX_TTGO_TWATCH ) || defined( ARDUINO_T ) // TTGO T-Watch

#define BUTTON_A_PIN 36
#define BUTTON_B_PIN -1

static constexpr std::uint32_t draw_cycle = 2;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;

#elif defined( LGFX_WIO_TERMINAL ) || defined (ARDUINO_WIO_TERMINAL) || defined(WIO_TERMINAL)

#define BUTTON_A_PIN 0x0200|28
#define BUTTON_B_PIN 0x0200|27

static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;

#endif

static LGFX lcd;
static LGFX_Sprite sp(&lcd);
static std::int32_t px, py;
static float ox, oy;
static float cx, cy, cr;
static float ax, ay;
static float zoom;
static float angle, rad;
static float add_angle = 0;
static float add_advance = 0;
static std::uint32_t draw_count = 0;
static std::uint32_t skip_count = 0;

static constexpr float deg_to_rad = 0.017453292519943295769236907684886;
static constexpr float gravity = -0.005;
static constexpr float zoom_speed = 0.02;

static void create_maze(void)
{
sp.clear(0);
sp.setColor(1);
sp.fillRect(0, 0, sp.width(), 16);
sp.fillRect(0, sp.height() - 16, sp.width(), 16);
sp.fillRect( 0, 0, 16, sp.height()-16);
sp.fillRect(sp.width()-16, 0, 16, sp.height()-16);
sp.setColor(3);
for (int y = 1; y < sp.height(); y += 2)
{
for (int x = 1; x < sp.width(); x += 2)
{
sp.writePixel(x, y);
int xx = x;
int yy = y;
do
{
xx = x;
yy = y;
switch (random(4)) {
case 0: xx = x + 1; break;
case 1: xx = x - 1; break;
case 2: yy = y + 1; break;
case 3: yy = y - 1; break;
}
} while (3 == sp.readPixelValue(xx, yy));
sp.writePixel(xx, yy);
}
}
}

static void draw(void)
{
draw_count += draw_cycle;
std::uint_fast8_t blink = 127+abs(((int)(draw_count<<1) & 255)-128);
sp.setPaletteColor(1, 127, 127, blink);
sp.setPaletteColor(2, 127, blink, 127);

float fx = (cx - ox);
float fy = (cy - oy);
float len = sqrt(fx * fx + fy * fy) * zoom;
float theta = atan2(fx, fy) + rad;
std::int32_t vx = round(sin(theta) * len);
std::int32_t vy = round(cos(theta) * len);
sp.pushRotateZoom(px - vx, py - vy, angle, zoom, zoom);
}

static void game_init(void)
{
px = lcd.width()>>1;
py = lcd.height()/3;

create_maze();
ox = sp.getPivotX();
oy = sp.getPivotY();

cx = (sp.width() >>1);
cy = (sp.height()>>1);
cr = 0.2;
zoom = zoom_min;
}

static bool game_main(void)
{
if (BUTTON_A_PIN >=0 && BUTTON_B_PIN >=0 && (lgfx::gpio_in(BUTTON_A_PIN) == 0 && lgfx::gpio_in(BUTTON_B_PIN) == 0))
{
zoom *= 1.0 - zoom_speed;
if (zoom < zoom_min) { zoom = zoom_min; }
}
else
{
zoom *= 1.0 + zoom_speed;
if (zoom > zoom_max) { zoom = zoom_max; }

add_angle -= add_angle / 10;

if (BUTTON_A_PIN >= 0 && BUTTON_B_PIN >= 0)
{
if (BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0) add_angle += 0.6;
if (BUTTON_B_PIN >=0 && lgfx::gpio_in(BUTTON_B_PIN) == 0) add_angle -= 0.6;
}
else
{
static bool pressed;
static bool flow;
if (BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0)
{
if (!pressed)
{
pressed = true;
flow = !flow;
}
add_angle += flow ? 0.6 : -0.6;
}
else
{
pressed = false;
}
}
}

angle += add_angle;
add_angle = add_angle * 9 / 10;
rad = angle * - deg_to_rad;

ax += sin(rad) * gravity;
ay -= cos(rad) * gravity;
ax = ax * 9.7 / 10;
ay = ay * 9.7 / 10;

float addy = (ay<0.0) ? -cr:cr;
auto tmpy = round(cy+ay+addy);

if ( 3 == sp.readPixelValue(round(cx), tmpy))
{
cy = tmpy - addy + (ay < 0.0 ? 0.5 : -0.5);
ay = -ay * 9.0 / 10;
}
else
{
cy += ay;
}

float addx = (ax<0.0) ? -cr:cr;
auto tmpx = round(cx+ax+addx);
if ( 3 == sp.readPixelValue(tmpx, round(cy)))
{
cx = tmpx - addx + (ax < 0.0 ? 0.5 : -0.5);
ax = -ax * 9.0 / 10;
}
else
{
cx += ax;
}

std::uint32_t pv = sp.readPixelValue(round(cx), round(cy));
if ( 0 == pv)
{
sp.drawPixel(round(cx), round(cy), 2);
}
else if (1 == pv) return true;

if (++skip_count == draw_cycle)
{
skip_count = 0;
draw();
}
return false;
}


void setup(void)
{
lgfx::lgfxPinMode(BUTTON_A_PIN, lgfx::pin_mode_t::input);
lgfx::lgfxPinMode(BUTTON_B_PIN, lgfx::pin_mode_t::input);

lcd.init();
lcd.startWrite();
lcd.setColorDepth(16);
sp.setColorDepth(2);
sp.createSprite(257, 257);
game_init();

#if defined ( LGFX_M5STICKC ) || defined ( ARDUINO_M5Stick_C )

AXP192 axp;
axp.begin();
axp.ScreenBreath(8);

#else

lcd.setBrightness(128);

#endif
}

void loop(void)
{
if (!game_main())
{
lcd.fillCircle(px, py, round(cr*zoom), 0xFFFF00U);
}
else
{
std::int32_t py0 = lcd.height() >> 1;
float cx0 = (cx + (sp.width() >>1)) / 2;
float cy0 = (cy + (sp.height()>>1)) / 2;
for (;;)
{
draw();
if (py < py0) ++py;
if (cx != cx0) cx += (cx0 - cx) / 256;
if (cy != cy0) cy += (cy0 - cy) / 256;

angle += .5;
rad = angle * - deg_to_rad;
zoom *= 1 - zoom_speed;
if (zoom < zoom_min)
{
zoom = zoom_min;
if ((BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0)
|| (BUTTON_B_PIN >=0 && lgfx::gpio_in(BUTTON_B_PIN) == 0)
) break;
}
}
game_init();
}
}
Loading

0 comments on commit 105ae24

Please sign in to comment.