Project

General

Profile

Backport #6898 » bug_trace.rb

uy (西行寺 うゆ), 08/21/2012 12:40 AM

 
# -*- encoding: UTF-8 -*-

# require "dxruby"
# require "dxrubyex"

require "ostruct"
#require "pp"
#
#
#
#
#
#
#

class Test_O
attr_accessor :x , :y , :d , :sym , :func
def initialize hs = Hash.new , &block
@x = hs[:x]
@y = hs[:y]
@d = hs[:d]
@sym = hs[:sym]
@func = -> o do
$a = block
block.call o rescue p $!, $a
end
end
def update
@func.call self
end
end
$test_o = []



module Yuyu_Nyannyan

attr_accessor :d
attr_accessor :dd_p
attr_accessor :dd_wait
attr_accessor :dd # 二次元配列 画像
attr_accessor :ddd # 三次元配列 画像
attr_accessor :x
attr_accessor :y
attr_accessor :speed , :angle
# task kannrenn
attr_accessor :func
attr_accessor :func_old # 初期化されてるかどうかのフラグで使った
attr_accessor :task
attr_accessor :type # 未使用っぽい
attr_accessor :up
attr_accessor :sym
# OpenStruct
attr_accessor :st
# variables
attr_accessor :n
attr_accessor :str # initialize で初期化しても大丈夫な
attr_accessor :sstr # cpu速度になったら 初期化させる
attr_accessor :remi
attr_accessor :lumia
attr_accessor :lacus
# Destructer
attr_accessor :destruct # def Destruct で yield 代入
# task add
attr_accessor :task_do # hash error 対策
# eval
attr_accessor :eval_do
# counter
attr_accessor :c

def initialize hs = Hash.new
@func = ->o do yield o end if iterator?
@task = Hash.new
@st = OpenStruct.new
@task_do = []
#kihon
@dd = hs[:dd] || []
if @dd.first
@d = @dd.first
else
@d = hs[:d]
end
@x = hs[:x]
@y = hs[:y]
#task kannei
@up = hs[:up]
# sym
@sym = hs[:sym] || :nil
# counter
@destruct = hs[:destruct] || ->{ }
@c = hs[:c] || 0
#__v
@n = hs[:n] || 0
# @str ||= hs[:str] || ""
# @sstr ||= hs[:sstr] || []
# @remi ||= hs[:remi] || nil #nil lambda nisuru?
# @lumia ||= hs[:lumia] || nil
# @lacus ||= hs[:lacus] || nil
# @eval_do ||= hs[:eval_do] || []
end

def __mainloop_sub ek
loop do
#
# 極稀に、funcが、nilになるはずはないのに、nilになってる ので
# Task で marge! をする事によって
#  nyan[key].func_old = task[key].func
# ここのtaskが別のポインタをさす変数に摩り替わってしまってるので
# これはあらかじめ  nyan = task でポインタを確保して
# 元のtaskを操作しないといけない
# でもtask側改良して task_doを入れたので 回避は出来たはず
#
#
#
# begin
nyan = task
task.each do | key , mm |
$aa = [ key , mm ]
miyu = mm.func.call mm
if miyu.class == self.class
nyan[key].func_old = nyan[key].func
nyan[key].func = miyu.func
end
end

task_do.each do | a , b |
task.store( a , b )
end
task_do.clear
if $de
$test_o.map &:update
end
# rescue => e
# p :__mainloop_sub
# p e
# end

break unless ek
# ------ ek==true ループのときだけ下の処理は実行される ---------
# Window.sync
# Window.update

# exit if Input.update
next
if $de_loop_command
exit if Input.keyPush? K_F9
break if Input.keyPush? K_F8
$Scarlet.izayoi = ! $Scarlet.izayoi if Input.keyPush? K_F2
Lumia.screenshot if Input.keyPush? K_F12
search_up( Yuyuko.top_sym ).delete if Input.keyPush? K_F6
delete if Input.keyPush? K_F4
# ------------
@@__debug_f3__code ||= 0
if Input.keyPush?(K_F3) and @@__debug_f3__code == 0
Window.fps = 0
@@__debug_f3__code = 1
elsif Input.keyPush?(K_F3) and @@__debug_f3__code == 1
Window.fps = 60
@@__debug_f3__code = 0
end
# --------------
end

break if task.empty?
end
end
def Main sym = Yuyuko.top_sym , hs = Hash.new
Task sym , hs do | o |
yield o
end
__mainloop_sub true
end # def

#`store': can't add a new key into hash during iteration (RuntimeError) 対策
def Task sym = "task" , hs = Hash.new
hs.store(:up , self )
hs.store(:sym , sym )

if sym.class == Symbol
# p Symbol.all_symbols.size
# p sym
# exit
end

begin
self.task.store( sym , self.class.new(hs) do | o |
yield o
end)
# p :task_add
rescue => e
# p e
#
# task_do で 要素の遅延追加を行う
#
self.task_do << [ sym , self.class.new(hs) do | o |
yield o
end ]
#
# 無理やりな代入
# ちょっと色々とrubyのバグか、設計のバグかに触りそうなのでこっちはやめておく
# 速度も遅いし
#
# self.task = self.task.clone.merge( { sym.to_sym => self.class.new(hs) do | o |
# yield o
# end })

end # rescue
end # def
def Task_Code sym = "taskcode" , hs = Hash.new
Task sym , hs do | o |
o.Code do
yield o
end # code
end # task
end # def
def __main_sub hs , ek
self.class.new do
yield
__mainloop_sub ek
end # new
end # def

