GNU GRUB / Linux 復旧作業の続き
前回までにわかっているのは以下。
root (hd0,0) #=> Filesystem type is ext2fs, partition type 0x83 root (hd0,1) #=> Filesystem type is unknown, partition type 0x5 root (hd0,2) #=> Error 22: No such partition root (hd0,3) #=> Error 22: No such partition root (hd0,4) #=> Filesystem type is unknown, partition type 0x82 root (hd0,5) #=> Filesystem type is ext2fs, partition type 0x83
poqte 君や znz さんに TAB でファイル名が保管できることを教わったので試してみる。調べる対象はこの二つでいいだろう。
- (hd0,0)
- (hd0,5)
(hd0,5) は /home だった。データは無事に残っている模様。プラポケのDB情報も毎日ここにダンプしていたので最悪別マシンにHDDをつなげばデータは吸い出せそうだ。
(hd0,1)。ここは / のようだ。ただ /boot には /boot/grub しかない。どういうことだろう?
やっぱり (hd0,2) と (hd0,3) は壊れてしまったのだろか。
テニスゲームの実装(5)
やっぱり絵がないのでこれ以上はすすめない。 まあ描画についてはあるていで出来ている。MyGameは拡大縮小のAPIのちょっと手を入れただけであとは大丈夫だった。
--
出来上がった表示物の表示と描画だけを行うプログラムを見ると 3 つに分かれているようだ。
ひとつはグラフィック・キー入力イベント等ゲーム製作に必要な部分を高レベルに抽象化したMyGame。SDLそのものがある程度は高レベルなんだけど、実際にゲームを作る上ではまだまだ低レベルすぎる。絵の表示なんてこれでいいのだ。
image = Image.new('sample.bmp') image.x, image.y = 100, 100 image.draw
ふたつめはVector3DとかCameraとか。あとはキャラクター等をクラスしたりして扱いをオブジェクトの生成等をSDLっぽく書けるようにする部分。これらはヘルパー郡としてスクリプトを分けた。ここでは eval とか使いまくっちゃう。
最後がヘルパー郡で定義した機能を使って SDL っぽく書く部分。ゲームバランス(レベルデザイン)とかはすべてここ。具体的には以下のような感じ(メソッド名はまだいいかげんだけど)。
require 'mygame/boot' require 'tennis_helper' COURT_H = 1189 COURT_W = 1097 class Player < Character image_resource 'images/player.bmp' end class Ball < Character image_resource 'images/ball.bmp' def initialize super @position = Vector3D[400, -200, 1300] @v = Vector3D[-16, -6, -40] end def run @v.y += 0.5 @position += @v if position.y > -10 position.y = -10 e = 0.8 @v *= [e, -e, e] end end end camera = Camera.new players = Array.new(2) { Player.new } ball = Ball.new bg = Image.new('images/bg.bmp') loop_game(30) do [players, ball].flatten.each &:run bg.draw camera.draw(players, ball) end
--
2番目のフレームワーク化の考察が EasyRocket なんだけど、今回は MyGame の検証なのでその辺は考えない。
テニスゲームの実装(4)
カメラワークは 3D 処理なので結局昨日の Vector3D を持ち出したほうがシンプルに書けた。
コートの表示とボールを飛ばすところまで出来た。次はキャラクターの表示とアクションだけどここから先はさすがに絵がないと作れないな。
Vector3D に rotate_y を追加。
class Vector3D < Array def rotate_y(ry) Vector3D[ x, y * Math.cos(ry) - z * Math.sin(ry), y * Math.sin(ry) + z * Math.cos(ry) ] end end
擬似 3D 描画を行うカメラクラス。
class Camera attr_accessor :position, :angle, :screen_z def initialize @position = Vector3D[0, 60, -3600] @angle = Vector3D[0, Math::PI / 9, 0] @screen_z = 1500.0 end def draw(*args) args.to_a.flatten.each do |e| temp = e.position.rotate_y(angle.y) - position perse = screen_z / temp.z e.view.x = temp.x * perse + screen.w / 2 e.view.y = temp.y * perse + screen.h / 2 e.view.scalex = e.view.scaley = perse * 1.0 e.view.draw end end end
テニスゲームの実装(3)
カメラクラスによる座標変換とスクリーン投影。
キャラクターをコート(コートのサイズは1000×1000)の四隅に見立てて、画面を見ながらキメウチでカメラのパラメータを割り出してみた。
class Camera def draw(*args) screen_z = 600.0 y = 60 z = -1300 ry = Math::PI / 4 args.to_a.flatten.each do |e| tx = e.x ty = e.y * Math.cos(ry) - e.z * Math.sin(ry) tz = e.y * Math.sin(ry) + e.z * Math.cos(ry) ty -= y perse = screen_z / (tz - z) e.view.x = tx * perse + screen.w / 2 e.view.y = ty * perse + screen.h / 2 e.view.scalex = e.view.scaley = perse * 2 e.view.draw end end end
あ、テニスのコートは正方形じゃない気がする。
テニスゲームの実装(2)
3Dだーっと思って昔の日記から Vector3D の考察を探し出してクラスを書いてみたが、視点固定の擬似3DならX軸回転とスクリーン投影だけでことたりるので Vector3D を使わなくてもシンプルに書けてしまうことに気づいた。
class Vector3D < Array %w(x y z).each_with_index do |e, i| eval "def #{e} ; self[#{i}] ; end" eval "def #{e}=a ; self[#{i}] = a ; end" end %w(+ - * /).each do |e| eval "def #{e}d Vector3D[self[0] #{e} d[0], self[1] #{e} d[1], self[2] #{e} d[2]] end" end end
[MyGame]テニスゲームの実装
描画に関して。
- 擬似 3D
- SDLなので表示物は 2D レンダリング
どう実装したものか悩むが、なにはともあれ実際に書いてみよう。行き詰ったら書き直せばいいのだ。
player1 = Player.new player2 = Player.new ball = Ball.new
主な登場人物はこんな感じだろうか。
2Dとはいえ少なくとも表示位置とサイズには3次元変換必要だ。カメラがいるな。
camera = Camera.new camera.draw [player1, player2, ball, net]
こんな感じでカメラに描画させてみる。 そうそう net も z ソートが必要だからカメラに描かせようか。 メソッド名は draw でいいか。それとも render がいい?
これらのクラスの中で描画に関しては処理できそうだ。描画以外の処理も重要だけど、ここではMyGameの検証が主な目的だから次は描画についてより深く考えてみるか。
GNU GRUB
poqute 君からツッコミをもらったので少し試してみる。
root (hd0,0) #=> Filesystem type is ext2fs, partition type 0x83 root (hd0,1) #=> Filesystem type is unknown, partition type 0x5 root (hd0,2) #=> Error 22: No such partition root (hd0,3) #=> Error 22: No such partition root (hd0,4) #=> Filesystem type is unknown, partition type 0x82 root (hd0,5) #=> Filesystem type is ext2fs, partition type 0x83
ふうむ。パーティション2と3が壊れて見えなくなったのかな?
それとも0が /boot だろうか。ext2のファイル一覧を見ることはできないのかなあ。
[Ruby]Rubyを観察してみる
require
require ってなに?組み込み関数だって。組み込み関数って何?Kernel モジュールで定義されているメソッドか。
メソッドなんだ。じゃあこんな事できるの?
ruby -e 'p require("pp")' #=> true
できた。
じゃあ再定義できるの?
ruby -e 'def require a; end; p require("pp")' #=> nil
できた。こんなことも知らなかったの?
うん。
def
def ってなに?さすがにこれはメソッドじゃないよね?
うんメソッドではないな。予約語かあ。予約語って何だ?
BEGIN class ensure nil self when END def false not super while alias defined? for or then yield and do if redo true begin else in rescue undef break elsif module retry unless case end next return until
Rubyスクリプトに登場するキーワードの種別をカテゴライズしてゆけばなにかわかりそうだ。それっぽいものを思いつきで列挙してみよう。
- 予約語
- 変数
- リテラル
- コメント
- メソッド
- .
- =
- == > とか。比較演算子
うーん、他になにかあるかな。
- クラス名、モジュール名
- ::
- ,
- ()
- {}
include もメソッドなんだあ。
- && || and or
- シンボル
- each {|e| の |
- + - * /
- def a(*args) の * とメソッド呼び出しで使う *
ぱっと思いつくのはこんなもんかな。
字句構造っていうのかな。なんか無駄に列挙した気がする。たぶんスクリプトをパースするときにどう解釈するかって話だよなあ。
--
今日ほど『オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル』がわかりやすいと思ったことはない。これとか。
http://blade.nagaokaut.ac.jp/ruby/man/ruby-man-1.4-jp/syntax.html
てゆーかさあ、いままで読んでなかったの?
うん。なんとなくカンでやってた。リファレンス読むと眠くなるし。
[Ruby]オレが知ってるRubyってなんだ
Rubyではスクリプトをテキストファイルを書く
スクリプトのファイル名は *.rb にする。
hello.rb
hello の部分はなんでもいい。
rubyにスクリプトファイルを与える
rubyにスクリプトファイルを渡してやればスクリプトファイルに書かれているプログラムが動く。
ruby hello.rb
シェルを知ってる?
Rubyでは文字を出力することができる
スクリプトファイル(hello.rb)に次のように書けばいい。
print 'HELLO'
出力ってなに?
Rubyではスクリプトが1行ずつ上から順に実行される
print 'A' print 'B' print 'C'
行単位……。
Rubyでは文字列を扱うことができる
スクリプトにはこんな風に書く。
'Hello' 'ABC' 'Z' '012345'
Rubyでは数値を扱うことができる
スクリプトにはこんな風に書く。
0 100
数値を表示する。
print 100
Rubyには変数がある
a = 'HELOO'
変数とは値に任意の名前をつけること。変数名はアルファベット小文字の文字列を使う。
絵がほしい。箱じゃないよ。ものに名前をつけているだけ。
moji = 'ABC' bye = 'Bye'
こうすると変数に代入された文字列が表示できる。
a = 'HELLO' print a
↓結果
HELLO
--
ぐはっ
- 数値
- 文字列
- 変数
- 流れ
- 流れを変える制御構造
よし。
Rubyの変数には数値を代入することもできる
a = 10 b = 20
Rubyでは四則演算が使える
a = 10 + 20 b = 10 - 5 c = 10 * 5 d = 10 / 5
1行目は「10 + 20 の計算結果を a とする」という意味。つまり a は 30
a = 10 + 20 print a #=> 30
『#=> 30』について。「print a を実行した結果 30 が出力されますよ」という意味。解説する上での便宜上『#=> ...』を使う。プログラムとは何も関係ない。実際のスクリプトは次のように書くだけ。
a = 10 + 20 print a
Rubyでは四則演算が使える(2)
a = 10 + 20 + 30 b = 10 + 20 * 5
b は次と同じ。
b = 10 + (20 * 5)
つまり b は次と同じ。
b = 10 + (100)
↓
b = 10 + 100
↓
b = 110
Rubyではプログラムの流れを変えることができる
a = 10 if a == 100 print 'A' end
何も出力されない。
a = 100 if a == 100 print 'A' end
A が出力される。
--
いつもこんな泥臭い感じになるなあ。
ほんとにこれがオレの知っているRuby!?何か忘れてない?