chichilku3 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/bin/chichilku3 +3 -0
 - data/bin/chichilku3-server +3 -0
 - data/client.json +6 -0
 - data/lib/client/chichilku3.rb +18 -0
 - data/lib/client/client.rb +289 -0
 - data/lib/client/client_cfg.rb +15 -0
 - data/lib/client/gui.rb +492 -0
 - data/lib/client/img/background1024x512.png +0 -0
 - data/lib/client/img/battle1024x576.png +0 -0
 - data/lib/client/img/connecting1024x512.png +0 -0
 - data/lib/client/img/grass1024x512.png +0 -0
 - data/lib/client/img/grey128.png +0 -0
 - data/lib/client/img/menu1920x1080.png +0 -0
 - data/lib/client/img/stick128/stick0.png +0 -0
 - data/lib/client/img/stick128/stick1.png +0 -0
 - data/lib/client/img/stick128/stick2.png +0 -0
 - data/lib/client/img/stick128/stick3.png +0 -0
 - data/lib/client/img/stick128/stick4.png +0 -0
 - data/lib/client/img/stick128/stick5.png +0 -0
 - data/lib/client/img/stick128/stick_crouching0.png +0 -0
 - data/lib/client/img/stick128/stick_crouching1.png +0 -0
 - data/lib/client/img/stick128/stick_crouching2.png +0 -0
 - data/lib/client/img/stick128/stick_crouching3.png +0 -0
 - data/lib/client/img/stick128/stick_crouching4.png +0 -0
 - data/lib/client/img/stick128/stick_crouching5.png +0 -0
 - data/lib/client/scoreboard.rb +25 -0
 - data/lib/client/test.rb +39 -0
 - data/lib/client/text.rb +86 -0
 - data/lib/server/chichilku3_server.rb +293 -0
 - data/lib/server/gamelogic.rb +121 -0
 - data/lib/server/server_cfg.rb +6 -0
 - data/lib/share/config.rb +53 -0
 - data/lib/share/console.rb +18 -0
 - data/lib/share/network.rb +145 -0
 - data/lib/share/player.rb +286 -0
 - data/server.json +4 -0
 - metadata +81 -0
 
    
        data/lib/client/gui.rb
    ADDED
    
    | 
         @@ -0,0 +1,492 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'gosu'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'client'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'text'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'scoreboard'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative '../share/console'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative '../share/player'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            KEY_A = 4
         
     | 
| 
      
 9 
     | 
    
         
            +
            KEY_C = 6
         
     | 
| 
      
 10 
     | 
    
         
            +
            KEY_D = 7
         
     | 
| 
      
 11 
     | 
    
         
            +
            KEY_H = 11
         
     | 
| 
      
 12 
     | 
    
         
            +
            KEY_J = 13
         
     | 
| 
      
 13 
     | 
    
         
            +
            KEY_K = 14
         
     | 
| 
      
 14 
     | 
    
         
            +
            KEY_L = 15
         
     | 
| 
      
 15 
     | 
    
         
            +
            KEY_M = 16
         
     | 
| 
      
 16 
     | 
    
         
            +
            KEY_Q = 20
         
     | 
| 
      
 17 
     | 
    
         
            +
            KEY_S = 22
         
     | 
| 
      
 18 
     | 
    
         
            +
            KEY_T = 23
         
     | 
| 
      
 19 
     | 
    
         
            +
            KEY_W = 26
         
     | 
| 
      
 20 
     | 
    
         
            +
            KEY_RIGHT = 79
         
     | 
| 
      
 21 
     | 
    
         
            +
            KEY_LEFT = 80
         
     | 
| 
      
 22 
     | 
    
         
            +
            KEY_DOWN = 81
         
     | 
| 
      
 23 
     | 
    
         
            +
            KEY_UP = 82
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            MENU_MAIN = 0
         
     | 
| 
      
 26 
     | 
    
         
            +
            MENU_CONNECT = 1
         
     | 
| 
      
 27 
     | 
    
         
            +
            MENU_USERNAME = 2
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            $time_point=Time.now
         
     | 
| 
      
 30 
     | 
    
         
            +
            $time_buffer=0
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            def get_frame_time
         
     | 
| 
      
 33 
     | 
    
         
            +
              diff = Time.now - $time_point
         
     | 
| 
      
 34 
     | 
    
         
            +
              $time_point = Time.now
         
     | 
| 
      
 35 
     | 
    
         
            +
              return diff
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            # Main Game getting gui form gosu
         
     | 
| 
      
 39 
     | 
    
         
            +
            class Gui < Gosu::Window
         
     | 
| 
      
 40 
     | 
    
         
            +
              def initialize(cfg)
         
     | 
| 
      
 41 
     | 
    
         
            +
                super WINDOW_SIZE_X, WINDOW_SIZE_Y
         
     | 
| 
      
 42 
     | 
    
         
            +
                self.caption = 'chichilku3'
         
     | 
| 
      
 43 
     | 
    
         
            +
                self.fullscreen = true if cfg.data['fullscreen']
         
     | 
| 
      
 44 
     | 
    
         
            +
                # images
         
     | 
| 
      
 45 
     | 
    
         
            +
                @background_image = Gosu::Image.new("lib/client/img/battle1024x576.png")
         
     | 
| 
      
 46 
     | 
    
         
            +
                @connecting_image = Gosu::Image.new("lib/client/img/connecting1024x512.png")
         
     | 
| 
      
 47 
     | 
    
         
            +
                @menu_image = Gosu::Image.new("lib/client/img/menu1920x1080.png")
         
     | 
| 
      
 48 
     | 
    
         
            +
                @stick = Gosu::Image.new("lib/client/img/stick128/stick0.png")
         
     | 
| 
      
 49 
     | 
    
         
            +
                @stick_crouching = []
         
     | 
| 
      
 50 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching0.png")
         
     | 
| 
      
 51 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching1.png")
         
     | 
| 
      
 52 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching2.png")
         
     | 
| 
      
 53 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching3.png")
         
     | 
| 
      
 54 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching4.png")
         
     | 
| 
      
 55 
     | 
    
         
            +
                @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching5.png")
         
     | 
| 
      
 56 
     | 
    
         
            +
                @stick_images = []
         
     | 
| 
      
 57 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick0.png")
         
     | 
| 
      
 58 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick1.png")
         
     | 
| 
      
 59 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick2.png")
         
     | 
| 
      
 60 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick3.png")
         
     | 
| 
      
 61 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick4.png")
         
     | 
| 
      
 62 
     | 
    
         
            +
                @stick_images << Gosu::Image.new("lib/client/img/stick128/stick5.png")
         
     | 
| 
      
 63 
     | 
    
         
            +
                @x = 0
         
     | 
| 
      
 64 
     | 
    
         
            +
                @y = 0
         
     | 
| 
      
 65 
     | 
    
         
            +
                @players = []
         
     | 
