Gauche:Gauche-glサンプル
Gauche-glサンプル
Gauche-gl のサンプルプログラム 19 個です。
Gauche-gl は、Gauche から OpenGL を使用するための拡張ライブラリです。
本ページのサンプルプログラムのソース一式は 以下に置いてあります。
https://github.com/Hamayama/Gauche-gl-examples
内トロコイド曲線
trochoid.scm
- Gauche-gl を使って、内トロコイド曲線を描くサンプルです。
スペースキーを押すと、パラメータを乱数で生成して次を表示します。
ESCキーを押すと終了します。
- このプログラムは、一定の角度ごとに座標を計算していくのですが、
「角度が何周したら(始点に戻るので)計算を終わりにしてよいか」
を求めるのに苦労した記憶があります。
(最大公約数が出てくるとは。。。)
hamayama(2015/06/19 14:46:02 UTC)(2015/07/20 17:52:39 UTC)
星の表示
planet.scm
- Gauche-gl を使って、星を表示するサンプルです。
ESCキーを押すと終了します。
- 各星の大きさと速度は、すべて同じ設定になっています。
3D→2Dの透視射影変換により、遠近感を生じています。
hamayama(2015/07/15 10:33:29 UTC)(2015/07/20 17:52:39 UTC)
格闘ゲーム
fighter.scm
- Gauche-gl を使用した、簡単な格闘ゲームです。
左側が自分になります。
矢印キーで左右移動。[z]キーでパンチ。[x]キーでキックです。
防御はありません。相打ちはノーダメージです。
パンチ後は下降中が無防備になります。
キック後は一定時間無防備になります。
Ready?の画面でしばらく待つとデモになります。
ESCキーを押すと終了します。
- 敵のアルゴリズムは、基本的に相手が攻撃したら自分も攻撃するというものです。
このため、大体は相打ちになります。
間合いを調整して、連続的に攻撃すると、勝ちやすいパターンがあります。
(攻撃を出している間に、もう次の攻撃のキーを押しっぱなしにしておく感じ)
- 本ゲームは、元々2Dだったものを、Gauche-gl を使って疑似3D風にしたものです。
簡単なキャラクターですが、モデルの作成には苦労しました。
あとは、影を付けたり、視点を変更したりしたかったのですが、それはまた次の機会にしようと思います。
hamayama(2015/07/20 17:52:39 UTC)
バッティングゲーム
batting.scm
- Gauche-gl を使用した、バッティングゲームです。
矢印キーでカーソルを左右に移動し、
スペースキーでボールを打ちます。
引き付けるほど飛びます(最大199m)。ただし見逃しは0mです。
ESCキーを押すと終了します。
- このゲームは見逃しの判定がかなりシビアです。
しかし、見逃しの直前が一番飛ぶようになっています。
hamayama(2015/07/27 08:44:11 UTC)
シューティングゲーム
shooting0101.scm
- Gauche-gl を使用した、簡単なシューティングゲームです。
矢印キーで上下左右移動。
[Ctrl]/[Space]/[a]/[z]キーのいずれかでビーム発射です(押し続けると発射し続けます)。
敵は若干固いので、しばらくビームを当て続ける必要があります。
また、敵を破壊すると一定範囲が誘爆します。
画面右上のレベル表示は、出現する敵の数と速度の目安になります。
ESCキーを押すと終了します。
- このゲームでは、自機や敵のキャラクターはすべて文字表示です。
ストロークフォントの1文字ごとに、サイズを微調整して、等幅フォントのように表示しています。
(GLUT_STROKE_MONO_ROMAN はすきまが広すぎて使えなかった。。。)
モデルを作らなくてよいので楽だと思ったのですが、座標の計算には苦労しました。
現状、文字列の表示については、左上が (0,0) で 右下が (*width*,*height*) のウィンドウ上の座標を使い、
物体(自機や敵等)の位置については、左上が (-*wd/2*,+*ht/2*) で 右下が (+*wd/2*,-*ht/2*) のOpenGLの座標を使っています。
Y軸が逆向きであるため混乱しましたが、変換関数(win-x 等)を作って対応しました。
- また、キーボードによっては、キーの同時押しの制限が存在し、
斜め移動とスペースキーの同時押しが効かない問題がありました。
キー割り当てがたくさんあるのはその回避のためです。
(2016/02/13 04:41:56 UTC)
- その後、デモ機能を追加してみました。スタート画面でしばらく待つとデモになります。
デモ中は、アルゴリズムによって自機を動かして、左右によけるようにしています。
アルゴリズムは、一番近い敵との距離がP1以下の場合には、逆方向によけるというのと、
そうでない場合には、確率P2で画面中央に戻っていくというものです。
P1 と P2 は乱数で少しずつ変化させて、生存時間の平均値をのばそうとしています。
しかし、さっぱり収束しないので、この方法ではだめのようです。。。
(2016/04/10 13:51:39 UTC)
- その後、敵と敵ミサイルの表示をグラフィックスに変更しました。多少見やすくなりました。
(2016/12/06 14:05:29 UTC)
hamayama(2016/02/08 08:31:57 UTC)(2016/02/13 04:41:56 UTC)
(2016/04/10 13:51:39 UTC)(2016/12/06 14:05:29 UTC)
ドライブゲーム
drive.scm
- Gauche-gl を使用した、簡単なドライブゲームです。
矢印キーで左右移動。
スペースキーでブレーキをかけます。
アクセルは自動です。スピードが上がると曲がりにくくなります。
ゴールするかコースアウトするとゲーム終了です。
(道路の端が画面の中心に来ると、コースアウトと判定されます)
ESCキーを押すと終了します。
- このゲームでは、道路の境界マークは、Z座標を変更せずに、色だけを変化させています。
このため、進んでいるように見えるのは、目の錯覚によるものです。
- カーブの表現は、曲がり量を c とすると、x=c*z*z のように計算して、画面の奥にいくほど
2乗に比例して 道路のX座標が変わるようにしています。
(実際のカーブは、もっと複雑だと思いますが。。。)
- コースは、コース番号 *courceno* をシード値とする疑似乱数で生成しています。
このため、*courceno* の値を変更すると、違ったコースで遊ぶことができます。
- 現状、タイムは単純にスピードだけで決まります。
(カーブの内側を通った方がゴールが近くなる等の補正はありません。。。)
hamayama(2016/07/16 13:34:08 UTC)
ジャンプアクション
jump.scm
- Gauche-gl を使用した、簡単なジャンプアクションゲームです。
矢印キーで左右移動。
スペースキーでジャンプします(長押しすると高く飛びます)。
雲には乗ることができます。
一定時間で出たり消えたりするゴールに触れるとステージクリアです。
飛んでいる敵に触れるとゲームオーバーです。
(ただし、敵の頭には乗ることができ、乗ると色が変わって無力化します)
ESCキーを押すと終了します。
- 今回は、画像ファイルを読み込んでキャラクターを表示するようにしました。
ドット絵の画像を作成して、普通の2Dゲームっぽくしています。
今のところ、24bitカラーで無圧縮のビットマップファイルのみ使用可能になっています。
- 作成中に苦労した点は、自機が物体の上に乗る処理のところです。
基本的には、当たり判定を行って、当たった物体の上に座標を移動させるのですが、
自然にみえるように試行錯誤で条件を追加しました。
また、複数の物体と自機が重なった場合には、より高い位置にある方の物体に乗るようにしました。
hamayama(2016/09/19 03:55:36 UTC)
シューティングゲーム2
shooting0201.scm
- Gauche-gl を使用した、簡単なシューティングゲームです。
矢印キーで上下左右移動。
[Ctrl]/[Space]/[a]/[z]キーのいずれかでビーム発射です(押し続けると発射し続けます)。
敵を破壊するには、コアの部分にビームを当てる必要があります。
また、敵を破壊すると一定範囲が誘爆します。
画面右上のレベル表示は、出現する敵の数と速度の目安になります。
また、スタート画面でしばらく待つとデモになります。
ESCキーを押すと終了します。
- 今回は、横視点のシューティングゲームにしてみました。
表示文字数が多いため、PCによっては重くなるようです。
敵を1枚絵にすれば軽くなると思いますが、文字単位で削れていく感じを表現したかったので、
今回はこのようにしています。
- その後、表示を簡略化して若干動作を軽くしました。
(2016/11/30 18:41:33 UTC)
hamayama(2016/11/18 08:54:55 UTC)(2016/11/30 18:41:33 UTC)
フライトゲーム
flight.scm
- Gauche-gl を使用した、簡単なフライトゲームです。
画面左下の小さい黄色が自機です。(画面の左上には自機の姿勢が表示されています)
スペースキーを押し続けると加速します。(上昇中はほとんど加速できません)
矢印キーの上下で方向を変えます。
(矢印キーの上で反時計回り、下で時計回りに角度を変えます)
画面の左右はつながっています。
画面右上のチェックポイント(オレンジ色の円)に触れてから、地面に着陸するとゴールです。
着陸の際は、地面への進入角が30度以下である必要があります。
(進入角が30度より大きいとバウンドしてしまいます)
[r]キーを押すとゲームをリセットします。
ESCキーを押すと終了します。
- 今回は、空を飛ぶ様子を表現しようと作成しました。座標の計算は2Dです。
ゲームにするためにゴールを設定していますが、気にせず自由に飛ぶのがよいです。
速度が上がれば宙返り等も可能です。
- 重力の計算式が間違っており、真上を向くとドローンのようにホバリングしてしまいます。
しかしこれはこれで面白いと思い、そのままにしてあります。
hamayama(2017/02/13 09:52:35 UTC)(2017/04/15 14:51:51 UTC)
迷路生成
maze.scm
- Gauche-gl を使用した、迷路を自動生成して表示するサンプルです。
スタート(水色)からゴール(赤色)までのルートも探索して表示します。
生成される迷路の上下左右はつながっています。
スペースキーを押すと、次の迷路を表示します。
ESCキーを押すと終了します。
参考「古くて新しい自動迷路生成アルゴリズム」
http://d.hatena.ne.jp/yaneurao/20130125
- 今回は、迷路の生成と探索を行ってみました。
もともと、上下左右にスクロールするゲームで使おうと思っていたため、
外壁がなく、上下左右がつながった迷路になっています。
- 迷路生成のアルゴリズムは、上記URLで説明されているドルアーガ版になっています。
棒倒し法と穴掘り法をまぜたような感じで、おもしろい迷路ができるようです。
- また、スタート(水色)からゴール(赤色)までのルートの探索には、幅優先探索を使用しています。
hamayama(2017/03/19 09:20:04 UTC)
時計
clock.scm
- Gauche-gl を使用した、アナログ時計を表示するサンプルです。
ESCキーを押すと終了します。
- アナログ時計についてですが、長針は秒の情報も内包しており、
短針は分と秒の情報も内包しています (目盛と目盛の間を針が指す場合)。
このため、複数の情報が重複して表示されていることになります。
また、短針の視点に立つと、1目盛は12分という微妙な単位であり、
長針の視点に立つと、数字の3を指していても15分であるという、
結構微妙な仕様があるように思いました。
(分かってしまえば、もちろん便利ですが。。。)
hamayama(2017/05/03 16:59:06 UTC)(2017/05/04 13:02:09 UTC)
探索ゲーム
walker.scm
- Gauche-gl を使用した、簡単な探索ゲームです。
矢印キーで上下左右移動。
迷路の出口に到達すればクリアです。
迷路のサイズは、5 x 5 = 25 部屋分となっています。
また、迷路の上下左右はつながっており、外周は存在しません。
スペースキーを押すと、壁にマーク(アルファベット)を付加できます。
マークは最大5つまでで、それをこえると古いものから消えていきます。
また、スタート画面でしばらく待つとデモになります。
[r]キーを押すとゲームをリセットします。
ESCキーを押すと終了します。
- 今回は、移動の表現にこだわってみました。
上下方向の移動には、階段を使うようにしています。
苦労した点は、座標の計算と、ドット絵の作成です(何かまだ動きが不自然ですが。。。)。
- 迷路のサイズが 5 x 5 と小さいので、しばらくさまよっていれば、大体出られます。
大きなサイズに設定すると、本当に迷ってしまい、難しすぎました。
部屋ごとに模様を変えたり、何か探索のヒントになるような表示があると、よかったかもしれません。
- その後、デモを追加しました。スタート画面でしばらく待つと、自動的にゴールまで歩いていきます。
(2017/08/17 12:41:13 UTC)
hamayama(2017/08/09 02:52:34 UTC)(2017/08/09 18:22:53 UTC)
(2017/08/17 12:41:13 UTC)
ワームシミュレータ
worm0101.scm, worm0201.scm
- Gauche-gl を使用した、ワームシミュレータです。
矢印キーかマウスボタン1でカーソルを移動します。
空腹状態のワームはカーソルを追跡します。
ESCキーを押すと終了します。
worm0101.scm は末尾から移動するタイプで、
worm0201.scm は先端から移動するタイプです。
- 今回は、多関節キャラクターの表現に挑戦してみました。
worm0101.scm の方は、角度については先端から順番に求めていき、
座標については末尾から順番に計算していくという、2フェーズの処理になっています。
worm0201.scm の方は、先端だけを移動させて、
残りの座標はキューで移動を遅らせることで、先端に追従するようにしています。
実行してみると、worm0101.scm の方が複雑な動き方をします。
- ワームは、カーソルに到達して食事が終わると、しばらくランダムに移動します。
また、3分間食事ができなかった場合にも、ランダムに移動します(永久パターン防止のため)。
hamayama(2018/05/02 13:59:13 UTC)(2018/05/03 16:19:49 UTC)
(2018/05/12 05:47:24 UTC)(2018/05/13 18:45:36 UTC)
シューティングゲーム3
shooting0301.scm
- Gauche-gl を使用した、簡単なシューティングゲームです。
矢印キーで上下左右移動。
[Ctrl]/[Space]/[a]/[z]キーのいずれかでビーム発射です(押し続けると発射し続けます)。
敵(ワーム)は、頭の部分にのみダメージを与えられます。
(かなり固いため、しばらくビームを当て続ける必要があります)
画面右上のレベル表示は、出現する敵の数の目安になります。
また、スタート画面でしばらく待つとデモになります。
ESCキーを押すと終了します。
- 今回は、ワームシミュレータのクラスをモジュール化して、
シューティングゲームの敵キャラクターにしてみました。
- ワームは、先端移動と末尾移動のアルゴリズムを交互に切り換えていき、
6回切り換えたら画面下に消えていくようにしています。
先端移動は、移動が速いですが動きは単調なので、予測して避けるとよいです。
末尾移動は、移動は遅いですが回転が速いので、末尾を中心とした行動半径内に入らないようにするとよいです。
(それでも、理不尽にやられるかもしれませんが。。。)
- 苦労した点は、ワームの動作アルゴリズムを途中で切り換えているところです。
先端移動(worm0201)と末尾移動(worm0101)は、内部のデータ構造が異なるので、
簡単に状態を引き継ぐことができませんでした。
このため、worm-convert というコンバート用のメソッドを作成して対応しました。
- その後、フラット表示(2D表示)にする設定を追加してみました。
gosh shooting0301.scm 1 0 1 のように第3引数に1を指定すると、フラット表示になります。
自分のPCでは、CPU使用率が10%程度下がるようでした(20%→10%)。
(データを一括転送するタイプの命令を使えば、3D表示のままでも負荷を減らせそうですが。。。)
hamayama(2018/05/27 07:49:58 UTC)(2018/06/01 14:59:30 UTC)
(2018/06/02 04:15:36 UTC)
振り子シミュレータ
pendulum.scm
- Gauche-gl を使用した、振り子シミュレータです。
ラグランジュの運動方程式とルンゲクッタ法により近似解を求めています。
ESCキーを押すと終了します。
- 今回は、N重振り子のシミュレータを作成してみました。
1~3重振り子の運動方程式を手作業で計算して、パターンが見えてきたため、
推測でN重の式を組み立てました。
それらしく動いていると思います。
- 苦労した点は、計算のデバッグです。少しでも符号や変数を間違えると、
結果が発散して表示が出ませんでした。
何度もチェックしてやっと動作するようになりました。
- 逆行列の計算には gauche.array を使用しています。
hamayama(2018/08/08 18:38:16 UTC)
物体(球)の衝突
collision.scm
- Gauche-gl を使用した、物体(球)の衝突をシミュレートするプログラムです。
(一部計算が正しくないところがあります)
ESCキーを押すと終了します。
- 今回は、運動量を保存する衝突の計算を行ってみました。
大きい (重い) 物体は、衝突後の速度があまり変わらないところが、
リアルっぽくてよいと思います。
- 現状、3個以上の物体が重なった場合には、正しい結果になりません。
(2個ずつ衝突を処理しているため)
- また、物体がめり込んだ場合に、衝突を連続的に検出して振動する
(1フレームごとに速度が反転する) 現象を簡単に回避するため、
衝突後の速度は、常に離れる方向になるように符号を操作しています。
- このため、実際には、衝突後に 2 個の物体が同じ方向に進むようなケース
(重い物体が高速で、軽い物体に衝突した場合 等) でも、
逆方向に進んでしまうという問題点があります。
(その後、1フレーム前の衝突数が0のときは、本処理を行わないようにしました)
hamayama(2020/05/04 08:35:37 UTC)
影のある星
shadow.scm
- Gauche-gl を使用した、影のある星を表示するプログラムです。
スペースキーを押すと、2D表示と3D表示を切り換えます。
ESCキーを押すと終了します。
- 今回は、月の満ち欠けのような表現を目指してみました。
- 2D表示では、X軸上の影の端点と星の上下の3点を通る円を計算して、影の境界としています。
そして、円は一部分のみを表示するため、クリッピング処理を行っています。
- 一方、3D表示の方は、球を表示して光源を移動したのみです。
hamayama(2021/06/21 23:58:30 UTC)
シューティングゲーム4
shooting0401.scm
- シューティングゲーム3 ( shooting0301.scm ) の視点を変更して、
疑似3D風にしたものです。
ゲームの内容は、シューティングゲーム3 と同じです。
- 2Dのエリアが画面におさまるように、カメラの位置と方向を計算するのには、苦労しました。
(reshape 手続きのあたり。アイデアとしては、視点を円上で動かすことで、
円周角の定理により画角 vangle が一定になるようにしています)
(ただ、glu-perspective の zNear と zFar の値は、まだ少し変になっている← v1.04で修正済み)
- このゲームは、敵が自分の座標を見ていなくて、
気まぐれに動いているところが気に入っています。
- あと、スタート画面でしばらく待つとデモになるのですが、
このデモの自機が AI っぽくてけっこううまいのも、気に入っています。
(実際には、近い敵はよけて、遠い敵は撃ちにいっているだけですが…)
hamayama(2022/04/23 02:29:39 UTC)
- Shiro(2022/04/23 07:44:32 UTC): そこはかとなくレトロな雰囲気がいい感じ。結構ムズいですね…
直方体オブジェ
rectangular.scm
- Gauche-gl を使用した、直方体オブジェを表示するプログラムです。
矢印キーと[z]/[x]/[Ctrl]キーで少し操作できます。
ESCキーを押すと終了します。
- これは、元々は、直方体を避けるゲームにしようと思っていたのですが、
自分に向かってくる直方体が思ったより心理的にきつかったため、
中央付近には来ないように条件を追加してデモアプリにしたものです。
hamayama(2024/07/21 12:53:38 UTC)
本ページのサンプルプログラムのソース一式は 以下に置いてあります。
https://github.com/Hamayama/Gauche-gl-examples