def Loop_sub hs = Hash.new , &block
__main_sub hs , true , &block
end
def Code hs = Hash.new , &block
__main_sub hs , false , &block
end
# taskloop
def Loop sym = "Loop" , hs = Hash.new
Task( "nyannyan" ) do |o|
o.Loop_sub do
o.Task(sym , hs) do |o|
yield o
end # task //
end # code //
end # task //
end # def

# ------------------------------- BUG ---------------------------------
#
# uniq_sym
#
# 現在の階層からかぶらないシンボルを返すのではなく
# 全階層から絶対にかぶらないシンボルを返す形に変える
# そうないとsearch_down_allとかで重複シンボルが上書きされる
# ただそれは速度に難ありなので、連番とかランダムな英数字で生成
#
# ---------------------------------------------------------------------
#
# symbol は200万程度生成するとruby落ちるので  文字列で生成する事
#
#
#



def uniq_sym str = "_rb_uniq_" , n = rand(1000)
# @@__uniq_sym__var ||= 0
# @@__uniq_sym__var += 1
# n = @@__uniq_sym__var

$st_uniq_sym ||= [*1..500].dmap.to_s
n = $st_uniq_sym.rotate![-1]
return str.to_s + "_" + n
return
tmp = "#{str}_#{n}"
if self.task.include? tmp
return uniq_sym str , n + 1
else
return tmp
end
end # def

# ---
def delete
o = self
unless o.task.empty?
o.task.each do | key , value |
value.delete if value
end
end
# デストラクタから delete 呼び出した時に
# 無限ループに突入するので、
#
de = o.destruct.clone
o.destruct = ->{ }
de.call
# o.destruct.call
if o.up
o.up.task.delete o.sym
end
end # def

# counter
def c
@c += 1
end

end





#
#
#
#
#
#
#
#
#
#
#
#
#
# 拡張 および実装中のものたち
#-----------------------------------------------------------------
#
# search系のメソッドについて
# 探索結果の中にに同名のシンボルがあると上書きされてしまう






class Nyannyan
# extend Scarlet::Default
include Yuyu_Nyannyan
# okk
#-------------------------------------deletge 関係 --------------------------------
# task ga empty ni nattara delete
def delete_lazy_empty
if task.empty?
delete
end
end

# doudaro
def delete_fake
@x = 5000
@y = 5000
# up.task[sym].func = ->*h{ }
end

# totyuu jissou
def delete_lazy wait
Task uniq_sym "task" do | o |
o.Code do
wait -= 1
if wait < 0
delete
end
end
end
end



def top_node
up.top_node if up
return self
end


#
#
# -------------------------------- 探索など ----------------------------------
#



# もしかして使えない
def return_sym sym = Yuyuko.top_sym
o = self
=begin
yu.task.each do|k,v|
v.delete
end
return 0
p yu.sym

=end
return unless o.up
if o.up.sym == sym
o.delete
else
o.up.return_sym sym
end
end # def
#
#
# しっっっぬほど遅い!
#
def search_down sym = /(.*)/ , o = self
o.task.each.inject(Hash.new) do | stack , ( key , value ) |
stack.merge! value.search_down_all_test sym unless value.task.empty?
return value unless key =~ /#{sym}/
stack.merge({ key => value })
end
end



# :window_691 =~ /(window_\d*)/
def search_up sym , yu = self
if sym.class == Regexp
# p yu.sym
# p sym
# p yu.sym =~ sym
# return yu if $&.to_sym == yu.sym if yu.sym =~ sym # nandakkekore....
return yu if yu.sym =~ /#{sym}/
else return yu if yu.sym == sym
end
return yu.up.search_up sym if yu.up
return false
end

def search_up_all sym = /(.*)/ , o = self
o.search_up_all_test(sym).merge({ o.sym => o })
end

# self 含めず
def search_up_all_test sym = /(.*)/ , o = self
o.up ? o.up.search_up_all_test(sym).merge( (o.up.sym=~sym) ? { o.up.sym => o.up } : Hash.new ) : Hash.new
end

# self含める
def search_down_all sym = /(.*)/ , o = self
o.search_down_all_test(sym).merge({ o.sym => o })
end


def search_down_all_test sym = /(.*)/ , o = self
o.task.each.inject(Hash.new) do | stack , ( key , value ) |
stack.merge! value.search_down_all_test sym unless value.task.empty?
next stack unless key =~ /#{sym}/
stack.merge({ key => value })
end
end

def search_do_up sym , o = self
o.up.task.each do | key , value |
return value if sym =~ key
end
nil
end
# searh_do_all test mada desu
def search_do_all sym = /(.*)/ , o = self
o.task.each.inject( Hash.new ) do | stack , ( key , value ) |
if sym =~ key
stack[key] = value
end
stack
end
# Hash.new
end
def search_do sym , o = self
o.task.each do | key , value |
return value if sym =~ /#{key}/
end
nil
end






#
#
# -------------------------------- symtax shuger ------------------------
#
#


def height
d.height
end
def width
d.width
end

def Destruct &b
@destruct = b
end


# 選択可にしたい、(あとで
def each_ary sym = /(.*)/
if iterator?
self.task.each_value do | m |
yield m
end
else
self.task.each_value
end
end # def

alias YuyuMain Main
end
Tree_Diagram = Nyannyan





# ruby 拡張



# a = {:sym=>:user_shot, :d=>nil, :x=>225.0, :y=>410.0, :speed=>nil, :angle=>nil , nil => 222 }

class Hash
def value_compact!
replace value_compact
end
def value_compact
Hash[ each.reject { | _ , v | v.nil? } ]
end

def key_compact!
replace key_compact
end
def key_compact
Hash[ each.reject { | k , _ | k.nil? } ]
end
end