| 
      
 66 
     | 
    
         
            +
                @cfg = cfg
         
     | 
| 
      
 67 
     | 
    
         
            +
                @tick = 0
         
     | 
| 
      
 68 
     | 
    
         
            +
                @console = Console.new
         
     | 
| 
      
 69 
     | 
    
         
            +
                @net_client = Client.new(@console, @cfg)
         
     | 
| 
      
 70 
     | 
    
         
            +
                @net_err = nil
         
     | 
| 
      
 71 
     | 
    
         
            +
                @state = @net_client.state
         
     | 
| 
      
 72 
     | 
    
         
            +
                @menu_page = MENU_MAIN
         
     | 
| 
      
 73 
     | 
    
         
            +
                @font = Gosu::Font.new(20)
         
     | 
| 
      
 74 
     | 
    
         
            +
                @is_debug = false
         
     | 
| 
      
 75 
     | 
    
         
            +
                @is_chat = false
         
     | 
| 
      
 76 
     | 
    
         
            +
                @is_scoreboard = false
         
     | 
| 
      
 77 
     | 
    
         
            +
                @chat_msg = "" # what we type
         
     | 
| 
      
 78 
     | 
    
         
            +
                @server_chat_msg = "" # what we get from server
         
     | 
| 
      
 79 
     | 
    
         
            +
                @chat_show_time = 4
         
     | 
| 
      
 80 
     | 
    
         
            +
                @server_chat_recv = Time.now - @chat_show_time
         
     | 
| 
      
 81 
     | 
    
         
            +
                @last_key = nil
         
     | 
| 
      
 82 
     | 
    
         
            +
                @events = {
         
     | 
| 
      
 83 
     | 
    
         
            +
                  :blood => []
         
     | 
| 
      
 84 
     | 
    
         
            +
                }
         
     | 
| 
      
 85 
     | 
    
         
            +
                @menu_items = []
         
     | 
| 
      
 86 
     | 
    
         
            +
                @selected_menu_item = 0
         
     | 
| 
      
 87 
     | 
    
         
            +
                @menu_textfield = TextField.new(self, 60, 200)
         
     | 
| 
      
 88 
     | 
    
         
            +
                # @chat_inp_stream = nil #TextInput.new
         
     | 
| 
      
 89 
     | 
    
         
            +
                # @chat_inp_stream.text # didnt get it working <--- nobo xd
         
     | 
| 
      
 90 
     | 
    
         
            +
                
         
     | 
| 
      
 91 
     | 
    
         
            +
                @last_pressed_button = {}
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                # depreciated ._.
         
     | 
| 
      
 94 
     | 
    
         
            +
                # @con_msg = Gosu::Image.from_text(self, "connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", Gosu.default_font_name, 45)
         
     | 
| 
      
 95 
     | 
    
         
            +
                init_menu()
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              def button_press?(button)
         
     | 
| 
      
 99 
     | 
    
         
            +
                last_btn = @last_pressed_button[button]
         
     | 
| 
      
 100 
     | 
    
         
            +
                @last_pressed_button[button] = button_down?(button)
         
     | 
| 
      
 101 
     | 
    
         
            +
                return false if last_btn == true
         
     | 
| 
      
 102 
     | 
    
         
            +
                button_down?(button)
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              # def update_pos(server_data)
         
     | 
| 
      
 106 
     | 
    
         
            +
              #   server_data = server_data.split('')
         
     | 
| 
      
 107 
     | 
    
         
            +
              #   @x = server_data[0].to_i * 20
         
     | 
| 
      
 108 
     | 
    
         
            +
              #   @y = server_data[1].to_i * 20
         
     | 
| 
      
 109 
     | 
    
         
            +
              # end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              def chat_tick
         
     | 
| 
      
 112 
     | 
    
         
            +
                if button_down?(Gosu::KB_ESCAPE)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  @is_chat = false
         
     | 
| 
      
 114 
     | 
    
         
            +
                elsif button_down?(Gosu::KB_RETURN)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @is_chat = false
         
     | 
| 
      
 116 
     | 
    
         
            +
                  return @chat_msg
         
     | 
| 
      
 117 
     | 
    
         
            +
                else
         
     | 
| 
      
 118 
     | 
    
         
            +
                  if !button_down?(@last_key)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    @last_key = nil # refresh blocker
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
                  if button_down?(Gosu::KB_BACKSPACE)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    # press shift to fast delete
         
     | 
| 
      
 123 
     | 
    
         
            +
                    if button_down?(Gosu::KB_LEFT_SHIFT) || @last_key != Gosu::KB_BACKSPACE
         
     | 
| 
      
 124 
     | 
    
         
            +
                      @chat_msg = @chat_msg[0..-2]
         
     | 
| 
      
 125 
     | 
    
         
            +
                      @last_key = Gosu::KB_BACKSPACE
         
     | 
| 
      
 126 
     | 
    
         
            +
                    end
         
     | 
| 
      
 127 
     | 
    
         
            +
                  end
         
     | 
| 
      
 128 
     | 
    
         
            +
                  for key in 4..30 do # alphabet lowercase
         
     | 
| 
      
 129 
     | 
    
         
            +
                    if button_down?(key)
         
     | 
| 
      
 130 
     | 
    
         
            +
                      if @last_key != key
         
     | 
| 
      
 131 
     | 
    
         
            +
                        @chat_msg += button_id_to_char(key)
         
     | 
| 
      
 132 
     | 
    
         
            +
                        @last_key = key
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
      
 134 
     | 
    
         
            +
                    end
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
                nil
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              def main_tick
         
     | 
| 
      
 141 
     | 
    
         
            +
                if @state == STATE_MENU
         
     | 
| 
      
 142 
     | 
    
         
            +
                  if @menu_page == MENU_CONNECT
         
     | 
| 
      
 143 
     | 
    
         
            +
                    enter_ip_tick
         
     | 
| 
      
 144 
     | 
    
         
            +
                  elsif @menu_page == MENU_USERNAME
         
     | 
| 
      
 145 
     | 
    
         
            +
                    enter_name_tick
         
     | 
| 
      
 146 
     | 
    
         
            +
                  else
         
     | 
| 
      
 147 
     | 
    
         
            +
                    menu_tick
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
                elsif @state == STATE_ERROR
         
     | 
| 
      
 150 
     | 
    
         
            +
                  if button_down?(Gosu::KB_ESCAPE)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    @state = STATE_MENU
         
     | 
| 
      
 152 
     | 
    
         
            +
                    @net_client.disconnect
         
     | 
| 
      
 153 
     | 
    
         
            +
                  end
         
     | 
| 
      
 154 
     | 
    
         
            +
                else
         
     | 
| 
      
 155 
     | 
    
         
            +
                  game_tick
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
              end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
              def enter_name_tick
         
     | 
| 
      
 160 
     | 
    
         
            +
                if button_down?(Gosu::KB_ESCAPE)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  @state = STATE_MENU
         
     | 
