class Main::MultiMap::Map
Constants
- Empty
- Hit
- Local
- Missed
- Remote
- Wasted
Public Class Methods
new(main,map_type,nx,ny)
click to toggle source
Calls superclass method
# File bin/tactical_fighter, line 201 def initialize(main,map_type,nx,ny) @nx=nx @ny=ny @main=main @map_type=map_type @shoot_fifo=Array.new @block_size=20 @line_width=(@block_size/7).to_i @planes=Array.new @plane_count=(0.03*@nx*@ny).to_i @plane_count.times{|i| @planes.push(Plane.new(@nx,@ny))} if local? super() set_visible_window(false) add(@widget=Gtk::Fixed.new) set_size_request(@nx*@block_size,@ny*@block_size) @map=Hash.new for i in 1 .. @nx @map[i]=Hash.new for j in 1 .. @ny @map[i][j]=Empty end end @widget.signal_connect('size-allocate'){|me,allocation| @block_size=(me.allocation.width-1)/@nx yblock_size=(me.allocation.height-1)/@ny @block_size=yblock_size if yblock_size<@block_size @line_width=(@block_size/7).to_i @xroot=me.allocation.x+(me.allocation.width-@nx*@block_size-1)/2 @yroot=me.allocation.y+(me.allocation.height-@ny*@block_size-1)/2 } @widget.signal_connect('expose-event'){|me,ev| cr=me.window.create_cairo_context #grid cr.set_source_rgb(0.8,0.8,0.8) cr.set_line_width(1) cr.set_line_cap(Cairo::LineCap::ROUND) for i in 0 .. @nx for j in 0 .. @ny cr.move_to(@xroot+i*@block_size,@yroot) cr.line_to(@xroot+i*@block_size,@yroot+@ny*@block_size) cr.move_to(@xroot,@yroot+j*@block_size) cr.line_to(@xroot+@nx*@block_size,@yroot+j*@block_size) end end cr.stroke cr.set_source_rgb(0.3,0.3,0.3) cr.rectangle(@xroot,@yroot,@nx*@block_size,@ny*@block_size) cr.stroke all_set?#invalidate planes #planes @planes.each{|plane| plane.draw(cr,@xroot,@yroot,@block_size)} for i in 1 .. @nx do for j in 1 .. @ny do if (cnt=count_plane_on_coordinates?(i,j))>1 plane=first_plane_on_coordinates?(i,j) cr.set_source_rgba(1.0*(cnt-1)/(@plane_count-1), if plane.ready? then 1 else 0 end, 1-1.0*(cnt-1)/(@plane_count-1),0.2) cr.rectangle(@xroot+(i-1)*@block_size+1,@yroot+(j-1)*@block_size+1,@block_size-2,@block_size-2) cr.fill end #battle-map case @map[i][j] when Hit then cr.set_source_rgb(1,0,0) cr.set_line_width(@line_width) cr.set_line_cap(Cairo::LineCap::ROUND) cr.move_to(@xroot+(i-1)*@block_size+@line_width*2,@yroot+(j-1)*@block_size+@line_width*2) cr.line_to(@xroot+i*@block_size-@line_width*2,@yroot+j*@block_size-@line_width*2) cr.move_to(@xroot+i*@block_size-@line_width*2,@yroot+(j-1)*@block_size+@line_width*2) cr.line_to(@xroot+(i-1)*@block_size+@line_width*2,@yroot+j*@block_size-@line_width*2) cr.stroke when Missed then cr.set_source_rgb(0,1,0) cr.set_line_width(@line_width) cr.set_line_cap(Cairo::LineCap::ROUND) cr.arc(@xroot+(i-0.5)*@block_size, @yroot+(j-0.5)*@block_size, @block_size/3, 0, Math::PI*2) cr.stroke when Wasted then cr.set_source_rgb(1,0,0) cr.set_line_width(@line_width) cr.set_line_cap(Cairo::LineCap::ROUND) cr.arc(@xroot+(i-0.5)*@block_size, @yroot+(j-0.5)*@block_size, @block_size/3, 0 , Math::PI*2) cr.move_to(@xroot+(i-1)*@block_size+@line_width*2,@yroot+(j-1)*@block_size+@line_width*2) cr.line_to(@xroot+i*@block_size-@line_width*2,@yroot+j*@block_size-@line_width*2) cr.move_to(@xroot+i*@block_size-@line_width*2,@yroot+(j-1)*@block_size+@line_width*2) cr.line_to(@xroot+(i-1)*@block_size+@line_width*2,@yroot+j*@block_size-@line_width*2) cr.stroke end end end cr.stroke #draw the shoot_fifo @shoot_fifo.each_index{|ind| @shoot_fifo[ind] layout=cr.create_pango_layout layout.text=(ind+1).to_s layout.set_width(@block_size * Pango::SCALE).set_alignment(Pango::Layout::ALIGN_CENTER) layout.set_font_description(Pango::FontDescription.new("Sans #{(@block_size*0.6).to_i}")) cr.update_pango_layout(layout) cr.move_to(@xroot+@block_size*(@shoot_fifo[ind][0]-1),@yroot+@block_size*(@shoot_fifo[ind][1]-1)) cr.set_source_rgba(0.9,0.1,0.1,0.5) cr.show_pango_layout(layout) cr.stroke } #draw round transparent charts on the map, the waste a smaller inside waste_ratio,hit_ratio = hit_counter r=@block_size-1 xc=@xroot+@block_size yc=@yroot+@ny*@block_size-@block_size cr.set_line_width(1) cr.set_source_rgba(0,2,0,0.1) cr.move_to(xc,yc) cr.arc(xc,yc,r,0,Math::PI*2) cr.move_to(xc,yc) cr.fill cr.stroke if hit_ratio>0 cr.set_source_rgba(1,0,0,0.1) cr.move_to(xc,yc) cr.line_to(xc+r,yc) cr.arc(xc,yc,r,0,Math::PI*2*hit_ratio) cr.line_to(xc,yc) cr.close_path cr.fill cr.stroke end r=@block_size/2-1 xc=@xroot+@block_size yc=@yroot+@ny*@block_size-@block_size cr.set_line_width(1) cr.set_source_rgba(0,2,0,0.3) cr.move_to(xc,yc) cr.arc(xc,yc,r,0,Math::PI*2) cr.move_to(xc,yc) cr.fill cr.stroke if waste_ratio>0 cr.set_source_rgba(1,0,0,0.3) cr.move_to(xc,yc) cr.line_to(xc+r,yc) cr.arc(xc,yc,r,0,Math::PI*2*waste_ratio) cr.line_to(xc,yc) cr.close_path cr.fill cr.stroke end #message message=nil if local? message="Prepare the planes".lng if @main.place? message="You Lost".lng if @main.lost? message="" if @main.won? end if remote? message="Shoot".lng if @main.shoot? message="Wait".lng if @main.wait? message="You Won".lng if @main.won? message="" if @main.lost? end unless message.nil? layout=cr.create_pango_layout layout.text=message layout.set_width(@block_size*@nx/2 * Pango::SCALE) font_size=@block_size layout.set_font_description(Pango::FontDescription.new("Sans #{font_size}")) cr.update_pango_layout(layout) while layout.size[0]/Pango::SCALE>@block_size*@nx do font_size-=1 layout.set_font_description(Pango::FontDescription.new("Sans #{font_size}")) cr.update_pango_layout(layout) end cr.move_to(@xroot+(@block_size*@nx-layout.size[0]/Pango::SCALE)/2,@yroot+(@block_size*@ny-layout.size[1]/Pango::SCALE)/2) cr.set_source_rgba(1,1,0,0.6) cr.show_pango_layout(layout) cr.stroke end true } signal_connect('button-press-event'){|me,ev| if ev.button == 1 if local? && @main.place? #start moving plane @xshift=((ev.x-@xroot)/@block_size).to_i+1 @yshift=((ev.y-@yroot)/@block_size).to_i+1 @dragged=false end if remote? x=((me.allocation.x+ev.x-@xroot)/@block_size).to_i+1 y=((me.allocation.y+ev.y-@yroot)/@block_size).to_i+1 if 1<=x && x<=@nx && 1<=y && y<=@ny && @map[x][y] == Empty if @main.shoot? #shoot the enemy set_cell_state(x,y,@main.shoot_enemy(x,y)) @main.wait unless @main.ended? elsif @main.wait? if @shoot_fifo.include?([x,y]) #remove from the fifo if already there @shoot_fifo.delete([x,y]) redraw_map else #add to shoot fifo @shoot_fifo.push([x,y]) redraw_cell(x,y) end end end end end if ev.button == 3 if local? && @main.place? #make plane ready if ev.event_type == Gdk::Event::BUTTON2_PRESS #double-right-click validate all planes @planes.each{|pl| pl.validate} redraw_map @main.ready if all_set? else if plane=first_head_on_coordinates?(((ev.x-@xroot)/@block_size).to_i+1,((ev.y-@yroot)/@block_size).to_i+1) if plane.ready? then plane.invalidate else plane.validate end redraw_map @main.ready if all_set? end end end if remote? #rotate guessed enemy plane x=((me.allocation.x+ev.x-@xroot)/@block_size).to_i+1 y=((me.allocation.y+ev.y-@yroot)/@block_size).to_i+1 if @map[x][y] == Wasted if plane=first_head_on_coordinates?(x,y) plane.rotate_cw(true) @planes.each{|plane| plane.validate} redraw_map end end end end } signal_connect('button-release-event'){|me,ev| if ev.button == 1 if local? && @main.place? && !@xshift.nil? && !@yshift.nil? #rotate plane x=((ev.x-@xroot)/@block_size).to_i+1 y=((ev.y-@yroot)/@block_size).to_i+1 plane=first_head_on_coordinates?(@xshift,@yshift) if !plane.nil? && !@dragged && !plane.ready? plane.rotate_cw redraw_map #also invalidate planes if needed end @xshift=nil @yshift=nil end end } signal_connect('motion-notify-event'){|me,ev| if local? && @main.place? && !@xshift.nil? && !@yshift.nil? #move plane if plane=first_head_on_coordinates?(@xshift,@yshift) x=((ev.x-@xroot)/@block_size).to_i+1 y=((ev.y-@yroot)/@block_size).to_i+1 if (x!=@xshift || y!=@yshift) && !plane.ready? @xshift,@yshift=plane.move_to(x,y) if plane.head?(x,y) @dragged=true redraw_map end end end end } end
Public Instance Methods
all_set?()
click to toggle source
# File bin/tactical_fighter, line 511 def all_set? cnt=0 for i in 1 .. @nx for j in 1 .. @ny if count_plane_on_coordinates?(i,j)>1 first_plane_on_coordinates?(i,j).invalidate cnt+=1 end end end good=cnt == 0 @planes.each{|plane| good=false unless plane.ready?} good end
all_wasted?()
click to toggle source
# File bin/tactical_fighter, line 549 def all_wasted? waste_cnt=0 for i in 1 .. @nx for j in 1 .. @ny waste_cnt+=1 if @map[i][j] == Wasted end end waste_cnt == @plane_count end
count_plane_on_coordinates?(x,y)
click to toggle source
# File bin/tactical_fighter, line 496 def count_plane_on_coordinates?(x,y) cnt=0 @planes.each{|plane| cnt+=1 if plane.on_coordinates?(x,y)} cnt end
fifo_shoot()
click to toggle source
# File bin/tactical_fighter, line 488 def fifo_shoot if @main.shoot? && coo=@shoot_fifo[0] #shoot the enemy from fifo set_cell_state(coo[0],coo[1],@main.shoot_enemy(coo[0],coo[1])) @shoot_fifo.delete_at(0) @main.wait unless @main.ended? end end
first_head_on_coordinates?(x,y)
click to toggle source
# File bin/tactical_fighter, line 506 def first_head_on_coordinates?(x,y) pl=nil @planes.each{|plane| pl=plane if plane.head?(x,y) && pl.nil?} pl end
first_plane_on_coordinates?(x,y)
click to toggle source
# File bin/tactical_fighter, line 501 def first_plane_on_coordinates?(x,y) pl=nil @planes.each{|plane| pl=plane if plane.on_coordinates?(x,y) && pl.nil?} pl end
hit?(x,y)
click to toggle source
# File bin/tactical_fighter, line 525 def hit?(x,y) cell_state=set_cell_state(x,y,if first_head_on_coordinates?(x,y) Wasted elsif first_plane_on_coordinates?(x,y) Hit else Missed end ) @main.lost if all_wasted? cell_state end
hit_counter()
click to toggle source
# File bin/tactical_fighter, line 558 def hit_counter waste_cnt=0 hit_cnt=0 miss_cnt=0 for i in 1 .. @nx for j in 1 .. @ny waste_cnt+=1 if @map[i][j] == Wasted hit_cnt+=1 if @map[i][j] == Hit miss_cnt+=1 if @map[i][j] == Missed end end return (waste_cnt.to_f/ @plane_count.to_f),hit_cnt.to_f/(hit_cnt.to_f+miss_cnt.to_f) end
local?()
click to toggle source
# File bin/tactical_fighter, line 482 def local? @map_type == Local end
redraw_cell(x,y)
click to toggle source
# File bin/tactical_fighter, line 479 def redraw_cell(x,y) @widget.window.invalidate(Gdk::Rectangle.new(@xroot+@block_size*(x-1),@yroot+@block_size*(y-1),@block_size,@block_size),false) end
redraw_map()
click to toggle source
# File bin/tactical_fighter, line 476 def redraw_map @widget.window.invalidate(Gdk::Rectangle.new(@widget.allocation.x,@widget.allocation.y,@widget.allocation.width,@widget.allocation.height),false) end
remote?()
click to toggle source
# File bin/tactical_fighter, line 485 def remote? @map_type == Remote end
set_cell_state(x,y,state)
click to toggle source
# File bin/tactical_fighter, line 537 def set_cell_state(x,y,state) @map[x][y]=state xwg=@xroot+x*@block_size ywg=@xroot+y*@block_size # redraw_map # #@widget.window.invalidate(Gdk::Rectangle.new(xwg+1,ywg+1,@block_size-2,@block_size-2),false) if remote? && state==Wasted @planes.push(pp=Plane.new(@nx,@ny)) pp.keep_on_map_by_rotate_only(x,y) end state end