レシピはこちら。
今回はちゃんと大さじ小さじのスプーンを購入したので、きちんと分量計りました。
これはカレーだ。
うまい!
そしてめっちゃ辛い!
そりゃそうだ、カレーの辛さにプラスしてラー油と一味唐辛子が入っているから。
汗がドバッと噴き出ました。
でも旨い。
こんな旨いものをレンジで簡単にできちゃうから、本当にリュウジさんはすごい。
これはリピートありだね。

前回までの状況はこちら。
前回はカメラの画像を表示させていただけですが、
今回はこの画像をファイルに保存します。
例えば、zキーを押すことで画像をファイルに保存することにします。
プログラムはこうなります。
from datetime import datetime
import cv2, os
def main():
cam = cv2.VideoCapture(0)
if cam == None:
return False
while True:
# カメラから映像を読み込む
_, img = cam.read()
cv2.imshow("preview", img)
key = cv2.waitKey(1)
if key == 122:
cv2.imwrite("test.png", img)
elif key < 255:
break
# 事後処理
cam.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
cv2.waitKey(1)が122というのは、押したキーがzキーだったと言うことを示しています。
画像ファイルに保存する場合はimwrite()を使ってフレームデータとファイル名を渡すとカレントディレクトリに指定ファイル名で保存されます。
一通り食事管理機能は完成したのですが、
正直、いまいち使いづらいです。
数値を毎回入力しなければならないので。
過去に入力したデータを再利用できないかな、と思っているのですが、
調べてみると、HTMLのinputタグにはtype=searchというものがありまして、
<input type="search" v-model="contents.item" autocomplete="on" list="keyword"/>
<datalist id="keyword">
<option value="札幌" />
<option value="札駅" />
<option value="新さっぽろ" />
<option value="東札幌" />
<option value="札束" />
</datalist>
こんな感じでautocomplete=”on” list=”キーワード”と記入すると、
こんな感じでdatalistタグのid=”キーワード”の内容が入力候補として表示されます。
これをうまく使えないかと。
品名の一部を入力→入力履歴を検索→候補を表示→履歴からデータを入力
という感じで、うまく処理できないかと思っています。
本来なら栄養素情報を別テーブルにしてそれを参照するという、正規化が必要なのだと思いますが、
いまからデータベースに変更を入れるのは、既存機能の大規模改修が発生(めんどくさい)ので、
それはそのままに、履歴検索用のテーブルを用意することにします。
それがあれば、入力履歴検索用のAPIを作成すれば行けるような気がします。
datalistの中のoptionタグがv-forでリストを反映させることができると思います。
ただ、大量のoptionが画面に表示されても鬱陶しいので、例えば、検索結果が10件以上だったらあえて表示させない、というのも、一つの手かもしれません。
とりあえず、こんな方針でやってみますか。
次回から着手します。
今回は画像を使ってみます。
画像はスプライトと呼ばれる単位で扱われます。
例えば、ただ画面に画像を表示する場合は、
bool SampleScene::init()
{
//////////////////////////////
// 1. super init first
if ( !Scene::init() )
{
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// add "HelloWorld" splash screen"
auto sprite = Sprite::create("pipo-charachip001b.png");
if (sprite == nullptr)
{
problemLoading("'pipo-charachip001b.png'");
}
else
{
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(sprite, 0);
}
return true;
}
画像をResources/res配下に設置し、
Sprite::create(“[画像ファイル名]”)スプライトの作成。
setPosition()で表示位置を決めてaddChild()でスプライトを設置すれば表示されます。
でも大抵は一枚の絵の中にいくつものパーツがまとめられているのが普通です。
なので、画像をクリッピングして、一部だけを表示させます。
// add "HelloWorld" splash screen"
auto sprite = Sprite::create("pipo-charachip001b.png", Rect(0,0,32,32));
if (sprite == nullptr)
{
problemLoading("'pipo-charachip001b.png'");
}
else
{
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(sprite, 0);
}
auto sprite2 = Sprite::create("pipo-charachip001b.png", Rect(0,32,32,32));
if (sprite2 == nullptr)
{
problemLoading("'pipo-charachip001b.png'");
}
else
{
// position the sprite on the center of the screen
sprite2->setPosition(Vec2(visibleSize.width/2 + origin.x + sprite->getContentSize().width, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(sprite2, 0);
}
return true;
じゃあ、これを使って、アニメーションさせます。
auto sprite = Sprite::create("pipo-charachip001b.png");
if (sprite == nullptr)
{
problemLoading("'pipo-charachip001b.png'");
}
else
{
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(sprite, 0);
}
Vector<SpriteFrame*> animFrames;
animFrames.reserve(12);
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(0,0,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(32,0,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(64,0,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(0,32,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(32,32,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(64,32,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(0,64,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(32,64,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(64,64,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(0,96,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(32,96,32,32)));
animFrames.pushBack(SpriteFrame::create("pipo-charachip001b.png", Rect(64,96,32,32)));
Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.1f);
Animate* animate = Animate::create(animation);
sprite->runAction(RepeatForever::create(animate));
auto moveBy = MoveBy::create(2, Vec2(50, 0));
sprite->runAction(moveBy);
return true;
SpriteFrameを組み合わせてAnimationを作成し、それからAnimateを作成します。
これからアクションを作成して、実行させます。
なかなか良い感じじゃないですか?
Pixel3からPixel4aに乗り換えたのですが、
非常に快適に動作しております。
Pixel3で動いていたアプリはほとんど動きますし、
最近始めた、戦国RENKAも問題無く動いております。
こういった3Dゲームでも問題ありません。
Pixel3のプロセッサーはSnapdragon 845であるのに対して、
Pixel4aのプロセッサーはSnapdragon 730Gです。
8XX番代はハイエンドプロセッサーにつけられる番号で、
7XX番代はミドルレンジプロセッサーにつけられる番号です。
この下には6XX番代もあり、これは低価格帯のスマホで使用されているプロセッサーです。
845と730Gは730Gの方が一世代新しいのですが、ハイエンドの845よりも快適に動いているように感じます。
おそらく、これはメモリ容量の差だと思うんですが、
それを考えると、いままではハイエンドの性能を生かし切れていなかったような気がしています。
やっぱり一般人にはハイスペックなんて必要なかった。
性能を生かし切れていない高い端末を買うよりも、安価でそこそこ動く端末の方がお買い得だと思いませんかね?
そう考えると、Pixel4aのコスパは最強で、低価格スマホで失敗するよりは、多少お金を積んでもPixel4aを勧めます。
ほんと、欠点は防水じゃ無いぐらいしか見つからない。
こちらのサイトに無限繁殖機構が紹介されていました。
https://wikiwiki.jp/craftopia/
リンク先は絵になってわかりづらいと思いますが、
要は、このように配置するみたいです。
矢印はコンベアーの動く向きです。
こうすることで牛が繁殖機に集まることになり、
自ら繁殖機の上に乗ってくれます。
上に積み重なっていくのは何でだろうねぇ?
もうちょっと細工すれば溢れた動物を処理できるかも。
前回までの状況はこちら。
はい、大幅に書き換えました。
詳細はgitHubのソースを見て欲しいのですが、
https://github.com/takishita2nd/HokkaidoWar
まず、メインシーンで使用していたデータは全てGameDataクラスに移動しました。
class GameData
{
public enum GameStatus
{
None,
SelectCity,
ActionEnemy,
ActionPlayer,
ShowResult,
GameEnd,
GameOver
}
public GameStatus gameStatus = GameStatus.None;
public List<City> Cities = null;
public List<City> AliveCities = null;
public Battle Battle = null;
public Player Player = null;
このクラスはシングルトンで管理します。
class Singleton
{
private static GameData _gameData = null;
public static GameData GetGameData()
{
if (_gameData == null)
{
_gameData = new GameData();
}
return _gameData;
}
このシングルトンクラス、ゲッターのでいいんじゃないかと思い始めた。
やっていることは同じですが。
メソッドでやるか、プロパティでやるかの違いです。
気が向いたら直します。
シーン遷移は全てシーンクラスのインスタンスを作り直します。
if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
{
var scene = new MainScene();
asd.Engine.ChangeScene(scene);
}
そのときに、ゲームデータを元に画面を作り直す、という感じです。
これで、バトルシーンからメインシーンに切り替わっても、ゲームが止まることは無くなりました。
これでやっと次に進める・・・。
繁殖機という設備がクラフトできたので、使ってみました。
繁殖機の上に赤い部分が二つあるので、ここに動物を運ぶと、繁殖機が動物を産みだしてくれます。
とは言っても無限ではないので、繁殖元の動物が死ぬと、繁殖機の動きが止まります。
あと、動物を運ぶのには、モンスタープリズムというアイテムが必要です。
はい、あのポケモンのあの丸いボールのような物です。
ある程度ダメージを与えて、このボールをぶつけると動物を捕まえることができ、好きなところに出現させることができます。
とりあえず、逃げないように囲って、繁殖場を作ってみたのですが、
勝手に動物が繁殖機に乗ってくれるような仕組みって無いんですかね?
あと、繁殖させた動物を処理する仕組みも考えてみたのですが、
コンベアーが燃えてしまいました。
壁も木材使うと燃えるので、これもダメですね。
コンベアーで上に運んで焚き火の上に落下させる方法が良いのかもしれない(確か、まだ作れない)
そろそろ次の文明に発展させるか・・・