| 
      
 162 
     | 
    
         
            +
                  @menu_page = MENU_MAIN
         
     | 
| 
      
 163 
     | 
    
         
            +
                elsif button_down?(Gosu::KB_RETURN)
         
     | 
| 
      
 164 
     | 
    
         
            +
                  if @last_key != Gosu::KB_RETURN
         
     | 
| 
      
 165 
     | 
    
         
            +
                    @cfg.data['username'] = @menu_textfield.text[0...NAME_LEN]
         
     | 
| 
      
 166 
     | 
    
         
            +
                    @state = STATE_MENU
         
     | 
| 
      
 167 
     | 
    
         
            +
                    @menu_page = MENU_MAIN
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                else
         
     | 
| 
      
 170 
     | 
    
         
            +
                  @last_key = nil
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
              end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
              def enter_ip_tick
         
     | 
| 
      
 175 
     | 
    
         
            +
                if button_down?(Gosu::KB_ESCAPE)
         
     | 
| 
      
 176 
     | 
    
         
            +
                  ip = @menu_textfield.text.split(":")
         
     | 
| 
      
 177 
     | 
    
         
            +
                  @cfg.data['ip'] = ip[0]
         
     | 
| 
      
 178 
     | 
    
         
            +
                  @cfg.data['port'] = ip[1] if ip.length > 1
         
     | 
| 
      
 179 
     | 
    
         
            +
                  @state = STATE_MENU
         
     | 
| 
      
 180 
     | 
    
         
            +
                  @menu_page = MENU_MAIN
         
     | 
| 
      
 181 
     | 
    
         
            +
                elsif button_press?(Gosu::KB_RETURN)
         
     | 
| 
      
 182 
     | 
    
         
            +
                  if @last_key != Gosu::KB_RETURN
         
     | 
| 
      
 183 
     | 
    
         
            +
                    ip = @menu_textfield.text.split(":")
         
     | 
| 
      
 184 
     | 
    
         
            +
                    @cfg.data['ip'] = ip[0]
         
     | 
| 
      
 185 
     | 
    
         
            +
                    @cfg.data['port'] = ip[1] if ip.length > 1
         
     | 
| 
      
 186 
     | 
    
         
            +
                    connect
         
     | 
| 
      
 187 
     | 
    
         
            +
                  end
         
     | 
| 
      
 188 
     | 
    
         
            +
                else
         
     | 
| 
      
 189 
     | 
    
         
            +
                  @last_key = nil
         
     | 
| 
      
 190 
     | 
    
         
            +
                end
         
     | 
| 
      
 191 
     | 
    
         
            +
              end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
              def menu_tick
         
     | 
| 
      
 194 
     | 
    
         
            +
                if button_down?(KEY_Q)
         
     | 
| 
      
 195 
     | 
    
         
            +
                  puts "quitting the game."
         
     | 
| 
      
 196 
     | 
    
         
            +
                  @cfg.save
         
     | 
| 
      
 197 
     | 
    
         
            +
                  exit
         
     | 
| 
      
 198 
     | 
    
         
            +
                elsif button_down?(KEY_C)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  connect_menu
         
     | 
| 
      
 200 
     | 
    
         
            +
                  return
         
     | 
| 
      
 201 
     | 
    
         
            +
                end
         
     | 
| 
      
 202 
     | 
    
         
            +
                if button_press?(KEY_DOWN) or button_press?(KEY_S) or button_press?(KEY_J) or button_press?(Gosu::MS_WHEEL_DOWN)
         
     | 
| 
      
 203 
     | 
    
         
            +
                  @selected_menu_item += 1 if @selected_menu_item < @menu_items.length - 1
         
     | 
| 
      
 204 
     | 
    
         
            +
                elsif button_press?(KEY_UP) or button_press?(KEY_W) or button_press?(KEY_K) or button_press?(Gosu::MS_WHEEL_UP)
         
     | 
| 
      
 205 
     | 
    
         
            +
                  @selected_menu_item -= 1 if @selected_menu_item > 0
         
     | 
| 
      
 206 
     | 
    
         
            +
                elsif button_press?(Gosu::KB_RETURN)
         
     | 
| 
      
 207 
     | 
    
         
            +
                  @menu_items[@selected_menu_item][1].call
         
     | 
| 
      
 208 
     | 
    
         
            +
                end
         
     | 
| 
      
 209 
     | 
    
         
            +
              end
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
              def game_tick
         
     | 
| 
      
 212 
     | 
    
         
            +
                if button_down?(Gosu::KB_ESCAPE)
         
     | 
| 
      
 213 
     | 
    
         
            +
                  if @state == STATE_CONNECTING
         
     | 
| 
      
 214 
     | 
    
         
            +
                    @state = STATE_MENU
         
     | 
| 
      
 215 
     | 
    
         
            +
                    @net_client.disconnect
         
     | 
| 
      
 216 
     | 
    
         
            +
                  elsif @state == STATE_INGAME
         
     | 
| 
      
 217 
     | 
    
         
            +
                    @state = STATE_MENU
         
     | 
| 
      
 218 
     | 
    
         
            +
                    @net_client.disconnect
         
     | 
| 
      
 219 
     | 
    
         
            +
                    return
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
      
 221 
     | 
    
         
            +
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
                net_request = '0000'.split('')
         
     | 
| 
      
 223 
     | 
    
         
            +
                protocol = 2
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                if @is_chat
         
     | 
| 
      
 226 
     | 
    
         
            +
                  msg = chat_tick
         
     | 
| 
      
 227 
     | 
    
         
            +
                  if !msg.nil?
         
     | 
| 
      
 228 
     | 
    
         
            +
                    # @console.dbg "rawmsg: #{msg}"
         
     | 
| 
      
 229 
     | 
    
         
            +
                    msg = msg.ljust(4, '0')
         
     | 
| 
      
 230 
     | 
    
         
            +
                    net_request = msg[0..3].split('')
         
     | 
| 
      
 231 
     | 
    
         
            +
                    # @console.dbg "prepedmsg: #{net_request}"
         
     | 
| 
      
 232 
     | 
    
         
            +
                    protocol = 4
         
     | 
| 
      
 233 
     | 
    
         
            +
                  end
         
     | 
| 
      
 234 
     | 
    
         
            +
                else
         
     | 
| 
      
 235 
     | 
    
         
            +
                  net_request[0] = '0' # space for more
         
     | 
| 
      
 236 
     | 
    
         
            +
                  if button_down?(KEY_S)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    net_request[0] = '1'
         
     | 
| 
      
 238 
     | 
    
         
            +
                  end
         
     | 
| 
      
 239 
     | 
    
         
            +
                  if button_down?(KEY_A)
         
     | 
| 
      
 240 
     | 
    
         
            +
                    net_request[1] = '1'
         
     | 
| 
      
 241 
     | 
    
         
            +
                  end
         
     | 
| 
      
 242 
     | 
    
         
            +
                  if button_down?(KEY_D)
         
     | 
