001 package org.agent; 002 003 import org.util.*; 004 import org.util.xml.io.*; 005 import org.util.xml.element.*; 006 import org.*; 007 import java.awt.*; 008 import javax.swing.*; 009 import java.awt.geom.*; 010 import java.awt.image.*; 011 import java.awt.event.*; 012 013 public class FieldPanel extends JComponent { 014 015 private BufferedImage image_; 016 private WorldData world_data_; 017 private double center_x_; 018 private double center_y_; 019 private double zoom_x_ = -1.0; 020 private double zoom_y_ = -1.0; 021 private double pole_rad_view_width_; 022 private double orientation_view_width_; 023 private double agent_view_r_ = 4; 024 private double dot_view_r_ = 2; 025 private Stroke line_stroke_; 026 private Stroke orientation_stroke_; 027 private Graphics2D user_graphics_access_; 028 private Graphics2D user_graphics_access_no_translated_; 029 030 public FieldPanel() { 031 setPreferredSize(new Dimension(400, 300)); 032 addComponentListener(new ComponentAdapter(){ 033 public void componentResized(ComponentEvent e) { 034 createImage(); 035 } 036 }); 037 addMouseWheelListener(new MouseWheelListener(){ 038 public void mouseWheelMoved(MouseWheelEvent e) { 039 int r = e.getWheelRotation(); 040 if(r<0) { 041 zoom_x_ *= 0.9; 042 zoom_y_ *= 0.9; 043 } else { 044 zoom_x_ *= 1.1; 045 zoom_y_ *= 1.1; 046 } 047 draw(); 048 } 049 }); 050 } 051 052 public void createImage() { 053 int w = getWidth(); 054 int h = getHeight(); 055 if(image_==null || image_.getWidth()<w || image_.getHeight()<h) 056 image_ = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 057 try{ 058 draw(); 059 }catch(Exception e){ 060 e.printStackTrace(); 061 } 062 } 063 064 public void update(WorldData world_data) { 065 world_data_ = world_data; 066 try{ 067 draw(); 068 }catch(Exception e){ 069 e.printStackTrace(); 070 } 071 } 072 073 public void draw() { 074 075 int w = getWidth(); 076 int h = getHeight(); 077 center_x_ = w/2; 078 center_y_ = h/2; 079 pole_rad_view_width_ = 3; 080 orientation_view_width_ = 5; 081 line_stroke_ = new BasicStroke((float)3); 082 orientation_stroke_ = new BasicStroke((float)2); 083 084 if(image_ == null) { 085 new Thread(new Runnable(){public void run(){ 086 createImage(); 087 }}).start(); 088 return; 089 } 090 user_graphics_access_ = null; 091 Graphics2D g2 = (Graphics2D)image_.getGraphics(); 092 Graphics2D g2_no_translated = (Graphics2D)g2.create(); 093 // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 094 g2.setColor(Color.green); 095 g2.fillRect(0, 0, w, h); 096 097 if(world_data_ == null) { 098 g2.setFont(g2.getFont().deriveFont((float)30)); 099 g2.setColor(Color.red); 100 g2.drawString("No data", 10, 40); 101 return; 102 } 103 104 double tblength = world_data_.topRightCorner().sub(world_data_.bottomRightCorner()).dis(); 105 agent_view_r_ = 0.03*tblength; 106 if(zoom_x_ == -1) { 107 zoom_y_ = getHeight()/tblength; 108 zoom_x_ = zoom_y_; 109 } 110 111 //g2.rotate(-Math.PI/2); 112 113 g2.translate(center_x_, center_y_); 114 g2.scale(zoom_x_, zoom_y_); 115 116 g2.setColor(Color.white); 117 g2.setStroke(line_stroke_); 118 drawLine(g2, world_data_.bottomRightCorner(), world_data_.bottomLeftCorner()); 119 drawLine(g2, world_data_.bottomRightCorner(), world_data_.topRightCorner()); 120 drawLine(g2, world_data_.topLeftCorner(), world_data_.topRightCorner()); 121 drawLine(g2, world_data_.topLeftCorner(), world_data_.bottomLeftCorner()); 122 123 drawLine(g2, world_data_.topCenter(), world_data_.bottomCenter()); 124 125 drawLine(g2, world_data_.bottomRightPole(), world_data_.topRightSmallArea()); 126 drawLine(g2, world_data_.topRightSmallArea(), world_data_.bottomRightSmallArea()); 127 drawLine(g2, world_data_.bottomRightSmallArea(), world_data_.topRightPole()); 128 129 drawLine(g2, world_data_.bottomLeftPole(), world_data_.topLeftSmallArea()); 130 drawLine(g2, world_data_.topLeftSmallArea(), world_data_.bottomLeftSmallArea()); 131 drawLine(g2, world_data_.bottomLeftSmallArea(), world_data_.topLeftPole()); 132 133 drawDot(g2, world_data_.bottomLeftGoal(), dot_view_r_); 134 drawDot(g2, world_data_.bottomRightGoal(), dot_view_r_); 135 drawDot(g2, world_data_.topLeftGoal(), dot_view_r_); 136 drawDot(g2, world_data_.topRightGoal(), dot_view_r_); 137 138 g2_no_translated.setColor(Color.black); 139 g2_no_translated.drawString(String.valueOf(world_data_.time()), 10, 10); 140 141 142 g2.setStroke(orientation_stroke_); 143 g2.setColor(Color.blue); 144 AgentState[] team_mate_list = world_data_.teamMates(); 145 for(AgentState team_mate : team_mate_list) 146 drawAgent(g2, team_mate); 147 148 g2.setColor(Color.red); 149 AgentState[] opponent_list = world_data_.opponents(); 150 for(AgentState opponent : opponent_list) 151 drawAgent(g2, opponent); 152 153 Vector ball = world_data_.ball(); 154 g2.setColor(Color.black); 155 drawDot(g2, ball, 5); 156 g2.setColor(Color.white); 157 drawDot(g2, ball, 4); 158 // drawString(g2_no_translated, "ball", ball); 159 160 g2.setColor(Color.gray); 161 g2.fill(new Arc2D.Double(-agent_view_r_, -agent_view_r_, agent_view_r_*2, agent_view_r_*2, 0, 360, Arc2D.CHORD)); 162 163 g2.setColor(Color.black); 164 165 user_graphics_access_ = g2; 166 user_graphics_access_no_translated_ = g2_no_translated; 167 168 repaint(); 169 } 170 171 /** 172 * you can set Color, Strock or RenderingHints for your draw. 173 */ 174 public Graphics2D getUserGraphicsAccess() throws Exception { 175 if(user_graphics_access_ == null) throw new Exception("cannot write while drawing by system."); 176 return user_graphics_access_; 177 } 178 179 180 181 /** 182 * repaint() have to call after this method. 183 */ 184 private void drawLine(Graphics2D g2, Vector v1, Vector v2) { 185 // g2.draw(new Line2D.Double(v1.calcX(), v1.calcY(), v2.calcX(), v2.calcY())); 186 g2.draw(new Line2D.Double(v1.calcY(), -v1.calcX(), v2.calcY(), -v2.calcX())); 187 } 188 private void drawDot(Graphics2D g2, Vector v, double r) { 189 // g2.fill(new Arc2D.Double(v.calcX()-r, v.calcY()-r-1, r+r+1, r+r+1, 0, 360, Arc2D.CHORD)); 190 g2.fill(new Arc2D.Double(v.calcY()-r, -v.calcX()-r-1, r+r+1, r+r+1, 0, 360, Arc2D.CHORD)); 191 } 192 private void drawString(Graphics2D g2, String message, Vector v) { 193 // g2.drawString(message, (int)(v.calcX()*zoom_x_+center_x_+3), (int)(v.calcY()*zoom_y_+center_y_-3)); 194 g2.drawString(message, (int)(v.calcY()*zoom_x_+center_x_+3), (int)(-v.calcX()*zoom_y_+center_y_-3)); 195 } 196 197 198 199 200 201 private void drawAgent(Graphics2D g2, AgentState agent) { 202 if(agent==null) return ; 203 org.util.Vector location = agent.getLocation(); 204 org.util.Vector orientation = agent.getOrientation(); 205 if(location == null) return ; 206 double r = agent_view_r_; 207 Color c = g2.getColor(); 208 g2.setColor(Color.black); 209 drawDot(g2, location, r+1); 210 g2.setColor(c); 211 drawDot(g2, location, r); 212 g2.setColor(Color.black); 213 drawLine(g2, location, location.add(orientation.normalize(10))); 214 g2.setColor(c); 215 } 216 217 218 public void drawLine(Vector v1, Vector v2) { 219 try{ 220 Graphics2D g2 = getUserGraphicsAccess(); 221 drawLine(g2, v1, v2); 222 repaint(); 223 }catch(Exception e){ 224 e.printStackTrace(); 225 } 226 } 227 public void drawDot(Vector v) { 228 try{ 229 Graphics2D g2 = getUserGraphicsAccess(); 230 drawDot(g2, v, 3); 231 repaint(); 232 }catch(Exception e){ 233 e.printStackTrace(); 234 } 235 } 236 public void drawString(String message, Vector v) { 237 try{ 238 Graphics2D g2 = getUserGraphicsAccess(); 239 g2 = user_graphics_access_no_translated_; 240 drawString(g2, message, v); 241 repaint(); 242 }catch(Exception e){ 243 e.printStackTrace(); 244 } 245 } 246 247 public void paint(Graphics g) { 248 int w = getWidth(); 249 int h = getHeight(); 250 if(image_ == null) { 251 g.drawString("now loading...", 10, 10); 252 new Thread(new Runnable(){public void run(){ 253 createImage(); 254 }}).start(); 255 } else 256 g.drawImage(image_, 0, 0, this); 257 } 258 259 public static void alert(Object message) { 260 System.out.println(message); 261 } 262 } 263 264 /* 265 <WorldData> 266 <time>5.25131</time> 267 <agent_id>0</agent_id> 268 <nickname>player1</nickname> 269 <status>found</status> 270 <max_agent>2</max_agent> 271 <playMode>play on</playMode> 272 <score> 273 <yellow>0</yellow> 274 <blue>0</blue> 275 </score> 276 <wheel_velocities> 277 <right>0</right> 278 <left>0</left> 279 </wheel_velocities> 280 <ball> 281 <dist>117</dist> 282 <angle>39</angle> 283 </ball> 284 <teamMate> 285 <id>1</id> 286 <nickname>player2</nickname> 287 <status>found</status> 288 <dist>89</dist> 289 <angle>48</angle> 290 <orientation>107</orientation> 291 </teamMate> 292 <opponent> 293 <id>5</id> 294 <nickname>player7</nickname> 295 <status>found</status> 296 <dist>167</dist> 297 <angle>46</angle> 298 <orientation>161</orientation> 299 </opponent> 300 <flag> 301 <id>top_left_pole</id> 302 <dist>152</dist> 303 <angle>-59</angle> 304 </flag> 305 <flag> 306 <id>bottom_left_pole</id> 307 <dist>116</dist> 308 <angle>-83</angle> 309 </flag> 310 <flag> 311 <id>top_right_pole</id> 312 <dist>310</dist> 313 <angle>57</angle> 314 </flag> 315 <flag> 316 <id>bottom_right_pole</id> 317 <dist>294</dist> 318 <angle>69</angle> 319 </flag> 320 <flag> 321 <id>top_left_corner</id> 322 <dist>236</dist> 323 <angle>-40</angle> 324 </flag> 325 <flag> 326 <id>bottom_left_corner</id> 327 <dist>126</dist> 328 <angle>-133</angle> 329 </flag> 330 <flag> 331 <id>top_right_corner</id> 332 <dist>359</dist> 333 <angle>41</angle> 334 </flag> 335 <flag> 336 <id>bottom_right_corner</id> 337 <dist>298</dist> 338 <angle>89</angle> 339 </flag> 340 <flag> 341 <id>top_left_goal</id> 342 <dist>148</dist> 343 <angle>-8</angle> 344 </flag> 345 <flag> 346 <id>bottom_left_goal</id> 347 <dist>14</dist> 348 <angle>85</angle> 349 </flag> 350 <flag> 351 <id>top_right_goal</id> 352 <dist>224</dist> 353 <angle>36</angle> 354 </flag> 355 <flag> 356 <id>bottom_right_goal</id> 357 <dist>169</dist> 358 <angle>78</angle> 359 </flag> 360 <flag> 361 <id>top_left_small_area</id> 362 <dist>83</dist> 363 <angle>-74</angle> 364 </flag> 365 <flag> 366 <id>bottom_left_small_area</id> 367 <dist>128</dist> 368 <angle>-48</angle> 369 </flag> 370 <flag> 371 <id>top_right_small_area</id> 372 <dist>259</dist> 373 <angle>68</angle> 374 </flag> 375 <flag> 376 <id>bottom_right_small_area</id> 377 <dist>277</dist> 378 <angle>55</angle> 379 </flag> 380 <flag> 381 <id>middle_center</id> 382 <dist>117</dist> 383 <angle>39</angle> 384 </flag> 385 <flag> 386 <id>top_center</id> 387 <dist>229</dist> 388 <angle>11</angle> 389 </flag> 390 <flag> 391 <id>bottom_center</id> 392 <dist>112</dist> 393 <angle>112</angle> 394 </flag> 395 </WorldData> 396 */