ゲームを作るよ!

Created by @techno_neko

## 自己紹介 - 仕事: 組み込み系 - Twitter: @techno_neko - 所属: Hokkaido.pm
## 絵を描くようにステージを作りたい!
## どうやって?
## 作った! - https://github.com/techno-cat/p5-Imager-LineTrace
## Imager::LineTraceとは? - 画像中のラインをトレースする - 結果は頂点座標 - 閉じた図形も判別可
## 用意した画像 ![用意した画像](./image/1-1.png "1-1") ※実際は、64x64の大きさ
## 用意した画像 - 黒い線が足場 - 緑がスタート - 赤がゴール
## トレースする ``` perl my $figures_ref = Imager::LineTrace::trace( file => $path ); ```
## 問題が発生!
## 緑と赤について - 実装上、R,G,Bのいずれかをトレースする - 緑: #00FF00 - 赤: #FF0000 - 白: #FFFFFF(背景色)
## 緑の要素だけに着目すると? - 緑: 0xFF - 白: 0xFF(背景色)
## これじゃ、トレースできない! 緑の点をトレースするのに、 赤(or 青)の要素をトレースするのはおかしい!
## 背景を黒にする ![黒背景の画像](./image/1-1_black.png "1-1") ※実際は、64x64の大きさ
## トレースする ``` perl my $figures_ref = Imager::LineTrace::trace( file => $path, ignore => 0 ); ``` "ignore"で背景色を指定する
## 座標のダンプ ``` perl my $i = 0; foreach my $figure (@{$figures_ref}) { print "-------- [", $i++, "] --------", "\n"; print "type :", $figure->{type}, "\n"; print "trace_value : ", sprintf("0x%06X", $figure->{value}), "\n"; print "is_closed : ", $figure->{is_closed}, "\n"; foreach my $p (@{$figure->{points}}) { printf( "(%2d,%2d)\n", $p->[0], $p->[1] ); } } ```
## 緑の要素でトレースする ``` perl my $figures_ref = Imager::LineTrace::trace( file => $path, channels => [1], ignore => 0 ); ``` - "channels"で指定する(0:R, 1:G, 2:B, 3:Alpha)
## 緑の要素でトレースする - 実は問題が残っている - 白のラインもトレースされちゃう - これは厳しい・・・
## 点の値を変えてみる - トレースは同じ値で行われる - はじめっからそうすれば良かった - でも、これは面倒!
## ライブラリに手を入れる - RGBを使ってトレースできるようにした! - 背景色が白でも良くなった! - でも、もう背景色は黒にしちゃったよ・・・
## トレースする ``` perl my $figures_ref = Imager::LineTrace::trace( file => $path, ignore => 0 ); ```
## PointとLineが検出できた! ``` -------- [0] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 ( 0, 0) (63, 0) -------- [1] -------- type :Point trace_value : 0x00FF00 is_closed : 0 (56, 1) -------- [2] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 (32, 8) (39, 8) -------- [3] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 (16,16) (31,16) -------- [4] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 ( 0,24) (15,24) -------- [5] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 (24,32) (31,32) -------- [6] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 (32,40) (39,40) -------- [7] -------- type :Line trace_value : 0xFFFFFF is_closed : 0 (40,48) (55,48) -------- [8] -------- type :Point trace_value : 0xFF0000 is_closed : 0 (48,49) ```
## これをどうするの?
## ソースコードに変換する!
## こんな感じ ``` perl use v5.14; use strict; use warnings; use lib "../lib"; use Imager::LineTrace; if ( (not @ARGV) or (not -e $ARGV[0]) ) { say "Usage: perl $0 file_path"; exit( 0 ); } my $figures_ref = Imager::LineTrace::trace( file => $ARGV[0], ignore => 0 ); my @lines = grep { $_->{type} =~ /Line/ } @{$figures_ref}; { print "const int n = " . scalar(@lines) . ";\n"; print "const CGFloat xyw[][3] = {\n"; my @buf = (); for my $line (@lines) { my $x0 = $line->{points}->[0]->[0]; # pt[0].x my $y0 = $line->{points}->[0]->[1]; # pt[0].y my $w = $line->{points}->[1]->[0] - $x0; # pt[1].x - pt[0].x push @buf, " { " . sprintf("%4.1f, %4.1f, %4.1f", $x0, $y0, $w ) . " }"; } print join( ",\n", @buf ), "\n"; print "};\n"; } # ここは使ってない my @points = grep { $_->{type} =~ /Point/ } @{$figures_ref}; ```
## これをコピペすれば・・・ ``` c const int n = 7; const CGFloat xyw[][3] = { { 0.0, 0.0, 63.0 }, { 32.0, 8.0, 7.0 }, { 16.0, 16.0, 15.0 }, { 0.0, 24.0, 15.0 }, { 24.0, 32.0, 7.0 }, { 32.0, 40.0, 7.0 }, { 40.0, 48.0, 15.0 } }; ```
## まとめ 1. App::pfswatchで画像ファイルを監視 1. 画像ファイルを更新するとソースコードも更新される 1. ビルドしてシミュレーター(or実機)に転送 1. テストプレイ 1. (以下、繰り返し)
## ご静聴ありがとうございました!