| 
      
 243 
     | 
    
         
            +
                    net_request[2] = '1'
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
                  if button_down?(Gosu::KB_SPACE)
         
     | 
| 
      
 246 
     | 
    
         
            +
                    net_request[3] = '1'
         
     | 
| 
      
 247 
     | 
    
         
            +
                  end
         
     | 
| 
      
 248 
     | 
    
         
            +
                  if button_press?(KEY_M)
         
     | 
| 
      
 249 
     | 
    
         
            +
                    @is_debug = !@is_debug
         
     | 
| 
      
 250 
     | 
    
         
            +
                  end
         
     | 
| 
      
 251 
     | 
    
         
            +
                  if button_down?(KEY_T)
         
     | 
| 
      
 252 
     | 
    
         
            +
                    @last_key = KEY_T
         
     | 
| 
      
 253 
     | 
    
         
            +
                    @is_chat = true
         
     | 
| 
      
 254 
     | 
    
         
            +
                    @chat_msg = ""
         
     | 
| 
      
 255 
     | 
    
         
            +
                  end
         
     | 
| 
      
 256 
     | 
    
         
            +
                  @is_scoreboard = button_down?(Gosu::KB_TAB)
         
     | 
| 
      
 257 
     | 
    
         
            +
                end
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
      
 259 
     | 
    
         
            +
                # Networking
         
     | 
| 
      
 260 
     | 
    
         
            +
                begin
         
     | 
| 
      
 261 
     | 
    
         
            +
                  net_data = @net_client.tick(net_request, protocol, @tick)
         
     | 
| 
      
 262 
     | 
    
         
            +
                rescue Errno::ECONNRESET, Errno::EPIPE
         
     | 
| 
      
 263 
     | 
    
         
            +
                  net_data = [@players, @flags, [0, NET_ERR_DISCONNECT, "connection to server lost"]]
         
     | 
| 
      
 264 
     | 
    
         
            +
                  @net_client.disconnect
         
     | 
| 
      
 265 
     | 
    
         
            +
                end
         
     | 
| 
      
 266 
     | 
    
         
            +
                return if net_data.nil?
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                @flags = net_data[1]
         
     | 
| 
      
 269 
     | 
    
         
            +
                @state = @flags[:state]
         
     | 
| 
      
 270 
     | 
    
         
            +
                msg = net_data[2]
         
     | 
| 
      
 271 
     | 
    
         
            +
                if msg
         
     | 
| 
      
 272 
     | 
    
         
            +
                  type = msg[0]
         
     | 
| 
      
 273 
     | 
    
         
            +
                  if type == 0
         
     | 
| 
      
 274 
     | 
    
         
            +
                    @net_err = msg[1..-1]
         
     | 
| 
      
 275 
     | 
    
         
            +
                    @state = STATE_ERROR
         
     | 
| 
      
 276 
     | 
    
         
            +
                  elsif type == 1
         
     | 
| 
      
 277 
     | 
    
         
            +
                    @server_chat_msg = msg[1]
         
     | 
| 
      
 278 
     | 
    
         
            +
                    @server_chat_recv = Time.now
         
     | 
| 
      
 279 
     | 
    
         
            +
                  end
         
     | 
| 
      
 280 
     | 
    
         
            +
                end
         
     | 
| 
      
 281 
     | 
    
         
            +
                return if @flags[:skip]
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
                @players = net_data[0]
         
     | 
| 
      
 284 
     | 
    
         
            +
              end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
              def update
         
     | 
| 
      
 287 
     | 
    
         
            +
                $time_buffer += get_frame_time
         
     | 
| 
      
 288 
     | 
    
         
            +
                if ($time_buffer > MAX_TICK_SPEED)
         
     | 
| 
      
 289 
     | 
    
         
            +
                  @tick += 1
         
     | 
| 
      
 290 
     | 
    
         
            +
                  main_tick
         
     | 
| 
      
 291 
     | 
    
         
            +
                  $time_buffer = 0
         
     | 
| 
      
 292 
     | 
    
         
            +
                end
         
     | 
| 
      
 293 
     | 
    
         
            +
              end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
              def draw_main_menu
         
     | 
| 
      
 296 
     | 
    
         
            +
                @menu_image.draw(0, 0, 0, UI_SCALE, UI_SCALE)
         
     | 
| 
      
 297 
     | 
    
         
            +
                offset = 0
         
     | 
| 
      
 298 
     | 
    
         
            +
                size = 2
         
     | 
| 
      
 299 
     | 
    
         
            +
                @menu_items.each_with_index do |menu_item, index|
         
     | 
| 
      
 300 
     | 
    
         
            +
                  offset += 20 * size
         
     | 
| 
      
 301 
     | 
    
         
            +
                  if index == @selected_menu_item
         
     | 
| 
      
 302 
     | 
    
         
            +
                    @font.draw_text("> #{menu_item[0]} <", 20, 20 + offset, 0, size, size, Gosu::Color::GREEN)
         
     | 
| 
      
 303 
     | 
    
         
            +
                  else
         
     | 
| 
      
 304 
     | 
    
         
            +
                    @font.draw_text("   #{menu_item[0]}   ", 20, 20 + offset, 0, size, size)
         
     | 
| 
      
 305 
     | 
    
         
            +
                  end
         
     | 
| 
      
 306 
     | 
    
         
            +
                end
         
     | 
| 
      
 307 
     | 
    
         
            +
              end
         
     | 
| 
      
 308 
     | 
    
         
            +
             
     | 
| 
      
 309 
     | 
    
         
            +
              def event_blood(x, y)
         
     | 
