あーさん日記

https://akkera102.sakura.ne.jp/gbadev/ の中の人

Arduboy 実験25

www.youtube.com
GitHub - akkera102/05_tiny_sokoban: Tiny Sokoban - arduboy


tiny sokobanです。レベルは全部で52面あります。
1,2面は難しいので、3,4面から始めることをお勧めします。


作りは至って普通なのでコメントしようもないですけど・・・。
蛇足な話をすると、ステージデータは1面につき64バイト固定です。
おかげで以下のようなコードになりました。

void LvSetResCode(void)
{
	u8* p = (u8*)txtLv + Lv.no * TXT_LV_BYTE;
	u8  x, y;

	for(y=0; y<LV_MAX_CY; y++)
	{
		for(x=0; x<LV_MAX_CX; x++)
		{
			Lv.code[x][y] = __LPM(p++);

			if(LvIsChr(x, y) == TRUE)
			{
				AnimeSetChr(x, y);
			}
		}
	}
}

最初はlex.c作って解析させてやるぜと息巻いてましたけど、
作っている途中で固定の方が簡単やん、という流れで上記のようになりました。
52面 * 64バイト = 3328バイト程度なので問題ありません。


壁について。よくあるブロックを並べていくのはかっこよくないと思います。
f:id:akkera102:20160325201437p:plain
これだとイケてない感じなので繋がっているように工夫しています。
f:id:akkera102:20160325201456p:plain
生成はpython先生の出番です。

# -*- coding: utf-8 -*-

import Image
import ImageDraw


im = Image.open("base.bmp")   # 真っ黒な画像 256色128x128。パレットを先に設定済
dw = ImageDraw.Draw(im)
cx = im.size[0]
cy = im.size[1]
b  = 0

for y in range(0, cy, 8):
	for x in range(0, cx, 8):
		if not (b & 0x01): dw.point((x, y), 255)
		if not (b & 0x02):  dw.line((x + 1, y, x + 6, y), 255)
		if not (b & 0x04): dw.point((x + 7, y), 255)

		if not (b & 0x08):  dw.line((x, y + 1, x, y + 6), 255)
		if not (b & 0x10):  dw.line((x + 7, y + 1, x + 7, y + 6), 255)

		if not (b & 0x20): dw.point((x, y + 7), 255)
		if not (b & 0x40):  dw.line((x + 1, y + 7, x + 6, y + 7), 255)
		if not (b & 0x80): dw.point((x + 7, y + 7), 255)
		b += 1

im.save("wall.bmp")

生成結果。
f:id:akkera102:20160325201556j:plain
なかなかいい壁さんです。想像どおりの仕上がりになりました。