忍者ブログ

マドノマグラの初心者自作ゲーム制作日誌 迷走モード

プログラミング初心者が自作ゲームを作成してみようとする動きを記す。現在迷走中。

ブログ履歴

2010/11/06: HSP3.22の環境を整えてみる
2009/11/09: Rubyで適当版自分用関連記事リンク作成プログラムを作る
2009/06/04: Visual C++(DXライブラリ使用)の環境を整えてみるも休止状態に
2009/03/17: ActionScript勉強の環境を整えるも結局休止状態に
2006/07/15: とりあえず分岐型ゲームを作る グリーンタワーVer1.2 ダウンロード(zip)
2006/07/02: ブログスタート。NScripterで何かを作ろうとする

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

リンゴ回収ゲーム ver1.00 を作成しながら、ちょっとずつプログラミングを学ぶ

今回は、Ruby/SDLで始めるゲームプログラミング【前編】をそのままなぞって、リンゴ回収ゲームの作成を行っていくことにした。

そこで紹介されていたサンプルパックをダウンロード、解凍し、その中に入っていた画像ファイル、fpstimer.rb、input.rb を活用して打ちこんでいった。

rb ファイルに注釈をつけながら勉強したので、元サイトに書かれているコードよりも、このエントリーの続き部分で書いたコードは注釈がやたら多くなっている。それ以外の部分でのコードはほぼ一緒である。

今回書いた rb ファイルは、main.rb、player.rb、items.rb の3つに分かれている。




main.rb
#! ruby -Ks

# リンゴ回収ゲーム Ver1.00

# ライブラリの読み込み
require "sdl"
require "lib/fpstimer"
require "lib/input"

# 定数の定義 HOLIZON は地平線の高さ
SCREEN_W = 640
SCREEN_H = 480
HOLIZON = 400

# メソッド定義 画像読み込み編
def load_image(fname)

# SDL::Surface.load で画像ファイル読み込み
# ちなみに、SDL::Surface#w で画像の横幅 SDL::Surface#h で画像の縦幅です
image = SDL::Surface.load(fname)

# SDL::Surface#set_color_key(flag,key)
# flagにSDL::SRCCOLORKEY指定で、keyの色が透明化するよ
image.set_color_key(SDL::SRCCOLORKEY, [255, 255, 255])

return image #生成した画像を返す
end

# ライブラリの読み込み player.rbはプレイヤーの挙動 items.rbは落ち物の挙動
require "player"
require "items"

# キー定義 input.rb まかせなので知らん。
class Input
define_key SDL::Key::ESCAPE, :exit
define_key SDL::Key::LEFT, :left
define_key SDL::Key::RIGHT, :right
end

# SDL の初期化、INIT_EVERYTHING (全て初期化の意味)
SDL.init(SDL::INIT_EVERYTHING)

# SDL.set_video_mode(幅、高さ、bppの値でビデオモードを設定,flags)
# SDL::SWSURFACE システムのメモリ内にバッファをとる。
screen = SDL.set_video_mode(SCREEN_W, SCREEN_H, 16, SDL::SWSURFACE)

# プレイヤー作成と、アイテム初期化、入力用変数初期化
player = Player.new(240)
items = Items.new
input = Input.new

#タイマーの生成 fpstimer.rb の FPSTimerLightで、1秒間60フレームに時間調整
timer = FPSTimerLight.new
timer.reset

# ゲーム本編ループ
loop do
input.poll # キーボードやジョイスティックを調べる
break if input.exit

# プレイヤーおよびアイテムを動かす 爆弾に当たったらループ脱出
player.act(input)
is_crashed = items.act(player)
break if is_crashed

# SDL::Surface#fill_rect 四角形の範囲を塗りつぶし
# 引数 [左上の x 座標、y 座標、幅、高さ、色]、色は RGB
screen.fill_rect(0, 0, SCREEN_W, HOLIZON, [128, 255, 255])
screen.fill_rect(0, HOLIZON, SCREEN_W, SCREEN_H - HOLIZON, [0, 128, 0])