=begin
p a.value_compact
p a
p a.value_compact!
p a

p a.key_compact!
p a
=end


#
# バグの元になるので デバッグ専用
#
def static_logic
@@__static_logic__var ||= Hash.new
au = @@__static_logic__var
if au[ caller.to_s ]
return false
else
au[ caller.to_s ] = true
return true
end
end

# 4.times do
# p 1
# p 2 if static_logic
# end




class Binding
def debug *var
p caller(1).first
sz = var.map(&:size).max + 5
var.map(&:to_s).each do | m |
p m.ljust( sz ) + eval(m).to_s
end
end # df
end

=begin
def __debug__marisa
mystia = 100
lorelei = 40
binding.debug *local_variables
end
# __debug__marisa

=end




class DelegateMap < BasicObject
def initialize enum
@enum = enum
end
def method_missing f , *h , &block
@enum.map do | e | e.__send__( f , *h , &block ) end
end
end

module Enumerable
def dmap &b
return map &b if iterator?
DelegateMap.new self
end
end


# p [[1], [2], [3]].dmap.push(6)


module Enumerable
def map4(op=nil, *args, &blk)
op ? map { |e| op.intern.to_proc[e, *args]} : map(&blk)
end
end

# p [[3],[4],[5],].mapp(:push,6,7)


module Enumerable
#
# 引数は未対応
# ["aaa" , "bbb" ].hmap(:capitalize , :succ , :chars , :to_a ) do |m|
#
=begin
def hmap_old *h , &block
ret = h.inject self do | a , m |
a.dmap.method(m).dmap.call
end
if iterator?
ret.map &block
else
ret
end
end
=end
#
# 引数に対応
# ["aaa" , "bbb" ].hmap(:+ , ["vv"] , :upcase , ) do |m|
# p m
# end
#
# p [ [ 1] ].dmap.method(:push).dmap[6]
def hmap *h , &block
rr = h.map do | m |
m if m.class == Array
end
rr.rotate!
# p rr
ret = h.zip(rr).inject self do | a , ( m , n ) |
next a if m.class == Array
a.dmap.method(m).dmap.call( *n )
end
if iterator?
ret.map &block
else
ret
end

end # d
end

# ["abc" , "dfg" ].hmap( :<< , ["zz"] , :split , [//] , :push , [1,2,3] ) do | m |
# p m
# end




module Lib_ruby_ex
alias_method :orig_exit, :exit
def exit *code
puts "Exiting with code #{code}" if code.empty?.!
orig_exit
end
end

include Lib_ruby_ex

#exit 1 , 2 , Object.allocate





class Object
def blank?
# return true if self.nil? or self==false or empty?
return true unless self
return true if empty?
rescue
return false
end
end




module Enumerable
alias nue map
end
class Hash
def nue
values.map
end
end

class Array
def not_empty?
not empty?
end
end



def loop2 n = nil
if iterator?
[n].cycle do
yield n
end
else
[n].cycle
end
end

#
# loop2(2).with_index 5 do | a , b |
# p a # => 2
# p b # => 5
# end


class Object
def var_add *h
extend Module.new { attr_accessor *h }
end
end

class Object
=begin
def var_add *h
h.map(&:to_sym).each do | m |
m = m.to_s.delete"="
# self.class.class_eval"
self.instance_eval"
def #{m}
@#{m}
end
def #{m}=x
@#{m} = x
end"
end
end
=end
def var_add_ex *h
h.map(&:to_s).each do | m |
m = m.delete"="
self.class.class_eval"
def #{m}
@#{m}
end
def #{m}=x
@#{m} = x
end"
end
end
end


# 末尾再帰最適化の


class Module
def recursion_tco func
func_p = "_tco_#{func}"
alias_method func_p , func
nanoha = "nanoha_kannbai"
arg = nil
ff = true
define_method func do | *h |
[ff=nil].cycle do |re|
return re if ff = (re = method(func_p)[*h]) != nanoha
h = arg
end if ff
arg = h
nanoha
end
end # def
end

=begin

class A
def f n , a = 1
if n == 0
a
else
f(n - 1 , a * n)
end
end
recursion_tco :f
end

p A.new.f 20000

=end



class Regexp
def +(r)
Regexp.new(source + r.source)
end
end




module Suika
def method_missing( name , *arg )
if arg.size == 0
str = <<TEXT
def #{name}
@#{name}
end
@#{name}
TEXT
elsif name.to_s.include? "="
str = <<TEXT
def #{name} miyu
@#{name} miyu
end
self.#{name} arg[0]
TEXT
else
p __method__ , str , name , arg , caller
exit
end
# puts str
instance_eval str
end
end

module OpenStruct_m
include Suika
end




#
# TOPDIR の設定などもしているので必ずプロジェクトの最上位ディレクトリにおいておく
#
#
#
#

#class Struct_xyd
# attr_accessor :x , :y , :d
#end
# Struct.new(:x,:y,:d).new

# フォントは、メタでサイズを
# font_10 ~100
# font_100
#
# などできるように メタする
#
# font2_100
#
#


# L_const nimo sukosi module Yuyuko
module Yuyuko
# FONT = Font.new(30, "Meiryo UI" )
# FONT_SELECT = Font.new(30, "Meiryo UI" )
# FONT_SELECT_NO = Font.new(30, "Meiryo UI" )
# TOP_NODE

class << self
attr_accessor :TOP_NODE
#
#
# attr_accessor :LOOP_NODE
# 枠
# このあたりも初期化場所を要検討
# でも、ここのデータはゲームごとにあまりいじらないデータとする
#
attr_accessor :client_x
attr_accessor :client_y
attr_accessor :client_width
attr_accessor :client_height

