Image Composite Editorを使ってゲーム動画からMapを生成する
結構前に深世海にハマってて思いついたので手順をまとめます
Image Composed Editorを使ってパノラマ合成で作ります
用意するもの
- Map生成用の動画
ブログ用の動画 pic.twitter.com/vxn6QeP7Yg
— じゃがいも(31) (@jagapoko) June 19, 2020
ScreenToGif forest.watch.impress.co.jp
Namery www.vector.co.jp
Image Composed Editor forest.watch.impress.co.jp
Map生成の流れ
- Switchでゲーム動画を撮影
- ScreenToGifで動画フレームの切り出し
- Nameryでリネーム
- Image Composed Editorで画像の結合
手順
動画の切り出し作業
ScreenToGifを起動して「エディタ」を選択
上のメニューから「ロード」を選択して撮影した動画をインポートする
フレームレートは15fpsぐらいに設定
(多いとその分時間がかかります)
画像編集タブから「切り抜き」を選択
合成の時に邪魔になりそうな部分を取り除きます
終わったら適用を押す
下のフレーム画像一覧を右クリックすると「フォルダーを表示」というメニューが出るのでクリック
開いたフォルダに入っている画像を一式別のフォルダにコピーします
出力画像のリネーム
Image Composed Editorで読んだときにフレーム順に読み込まれるように名前を連番にします
Nameryを起動して、ScreenToGifで出力したフォルダを選択
ファイルリストを全選択、右側のリネーム設定で「文字列+連番」「開始/桁」を1/4に設定してリネーム実行
Image Composed Editorでパノラマ化
Image Composed Editorを起動して「New Panorama from Images」を選択
ファイルを開くダイアログで、リネーム済みの画像を全選択して「開く」を押す
画像がフレーム順に読み込まれることを確認したら右上の「Next」を押す
パノラマの生成が始まるので待つ
画像が少ないほど生成が早いのであまりにも時間がかかる場合はフレーム数を落としたほうがいいかも
割といい感じにMapが合成された
右のオプションで補正方法を選べる。気に入ったものを選択して「Next」を押す
画像の切り抜き設定。特に切り抜く必要がなければ「Next」
最後に「Export to disk」を押してファイル保存
これでMap生成は完了
長い動画だと合成に時間がかかって精度も落ちちゃうから短い動画で何個もMapを作る感じになるかなー
ワグナス!今年も梅酒を漬けたぞ!
漬けました
左からジン梅酒・ブランデー梅酒・梅シロップ
というわけで以下レシピ
○ジン梅酒
・梅1kg
・ビーフィーター 1.4l
・氷砂糖1kg
○ブランデー梅酒
・梅1kg
・梅酒用ブランデー1.8l
・氷砂糖 1kg
○梅シロップ
・梅1.5kg
・氷砂糖1kg
・上白糖 700g
・りんご酢 60cc
○梅の下処理
1. 梅を洗います
2. アク抜きのため水に4時間ぐらいつける
3. 水気を取ってヘタを取る
4. フォークで穴を開ける
5. 一晩凍らせる
○漬け方
1. 梅と氷砂糖が層になる感じで交互に詰めていきます
2. 梅シロップは最後に上白糖をドバーッします
3. お酒やりんご酢を最後に入れます
こんな感じであとは定期的にかき混ぜて待ってれば完成
ジン梅酒のソーダ割りが楽しみすなあ
深世海 臨時潜水スタンダード 9分切り安定ルート ボス編
前回の続きを書いていきます whitedog0215.hatenablog.jp
攻略といってもそんなに大したことは書いてなくて
パターン化しやすい序盤になるべく体力を削って後は気合で戦う、が基本戦略になります
vs 資源探査機 大型
矢とドリルをメインにして戦います
ボスの攻撃パターンは大体↓な感じ
自爆(緑)
ほとんどモーションがないので食らいやすい
ボンベもかなり持ってかれるの危ない自爆(赤)
予告が出るのでわかりやすい
攻撃を当てて続けてればやめてくれる?ジャンプ
踏みつぶされるとダメージ
- フックショット(上)
遅延行為
なるべく上に行かれる前に攻撃して落とそう
天井に行っちゃったら殴って落とすか、下を通って落ちてくるのを待つかになる
- フックショット(横)
地上で立っていれば当たらない
当たっちゃうと引き寄せてから自爆(赤)を発動するのでブーストで逃げないと危険
ある程度攻撃を当てたらひっくり返ってダメージが入るようになるので、2回ひっくり返して倒すパターンを組んでいきます
(ひっくり返る条件がよくわからん...)
1.ボス部屋に入ったら画像の位置ぐらいに立ち、ボス登場のエフェクトが出たらドリルを発射
2.前ジャンプして2発目を発射、なるべく1発目のドリルと同時にボスに当たるようにする
3.武器を矢に切り替えて攻撃、ボスがひっくり返ってから起きるまで矢を連射
体力を2/3以上削れていれば上出来
4.以降はアドリブ
基本的な戦い方はボスの移動や攻撃に合わせてドリルを1発発射+追撃の矢で頑張ってひっくり返すになります
ひっくり返ったら勝ち確なのでがんばりましょう
vs ダンクルオステウス
ボムと矢をメインにして戦います
攻撃パターンは↓
トルネード突進はされないように頑張る
噛みつき
無敵空間から噛みついてくる
避けるのは全然難しくないが、めっちゃ時間を持ってかれる青玉
こちらに泳いでくるときに1~3個放出する
主人公を追尾してきて当たるとめちゃくちゃ酸素を消費させられる
矢で除去しておこう赤玉
泳ぎながらたくさん放出してくる。海にゴミを流すな
範囲内に入ると自爆する機能を持っている
事故死率が高いので噛みつき攻撃待ち中になるべく破壊しておくのが吉
7個ターゲットを壊せば終わりだけど、1個ターゲットを壊すと30秒ぐらい手を出せなくなる最悪の遅延能力を持ったボス
ボムでまとめてターゲットを破壊しながら残ったターゲットを矢で破壊する、が基本戦略になります
1.ボス部屋に入る前に画像の位置あたりから右下に向かってボム発射
ターゲットを3つぐらい破壊できる
2.1でダメージを与えた直後にボム発射、自分は1枚目の画像のような位置関係が好み
2枚目の画像はボムの爆発と同時に矢でのターゲット破壊も狙っているところ
うまくできるとおいしいです
3.以降はアドリブ
噛みつき攻撃を回避、青玉を矢で除去して最後のボムでターゲット破壊を狙いましょう
2と同様に矢でもターゲット破壊を狙います
ターゲットが残り1個ならボムなしでいいと思います
道中と合わせてボス編もうまくできるようになれば7分台は安定してくると思います
みんなでやろう臨時潜水TA
てかもっと深世海の攻略記事増えてもいいと思うからみんな書いてよ
俺も書いたんだからさ
最近臨時潜水ばっかりやってたから本編2週目に戻るぞー
深世海 臨時潜水スタンダード 9分切り安定ルート 道中編
深世海で検索しても全然攻略記事がなかったので自分で書きます
これが一番簡単で早いと思います
(この記事は攻略のネタバレを含んでいます)
故郷エリア
最初の分岐を左側に進み、壁を破壊
右に進み、岩を砕いてから矢を取ります
左に歩きつつ、ボンベが降ってくるので取ります
手前のサンゴを矢で倒し、滑りながらサンゴの間を抜けて右へ
サメと資源採掘機 歩型はスルーして左のルートに進んでいきます
サンゴの手前で少し浮遊してタイミングをずらしてからサンゴの間を進みます
1本目のつららに乗り、下向きに矢を打つとうまく通り抜けることができます
つららエリアを抜けると左隅に穴があるのでそこから下へ抜けていきます
大海溝エリア
吊にフックショットを当てて落下していくだけです
砕いた岩に当たるとダメージを受けるので早めにフックショットを離して吊とは距離を取っておきましょう
底まで下りたら酸素残量をキープしながら右へ
古代遺跡エリア
遺跡は真ん中のルートを通ります
酸素をキープできていれば補給なしで進んで大丈夫です。もし足りなければ通路そばの岩を砕いて補給
真ん中ルートの底に着いたらスイッチを押して左へ進み、ウツボの下を通過
上に進んで岩を砕いて補給、そのまま右へ
ウツボが2匹いるところはウツボの下をくぐってからブースト使いながら下へ
スイッチを押し、ドリルとボンベを取ります
早速ドリルで地面を砕いて道を作ります。この時岩を狙うようにすれば1発で済むのでGood
雑魚ボス部屋の前ですが、矢は足りているので取らなくて大丈夫です
2体いますが矢を3発ずつすべてきっちり当てて倒しましょう
沈没船エリア
ボスを倒したときに出る泡を纏い、ブーストを使って下に進んでいきます
ボムが欲しいので分岐は右へ
丸形の通路に入りボンベをスルーして右上へ(より安定させたい場合は取って大丈夫)
オニキンメ?が2体いる場所はブーストを使いながら棍棒で殴るようにすると進みやすいです
通路を抜けてボムを取得
水面で酸素を補充してから潜り、天井に沿って進んで生体調査機(洗脳)の上側を通過
ここでブーストを使ってしまうと酸素が足りなくなるため使わないようにします
(運が悪く生体調査機(洗脳)に殴られることもありますが、ボンベが足りてるのでそのまま進んで大丈夫です)
そのあとのくらげエリアは壁に沿って進んで抜けます
粘菌ゾーンはブーストを使って抜けていきます
1体目、2体目は画像のあたりでブーストを使えばボムを温存して進むことができます
酸素がやばいのでボンベを拾ってから吊につかまって左へ
海底火山エリア
吊からフックショットを離したら右側の通路へボムを撃ち、岩を砕いて酸素を補給
粘菌がおとなしくなってから通路を進み、フックショットで爆弾を破壊
左側の地面を破壊してもう一度フックショットで爆弾を破壊
ボンベを取りつつ壁を滑っていくと地面に穴が開きます
粘菌回避のため右へ進むとスケーリーフットがまとわりついてくるので棍棒で倒します
左に進んで2体の資源探査機 小型の間ぐらいにボムを撃ちこみます
資源探査機 小型の左側に回り込んでから矢を撃って1体目を倒し、残った2体目も棍棒で倒します
下へ進むとボンベと岩があるのでとりあえず補給
溶岩の上を滑って進み、溶岩の噴出を待ってからジャンプ
そのあとに下にブーストすることでうまく抜けられます
右側の溶岩に沿ってゆっくり下りていき、資源探査機 小型のフックショットを誘導して左に切り返し
溶岩の噴出を待ってから左に進みます
最後の矢で下に道がある溶岩を破壊してボス前最後の補給エリアに到着!
酸素と矢とドリルを補給してボスに挑みましょう
早くて5分ぐらい、グダグダになっても6分ちょっとでここまで来れると思います
あとはボスを3分で倒すだけ!できらぁ!
※追記
ボス編を書きました
豆苗 成長記録のまとめ
豆苗育てて14日目においしくいただきました
よくね?
以下まとめ
- いちごパックの大きくてそこの浅いタイプが豆苗育成にぴったり
- 水と日光だけで育つ
- 水は毎日変える(根本部分だけ水につかるようにする。種は水の上)
- ほどほどに日に当てるとよい
- 日に当てる側は定期的に入れ替えたほうが伸びそう(入れ替えないと日に近いほうが背が低くなる)
ごちそうさまでした
C# WPF enumに属性を付けてComboBoxにバインドして便利に使う
参考元
こちらの記事を参考にさせていただきました
できること
↓のような感じで項目名と属性で追加情報を付けたenumを定義しておけば
public enum Fruit { 未選択, [Price("\\150"), Color(KnownColor.Red), ResourceName("apple.png")] りんご, [Price("\\80"), Color(KnownColor.Yellow), ResourceName("banana.png")] ばなな, [Price("\\120"), Color(KnownColor.Orange), ResourceName("orange.png")] みかん }
項目名をそのままコンボボックスで使ったり、追加情報を簡単に取得することができるようになります
ソースコード
ソースコードはこちら github.com
ポイント
属性の定義方法や必要な拡張メソッド等は参考記事を参照してください
(参考記事内のコードスニペットattrgを使用させていただきました)
public enum Fruit { 未選択, [Price("\\150"), Color(KnownColor.Red), ResourceName("apple.png")] りんご, [Price("\\80"), Color(KnownColor.Yellow), ResourceName("banana.png")] ばなな, [Price("\\120"), Color(KnownColor.Orange), ResourceName("orange.png")] みかん }
- enumで列挙した値をすべて取り出して、コンボボックスのデータソースに追加します
DataSource = new ReactiveCollection<Fruit>(); foreach (Fruit g in Enum.GetValues(typeof(Fruit))) { DataSource.Add(g); }
SelectedItem.Subscribe(g => { ItemName.Value = $"Item : {g}"; ItemPrice.Value = $"Price : {g.GetPrice()}"; ItemColor.Value = $"Color : {g.GetColor()} "; SelectedColor.Value = g.GetColor().ToMediaColor(); ItemImage.Value = new Uri($"..\\Resource\\{g.GetResourceName()}", UriKind.Relative); });
ReactivePropertyの便利メソッド(ToReactivePropertyとToReactivePropertyAsSynchronized)
名前が長くて呼び出し方をよく忘れてしまいますが、ViewModelとModelで片方向・双方向バインドができてとても便利です
なるべく短くまとめたいと思います
ToReactiveProperty系メソッド
- ToReactiveProperty
- ToReadOnlyReactiveProperty
- ToReadOnlyReactivePropertySlim
Modelの値が変更されたとき、ViewModelへの通知を行います(片方向)
こんな感じでボタンを押すとTextBlockに値のカウントを増やす動きを作ります
まずはサンプルコード
- ViewのButtonとTextBlock
<Button Width="100" Height="40" Content="Button" Command="{Binding ButtonCommand}" FontSize="20"/> <TextBlock Text="{Binding Counter.Value}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50"/>
- ModelとViewModel
public class Model : BindableBase { private int pushCount; public int PushCount { get { return pushCount; } set { SetProperty(ref pushCount, value); } } } public class MainWindowViewModel : BindableBase { public ReactiveCommand ButtonCommand { get; } = new ReactiveCommand(); public ReadOnlyReactivePropertySlim<int> Counter { get; } public MainWindowViewModel() { var model = new Model(); this.ButtonCommand.Subscribe(() => { model.PushCount++; }); this.Counter = model.ObserveProperty(x => x.PushCount).ToReadOnlyReactivePropertySlim(); } }
- 大事なポイント
this.PushCount = model.ObserveProperty(x => x.PushCount).ToReadOnlyReactivePropertySlim();
ModelはINotifyChangedを継承する必要があります(BindableBaseはINotifyChangedを継承したPrismのクラス)
ObservePropertyから変更通知を受け取りたいプロパティを指定してToReactivePropertyします
こうすることで
- ボタンが押されたらModel.PushCountの値を変更
- Model.PushCountがViewModelCounterへ変更を通知
- 表示の更新
という動きが実現できます
ToReactivePropertyAsSynchronized
- ViewModelの値が変更された時、Modelに変更の通知
- Modelの値が変更された時、ViewModelに変更の通知
を行います(双方向)
サンプルコード
- Viewのそれぞれ
<TextBox Width="200" Height="40" Text="{Binding Input.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="20"/> <TextBlock Text="{Binding Output.Value}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="40"/> <Button Width="100" Height="40" Content="VM" Command="{Binding ViewModelChangeCommand}" FontSize="20"/> <Button Width="100" Height="40" Content="M" Command="{Binding ModelChangeCommand}" FontSize="20"/>
- ModelとViewModel
public class Model : BindableBase { private string input; public string Input { get { return input; } set { SetProperty(ref input, value); } } } public class MainWindowViewModel : BindableBase { public ReactiveProperty<string> Input { get; } public ReadOnlyReactivePropertySlim<string> Output { get; } public ReactiveCommand ViewModelChangeCommand { get; } = new ReactiveCommand(); public ReactiveCommand ModelChangeCommand { get; } = new ReactiveCommand(); public MainWindowViewModel() { var model = new Model(); this.Input = model.ToReactivePropertyAsSynchronized(x => x.Input); this.Output = model.ObserveProperty(x => x.Input).ToReadOnlyReactivePropertySlim(); this.ModelChangeCommand.Subscribe(() => { model.Input = "M"; }); this.ViewModelChangeCommand.Subscribe(() => { this.Input.Value = "VM"; }); } }
- 大事なポイント
this.Input = model.ToReactivePropertyAsSynchronized(x => x.Input);
INotifyChangedを継承したModelからToReactivePropertyAsSynchronizedを呼び出し、双方向バインドしたいプロパティを指定します
こうすることで
- TextBoxに文字を入力するとViewModel.Inputの値が変更
- ViewModel.InputがModel.Inputに変更を通知
- Model.InputがViewModel.Outputに変更を通知(表示の更新)
という動きができています。さらにボタンを押したときには
Mボタンの場合
ボタンが押されたらModel.Inputの値を変更
Model.InputがViewModel.InputとViewModel.Outputに変更を通知(TextBoxとTextBlockの表示更新)
VMボタンの場合
ボタンが押されたらViewModel.Inputの値を変更(TextBoxの表示更新)
- ViewModel.InputがModel.Inputに変更を通知
- Model.InputがViewModel.Outputに変更を通知(TextBlockの表示の更新)
という動きになります
わざわざモデルの値を見に行く必要がなくなるので便利