# プレイヤーとアイテムの描画、下準備
player.render(screen)
items.render(screen)

#タイマー処理
timer.wait_frame do

# SDL::Screen.update_rect で画面まとめて更新
# 引数[左上の x 座標、y 座標、幅、高さ、色]
screen.update_rect(0, 0, 0, 0) # 4つとも 0を指定で画面全体が更新
end

end

player.rb
#! ruby -Ks

# プレイヤー座標とキャラ絵
class Player
def initialize(x)
@image = load_image("image/nos_front.png")
@x = x
@y = HOLIZON - @image.h
end

# player.x player.yで @x @y の値を外から取得可
attr_reader :x, :y

# キャラの中心座標(items.rb の当たり判定用)
def center
cx = @x + (@image.w / 2)
cy = @y + (@image.h / 2)

[cx, cy]
end

# キーなどが押された時の座標移動
def act(input)
@x -= 8 if input.left
@x += 8 if input.right
@x = 0 if @x < 0
@x = SCREEN_W-@image.w if @x >= SCREEN_W-@image.w
end

# 画像表示、下準備
def render(screen)
screen.put(@image, @x, @y)
end
end

items.rb
#! ruby -Ks

# Itemクラス リンゴと爆弾で共通。これは Items からの呼び出ししかない。
class Item
def initialize(x, y, v)
@x, @y, @v = x, y, v
@is_dead = false
end
attr_reader :v, :image
attr_accessor :x, :y, :is_dead

# 2点間の距離の計算 ピタゴラスの定理から平方根をとっている。
def distance(x1, y1, x2, y2)
Math.sqrt((x1-x2)**2 + (y1-y2)**2)
end

end

# リンゴ
class Apple < Item
def initialize(x, y, v)
super
@image = load_image("image/ringo.bmp")
end

# リンゴの当たり判定
def collides?(player)
px, py = player.center
distance(@x + @image.w / 2, @y + @image.h / 2, px, py) < 56
end

end

# 爆弾
class Bomb < Item
def initialize(x, y, v)
super
@image = load_image("image/bomb.bmp")
end

# 爆弾の当たり判定
def collides?(player)
px, py = player.center
distance(@x + @image.w / 2, @y + @image.h / 2, px, py) < 42
end

end

# Items クラス
class Items
def initialize

# @items は配列っぽい?
@items = [ ]
end


def act(player)

#爆弾当たったかどうかのフラグ 当たれば true を返して、main.rb でループ脱出
crash = false

#それぞれのアイテムの落下移動
@items.each do |item|
item.y += item.v
item.is_dead = true if item.y > SCREEN_H
end

# 当たり判定 リンゴならリンゴが消えるフラグオン、爆弾ならクラッシュオン
@items.each do |item|
case item
when Apple
item.is_dead = true if item.collides?(player)
when Bomb
crash = true if item.collides?(player)
end
end

#画面外に出たもの+プレイヤーと重なったリンゴ 消去
# a.reject!{| item | 条件} 条件真なら、a から item 除去
@items.reject!{|item| item.is_dead}

#新しいアイテムを補充 (つねに画面内に 5 個のアイテムがあるように)
while @items.size < 5
newx = rand(SCREEN_W)
newv = rand(9) + 4
if rand(100) < 60
@items << Bomb.new(newx, 0, newv)
else
@items << Apple.new(newx, 0, newv)
end
end

# 爆弾に当たったかどうかを返す
return crash

end

# 各アイテムの描画準備
def render(screen)
@items.each do |item|
screen.put(item.image, item.x, item.y)
end
end
end
PR

この記事にコメントする

NAME
TITLE
MAIL
URL
COMMENT
PASS

この記事へのトラックバック

この記事にトラックバックする:

PR

カテゴリー

最新記事

アーカイブ

プロフィール

HN:
マドノマグラ
性別:
非公開
職業:
趣味:
駄文書き
自己紹介:
ゲームを作ろうとしているうちに、言語学習に飽きていく。典型的なダメな人パターンに陥るアホな人

リンク

ブログ内検索

バーコード

RSS

忍者ブログ │ [PR]