attr_accessor :border_right
attr_accessor :border_left
attr_accessor :border_top
attr_accessor :border_bottom

[
:font_select_no_color , [ 0xc9 , 0xab , 0xd3 ] ,
:font_select_color , [ 0x95 , 0xc7 , 0xab ] ,
# :font_select_no , FONT_SELECT_NO ,
# :font_select , FONT_SELECT ,
# :font , FONT ,
# :font2 , Font.new(70, "Comic Sans MS" ) ,
:top_sym , "hakugyokuro" ,
:TOPDIR , File.dirname(__FILE__)+"/" ,
# :dd , Image.new(1,1,[1,100,100,100])
].each_slice(2) do | sym , nnn |
define_method sym do
nnn
end
end
#
#
# これちょっと不安なので後で何とかしたいゆ
#
# eval( open("./dat/meta/const_font_meta_data.rb").read )
# .each_slice(2) do | sym , nnn |
# define_method sym do
# nnn
# end
# end
# font _meta
# define _ meta
end
end


# ----------- init --------
#Window.caption = ""
#Window.x = 40
#Window.y = 0
#Window.width = 640
#Window.height = 480
# true --- window mode --------------- false --- full screen mode ---------
#Window.windowed = true
#Window.windowed = false
#Window.fps = 60
#
# Window.frameskip?
# Window.frameskip=val
# true で 1フレームだけ描画処理を省く
# Window.frameskip = true
#Window.bgcolor = [0,0,0]
#Window.create


# Scarlet
class STACK_Scarlet
attr_accessor :sound # BGM 効果音
attr_accessor :dd # 画像 まとめ
attr_accessor :frandoll # :ok 格納用
attr_accessor :remilia # シーン間の変数
attr_accessor :izayoi # DEBUG mode is true
attr_accessor :message # ハッシュにメッセージ入れて .message[:field].pop のような感じに
attr_accessor :stack # stack 雑用
def initialize
# top レベルのメッセージ last.rb
@frandoll = []
# シーン間のデータやり取り
@remilia = Hash.new
@remilia.default_proc = lambda do | h , k |
h[ k ] = Hash.new
end
# なんだっけ・・・
@izayoi = true
# シーン、オブジェクト間など、色々なメッセージ
@message = Hash.new
@message.default_proc = lambda do | h , k |
h[ k ] = []
end
#
# 雑用スタック
@stack = Hash.new
@stack.default_proc = lambda do | h , k |
h[ k ] = []
end
# oto

@sound = Hash.new
@sound[:bgm_all_stop] = ->*h{
if h.first
@sound[ h.first ].stop rescue p :__const_rb_sound__bug
else
@sound.each do | k , v |
@sound[ k ].stop rescue p
end
end
}
def @sound.play_ex name
$Scarlet.sound[:bgm_all_stop].call
$Scarlet.sound[ name ].play
end
# play_ex で 停止 & 再生にする
# $S.sound[:sym].play_ex


(["shot"]*20).zip([""].cycle.each_with_index).each do |m|
# m = m.flatten.join.to_sym
# @dd.var_add_ex m
end



# @sound.su = Sound.new("sound/te.mid")
# @sound.su.loop_count = 0
end
end
$Scarlet = STACK_Scarlet.new

# debug mode
# true false
$de = true
$de_loop_command = true
# Create_mode ## last.rb


# ---------------------







class Lumia_I____
attr_accessor :yakumo # misiyou
attr_accessor :img
attr_accessor :nn
def initialize img , nn = 20
@nn = nn
@img = img

# m = img.size
# @yakumo = Yakumo_ran.lo({
# start: 0 ,
# limit: m ,
# loopwait_ex_wait: 20 ,
# loopwait_ex: [*0..m] ,
# add: 1 ,
# })
end
# def dd
# @img[ @yakumo.call ]
# end

def copy_new
self.class.new @img
end
#
#
# img[ @c ] ni suru
#
def width
@img.first.width
end
def height
@img.first.height
end
def first
@img.first
end

end


module Lumia
class << self

def repl s
(s =~ /\(.*?(\(.*)\)/ ? s.sub($1,(repl $1).to_s) : s).scan(/\((.*?)\s(.*)\)/).flatten.last.split.map(&:to_f).inject *(eval "[$1=~/[a-z|A-Z]/,:#{$1}].compact")
end
# repl"(print (+ 8 9))"
# puts
# p repl"(* 8 9 5 5 5 5)"
# repl"(p (* 59 5 (* 4 (/ 10 6))))"

def recursion &b
f = ->*n{ b[ *n , &f ] }
end

def y_combinator &b
lambda do |f|
lambda{|x|lambda{|y| f[x[x]] [y]}}[
lambda{|x|lambda{|y| f[x[x]] [y]}}]
end[ lambda{|f|lambda{|n| b[n , &f] }}]
end

def require file
super File.dirname(__FILE__) + "/" + file
end
def extsplit s
s =~ /(.*)\.(.*)/
[ $1 , $2 ]
end
def ary_nest a,n
return a if n <= 0
ary_nest [].push(a) , n-1
end
def ary2 a , b , c = 0
(0...a).map do (0...b).map do c end end
end

def blockhit x1 , y1 , w1 , h1 , x2 , y2 , w2 , h2
x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2
end
def work x , y , s , a
x += (s * Math::cos(a * Math::PI/180 ))
y += (s * Math::sin(a * Math::PI/180 ))
[x , y , s , a]
end

def circle_pixel_hit x1, y1, w1, h1, r1, x2, y2, w2, h2, r2
return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) - r1*r2 <= 0
end
# w/2 まで関数で計算する
def circlehit2 x1, y1, w1, h1, r1, x2, y2, w2 , h2 , r2
x1 = x1+w1/2
y1 = y1+h1/2
y2 = y2+h2/2
x2 = x2+w2/2
return ((x1-x2)**2+(y1-y2)**2)-((r1+r2)**2) <= 0
end
# w / 2 を考慮しない
def circlehit x1, y1, w1, h1, r1, x2, y2, w2 , h2 , r2
x1 = x1+w1
y1 = y1+h1
y2 = y2+h2
x2 = x2+w2
return ((x1-x2)**2+(y1-y2)**2)-((r1+r2)**2) <= 0
end

