00001 /* 00002 * $Id: RCViewPort_8java-source.html,v 1.2 2002/07/07 20:59:52 stork Exp $ 00003 * 00004 * $Log: RCViewPort_8java-source.html,v $ 00004 * Revision 1.2 2002/07/07 20:59:52 stork 00004 * update dokumenation 00004 * 00005 * Revision 1.5 2002/07/04 19:02:20 oliver 00006 * # clipping algorithm: all objects outside of viewing cone are no longer displayed 00007 * # debugged display of viewing cone: angle and line length displayed correctly now 00008 * 00009 * Revision 1.4 2002/07/02 22:40:15 oliver 00010 * # Viewing cone of current player 00011 * # goal line and middle line 00012 * # all other players visible 00013 * 00014 * Revision 1.3 2002/06/23 12:58:12 oliver 00015 * - RCViewPort inherits from JComponent now --> double buffering -->no flickering 00016 * - Display of each players quad & the ball 00017 * 00018 * Revision 1.2 2002/06/17 15:33:20 oliver 00019 * Update of RCDisplay & RCViewport; first step of visualisation: 00020 * Window popup, own player and lines visible 00021 * 00022 * Revision 1.1.1.1 2002/05/21 20:32:06 stork 00023 * empty project 00024 * 00025 */ 00026 00027 import javax.swing.*; 00028 import javax.swing.border.*; 00029 import java.awt.*; 00030 import java.awt.event.*; 00031 import java.io.*; 00032 import java.math.*; 00033 00034 00035 public class RCViewPort extends JComponent implements RCType 00036 { 00037 public RCWorld World; 00038 public int Width; // default width 00039 public int Height; // default height 00040 public int Scale; // scaling factor 00041 public int Border; // border in pixel 00042 00043 00048 public RCViewPort(RCWorld World) 00049 { 00050 this.World = World; 00051 this.Width = 105; 00052 this.Height = 68; 00053 this.Scale = 4; 00054 this.Border = 5; 00055 } 00056 00057 00064 public void paint( Graphics g ) 00065 { 00066 // does the actual drawing 00067 g.setColor(new Color(0,130,0)); // the grass is green 00068 g.fillRect(0,0, Width*Scale+2*Border, 00069 Height*Scale+2*Border); 00070 00071 // draw the lines 00072 g.setColor(Color.white); 00073 g.drawLine(Border, Border, Border+Width*Scale, Border); // borderlines 00074 g.drawLine(Border+Width*Scale, Border, Border+Width*Scale,Border+Height*Scale); 00075 g.drawLine(Border+Width*Scale, Border+Height*Scale, Border, Border+Height*Scale); 00076 g.drawLine(Border, Border, Border, Border+Height*Scale); 00077 00078 g.drawLine( transX(0.0), transY(-34.0), transX(0.0), transY(34.0) ); // middleline 00079 00080 g.setColor(Color.black); 00081 g.drawLine( transX(-52.5), transY(-7.01), transX(-52.5), transY(7.01) ); // goalmouth on the right 00082 g.drawLine( transX( 52.5), transY(-7.01), transX( 52.5), transY(7.01) ); // goalmouth on the left 00083 00084 00085 00086 // draw current player 00087 RCObject player = World.getOurself(); 00088 g.setColor(Color.blue); 00089 g.drawOval( transX((World.getOurself()).X(0)), // "the loonatic is on the grass ..." 00090 transY((World.getOurself()).Y(0)), 5, 5); // (Pink Floyd, Dark Side Tf The Moon) 00091 00092 // draw the current player-sectors 00093 g.setColor(Color.yellow); 00094 00095 g.drawLine( transX(World.X1), transY(World.Y1), 00096 transX(World.X2), transY(World.Y1) ); 00097 00098 g.drawLine( transX(World.X2), transY(World.Y1), 00099 transX(World.X2), transY(World.Y2) ); 00100 00101 g.drawLine( transX(World.X1), transY(World.Y2), 00102 transX(World.X2), transY(World.Y2) ); 00103 00104 g.drawLine( transX(World.X1), transY(World.Y1), 00105 transX(World.X1), transY(World.Y2) ); 00106 00107 00108 00109 // draw the current player's viewing cone (visible_distance 3.0 & visible_angle 90.0 deg & 00110 // team_too_far_length 60.0) 00111 00112 int selfX = transX((World.getOurself()).X(0)); 00113 int selfY = transY((World.getOurself()).Y(0)); 00114 00115 int linksX=transX((World.getOurself()).X(0) + 60.0*(Math.cos( ((World.angle-45)/180)*Math.PI))); 00116 int linksY=transY((World.getOurself()).Y(0) + 60.0*(Math.sin( ((World.angle-45)/180)*Math.PI))) ; 00117 00118 g.setColor(Color.yellow); 00119 g.drawLine( selfX, selfY, linksX, linksY ); 00120 00121 00122 int mitteX=transX((World.getOurself()).X(0) + 60.0*(Math.cos( (World.angle/180)*Math.PI ))); 00123 int mitteY=transY((World.getOurself()).Y(0) + 60.0*(Math.sin( (World.angle/180)*Math.PI ))); 00124 00125 g.setColor(Color.red); 00126 g.drawLine( selfX, selfY, mitteX, mitteY ); 00127 00128 00129 int rechtsX=transX((World.getOurself()).X(0) + 60.0*(Math.cos( ((World.angle+45)/180)*Math.PI))); 00130 int rechtsY=transY((World.getOurself()).Y(0) + 60.0*(Math.sin( ((World.angle+45)/180)*Math.PI))); 00131 00132 g.setColor(Color.blue); 00133 g.drawLine( selfX, selfY, rechtsX, rechtsY ); 00134 00135 00136 00137 00138 // draw the ball if visible 00139 00140 g.setColor(Color.white); 00141 00142 if ( in( transX(World.Ball.X(0)), transY(World.Ball.Y(0)), 00143 selfX , selfY, 00144 linksX , linksY, 00145 mitteX , mitteY, 00146 rechtsX, rechtsY ) == true ) 00147 { g.drawOval(transX(World.Ball.X(0)), transY(World.Ball.Y(0)), 5, 5); } 00148 00149 00150 00151 // draw the enemy 00152 00153 g.setColor(Color.red); 00154 for (int x = 0; x < 11; x++) 00155 { 00156 if ( in( transX(World.Enemies[x].X(0)), transY(World.Enemies[x].Y(0)), 00157 selfX , selfY, 00158 linksX , linksY, 00159 mitteX , mitteY, 00160 rechtsX, rechtsY ) == true ) 00161 { g.drawOval(transX(World.Enemies[x].X(0)), transY(World.Enemies[x].Y(0)), 3, 3); } 00162 } 00163 00164 00165 00166 // draw the friends 00167 00168 g.setColor(Color.blue); 00169 00170 for (int x = 0; x < 11; x++) 00171 { 00172 if ( in( transX(World.Friends[x].X(0)), transY(World.Friends[x].Y(0)), 00173 selfX , selfY, 00174 linksX , linksY, 00175 mitteX , mitteY, 00176 rechtsX, rechtsY ) == true ) 00177 { g.drawOval(transX(World.Friends[x].X(0)), transY(World.Friends[x].Y(0)), 3, 3); } 00178 } 00179 } 00180 00181 00182 00183 00191 public int ccw( int x0, int y0, 00192 int x1, int y1, 00193 int x2, int y2 ) 00194 { 00195 int dx1, dx2, dy1, dy2; 00196 00197 dx1 = x1 - x0; 00198 dy1 = y1 - y0; 00199 dx2 = x2 - x0; 00200 dy2 = y2 - y0; 00201 00202 if ( dx1*dy2 > dy1*dx2 ) return +1; 00203 if ( dx1*dy2 < dy1*dx2 ) return -1; 00204 00205 if ((dx1*dx2 < 0) || (dy1*dy2 < 0)) return -1; 00206 if ((dx1*dx1 + dy1*dy1) < (dx2*dx2 + dy2*dy2)) return +1; 00207 00208 return 0; 00209 } 00210 00211 00212 00222 public boolean intersect( int l1_x1, int l1_y1, 00223 int l1_x2, int l1_y2, 00224 int l2_x1, int l2_y1, 00225 int l2_x2, int l2_y2 ) 00226 { 00227 return ((( ccw(l1_x1, l1_y1, 00228 l1_x2, l1_y2, 00229 l2_x1, l2_y1 ) * ccw(l1_x1, l1_y1, 00230 l1_x2, l1_y2, 00231 l2_x2, l2_y2)) <= 0) && 00232 (( ccw(l2_x1, l2_y1, 00233 l2_x2, l2_y2, 00234 l1_x1, l1_y1 ) * ccw(l2_x1, l2_y1, 00235 l2_x2, l2_y2, 00236 l1_x2, l1_y2)) <= 0)); 00237 } 00238 00239 00240 00249 public boolean in(int x , int y , // Is THIS given point within the polygon defined by ... 00250 int x0, int y0, // 00251 int x1, int y1, // 00252 int x2, int y2, // 00253 int x3, int y3 ) // ... these vertices? 00254 00255 { 00256 int count=0; 00257 00258 if (intersect(x, y, 0, -34, x0, y0, x1, y1)) count++; 00259 if (intersect(x, y, 0, -34, x1, y1, x2, y2)) count++; 00260 if (intersect(x, y, 0, -34, x2, y2, x3, y3)) count++; 00261 if (intersect(x, y, 0, -34, x3, y3, x0, y0)) count++; 00262 00263 if ( count%2 != 0) return true; // odd number of crossing points: point is within! 00264 else return false; // otherwise it isn't. 00265 } 00266 00267 00268 00269 00270 00276 public Dimension getPreferredSize() 00277 { 00278 return new Dimension(Width*Scale+2*Border, 00279 Height*Scale+2*Border); 00280 } 00281 00282 00286 public Dimension getMinimumSize() 00287 { 00288 return new Dimension(Width*Scale+2*Border, 00289 Height*Scale+2*Border); 00290 } 00291 00292 00296 public Dimension getSize() 00297 { 00298 return new Dimension(Width*Scale+2*Border, 00299 Height*Scale+2*Border); 00300 } 00301 00302 00303 00310 public int transX( double x ) 00311 { 00312 if( World.Side == LEFT ) 00313 { 00314 // return Math.abs((int)((Border+Scale*Width/2.0)+Scale*x)); 00315 return (int)((Border+Scale*Width/2.0)+Scale*x); 00316 } 00317 else 00318 { 00319 // return Math.abs((int)((Border+Scale*Width/2.0)-Scale*x)); 00320 return (int)((Border+Scale*Width/2.0)-Scale*x); 00321 } 00322 } 00323 00324 00325 00332 public int transY(double y) 00333 { 00334 if (World.Side == LEFT) 00335 { 00336 // return Math.abs((int)((Border+Scale*Height/2.0)+Scale*y)); 00337 return (int)((Border+Scale*Height/2.0)+Scale*y); 00338 } 00339 else 00340 { 00341 // return Math.abs((int)((Border+Scale*Height/2.0)-Scale*y)); 00342 return (int)((Border+Scale*Height/2.0)-Scale*y); 00343 } 00344 } 00345 } 00346