TextMeshPro のrichTextタグで文章内に簡単に画像を含ませることができます!
今回はその方法を書きます。
- はじめに
- 準備:Sprite Assetを作ろう
- Sprite Assetの設定
- richTextタグで作ったSprite Assetを使おう
- 複数のSprite Assetから画像を取得したい場合
TextMeshPro のrichTextタグで文章内に簡単に画像を含ませることができます!
今回はその方法を書きます。
この記事での環境
Runnable
インタフェースをラムダの書き方で実装した場合。
Runnable runnable1 = () ->{ System.out.println("lambda!"); }; runnable1.run();
lambda!
Runnable
はご存知の通りrun
メソッドしかない。
戻り値と引数もない。
なので、上記のように、run
メソッドの処理を特にrun
というメソッドを宣言せずに実装できた。
関数型インタフェースという仕組みを使う。
この後のstreamAPIも絡むので、よく使われるであろう3つについてかく。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Function.html
T
は引数の型。R
は戻り値の型を指定する。
Function<Integer, String> asterisker = (i) -> { return "*" + i; }; String result = asterisker.apply(10); System.out.println(result);
*10
上記は10という数字を引数で渡して、アスタリスクの文字列を先頭に足して文字列を返す処理。
引数2つ渡したい!なんて場合は、BiFunction
なんてのもある。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/BiFunction.html
BiFunction<Integer, Integer, String> asterisker = (i, i2) -> { return "*" + (i * i2); }; String result = asterisker.apply(10, 2); System.out.println(result);
*20
https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Consumer.html
T
は引数の型。Function
の戻り値がない版?
Consumer<String> buyer = (goods) -> { System.out.println(goods + "を購入しました"); }; buyer.accept("おにぎり");
おにぎりを購入しました
https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Predicate.html
T
は引数の型。test
メソッドは評価した結果をbooleanで返してくれる。
Predicate<String> buyer = (goods) -> { return goods.equals("おにぎり"); }; boolean result = buyer.test("おにぎり"); System.out.println(result);
true
関数型インタフェース、そもそもどういう使い方するの?ってところ。。
int[] numbers = {-1, 2, 0, -3, 8}; List<Integer> numbersList = new ArrayList<>(); for(int n : numbers){ numbersList.add(n); }
まず数字が入ったリストを適当に用意した。この数字の順番をソートしたい。
Collections#sort
の第二引数では、ソートする方法をComparator
で定義することができる。
下記は、Comparator
をラムダで、小さい値→大きい値にソートするように書いた例。
Collections.sort(numbersList, (a, b) -> { return a - b; }); for(Integer n : numbersList) { System.out.print(n + ","); }
-3,-1,0,2,8,
まず、リストなどの大元であるCollections
にstream
というメソッドがjava8から追加された。
Stream<E>
を戻り値で返してくれる。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html
先ほどと同じように、数値型のリストに適当な値を入れておきました。
int[] numbers = {-1, 2, 0, -3, 8}; List<Integer> numbersList = new ArrayList<>(); for(int n : numbers){ numbersList.add(n); }
numbersList.stream().forEach((i) -> { System.out.print(i + ","); });
-1,2,0,-3,8,
リストの中身が変数i
に入ってくるので、それをsysoutしているだけのプログラム。
forEarch
はConsumer
を受け取るので、
今回の数値の場合だと、Constumer<Integer>
を受け取っていることになる。
numbersList.stream().filter((i) -> { return i > 0; }).forEach((i) -> { System.out.print(i + ","); });
2,8,
意味の通り、フィルタリングしてくれる。
filter
はPredicate
を受け取るので、
Predicate
の中で評価してbooleanの値を返しtrueのものだけ抜粋する。
numbersList.stream() .filter((i) -> { return i > 0;}) .map((i) -> { return "*" + i + "*"; }) .forEach((s) -> { System.out.print(s + ","); });
*2*,*8*,
map
はFunction
を受け取るので、
Function
の中で受け取った数値を文字列として返している。
https://github.com/XVimProject/XVim
xvimとはxcodeでvimが使えるようにするプラグインのことです。
今回はこれをxcode8.3に入れます。
xcodeをバージョンアップしたらxvimが使えなくなってしまったので、それの解消方法をまとめときます。
この記事は以下の記事から今回自分が必要だった部分だけ抜粋させていただきました。感謝。
macOS sierra Xcode8.3.2(8E2002)
cd ~/XVim // Xvimを置いてるディレクトリへ移動。このディレクトリは適宜変更してください。 make uninstall rm -r ~/XVim
https://github.com/XVimProject/XVim/blob/master/INSTALL_Xcode8.md
証明書を作る手順は上の通り。
ここでは上の手順の通りに XcodeSigner という名前で作ったので、それを登録します。違う名前で作った人は XcodeSignerの部分を変えてください。
sudo codesign -f -s XcodeSigner /Applications/Xcode.app
xcodeを8.3にした時点で何度かインストールをしてみたのですが、make自体が通らなくなってしまいました。
issueに上がっていたみたいですでに対応してくれた人がいるらしいのでそちらのソースでコンパイルすることにします。
git clone https://github.com/keith/XVim.git git fetch origin xcode-8.3-release git checkout xcode-8.3-release make
これでmakeが通るようになりました。
手動でやってもいいんですが、一括でやってくれる上のツールをインストールします。
gem install update_xcode_plugins update_xcode_plugins
自分の場合、これでうまく行かなかったので以下をしたところ、無事xvimが有効になりました。
update_xcode_plugins --unsign
apkファイル作ろうとした際に以下のエラー発生。
Execution failed for task ':android:compileReleaseJavaWithJavac'.compileSdkVersion 'android-24' requires JDK 1.8 or later to compile.
この直前に targetSdkVersion
を24にあげてました。
エラーメッセージにある通り、API24 から?(おそらく。23では大丈夫だったため) JDK1.8 が必要になったらしいです。
インストールしてあるjdkのバージョンを確認。
java -version
または
javac -version
知らなかったけど、コンパイラのバージョンを見るときは, java
じゃなくて javac
でみたほうがいいらしい。
確認した結果versionは1.8でした。なのにこのエラーが出る。
javaが複数いるっぽい気がしたので、/Library/Java/JavaVirtualMachines
のディレクトリを見てみると、jdk7と8がいる。#Mac OSX Yosemite でやってました。
なんとなくjdk7のほうが使われているようなので、jdk7をアンインストールしてみます。
oracleの↑のページの通りにやればいい。ディレクトリごと消すだけ。権限がないときは、sudo
は必要でした。
rm -rf jdk1.7.0_06.jdk
これはjdk7の手順みたいです。jdk6以前は違うみたいなので注意。
これでとりあえずいくようになりました。
直接android studio 使っている人とかは、android studio の設定で使うjdk決めれたりするみたいだし、 jdkのバージョン複数持ってないといけない人もいると思うので、古いバージョンは削除してもOK! な環境な人しかダメなんで、とりあえずってかんじです…
ふと、scaleする起点?中心?の位置が画像の左下とか真ん中とかしかやったことなくって、
= Actor#setOrigin (int alignment)
画像内の好きな位置にしたかったんだけど、わかんなかったからしょぼいけどメモ。
public class MyGdxGame extends ApplicationAdapter { SpriteBatch batch; Image img; Stage stage; @Override public void create () { stage = new Stage( ); batch = new SpriteBatch(); img = new Image(new Texture("badlogic.jpg")); stage.addActor(img); //img.setOrigin( Align.center ); //真ん中 //img.setOrigin( img.getWidth()/2, img.getHeight()/2 ); //これも真ん中 img.setOrigin( img.getWidth() / 2, 0 ); // img.addAction( Actions.scaleTo(0.0f, 0.0f, 2f) ); } @Override public void render () { Gdx.gl.glClearColor( 1, 0, 0, 1 ); Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT ); batch.begin(); stage.draw(); batch.end(); stage.act( Gdx.graphics.getDeltaTime() ); } @Override public void dispose () { batch.dispose(); }
HelloCocos/proj.android-studio/Android.mk
android-studioでビルドしているのでこのディレクトリは以下のAndroid.mkを編集する
LOCAL_SRC_FILESにcpp名を追加する
LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../../Classes/AppDelegate.cpp \ ../../../Classes/HelloWorldScene.cpp \ ../../../Classes/LogoScene.cpp \ ../../../Classes/MainMenuScene.cpp \ ../../../Classes/HighScoreScene.cpp
cocos2d-x-3.10//tools/cocos2d-console/bin/cocos run -s ~/snk_cocos/snk -p android --android-studio
事前にinitとかで以下のcocos2d::Node#scheduleUpdateを呼んでおく必要がある
this->scheduleUpdate();
updateメソッドがマイフレ使える
void update(float dt);
・メンバがポインタの場合は、宣言でいい。定義はいらない=ヘッダをincludeしてクラスの定義を読み込む必要がない。
・引数、戻り値も宣言でいい。
・メンバが実態の場合は、定義を持つ必要がある。
・意識せずにヘッダを2回includeしててclassが二重定義になってエラった → インクルードガードすればOK。
⇒基本的に全部のヘッダはインクルードガードする!
#ifndef
マクロは、xxが定義されてなければ #endif
までで囲った処理を実行する、という意味なので、
これで、クラスの定義が1度しか呼ばれないことになる。
#ifndef _PART_H_ #define _PART_H_ //1回目のみ呼ばれる namespace cocos2d { class Vec2; //cocos2d::Vec2というクラスがあるよ、という宣言。Vec2はポインタで持っているので定義はいらない } class Part : public cocos2d::Node { public: Part(cocos2d::Vec2* pos); ~Part(); Part* getPos(); void setPos(Part* pos); private: cocos2d::Vec2* _pos; }; #endif // _PART_H_
cppでランダムな数値を取得するにはrand()
が使える
rand() % 3;
上記の例は、0〜2までの値を取得できる。ランダムな数値を3で割った割った余は、0〜2の数字だからだ。
cocos2dxにもlibgdxと同じでActionの概念がある。
・NodeにrunAction
メソッドを持っているのでそれに登録してあげればいい。
//3秒で180度回転。単位は「度」でOK runAction(RotateBy::create(3, 180));
・上記のままだと等速で処理を行うのでだんだんはやくしたりとかしたい場合はイージングを設定する
runAction(EaseIn::create(RotateBy::create(3, 180), 2));
・単純にxxの処理をしたい、という場合はCallFuncN
を使う
auto print = CallFuncN::create([this](Node* node){ printf("aaaaaa"); });
・シーケンス 順次実行 Sequence
auto rotate = EaseIn::create(RotateBy::create(3, 180), 2); auto scale = EaseIn::create(ScaleBy::create(1, 0.5f), 3); auto action = Sequence::create(rotate, scale, NULL); //最後は必ずNULLを設定しないとダメ runAction(action);