def DegToRad x
x*Math::PI/180
end
def RadToDeg x
x*180/Math::PI
end
def firstatan x , y, xxx, yyy
RadToDeg( Math.atan2( yyy - y , xxx - x ))
end

def homing x , y , xxx , yyy , angle , as
tmp = Lumia.homing_angle x , y, xxx , yyy
angle += as if angle < tmp
angle -= as if angle > tmp
angle
end
#--------------------------
def get_center xy, wh , len
xy + ( wh * 0.5 ) - ( len * 0.5 )
end

alias move work
alias homing_angle firstatan



# --------------------------------- 以下 dxrubyやライブラリ 依存 含む----------------------------
#
# 使わないほうがいいかも
#
# Nazrinに仕様を書く
#
#
def rect_delete o
unless Lumia.blockhit o.x , o.y , o.d.width , o.d.height ,
-100 , -100 , Window.width+200 , Window.height+200
o.delete
end
end



def hit_check_box o , m
o.x + o.d.width > m.x && o.x < m.x + m.d.width &&
o.y + o.d.height > m.y && o.y < m.y + m.d.height
end

def get_xy_center__SfS_fs o , oo
return get_xy_center_d o , oo if oo.class == Image
get_xy_center_d o , oo.d
end




# -------------------------------
# ちょっとテスト
#
def get_xy_center__ o , oo
if oo.class == Image
get_xy_center_d o , oo
elsif oo.class == Lumia_I
get_xy_center_d o , oo.first
elsif oo.class == Lumia_S # String
[ o.x , o.y , oo ]
# get_xy_center_d o , Image.new(d.size, d.get_witdh)
# elsif o.class == oo.class
# get_xy_center_d o , oo.d
else
get_xy_center_d o , oo.d
# p o.class , oo.class
# p "err"
# p __method__
end
end
def get_xy_center o , oo
if oo.class == Image
oo_tmp = oo
# elsif oo.class == Lumia_I
# oo_tmp = oo.first
# elsif oo.class == String # Lumia_S # String
# return [ o.x , o.y , oo ]
else
oo_tmp = oo.d
end

return get_xy_center_d o , oo_tmp

if o.class == Image
o_tmp = o
elsif o.class == Lumia_I
o_tmp = o.first
elsif o.class == String # Lumia_S # String
return [ o.x , o.y , oo ]
else
o_tmp = o.d
end
get_xy_center_d o_tmp , oo_tmp
end


def get_xy_center_d o , b
[ o.x + ( o.d.width / 2 ) - ( b.width / 2 ) , o.y + ( o.d.height / 2 ) - ( b.height / 2 ) ]
end
# def get_xy_center_d x , y , d , ddd
# [ x + ( d.width / 2 ) - ( ddd.width / 2 ) , y + ( d.height / 2 ) - ( ddd.height / 2 ) ]
# end
#
# o じゃなくdが渡された時に、型みて、dを辿ってメソッド実行するみたいな機構を、
# Lumiaのほかのメソッド用にも作りたい
#
def get_client_xy_center o
return get_client_xy_center_d o if o.class == Image
get_client_xy_center_d o.d
end
def get_client_xy_center_d d
[ Yuyuko.client_x + (Yuyuko.client_width / 2 - d.width / 2) ,
Yuyuko.client_y + (Yuyuko.client_height / 2 - d.height / 2) ,
]
end

def get_homing_center o , v
vx = v.x + v.d.width / 2 - o.d.width / 2
vy = v.y + v.d.height / 2 - o.d.height / 2
[ vx , vy ]
end

def get_wh dirname
tmp = Image_load(dirname)
return [tmp[0][0].width , tmp[0][0].height]
end
end
# Image と Sound の ロード関数を一緒にするための記述
class << self
# [[]]
def Sound_load pas , remi = "{wav}"
__load( pas , Sound , remi )
end
# []
def Sound_load_miko pas , remi = "{wav}"
__ImageSound_load_miko pas Sound , patan
end
# Sound
def Sound_load_alice pas
Image_load_alice pas , Sound
end


def __ImageSound_load_miko pas , remi , patan
a = __load( pas , remi , patan )
if a.empty? || a.class != Array
p "#{__method__} pas is not directory #{pas} #{remi}"
p caller
end
return a.flatten - []
end
# [[]]
def Image_load pas , remi = "{png,bmp,jpg,jpeg,gif}"
__load( pas , Image , remi )
end
# []
def Image_load_miko pas , patan = "{png,bmp,jpg,jpeg,gif}"
a = __ImageSound_load_miko pas , Image , patan
# Lumia_I.new( a )
end
# Image
def Image_load_alice pas , remi = Image
a = __load( pas , remi , "{" + "#{File.extname(pas)}" + "}" )
if a.empty? || a.class == Array
p "#{__method__} pas is not file #{pas} #{remi}"
p caller
end
return a
end

