WHITELEAF:Kindle応援サイト

KindleでWEB小説を読もう! Narou.rb 公開中

元ネタ:http://twitter.com/mirichi/status/16602971260
ここまで書いてわけわかんなくなったので終了。やりたい事と違う……
(ruby 1.9.1 以上が必要(たぶん))

require "dxruby"

module MetaGame
  module Core
    @@initialize_parameters = {}
    @@handler_names = {}
    @@object_container = []

    def regist(object)
      @@object_container << object
    end

    def regist_handler(name)
      @@handler_names[self] ||= []
      @@handler_names[self] << name
    end

    def push_initialize_parameter(parameters)
      @@initialize_parameters[self] ||= []
      parameters.each do |value|
        @@initialize_parameters[self] << value
      end
    end

    def search_object(object_type)
      @@object_container.each do |object|
        return object if object.kind_of?(object_type)
      end
      return nil
    end

    module Setting
      include Core

      def position(args)
        push_initialize_parameter(args)
      end

      def profile(args)
        push_initialize_parameter(args)
      end

      def create(args = nil)
        number = args && args[:number] || 1
        number.times do |i|
          param_str = attr_str = ""
          init_handler_str = update_handler_str = draw_handler_str = ""
          @@initialize_parameters[self] ||= {}
          @@initialize_parameters[self].each do |params|
            param_str += "@#{params[0]} = "
            attr_str += ":#{params[0]}, "
            param_value = params[1]
            if param_value.kind_of?(Range)
              param_value = rand(param_value.count) + param_value.min
            end
            param_str += "#{param_value}\n"
          end
          @@handler_names[self] ||= {}
          @@handler_names[self].each do |name|
            init_handler_str += "#{name}_init\n"
            update_handler_str += "#{name}_update\n"
            draw_handler_str += "#{name}_draw\n"
          end
          class_eval(%Q(
            def initialize
              #{param_str}
              #{init_handler_str}
              if self.kind_of?(Render)
                render_init
              end
            end
            def update
              #{update_handler_str}
              if self.kind_of?(Render)
                render_update
              end
            end
            def draw
              #{draw_handler_str}
              render_draw
            end
            attr_accessor #{attr_str}
          ))
          regist(self.new)
        end
      end

      def render(args)
        push_initialize_parameter(args)
      end

      def method_missing(name, args = {})
        regist_handler(name)
        push_initialize_parameter(args)
      end
    end

    module Render
      def render_init
        @image = Image.new(@width, @height, @color)
      end

      def render_update
      end

      def render_draw
        Window.draw(@x, @y, @image)
      end
    end

    class MainLoop
      include Core

      def self.run
        Window.loop do
          @@object_container.each do |object|
            object.update
            if object.kind_of?(Render)
              object.draw
            end
          end
        end
      end
    end
  end

  class Body
    extend Core::Setting
    include Core::Render
  end

  module Input_
    def input_init
    end

    def input_update
      rx = 0
      ry = 0
      @x -= 2 if Input.keyDown?(K_LEFT)
      @x += 2 if Input.keyDown?(K_RIGHT)
      @y -= 2 if Input.keyDown?(K_UP)
      @y += 2 if Input.keyDown?(K_DOWN)
    end

    def input_draw
    end
  end

  module Gravity
  end

  module Collision
  end

  module AI
    include Core

    def homing_init
      @player = search_object(@target)
    end

    def homing_update
      rx = (@x - @player.x) <=> 0
      ry = (@y - @player.y) <=> 0
      @x -= rx * @speed / 10.0
      @y -= ry * @speed / 10.0
    end

    def homing_draw
    end
  end

  def boot
    Core::MainLoop.run
  end
end

#
# ゲーム部分
#
include MetaGame

class BackGround < Body
  position :x => 0, :y => 0
  profile :width => 640, :height => 480
  render :color => [255, 255, 255]
  create
end

class Plane < Body
  include Collision
  position :x => 0, :y => 380
  profile :width => 640, :height => 100
  render :color => [128, 128, 128]
  create
end

class Player < Body
  include Input_, Gravity, Collision
  input
  position :x => 50, :y => 310
  profile :width => 40, :height => 70
  render :color => [0, 0, 0]
  create
end

class Enemy < Body
  include Collision, AI
  position :x => 200...600, :y => 0...200
  profile :width => 30, :height => 30
  homing :target => Player, :speed => 5..10
  render :color => [0, 255, 0]
  create :number => 10
end

boot