ミサイル発射だけ

左右のキーで移動。
スペースでミサイル発射。
ミサイルは連続5発まで。
この設定でつくったよ。
ゲーム性は無い。
練習だぁ。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class EventHandle
def initialize(handle)
@handle = handle
@type = {
SDL::Event::KeyDown => :sym,
SDL::Event::KeyUp => :sym,
SDL::Event::MouseButtonDown => :button,
SDL::Event::MouseButtonUp => :button
}
end

def handling(event)
name = event.class
if @type[name]
if callback = @handle[[name,event.method(@type[name]).call]]
return callback.call(event)
end
end
if callback = @handle[name]
return callback.call(event)
end
nil
end
end

class BackGround
def initialize(info)
@w,@h = info.w,info.h
@color = Cairo::Color::BLACK
end

def update(c)
c.set_source_color(@color)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Player
attr_accessor :dx

def initialize(info)
@info = info
@w,@h = 35,30
@x,@y = (@info.w - @w )/ 2 ,465
@image = Cairo::ImageSurface.new(@w,@h)
context = Cairo::Context.new(@image)
context.set_source_color(Cairo::Color::CYAN)
context.triangle((@w + 1) / 2,0,0,@h,@w,@h)
context.fill
@dx = 0
end

def center_x
@x + (@w + 1) / 2
end

def update(c)
@x += @dx * 8
@x = 0 if @x < 0
@x = @info.w - @w if @x >= @info.w - @w
c.set_source(@image,@x,@y)
c.paint
end
end

class Missile
def initialize(x)
@w,@h = 5,30
@image = Cairo::ImageSurface.new(@w,@h)
@x = x - (@w + 1) / 2
@y = 450
@v = -10
context = Cairo::Context.new(@image)
context.set_source_color(Cairo::Color::YELLOW)
context.rectangle(0,0,@w,@h)
context.fill
end

def y
@y
end

def update(c)
@y += @v
c.set_source(@image,@x,@y)
c.paint
end
end

class Phase
def initialize(info)
@info = info
@surface = Cairo::ImageSurface.new(@info.w,@info.h)
@bg = BackGround.new(@info)
@player = Player.new(@info)
@missiles = []
@fire = false
@fire_ticks = 0
@handle = EventHandle.new(
[SDL::Event::KeyDown,SDL::Key::LEFT] => proc{@player.dx -= 1},
[SDL::Event::KeyDown,SDL::Key::RIGHT] => proc{@player.dx += 1},
[SDL::Event::KeyUp,SDL::Key::LEFT] => proc{@player.dx += 1},
[SDL::Event::KeyUp,SDL::Key::RIGHT] => proc{@player.dx -= 1},
[SDL::Event::KeyDown,SDL::Key::SPACE] => proc{@fire = true},
[SDL::Event::KeyUp,SDL::Key::SPACE] => proc{@fire = false}
)
end

def handling(event)
@handle.handling(event)
end

def update
@missiles.reject!{|obj| obj.y < 20}
if @fire
if @missiles.size < 5
if @fire_ticks > 3
obj = Missile.new(@player.center_x)
@missiles << obj
@fire_ticks = 0
end
end
end
@fire_ticks += 1
context = Cairo::Context.new(@surface)
@bg.update(context)
@missiles.each {|obj| obj.update(context)}
@player.update(context)
@surface
end
end

class Game
def initialize(screen)
@screen = screen
info = Struct.new(:w,:h)
@info = info.new(@screen.w,@screen.h)
@phase = Phase.new(@info)
@handle = EventHandle.new(
[SDL::Event::KeyDown,SDL::Key::ESCAPE] => proc{exit},
SDL::Event::Quit => proc{exit}
)
end

def handling(event)
@handle.handling(event)
@phase.handling(event)
end

def update
cairo = @phase.update
suface = SDL::Surface.new_from(cairo.data,@info.w,@info.h,32,cairo.stride,0,0,0,0)
@screen.put(suface,0,0)
end

def run
loop do
while e=SDL::Event.poll
self.handling(e)
end
self.update
@screen.flip
SDL.delay(20)
end
end
end

SDL.init(SDL::INIT_VIDEO)
SDL::WM.set_caption("Game","")
SDL::Mouse.hide
w,h = 500,500
@screen = SDL::Screen.open(w,h,SDL::Screen.info.bpp,SDL::SWSURFACE)
Game.new(@screen).run
[PR]
by gaziya | 2011-05-06 22:41