# Lumia.i_Nyannyan
# Lumia.i_miko
# Lumia.i_alice
alias i_Nyannyan Image_load
alias i_miko Image_load_miko
alias i_alice Image_load_alice


def __load s , remi , patan
stk = [[]]
dir = []
(@@load_sub___stack___ ||= lambda do | s , remi , patan |
if dir.index s
return stk[dir.index(s)] if File.directory?(s)
return stk[dir.index(s)][0][0]
end
miko = stk[-1]
if File.directory?(s)
Dir["#{s}/*"].select do | m |
File.directory? m
end.each_with_index do | kd , k |
miko << Dir[ "#{s}/#{k}/*."+patan ].map do | m |
# miko[k] = Dir[ "#{kd}/*."+patan ].map do | m | # 0 1 2 じゃなく任意のフォルダ名
remi.load m
end
end
# 0 1 2 の フォルダがないときはこっちで位置次元配列
if miko.empty? # 多次元配列読み込みじゃなければ、一次元配列読み込み
miko << Dir[ "#{s}/*."+patan ].map do | m |
remi.load( m )
end
end
# 二次元配列return
dir << s
stk << []
return miko
elsif File.file?(s)
miko << []
miko[0][0] = remi.load s
dir << s
stk << []
return miko[0][0]
end
p "err2"
end).call( s , remi , patan )
end
end
def self.screenshot dir = "_screenshot"
pwd = Dir.pwd
Dir.chdir Yuyuko.TOPDIR
Dir.mkdir( dir ) unless File.exist?( dir )
file = dir + "/screenshot" + Time.new.strftime("%Y%m%d%H%M%S") + ".jpg"
Window.getScreenShot( file )
Dir.chdir pwd
return file
end


end





#
# count_loop_wait_create
#
# Yakumo_ran.rb に実装
#
#

# -------------------- count_lambda --------------------- #
module Yukarin
def self.key_focus_create2 p = 0
lambda do |size , key0 , key1 , pp = nil , *h |
p = pp || p
p = (p-=1) % size if Input.vkeyDownWait2?( key0 , *h)
p = (p+=1) % size if Input.vkeyDownWait2?( key1 , *h)
return p
end
end

def self.key_focus_create p = 0
lambda do |size , key0 , key1 , pp = nil |
p = pp || p
p = (p-=1) % size if Input.vkeyPush?( key0 )
p = (p+=1) % size if Input.vkeyPush?( key1 )
return p
end
end

def self.key_focus_create_test p = 0
lambda do |size , key0 , key1 , pp = nil , met = :keyPush? |
p = pp || p
p = (p-=1) % size if Input.method( met ).call( key0 )
p = (p+=1) % size if Input.method( met ).call( key1 )
return p
end
end
# 0...1...2...3...4...5...6
def self.count_limit_create c , limit , add
# start , limit = limit , start if add < 0
# c =
if add > 0
# plus
return lambda do
c += add
c = limit if c >= limit
return c
end
else
# minus
return lambda do
c += add
c = limit if c <= limit
return c
end
end
end
# 0...1...2...3...4...0...1...2...3...4
=begin
# 降順 未対応
def self.count_loop_create start , limit , add
c = start
start , limit = limit , start if add < 0
lambda do
c += add
c = start if c >= limit
return c
end
end
=end
# 0...1...2...3...4...3...2...1...0
def self.count_loop_create start , limit , add
c = start
lambda do
c += add
if add < 0
c = start if c <= limit
else
c = start if c >= limit
end
return c
end
end

def self.count_loop_rev_create start , limit , add
c = start
start , limit = limit , start if add < 0
lambda do
c += add
add *= -1 if c >= limit || c <= start
c = limit if c >= limit
c = start if c <= start
return c
end
end

def self.count_select type
case type
when nil
return lambda do | *h | lambda do | *hh | end end
when :default
return lambda do | *h | count_limit_create *h end
when :loop
return lambda do | *h | count_loop_create *h end
when :loop_rev
return lambda do | *h | count_loop_rev_create *h end
end
end
# todo
# hash ni
# blend add
#
def self.__fead_inout_create_sub o , hs = Hash.new
[ :rot , :scalex , :scaley , :alpha ]
.each do |m|
if hs[m].class == Array
au = hs[m].clone
hs[m] = Hash.new
hs[m][:type] = au[0]
hs[m][:start] = au[1]
hs[m][:limit] = au[2]
hs[m][:add] = au[3]
end
end

o.x = hs[:x]
o.y = hs[:y]
o.d = hs[:d]
o.st.fade_z = hs[:z] || 0
hs_rot = hs[:rot] || Hash.new
hs_scalex = hs[:scalex] || Hash.new
hs_scaley = hs[:scaley] || Hash.new
hs_alpha = hs[:alpha] || Hash.new
o.st.rot_hik = ({ type: hs_rot[:type] || :default , start: hs_rot[:start] || 0 , limit: hs_rot[:limit] || 0 , add: hs_rot[:add] || 0 })
o.st.scalex_hik = ({ type: hs_scalex[:type] || :default , start: hs_scalex[:start] || 1 , limit: hs_scalex[:limit] || 1 , add: hs_scalex[:add] || 0 })
o.st.scaley_hik = ({ type: hs_scaley[:type] || :default , start: hs_scaley[:start] || 1 , limit: hs_scaley[:limit] || 1 , add: hs_scaley[:add] || 0 })
o.st.alpha_hik = ({ type: hs_alpha[:type] || :default , start: hs_alpha[:start] || 255 , limit: hs_alpha[:limit] || 0 , add: hs_alpha[:add] || 0 })
create_remilambda = lambda do | hs |
self.count_select(hs[:type]).call hs[:start] , hs[:limit] , hs[:add]
end
o.st.rotremi = create_remilambda[ o.st.rot_hik ]
o.st.scalexremi = create_remilambda[ o.st.scalex_hik ]
o.st.scaleyremi = create_remilambda[ o.st.scaley_hik ]
o.st.alpharemi = create_remilambda[ o.st.alpha_hik ]
# font = hs[:font] || Yuyuko.font
# -------------- --------------------------------------------------------------
# dd = o.d.copy_new rescue nil
# n = 0
# ch = Yakumo_chen.count_true o.d_p || 20
# Window.draw_Lumia の 定義を考える

