Luaを使ってみる

序文

ArchLinuxを使ってLuaでWelloWorldをやってみる。

なんでLua

  • 「いっぺん型の無い言語触ってみろ」って言われた
  • ゲームプログラミングに使われてるみたいなので軽くゲーム作ってみる(最近はどうか知らん)
  • ggezの説明欄に"It aims to implement an API based on (a Rustified version of) the LÖVE game framework."とか書いてた。(Luaでゲームを作成するフレームワーク
  • 名前が好き ((ここが重要

Luaとは?

  • スクリプト言語
  • 実行速度が早い
  • 組み込み(他の言語にちょっとくっつけるな感じ)に良く使われる

環境構築

Luaを入れる

$ sudo pacman -S luaを打つ。

f:id:celluloce:20181126151244p:plain

入ってた。

LuaRockを入れる

Luaのパッケージマネージャー。
$ pacman -S luarocks を打つ。

f:id:celluloce:20181126151539p:plain

これは入ってなかった。

書く

print("Ideal World !!")

これだけでいい。

実行

[celluloce: Lua]$ lua hello.lua 
Ideal World !!

以上

まとめ

LuaでHelloWorldやった。

追記

今回パッケージマネージャいらなかった。

スヌース始めた

序文

煙が出る煙草は喫するための環境が限られているため無煙煙草を始めた。
得た知見を書き示す。

スヌースとは

嗅ぎ煙草の一種で、口腔内(歯茎と上唇に挟む)で煙草葉から直接ニコチンを摂取する。
同じ嗅ぎ煙草でスナッフというのがあるが、これは鼻腔内で煙草葉から直接摂取する。
私は鼻炎になりやすいので後者はあんま使いたくない。
双方とも燃焼させず、煙が出ない。

喫んでみて

AlCapone バニラ, ミントとゼロスタイル バニラを喫んだ。
ちなみに全体的にシガレット 口腔喫煙と比較して効きが強い。

AlCapone バニラ味

初めてがこれ。
挟んだところが痛いが、効きは結構強い。
若干のバニラと人工甘味料な味。 ニコチンの作用か頭が軽くなり普段の作業効率が上がったので1日2回くらい使ってた。
(短時間の間に連続で使用すると吐き気を催す等をした 用量を見極めて使用しましょう)

ゼロスタイル バニラ味

最近買った。
バニラと書いているがクッキーのような匂い。
超甘い上に塩味がある。
で超不味い。
効きも弱め。

AlCapone ミント味

ゼロスタイルバニラが超不味かったので書い直した。
ミントもあって挟んだところが結構痛い。
ミント味のガムを思い出す。
が、やはりAlCaponeは良い。

まとめ

燃焼煙草(造語)より結構良い。
ただ強いのであんま人に勧められない。

Linuxで作ったゲームをWindows10で動かそうとした話

序文

1年くらい前からArchLinux環境でRustで弾幕シューティングを制作していた。(以下リンク)

https://github.com/celluloce/poi-project/

初期はPistonゲームエンジンで作ろうとしたが、超絶使いにくかったのでggezゲームエンジンに切り替えた。
精神療養のつもりで時々触る程度であったが、大学の文化祭で展示しようと最近になってえっちらおっちら進めた。
で、その過程で特にWindows10で動かそうとして苦労したことを書き示す。
(文化祭の展示には.exeファイルとして提出しなければならない)

ggezとは

SDL2依存の、Rustで書かれたゲームエンジン
2Dゲームを簡単に作れるのが特徴。
ソースコードを読む限り、SDL2に肉付けしたくらいの低級なゲームエンジン

Windows10でSDL2環境

上記の通り制作ゲームはSDL2に依存している。
でこのSDL2環境をWindows10で整えるのが超めんどくさかった。

ちなみにArchLinuxだと$sudo pacman -S sdl2打つだけで環境構築が終了する。

Rust-SDL2のドキュメントを参照してみる

GitHub - Rust-SDL2/rust-sdl2: SDL2 bindings for RustWindowsでの環境構築が書かれてたので試してみた。
がしかし部室のPCでRust環境を構築したのに、C:\Program Files\Rust\が存在しなかった。
Rustコンパイラ先生どうやって動いてるんだよ...

ちなみにこの時ブチ切れて「自分のゲームを遊びたいならUbuntuインストールして遊べ!」と暴言を吐いた。

MSYS2を使う

Linuxユーザの強い味方、MSYS2を使ってみた。
参照:http://takaya030.hatenablog.com/entry/2018/01/17/183235

サンプルコードが動かない等が起きたが、C++わからないので無視した。
で制作ゲームをコンパイルしたら通らない。
なんでだよ...

結局

某C++erに手伝って貰った。
RUSTFLAGS="-L/mingw64/lib" cargo build --releaseで何とかBuildできた。
他のアプローチとしては、build.rsを書いたりすることで解決するようだ。

ロスコンパイルすればいいのでは?

英文読む気力がなくしかもパッケージ依存が酷かったので諦めた。

ゲームを遊ぶのにSDL2環境構築は必要か?

Buildして.exeファイルにしてしまえば、あとは同じディレクトリにSDL2.dllを置くだけで実行できる。
置くだけでおk。
配布時も同封すればおk。

Windowサイズが巨大化

準備日直前にとりあえず展示できる形に仕上がったが、ディスク書き込み直前に後輩のWindows10環境で実行させてみたら、画面に収まらないほど巨大なゲーム画面が表示された。
1280*960サイズのゲームで、後輩PCは1920*1080だから余裕で収まるはずなのに。
というかフォントサイズもなんかおかしい。

画像上:理想
画像下:再現 f:id:celluloce:20181124000302p:plain

f:id:celluloce:20181124000004p:plain

とにかくフォントサイズは1.6倍すると丁度良い大きさになることがわかった。
で問題はWindowサイズが巨大化する現象で、これはWindowサイズを960*720に縮小するしか無かった。
でWindowサイズを1280*960固定で制作していたため、全てのキャラクタ描写や速度や位置を縮小版に合わせて書き換えなければならなかった。

まあX軸とY軸の値をそれぞれ(window x size) / 1280, (window y size) / 720倍にすりゃいいからそんなめんどくさい作業では無かった。
実際超めんどくさかった。
(具体的には初期値と値の更新の式いずれかに演算させるのだが、間違って双方に演算させてしまったりなど難航した)

この作業で文化祭前日の準備に全く参加できなかった。
後の楽しみは打ち上げのみになった。
ちなみに配布ディスクに修正版が焼かれることは無かった。

おまけ:オーディオ環境

Windows関係ない。

ggezを使って書かれたコードをオーディオ環境の無い(内蔵スピーカが壊れてたり等)状態で実行すると、ggezがAudioErrorを吐いて実行時エラーを起こす。

これはライブラリ外で設定できず(多分)、イヤホンジャックにイヤホンを刺す等をすると解決する。
なお制作ゲームにBGM等は無い。

まとめ

  • SDL2はマルチプラットフォーム対応(開発はLinux使おう)
  • ggezをWindowsで実行するなら小さめのWindowサイズで、フォントサイズは1.6倍
  • Windowサイズ変更に強いコードを書こう
  • ggezはAudio環境が必要
  • F*ckingWindows

Rustの b"..." がよくわからなかった調べた

序文

Rustのb"..."がよくわからなかったからコード書いて挙動を調べた。

実験

以下コードを走らせる。

参照:

fn main() {
let s: &str = "myon";
let b: &[u8] = b"myon";
let v: Vec<u8> = "myon".bytes().collect();
let i: &[u8] = "myon".as_bytes();

println!("{}", s);
println!("{:?}", b);
println!("{:?}", v);
assert_eq!(b, i);
}

結果:

myon
[109, 121, 111, 110]
[109, 121, 111, 110]

b"..."って何なんだ?

公式Doc.より引用:

Byte string literal; constructs a [u8] instead of a string

バイト文字列(byte string)を生成するんだな。

要はUTF-8にデコード(Rustの文字列はUTF-8のみ)する前の文字列を、スライス&[...]として生成するものなのだろう。

(実際よくわからない)

まとめ

assert_eq!(b"myon", "myon".as_bytes());

「なぜusing namespace std;を避けるべきか」を読んだ感想

「なぜusing namespace std;を避けるべきか」を読んだ感想

序文

なぜusing namespace std;を避けるべきか を読んだのでRust交えて感想書く。

using namespace std;とは?

ちゃんと調べてないが見た感じ機能としてはRustのuseと殆ど同じようである。
ただこの場合、Rustな表現だと(絶対誰かに怒られる怒らないで)use std::* な感じだろうか。

名前衝突

正直C++よくわかんない(本当にわからない(本当にわk...))のでよくわからないが、 using namespace std;やるだけで名前衝突が起こりやすくなるようだ。
普段私はRust書いてるので意識したことはないので、手始めに名前衝突させてみようと考えた。

実験:Rustで名前衝突させてみよう

手元のVimで以下コードを書いてみた。

// Rust
use std::string::String::*;
use std::vec::Vec::*;

fn main() {
    let s = new();
}   

new()関数は値の初期化によく使われるので真っ先に思いついた。
で走らせたらコンパイルが通らない。

error[E0432]: unresolved import `std::string::String`
 --> poi.rs:1:18
  |
1 | use std::string::String::*;
  |                  ^^^^^^ Not a module `String`

error[E0432]: unresolved import `std::vec::Vec`
 --> poi.rs:2:15
  |
2 | use std::vec::Vec::*;
  |               ^^^ Not a module `Vec`

error[E0425]: cannot find function `new` in this scope
 --> poi.rs:5:10
  |
5 |     let s = new();
  |             ^^^ not found in this scope
  

要はStringVecはモジュールじゃないからだめだって。

可読性

複数のライブラリを使うときに、どの関数がどの名前空間にあるかわからないと、正しい関数を呼び出せているかわかりにくくなります。 using namespaceによって名前空間が省略されていると、それができないんですね。

C++わからない(本t...)けどこれならわかる。
Rustであれば、上述のエラーを読んだ感じなんとなくモジュールを用いる事によってによって衝突を避けられてるというのがわかる。

名前空間が深い場合においてのuse namespaceを 可読性を持ちながら有効な記述例@yumetodo先輩が書き記していた。
それが以下コード。引用

#include <chrono>
#include <iostream>
void foo(){}
int main()
{
    namespace ch = std::chrono;
    using clock = ch::high_resolution_clock;
    const auto t1 = clock::now();
    foo();
    const auto t2 = clock::now();
    std::cout << ch::duration_cast<ch::miliseconds>(t2 - t1).cout() << std::endl;
}

うーん...ちょっとめんどくさい。

まとめ

モジュール使うと上記の問題が全部解決するって。
だから皆Rust使おう。

ローリングマシーンなるものを購入した

本文

普段私はいわゆる手巻き煙草(チェ ブルー)を愛飲している。
最近縦横15cmくらいの手巻き寿司を巻くあれ(巻きすと言うのか?)のようなものを使っていた。
200円くらいでかなり安価であったが、大きさも定まらないしきれいに巻けない。

で今日、ラノベを読みながら電車に乗っていたら間違えて新宿で降りてしまった。
降りたついでにkagayaという煙草屋に足を運んだ。
以前から気になっていたローリングマシーンなるものが目に入り、2000円となかなかな値段がするが、意を決して購入した。メーカーはMASCOTTEで、EXTRA SLIMが巻けるタイプのものだ。
ついでにシガリロ(PALOMA)も購入した。

早速喫煙所で開封して使ってみた。
使った人ならわかるが、中の布が固いのか上手く葉を溝に入れられない。
指で抑えながら葉を詰めることになる。
で紙を置いて、蓋を閉めてみる。

するとどうだろう、きれいな超極細で固〜い手巻き煙草が出てきた。
咥えてみると殆ど空気が通らない...
みっちみちである。

この時初めてSLIM + EXTRA SLIMの意味が理解できた。
このローリングマシーンは巻く太さを8mmのREGULARサイズに咥え、7mm, 5.3mmのSLIM, EXTRA SLIMと設定できるのだ。
そして初期状態が5.3mmの超極細EXTRA SLIMであった。

自作のシガレットホルダー(8mm)に収まらないので両切りの状態でそのまま吸った。
吸いながらインターネットで色々調べつつ、8mmに設定して再び巻いてみた。

するとどうだろう、きれいで丁度いい大きさの煙草が出てくるではないか。
葉を詰めて蓋を閉めるだけで巻けるのだからとてもいい。
コミケを前日に控えた出費であったがいい買い物であった。

まとめ

ローリングマシーンはとてもいい。

Rust ArchでPistonを動かそう

序文

Rustで書かれたゲームエンジンPistonを見つけた。

早速git cloneしてあれこれ書いて、cargo runで走らせる。
どっきどっきわっくわっくしながら待っている。

そして次の結果が出た。

f:id:mukichem24:20171227040130p:plain

は?

ということで、本記事ではManjaro Linux(Arch Linux)でPistonにご挨拶する方法を書き記す。
タイトル詐欺だと?ManjaroもArchも似たようなもんじゃ((暴言

解決法を探す

ということで吐かれたエラーをコピペしてググってみる。

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "Couldn\'t find any pixel format that matches the criterias."', /checkout/src/libcore/result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

やはり同じような悩みを抱える人間は存在するものである。
このページにたどり着く。

圧倒的英語文献と天才的な英語力を持つ私との激しい戦闘の末、以下の文章を見つけた。

Now that Ubuntu 17.10 artful has been released with Mesa version 17.2.2 this issue will affect more people. Including me!

The bug is indeed a regression of Mesa from the 17.1 branch to the 17.2 branch.

...よくわからないが((おい どうもmesaのヴァージョンが17.2だと動かないとか何とか。

ということでmesaのヴァージョンを下げてみよう!!
ちなみに2017年12月27日現在で最新版は17.3.0-2である。
え?問題は17.3ではなく17.2と?同じエラー吐かれたのだから同じだろ。

解決法 downgraderを使う

さっきのページを読み進めると解決法は示してあるが、Archにやさしい手段ではない。

mesapacmanのパッケージにあるのだから、「pacman 古いバージョン」でググったら何か出るのではないだろうか。

とググったらあった。パッケージのダウングレード

色々方法はあるが、私はdowngraderを使った。

AURのインストールがわからなかったら後述の追記を見てね。

インストールが済んだらターミナル上でdowngrader mesaと入力する。
すると以下の文が出る。

 Downgrade package: mesa  
1: mesa-9.2.5-1  (from ALA)
2: mesa-9.2.4-1  (from ALA)
3: mesa-9.2.3-2  (from ALA)
4: mesa-9.2.3-1  (from ALA)
5: mesa-9.2.2-1  (from ALA)
6: mesa-9.2.1-1  (from ALA)
7: mesa-9.2.0-2  (from ALA)
8: mesa-9.2.0-1  (from ALA)
9: mesa-17.3.1-2  (from ALA)
10: mesa-17.3.1-1  (from ALA)
11: mesa-17.3.0-2  (from ALA)
12: mesa-17.3.0-1  (from ALA)
13: mesa-17.2.6-1  (from ALA)
14: mesa-17.2.5-1  (from ALA)
15: mesa-17.2.4-1  (from ALA)
16: mesa-17.2.3-2  (from ALA)
17: mesa-17.2.3-1  (from ALA)
18: mesa-17.2.2-1  (from ALA)
19: mesa-17.2.1-3  (from ALA)
20: mesa-17.2.1-1  (from ALA)
21: mesa-17.2.0-3  (from ALA)
22: mesa-17.2.0-2  (from ALA)
23: mesa-17.1.8-2  (from ALA)
24: mesa-17.1.8-1  (from ALA)
25: mesa-17.1.7-2  (from ALA)
26: mesa-17.1.7-1  (from ALA)
27: mesa-17.1.6-1  (from ALA)
28: mesa-17.1.5-1  (from ALA)
29: mesa-17.1.4-1  (from ALA)
30: mesa-17.1.3-1  (from ALA)
>> Please enter package number, [q] to quit

ここで17.1にしたいのだから23を入力してみよう。
するとえっちらおっちらダウングレードしてくれる。

※最新版に依存しているパッケージがあると最悪動かなかったりする(多分)のでダウングレードする際は注意してね。まあ動かなくなるのはそのパッケージだけだからそんな気にしなくていい。

ここで再びPistonのディレクトリでcargo runを入力する。

f:id:mukichem24:20171227040204p:plain

やったぜ!!

古いバージョンを維持する

ここでpacman -Suyでパッケージを更新すると、mesaもアップグレードしてしまう。
苦労してダウングレードしたのに再びアップグレードされては困る。

特定のパッケージをアップグレードして欲しく無いときは、/etc/pacman.confファイルの#IgnorePkg =IgnorePkg = mesaと書き換えればいい。
#はちゃんと消してね。

なお編集する際は管理者権限でエディタを開く必要がある。例えば、nanoを使う場合はsudo nano /etc/pacman.conf, vimを使う場合はsudo vim /etc/pacman.confと入力すれば良い。

これでpacman -Suyでパッケージを更新しても、mesaのバージョンは更新されない。
やったぜ!!
参考文献(2017/12/27)

結論

  • Pistonを使うにはmesaのヴァージョンを17.1にする必要がある
  • pacmanのパッケージのヴァージョンを下げるには幾つか方法があるが、私はdowngraderを使った
  • pacman -Suyによるパッケージの更新でパッケージをアップグレードさせないためには、/etc/pacman.confIgnorePkg = *パッケージ名*を記述すれば良い

追記

疲れたから後で書く