| 
      
 310 
     | 
    
         
            +
                @events[:blood] << [
         
     | 
| 
      
 311 
     | 
    
         
            +
                  x,
         
     | 
| 
      
 312 
     | 
    
         
            +
                  y,
         
     | 
| 
      
 313 
     | 
    
         
            +
                  0,
         
     | 
| 
      
 314 
     | 
    
         
            +
                  [
         
     | 
| 
      
 315 
     | 
    
         
            +
                    [x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
         
     | 
| 
      
 316 
     | 
    
         
            +
                    [x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
         
     | 
| 
      
 317 
     | 
    
         
            +
                    [x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
         
     | 
| 
      
 318 
     | 
    
         
            +
                    [x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
         
     | 
| 
      
 319 
     | 
    
         
            +
                    [x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)]
         
     | 
| 
      
 320 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 321 
     | 
    
         
            +
                ]
         
     | 
| 
      
 322 
     | 
    
         
            +
              end
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
              def draw_events
         
     | 
| 
      
 325 
     | 
    
         
            +
                bloods = []
         
     | 
| 
      
 326 
     | 
    
         
            +
                @events[:blood].each do |blood|
         
     | 
| 
      
 327 
     | 
    
         
            +
                  x = blood[0]
         
     | 
| 
      
 328 
     | 
    
         
            +
                  y = blood[1]
         
     | 
| 
      
 329 
     | 
    
         
            +
                  tick = blood[2]
         
     | 
| 
      
 330 
     | 
    
         
            +
                  splashes = blood[3]
         
     | 
| 
      
 331 
     | 
    
         
            +
                  new_splashes = []
         
     | 
| 
      
 332 
     | 
    
         
            +
                  splashes.each do |splash|
         
     | 
| 
      
 333 
     | 
    
         
            +
                    sx = splash[0]
         
     | 
| 
      
 334 
     | 
    
         
            +
                    sy = splash[1]
         
     | 
| 
      
 335 
     | 
    
         
            +
                    dx = splash[2]
         
     | 
| 
      
 336 
     | 
    
         
            +
                    dy = splash[3]
         
     | 
| 
      
 337 
     | 
    
         
            +
                    sw = splash[4]
         
     | 
| 
      
 338 
     | 
    
         
            +
                    sh = splash[5]
         
     | 
| 
      
 339 
     | 
    
         
            +
                    sx += dx
         
     | 
| 
      
 340 
     | 
    
         
            +
                    sy += dy
         
     | 
| 
      
 341 
     | 
    
         
            +
                    dy += 1 # gravity
         
     | 
| 
      
 342 
     | 
    
         
            +
                    draw_rect(sx, sy, sw, sh, 0xAAFF0000)
         
     | 
| 
      
 343 
     | 
    
         
            +
                    new_splashes << [sx, sy, dx, dy, sw, sh]
         
     | 
| 
      
 344 
     | 
    
         
            +
                  end
         
     | 
| 
      
 345 
     | 
    
         
            +
                  unless tick > 200
         
     | 
| 
      
 346 
     | 
    
         
            +
                    bloods << [x, y, tick + 1, new_splashes]
         
     | 
| 
      
 347 
     | 
    
         
            +
                  end
         
     | 
| 
      
 348 
     | 
    
         
            +
                end
         
     | 
| 
      
 349 
     | 
    
         
            +
                @events[:blood] = bloods
         
     | 
| 
      
 350 
     | 
    
         
            +
              end
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
              def draw
         
     | 
| 
      
 353 
     | 
    
         
            +
                # draw_quad(0, 0, 0xffff8888, WINDOW_SIZE_X, WINDOW_SIZE_Y, 0xffffffff, 0, 0, 0xffffffff, WINDOW_SIZE_X, WINDOW_SIZE_Y, 0xffffffff, 0)
         
     | 
| 
      
 354 
     | 
    
         
            +
                if @state == STATE_MENU
         
     | 
| 
      
 355 
     | 
    
         
            +
                  if @menu_page == MENU_CONNECT
         
     | 
| 
      
 356 
     | 
    
         
            +
                    @connecting_image.draw(0, 0, 0)
         
     | 
| 
      
 357 
     | 
    
         
            +
                    @font.draw_text("Enter server ip", 20, 20, 0, 5, 5)
         
     | 
| 
      
 358 
     | 
    
         
            +
                    @menu_textfield.draw(0)
         
     | 
| 
      
 359 
     | 
    
         
            +
                  elsif @menu_page == MENU_USERNAME
         
     | 
| 
      
 360 
     | 
    
         
            +
                    @connecting_image.draw(0, 0, 0)
         
     | 
| 
      
 361 
     | 
    
         
            +
                    @font.draw_text("Choose a username", 20, 20, 0, 5, 5)
         
     | 
| 
      
 362 
     | 
    
         
            +
                    @menu_textfield.draw(0)
         
     | 
| 
      
 363 
     | 
    
         
            +
                  else
         
     | 
| 
      
 364 
     | 
    
         
            +
                    draw_main_menu()
         
     | 
| 
      
 365 
     | 
    
         
            +
                  end
         
     | 
| 
      
 366 
     | 
    
         
            +
                elsif @state == STATE_CONNECTING
         
     | 
| 
      
 367 
     | 
    
         
            +
                  @connecting_image.draw(0, 0, 0)
         
     | 
| 
      
 368 
     | 
    
         
            +
                  @font.draw_text("connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", 20, 20, 0, 2, 5)
         
     | 
| 
      
 369 
     | 
    
         
            +
                  # @con_msg.draw(100,200,0)
         
     | 
| 
      
 370 
     | 
    
         
            +
                elsif @state == STATE_INGAME
         
     | 
| 
      
 371 
     | 
    
         
            +
                  @background_image.draw(0, 0, 0)
         
     | 
| 
      
 372 
     | 
    
         
            +
                  @players.each do |player|
         
     | 
| 
      
 373 
     | 
    
         
            +
                    event_blood(player.x, player.y) if player.state[:bleeding]
         
     | 
| 
      
 374 
     | 
    
         
            +
                    player.draw_tick
         
     | 
| 
      
 375 
     | 
    
         
            +
                    @console.dbg "drawing player id=#{player.id} pos=#{player.x}/#{player.y}"
         
     | 
| 
      
 376 
     | 
    
         
            +
                    # draw_rect(player.x, player.y, TILE_SIZE, TILE_SIZE, Gosu::Color::WHITE)
         
     | 
| 
      
 377 
     | 
    
         
            +
                    # @stick.draw(player.x, player.y, 0)
         
     | 
| 
      
 378 
     | 
    
         
            +
                    if player.state[:crouching]
         
     | 
| 
      
 379 
     | 
    
         
            +
                      @stick_crouching[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
         
     | 
| 
      
 380 
     | 
    
         
            +
                    else
         
     | 
| 
      
 381 
     | 
    
         
            +
                      @stick_images[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
         
     | 
| 
      
 382 
     | 
    
         
            +
                    end
         
     | 
| 
      
 383 
     | 
    
         
            +
                    if @is_debug # print id
         
     | 
| 
      
 384 
     | 
    
         
            +
                      draw_rect(player.x - 2, player.y - 60, 32, 20, 0xAA000000)
         
     | 
| 
      
 385 
     | 
    
         
            +
                      @font.draw_text("#{player.id}:#{player.score}", player.x, player.y - 60, 0, 1, 1)
         
     | 
| 
      
 386 
     | 
    
         
            +
                      # @font.draw_text("#{player.id}:#{player.img_index}", player.x, player.y - TILE_SIZE * 2, 0, 1, 1)
         
     | 
| 
      
 387 
     | 
    
         
            +
                      if player.state[:crouching]
         
     | 
| 
      
 388 
     | 
    
         
            +
                        draw_rect(player.x, player.y, TILE_SIZE, TILE_SIZE/2, 0xAA00EE00)
         
     | 
| 
      
 389 
     | 
    
         
            +
                      else
         
     | 
| 
      
 390 
     | 
    
         
            +
                        draw_rect(player.x, player.y, TILE_SIZE/2, TILE_SIZE, 0xAA00EE00)
         
     | 
| 
      
 391 
     | 
    
         
            +
                      end
         
     | 
| 
      
 392 
     | 
    
         
            +
                      else
         
     | 
| 
      
 393 
     | 
    
         
            +
                    end
         
     | 
| 
      
 394 
     | 
    
         
            +
                    @font.draw_text(player.name, player.x - (TILE_SIZE/6), player.y - TILE_SIZE / 2, 0, 1, 1, 0xff_000000)
         
     | 
| 
      
 395 
     | 
    
         
            +
                  end
         
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
      
 397 
     | 
    
         
            +
                  # chat input
         
     | 
| 
      
 398 
     | 
    
         
            +
                  if @is_chat
         
     | 
| 
      
 399 
     | 
    
         
            +
                    @font.draw_text("> #{@chat_msg}", 10, WINDOW_SIZE_Y - 30, 0, 1, 1)
         
     | 
| 
      
 400 
     | 
    
         
            +
                  end
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                  # chat output
         
     | 
| 
      
 403 
     | 
    
         
            +
                  if @server_chat_recv + @chat_show_time > Time.now
         
     | 
| 
      
 404 
     | 
    
         
            +
                    @font.draw_text(@server_chat_msg, 10, WINDOW_SIZE_Y - 60, 0, 1, 1)
         
     | 
| 
      
 405 
     | 
    
         
            +
                  end
         
     | 
| 
      
 406 
     | 
    
         
            +
             
     | 
| 
      
 407 
     | 
    
         
            +
                  if @is_debug
         
     | 
| 
      
 408 
     | 
    
         
            +
                    player = Player.get_player_by_id(@players, @flags[:id])
         
     | 
| 
      
 409 
     | 
    
         
            +
                    unless player.nil?
         
     | 
| 
      
 410 
     | 
    
         
            +
                      draw_rect(5, 10, 295, 75, 0xAA000000)
         
     | 
| 
      
 411 
     | 
    
         
            +
                      @font.draw_text("Press m to deactivate debug mode", 10, 10, 0, 1, 1)
         
     | 
| 
      
 412 
     | 
    
         
            +
                      @font.draw_text("x: #{player.x} y: #{player.y}", 10, 30, 0, 1, 1)
         
     | 
| 
      
 413 
     | 
    
         
            +
                      @font.draw_text("gamestate: #{@flags[:gamestate]}", 10, 60, 0 , 1, 1)
         
     | 
| 
      
 414 
     | 
    
         
            +
                      # thats useless because collide/delta speed is not sent over the network
         
     | 
| 
      
 415 
     | 
    
         
            +
                      # @font.draw_text("dx: #{player.dx} dy: #{player.dy}", 10, 50, 0, 1, 1)
         
     | 
| 
      
 416 
     | 
    
         
            +
                      # @font.draw_text(player.collide_string, 10, 70, 0, 1, 1)
         
     | 
| 
      
 417 
     | 
    
         
            +
                    end
         
     | 
| 
      
 418 
     | 
    
         
            +
                  end
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
                  draw_events()
         
     | 
| 
      
 421 
     | 
    
         
            +
             
     | 
| 
      
 422 
     | 
    
         
            +
                  if @is_scoreboard
         
     | 
| 
      
 423 
     | 
    
         
            +
                    draw_scoreboard(WINDOW_SIZE_X, WINDOW_SIZE_Y, @players, @font)
         
     | 
| 
      
 424 
     | 
    
         
            +
                  end
         
     | 
| 
      
 425 
     | 
    
         
            +
                elsif @state == STATE_ERROR
         
     | 
| 
      
 426 
     | 
    
         
            +
                  net_err_code = @net_err[0]
         
     | 
| 
      
 427 
     | 
    
         
            +
                  net_err_msg = @net_err[1]
         
     | 
| 
      
 428 
     | 
    
         
            +
                  @connecting_image.draw(0, 0, 0)
         
     | 
| 
      
 429 
     | 
    
         
            +
                  if net_err_code == NET_ERR_SERVER_OUTDATED || net_err_code == NET_ERR_CLIENT_OUTDATED
         
     | 
| 
      
 430 
     | 
    
         
            +
                    server_version = net_err_msg[0..4]
         
     | 
| 
      
 431 
     | 
    
         
            +
                    net_err_msg = net_err_msg[5..-1]
         
     | 
| 
      
 432 
     | 
    
         
            +
                    @font.draw_text("Server version: #{server_version} Your version: #{GAME_VERSION}", 50, 150, 0, 2, 2)
         
     | 
| 
      
 433 
     | 
    
         
            +
                  end
         
     | 
| 
      
 434 
     | 
    
         
            +
                  @font.draw_text("#{NET_ERR[net_err_code]}", 50, 30, 0, 5, 5)
         
     | 
| 
      
 435 
     | 
    
         
            +
                  @font.draw_text("#{net_err_msg}", 50, 200, 0, 2, 2)
         
     | 
| 
      
 436 
     | 
    
         
            +
                else
         
     | 
| 
      
 437 
     | 
    
         
            +
                  @connecting_image.draw(0, 0, 0)
         
     | 
| 
      
 438 
     | 
    
         
            +
                  @font.draw_text('UNKOWN CLIENT STATE!!!', 20, 20, 0, 2, 10)
         
     | 
| 
      
 439 
     | 
    
         
            +
                end
         
     | 
| 
      
 440 
     | 
    
         
            +
              end
         
     | 
| 
      
 441 
     | 
    
         
            +
             
     | 
| 
      
 442 
     | 
    
         
            +
              private
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
      
 444 
     | 
    
         
            +
              def connect()
         
     | 
| 
      
 445 
     | 
    
         
            +
                begin
         
     | 
| 
      
 446 
     | 
    
         
            +
                  @net_client.connect(@cfg.data['ip'], @cfg.data['port'])
         
     | 
| 
      
 447 
     | 
    
         
            +
                  @state = STATE_CONNECTING;
         
     | 
| 
      
 448 
     | 
    
         
            +
                  @menu_page = MENU_MAIN
         
     | 
| 
      
 449 
     | 
    
         
            +
                rescue Errno::ECONNREFUSED
         
     | 
| 
      
 450 
     | 
    
         
            +
                  @state = STATE_ERROR
         
     | 
| 
      
 451 
     | 
    
         
            +
                  @menu_page = MENU_MAIN
         
     | 
| 
      
 452 
     | 
    
         
            +
                  @net_err = [NET_ERR_DISCONNECT, "connection refused"]
         
     | 
| 
      
 453 
     | 
    
         
            +
                  @net_client.disconnect
         
     | 
| 
      
 454 
     | 
    
         
            +
                end
         
     | 
| 
      
 455 
     | 
    
         
            +
              end
         
     | 
| 
      
 456 
     | 
    
         
            +
             
     | 
| 
      
 457 
     | 
    
         
            +
              def connect_menu()
         
     | 
| 
      
 458 
     | 
    
         
            +
                @last_key = Gosu::KB_RETURN
         
     | 
| 
      
 459 
     | 
    
         
            +
                self.text_input = @menu_textfield
         
     | 
| 
      
 460 
     | 
    
         
            +
                @menu_textfield.text = "#{@cfg.data['ip']}:#{@cfg.data['port']}"
         
     | 
| 
      
 461 
     | 
    
         
            +
                @state = STATE_MENU
         
     | 
| 
      
 462 
     | 
    
         
            +
                @menu_page = MENU_CONNECT
         
     | 
| 
      
 463 
     | 
    
         
            +
              end
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
              def username_page()
         
     | 
| 
      
 466 
     | 
    
         
            +
                @last_key = Gosu::KB_RETURN
         
     | 
| 
      
 467 
     | 
    
         
            +
                self.text_input = @menu_textfield
         
     | 
| 
      
 468 
     | 
    
         
            +
                @menu_textfield.text = "#{@cfg.data['username']}"
         
     | 
| 
      
 469 
     | 
    
         
            +
                @state = STATE_MENU
         
     | 
| 
      
 470 
     | 
    
         
            +
                @menu_page = MENU_USERNAME
         
     | 
| 
      
 471 
     | 
    
         
            +
              end
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
              def toggle_fullscreen()
         
     | 
| 
      
 474 
     | 
    
         
            +
                if @cfg.data['fullscreen']
         
     | 
| 
      
 475 
     | 
    
         
            +
                  @cfg.data['fullscreen'] = self.fullscreen = false
         
     | 
| 
      
 476 
     | 
    
         
            +
                else
         
     | 
| 
      
 477 
     | 
    
         
            +
                  @cfg.data['fullscreen'] = self.fullscreen = true
         
     | 
| 
      
 478 
     | 
    
         
            +
                end
         
     | 
| 
      
 479 
     | 
    
         
            +
              end
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
              def init_menu()
         
     | 
| 
      
 482 
     | 
    
         
            +
                @menu_items = []
         
     | 
| 
      
 483 
     | 
    
         
            +
                add_menu_item("[c]onnect", Proc.new { connect_menu() })
         
     | 
| 
      
 484 
     | 
    
         
            +
                add_menu_item("username", Proc.new { username_page() })
         
     | 
| 
      
 485 
     | 
    
         
            +
                add_menu_item("fullscreen", Proc.new { toggle_fullscreen() })
         
     | 
| 
      
 486 
     | 
    
         
            +
                add_menu_item("[q]uit", Proc.new { exit() })
         
     | 
| 
      
 487 
     | 
    
         
            +
              end
         
     | 
| 
      
 488 
     | 
    
         
            +
             
     | 
| 
      
 489 
     | 
    
         
            +
              def add_menu_item(name, callback)
         
     | 
| 
      
 490 
     | 
    
         
            +
                @menu_items.push([name, callback])
         
     | 
| 
      
 491 
     | 
    
         
            +
              end
         
     | 
| 
      
 492 
     | 
    
         
            +
            end
         
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            def draw_scoreboard(win_size_x, win_size_y, players, font)
         
     | 
| 
      
 3 
     | 
    
         
            +
                # TODO: do not compute those every frame
         
     | 
| 
      
 4 
     | 
    
         
            +
                padX = win_size_x / 3
         
     | 
| 
      
 5 
     | 
    
         
            +
                sizeX = win_size_x / 3
         
     | 
| 
      
 6 
     | 
    
         
            +
                padY = win_size_y / 6
         
     | 
| 
      
 7 
     | 
    
         
            +
                sizeY = win_size_y / 3
         
     | 
| 
      
 8 
     | 
    
         
            +
                slot_height = sizeY / MAX_CLIENTS
         
     | 
| 
      
 9 
     | 
    
         
            +
                text_scale = slot_height / 15
         
     | 
| 
      
 10 
     | 
    
         
            +
                # background
         
     | 
| 
      
 11 
     | 
    
         
            +
                draw_rect(padX, padY, sizeX, sizeY+3, 0xaa000000)
         
     | 
| 
      
 12 
     | 
    
         
            +
                # left border
         
     | 
| 
      
 13 
     | 
    
         
            +
                draw_rect(padX, padY, 3, sizeY+3, 0xaa000000)
         
     | 
| 
      
 14 
     | 
    
         
            +
                # right border
         
     | 
| 
      
 15 
     | 
    
         
            +
                draw_rect(padX + sizeX - 3, padY, 3, sizeY+3, 0xaa000000)
         
     | 
| 
      
 16 
     | 
    
         
            +
                (0..MAX_CLIENTS).each do |i|
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # row borders
         
     | 
| 
      
 18 
     | 
    
         
            +
                    draw_rect(padX + 3, padY + (i * slot_height), sizeX - 6, 3, 0xaa000000)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
                players.each_with_index do | player, i |
         
     | 
| 
      
 21 
     | 
    
         
            +
                    score_offset = text_scale * 10 * player.score.to_s.length
         
     | 
| 
      
 22 
     | 
    
         
            +
                    font.draw_text(player.name, padX + 5, padY + (i * slot_height), 0, text_scale, text_scale)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    font.draw_text(player.score, padX + sizeX - score_offset, padY + (i * slot_height), 0, text_scale, text_scale)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/client/test.rb
    ADDED
    
    | 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../share/player'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            def server_package_to_player_strs(slots, data)
         
     | 
| 
      
 4 
     | 
    
         
            +
              players = []
         
     | 
| 
      
 5 
     | 
    
         
            +
              slots.times do |index|
         
     | 
| 
      
 6 
     | 
    
         
            +
                players[index] = data[index * 8..index * 8 + 7]
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              players
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            def player_strs_to_objects(player_strs)
         
     | 
| 
      
 12 
     | 
    
         
            +
              players = []
         
     | 
| 
      
 13 
     | 
    
         
            +
              player_strs.each do |player_str|
         
     | 
| 
      
 14 
     | 
    
         
            +
                id = player_str[0..1].to_i
         
     | 
| 
      
 15 
     | 
    
         
            +
                x = player_str[2..4].to_i
         
     | 
| 
      
 16 
     | 
    
         
            +
                y = player_str[5..7].to_i
         
     | 
| 
      
 17 
     | 
    
         
            +
                # puts "id: #{id} x: #{x} y: #{y}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                players << Player.new(id, x, y) unless id.zero?
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              players
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            def server_package_to_player_array(data)
         
     | 
| 
      
 24 
     | 
    
         
            +
              # /(?<count>\d{2})(?<player>(?<id>\d{2})(?<x>\d{3})(?<y>\d{3}))/
         
     | 
| 
      
 25 
     | 
    
         
            +
              slots = data[0..1].to_i # save slots
         
     | 
| 
      
 26 
     | 
    
         
            +
              data = data[2..-1] # cut slots off
         
     | 
| 
      
 27 
     | 
    
         
            +
              players = server_package_to_player_strs(slots, data)
         
     | 
| 
      
 28 
     | 
    
         
            +
              # puts players
         
     | 
| 
      
 29 
     | 
    
         
            +
              player_strs_to_objects(players)
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            # 3 players
         
     | 
| 
      
 33 
     | 
    
         
            +
            pl3 = '03011001010220020203300303'
         
     | 
| 
      
 34 
     | 
    
         
            +
            p server_package_to_player_array(pl3)
         
     | 
| 
      
 35 
     | 
    
         
            +
            p server_package_to_player_array(pl3).count
         
     | 
| 
      
 36 
     | 
    
         
            +
            # 2 players (first has id 00 -> offline)
         
     | 
| 
      
 37 
     | 
    
         
            +
            pl2 = '03001001010220020203300303'
         
     | 
| 
      
 38 
     | 
    
         
            +
            p server_package_to_player_array(pl2)
         
     | 
| 
      
 39 
     | 
    
         
            +
            p server_package_to_player_array(pl2).count
         
     | 
    
        data/lib/client/text.rb
    ADDED
    
    | 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # https://github.com/gosu/gosu-examples/blob/master/examples/text_input.rb
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "gosu"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class TextField < Gosu::TextInput
         
     | 
| 
      
 5 
     | 
    
         
            +
              FONT = Gosu::Font.new(60)
         
     | 
| 
      
 6 
     | 
    
         
            +
              WIDTH = 800
         
     | 
| 
      
 7 
     | 
    
         
            +
              LENGTH_LIMIT = 20
         
     | 
| 
      
 8 
     | 
    
         
            +
              PADDING = 5
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              INACTIVE_COLOR  = 0xcc_666666
         
     | 
| 
      
 11 
     | 
    
         
            +
              ACTIVE_COLOR    = 0xcc_555555
         
     | 
| 
      
 12 
     | 
    
         
            +
              SELECTION_COLOR = 0xcc_444444
         
     | 
| 
      
 13 
     | 
    
         
            +
              CARET_COLOR     = 0xff_ffffff
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
              attr_reader :x, :y
         
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
              def initialize(window, x, y)
         
     | 
| 
      
 18 
     | 
    
         
            +
                # It's important to call the inherited constructor.
         
     | 
| 
      
 19 
     | 
    
         
            +
                super()
         
     | 
| 
      
 20 
     | 
    
         
            +
                
         
     | 
| 
      
 21 
     | 
    
         
            +
                @window, @x, @y = window, x, y
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                # Start with a self-explanatory text in each field.
         
     | 
| 
      
 24 
     | 
    
         
            +
                self.text = "Click to edit"
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              # In this example, we use the filter method to prevent the user from entering a text that exceeds
         
     | 
| 
      
 28 
     | 
    
         
            +
              # the length limit. However, you can also use this to blacklist certain characters, etc.
         
     | 
| 
      
 29 
     | 
    
         
            +
              def filter new_text
         
     | 
| 
      
 30 
     | 
    
         
            +
                allowed_length = [LENGTH_LIMIT - text.length, 0].max
         
     | 
| 
      
 31 
     | 
    
         
            +
                new_text[0, allowed_length]
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              def draw(z)
         
     | 
| 
      
 35 
     | 
    
         
            +
                # Change the background colour if this is the currently selected text field.
         
     | 
| 
      
 36 
     | 
    
         
            +
                if @window.text_input == self
         
     | 
| 
      
 37 
     | 
    
         
            +
                  color = ACTIVE_COLOR
         
     | 
| 
      
 38 
     | 
    
         
            +
                else
         
     | 
| 
      
 39 
     | 
    
         
            +
                  color = INACTIVE_COLOR
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
                # ChillerDragon's epic shadow to at least have edited the stolen sample a lil bit
         
     | 
| 
      
 42 
     | 
    
         
            +
                Gosu.draw_rect (x - PADDING) + 5, (y - PADDING) + 5, WIDTH + 2 * PADDING, height + 2 * PADDING, INACTIVE_COLOR, z
         
     | 
| 
      
 43 
     | 
    
         
            +
                Gosu.draw_rect x - PADDING, y - PADDING, WIDTH + 2 * PADDING, height + 2 * PADDING, color, z
         
     | 
| 
      
 44 
     | 
    
         
            +
                Gosu.draw_rect x - PADDING, y - PADDING, WIDTH + 2 * PADDING, height + 2 * PADDING, color, z
         
     | 
| 
      
 45 
     | 
    
         
            +
                
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Calculate the position of the caret and the selection start.
         
     | 
| 
      
 47 
     | 
    
         
            +
                pos_x = x + FONT.text_width(self.text[0...self.caret_pos])
         
     | 
| 
      
 48 
     | 
    
         
            +
                sel_x = x + FONT.text_width(self.text[0...self.selection_start])
         
     | 
| 
      
 49 
     | 
    
         
            +
                sel_w = pos_x - sel_x
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                # Draw the selection background, if any. (If not, sel_x and pos_x will be
         
     | 
| 
      
 52 
     | 
    
         
            +
                # the same value, making this a no-op call.)
         
     | 
| 
      
 53 
     | 
    
         
            +
                Gosu.draw_rect sel_x, y, sel_w, height, SELECTION_COLOR, z
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                # Draw the caret if this is the currently selected field.
         
     | 
| 
      
 56 
     | 
    
         
            +
                if @window.text_input == self
         
     | 
| 
      
 57 
     | 
    
         
            +
                  Gosu.draw_line pos_x, y, CARET_COLOR, pos_x, y + height, CARET_COLOR, z
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                # Finally, draw the text itself!
         
     | 
| 
      
 61 
     | 
    
         
            +
                FONT.draw_text self.text, x, y, z
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
              
         
     | 
| 
      
 64 
     | 
    
         
            +
              def height
         
     | 
| 
      
 65 
     | 
    
         
            +
                FONT.height
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              # Hit-test for selecting a text field with the mouse.
         
     | 
| 
      
 69 
     | 
    
         
            +
              def under_mouse?
         
     | 
| 
      
 70 
     | 
    
         
            +
                @window.mouse_x > x - PADDING and @window.mouse_x < x + WIDTH + PADDING and
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @window.mouse_y > y - PADDING and @window.mouse_y < y + height + PADDING
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
              
         
     | 
| 
      
 74 
     | 
    
         
            +
              # Tries to move the caret to the position specifies by mouse_x
         
     | 
| 
      
 75 
     | 
    
         
            +
              def move_caret_to_mouse
         
     | 
| 
      
 76 
     | 
    
         
            +
                # Test character by character
         
     | 
| 
      
 77 
     | 
    
         
            +
                1.upto(self.text.length) do |i|
         
     | 
| 
      
 78 
     | 
    
         
            +
                  if @window.mouse_x < x + FONT.text_width(text[0...i])
         
     | 
| 
      
 79 
     | 
    
         
            +
                    self.caret_pos = self.selection_start = i - 1;
         
     | 
| 
      
 80 
     | 
    
         
            +
                    return
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
                # Default case: user must have clicked the right edge
         
     | 
| 
      
 84 
     | 
    
         
            +
                self.caret_pos = self.selection_start = self.text.length
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     |