# -------------------
lambda do
next
o.st.rot = o.st.rotremi.call
o.st.alpha = o.st.alpharemi.call
o.st.scalex = o.st.scalexremi.call
o.st.scaley = o.st.scaleyremi.call
if o.dd.first
Window.drawEx( o.x , o.y, o.dd_get , ({ :angle => o.st.rot, :alpha => o.st.alpha,
:scalex => o.st.scalex, :scaley => o.st.scaley , :z => o.st.fade_z }) )

elsif o.d.class == Image
Window.drawEx( o.x , o.y, o.d, ({ :angle => o.st.rot, :alpha => o.st.alpha,
:scalex => o.st.scalex, :scaley => o.st.scaley , :z => o.st.fade_z }) )
# elsif o.d.class == Lumia_I
# -------------------------------------------------------------------------
# if ch.call
# n = (n+1)%3
# end
# Window.drawEx( o.x , o.y, o.d.img[ n ] , ({ :angle => o.st.rot, :alpha => o.st.alpha,
# :scalex => o.st.scalex, :scaley => o.st.scaley , :z => o.st.fade_z }) )
# Window.drawEx( o.x , o.y, o.d.dd , ({ :angle => o.st.rot, :alpha => o.st.alpha,
# :scalex => o.st.scalex, :scaley => o.st.scaley , :z => o.st.fade_z }) )
# ----------------------------------------------------------------------------------
end
# 画像に書き込む形がいいかもしれない
# if o.text
# Window.drawFont( o.x , o.y, o.d, font , ({ :angle => o.st.rot, :alpha => o.st.alpha,
# :scalex => o.st.scalex, :scaley => o.st.scaley , :z => o.st.fade_z }) )
# end

end
end # def
class << self
alias fade_create __fead_inout_create_sub
alias cc count_limit_create
alias lo count_loop_create
alias lr count_loop_rev_create
end
end

#
=begin
# fade_create  __fead_inout_create_sub に1個仲介させて、 Arrayでの指定も出来るようにしたい
#
if hs.class == Array
# テストしてないコード、 
mi = Hash.new
mi[:type] = hs.shift
mi[:start] = hs.shift
mi[:limit] = hs.shift
mi[:add] = hs.shift
hs = mi.clone
end
=end

#--------------------------------------------------
#
# Yukarin.count_limit_create
# sita ato ni .extend site tukau
#
# なんか動かないかも /// 色々と動かない事多いので使用は様子見
#--------------------------------------------------
=begin
module Yukarin_plus
def self
call
end
def to_s
call
end
def / n
call / n
end
def * n
call * n
end
def + n
call + n
end
def - n
call - n
end
def ** n
call ** n
end

end
# ---------------------
#
#
=end



module Yakumo_chen
class Count
attr_accessor :n
attr_accessor :c
def initialize n
@n = n
@c = 0
end
def call
@c += 1
if @c == @n
@c = 0
return true
end
return false
end # d
def copy_new
self.class.new @n
end

end
class << self
def count_true n
Count.new n
end
end
end

=begin
a = Yakumo_chen.count_true 5
10.times do |i|
print i , " "
p a.call
end

=end









module Mikomiko_module
end

class Nyannyan
include Mikomiko_module
end

class Nyannyan
def neko sym , x , y , d , hs = Hash.new
miko( {
sym: sym , x: x , y: y , d: d ,
}.merge(hs) ) do | o |
yield o if iterator?
end # miko
end # d
end


module Mikomiko_module
# 初期化用
module Miko_m
def Init
if @__miko_m_init.nil?
@__miko_m_init = true
yield
end
end
end


# 最低限
def miko__old hs = Hash.new , &block

o = self
angle = hs[:angle] || 0
speed = hs[:speed] || 0
hs[:x] = hs[:x] || 0
hs[:y] = hs[:y] || 0
hs[:d] = hs[:d] || Yuyuko.dd
sym = hs[:sym_uniq] || uniq_sym(hs[:sym])
o.Task( sym ) do |o|
remi = Yukarin.fade_create o , hs
o.extend Miko_m

o.Code do
remi.call
o.x , o.y = Lumia.move o.x , o.y , speed , angle
yield o if iterator?
end # code //
end # task //
end # df

end



#
#
#
#
# もういいや、 全部これでやらせる
# タスク 当たり判定 えふぇくと ゆーざー てき しょっと 
#-------------------------------------------
#

module Mikomiko_module

def miko hs = Hash.new
o = self
nodelete = hs[:nodelete] # rect

angle = hs[:angle] || 0
speed = hs[:speed] || 0
hs[:x] = hs[:x] || 0
hs[:y] = hs[:y] || 0
hs[:d] = hs[:d] || Image.new(60,60,[100,140,200])
sym = hs[:sym_uniq] || uniq_sym(hs[:sym])

# p hs[:dd]
o.Task( sym , hs ) do |o|

if hs[:dd].class == Array
# hs[:d] = hs[:dd].first
end

o.extend Miko_m
o.speed = speed
o.angle = angle
remi_ex = []
remi_ex << ->{ Nazrin.rect_delete o } if not nodelete

lumia_move = ->{
instance_exec o.speed , o.angle do | spd , ang |
spd = o.speed.call if speed.respond_to?(:call)
ang = o.angle.call if angle.respond_to?(:call)
o.x , o.y = Lumia.move o.x , o.y , spd , ang # if ang != 0
end
}

func = ->do
remi_ex << lumia_move
remi_ex << Yukarin.fade_create( o , hs )
o.extend Nazrin
o.var_add :collision
o.collision = CollisionCircle.new( o , 0 , 0 , 5 )
remi_ex << ->{ o.collision.draw if $Scarlet.izayoi }
end
effect = ->do
remi_ex << lumia_move
remi_ex << Yukarin.fade_create( o , hs )
end

case o.sym
when /user_shot/
func.call
o.collision = CollisionCircle.new( o , 0 , 0 , 10 )

o.life = 1
o.atack = 1
when /user/
func.call
o.life = 10
o.atack = 1
when /enemy_shot/
func.call
o.life = 1
o.atack = 1
when /enemy/
func.call
o.collision = CollisionCircle.new( o , 0 , 0 , 20 )
o.life = 10
o.atack = 1
when /effect/
effect.call
when /item_tokuten/
func.call
o.life = 1
o.atack = 0
when /item/
func.call
o.collision = CollisionCircle.new( o , 0 , 0 , 20 )

o.life = 1
o.atack = 0

when /task/
# 未使用?
else
# p o.sym
# p "symbol_err"
end
# sound play
#
o.Code do
remi_ex.map(&:call)
yield o if iterator?

end # code //
end # task //
end # df
end






def __mainloop_sub o , ek
loop do
#
# 極稀に、funcが、nilになるはずはないのに、nilになってる ので
# Task で marge! をする事によって
#  nyan[key].func_old = task[key].func
# ここのtaskが別のポインタをさす変数に摩り替わってしまってるので
# これはあらかじめ  nyan = task でポインタを確保して
# 元のtaskを操作しないといけない
# でもtask側改良して task_doを入れたので 回避は出来たはず
#
#
#
# begin
nyan = o.task
o.task.each do | key , mm |
$aa = [ key , mm ]
miyu = mm.func.call mm
if miyu.class == self.class
nyan[key].func_old = nyan[key].func
nyan[key].func = miyu.func
end
end

o.task_do.each do | a , b |
o.task.store( a , b )
end
o.task_do.clear
if $de
$test_o.map &:update
end
# rescue => e
# p :__mainloop_sub
# p e
# end

break unless ek
# ------ ek==true ループのときだけ下の処理は実行される ---------
Window.sync
Window.update

exit if Input.update
if $de_loop_command
exit if Input.keyPush? K_F9
break if Input.keyPush? K_F8
$Scarlet.izayoi = ! $Scarlet.izayoi if Input.keyPush? K_F2
Lumia.screenshot if Input.keyPush? K_F12
search_up( Yuyuko.top_sym ).delete if Input.keyPush? K_F6
delete if Input.keyPush? K_F4
# ------------
@@__debug_f3__code ||= 0
if Input.keyPush?(K_F3) and @@__debug_f3__code == 0
Window.fps = 0
@@__debug_f3__code = 1
elsif Input.keyPush?(K_F3) and @@__debug_f3__code == 1
Window.fps = 60
@@__debug_f3__code = 0
end
# --------------
end

break if task.empty?
end
end






def bug_p o

b = 0
$test_o << Test_O.new({
x:40 ,y:300,d: nil, sym: :effect
}) do |o|

n = o.func.clone
o.func = ->o{
$aa = n
n.call o rescue p $! , $aa
b += 1
b%1000==0 and p b
}
o.x += 0.1

Window.draw o.x , o.y , o.d
end
end










# ----------------------------------- main --------------------------------------









Tree_Diagram.new.Main do | o |
Yuyuko.TOP_NODE = o

o.Loop :field do |o|

bug_p o

$__db ||= 0
if $__db == 0
$__db = 1
2.times do |i|



def miko oo , hs = Hash.new
o = oo
nodelete = hs[:nodelete] # rect

angle = hs[:angle] || 0
speed = hs[:speed] || 0
hs[:x] = hs[:x] || 0
hs[:y] = hs[:y] || 0
# hs[:d] = hs[:d] || Image.new(60,60,[100,140,200])
sym = hs[:sym_uniq] || o.uniq_sym(hs[:sym])

# p hs[:dd]
o.Task( sym , hs ) do |o|

if hs[:dd].class == Array
# hs[:d] = hs[:dd].first
end

o.extend Module.new do
def Init
if @__miko_m_init.nil?
@__miko_m_init = true
yield
end
end
end

o.speed = speed
o.angle = angle
remi_ex = []

lumia_move = ->{
instance_exec o.speed , o.angle do | spd , ang |
spd = o.speed.call if speed.respond_to?(:call)
ang = o.angle.call if angle.respond_to?(:call)
o.x , o.y = Lumia.move o.x , o.y , spd , ang # if ang != 0
end
}
remi_ex << lumia_move
remi_ex << Yukarin.fade_create( o , hs )
__mainloop_sub o ,false do
# o.Code do
remi_ex.map(&:call)
yield o if iterator?

end # code //
end # task //
end # df




miko o , ({ sym: :effect ,
}) do | o | end # o
end # times
end


o.Code do
end
end
o.Code do
end

end




    (1-1/1)