// (c) 1998 Ekkehard Kraemer (ekraemer@pluto.camelot.de) import java.awt.*; /** * Sorry, not documented yet. *

* Source */ class Ball extends Rectangle { Ball(BojngInterface bojng,int x,int y) { this.bojng=bojng; sprad=Images.ball.getWidth(null); if (Images.ball.getHeight(null)>sprad) sprad=Images.ball.getHeight(null); sprad=sprad/2+1; width=sprad*2; height=sprad*2; moveTo(x,y,PI.drittel); } Ball(Ball ball,double angleDisp) { width=ball.width; height=ball.height; x=ball.x; y=ball.y; sprad=ball.sprad; speed=ball.speed; angle=ball.angle+angleDisp; while (angle<0) angle+=PI.zwei; while (angle>=PI.zwei) angle-=PI.zwei; xstart=ball.xstart; ystart=ball.ystart; xspeed=ball.xspeed; yspeed=ball.yspeed; curTime=ball.curTime; xcur=ball.xcur; ycur=ball.ycur; bounceBottom=ball.bounceBottom; bojng=ball.bojng; } void moveTo(int x,int y) { moveTo(x,y,angle); } void moveTo(int x,int y,double a) { angle=a; while (a<0) a+=PI.zwei; while (a>=PI.zwei) a-=PI.zwei; correctAngle(); xstart=x; ystart=y-sprad/2; curTime=0; calcSpeed(); calcCurXY(); } boolean tick() { if (speedUpCntr<=0) speedUpCntr=speedUpTime/bojng.ms(); else { speedUpCntr--; if (speedUpCntr<=1) { speed+=0.2; System.err.println("speedup"); } } remove(); boolean rc=move(); draw(); return rc; } // xspeed, yspeed aus speed und angle berechnen void calcSpeed() { xstart+=xspeed*curTime; ystart+=yspeed*curTime; xspeed=Math.cos(angle)*speed; yspeed=-Math.sin(angle)*speed; } // Draws the ball on backimg void draw() { bojng.drawImage(Images.ball,x,y); //bojng._update().add(this); } // Removes the ball from backimg void remove() { bojng.drawBackground(x,y,width,height); } // Moves the ball coordinates, no drawing boolean move() { curTime++; if (bounceWalls()) return true; bounceBlocks(); return false; } void calcCurXY() { xcur=xstart+xspeed*curTime; ycur=ystart+yspeed*curTime; x=(int)(xcur-sprad); y=(int)(ycur-sprad); } boolean bounceWalls() { boolean bounceX=false,bounceY=false; double offset=0; calcCurXY(); if (xcur-sprad<0) { bounceX=true; while (xcur-sprad<0) { curTime-=0.1; offset+=0.1; calcCurXY(); } } else if (xcur+sprad>=bojng._imgwidth()) { bounceX=true; while (xcur+sprad>=bojng._imgwidth()) { curTime-=0.1; offset+=0.1; calcCurXY(); } } if (ycur-sprad<0) { bounceY=true; while (ycur-sprad<0) { curTime-=0.1; offset+=0.1; calcCurXY(); } } else if (ycur+sprad>=bojng._imgheight()) { if (bounceBottom) { bounceY=true; while (ycur+sprad>=bojng._imgheight()) { curTime-=0.1; offset+=0.1; calcCurXY(); } } else { if (ycur-sprad>=bojng._imgheight()) return true; // ball out } } if (bounceX || bounceY) { bounce(bounceX,bounceY); curTime=offset; } return false; } void bounce(boolean bounceX,boolean bounceY) { if (bounceX && bounceY) { angle=PI.PI+angle; while (angle>=PI.zwei) angle-=PI.zwei; } else { if (bounceX) { if (0<=angle && angle=PI.zwei) angle-=PI.zwei; } } if (bounceX || bounceY) { correctAngle(); xstart=xstart+xspeed*curTime; ystart=ystart+yspeed*curTime; xspeed=Math.cos(angle)*speed; yspeed=-Math.sin(angle)*speed; } } // sehr flache Winkel vermeiden void correctAngle() { double min=PI.zwanzigstel; while (angle<0) angle+=PI.zwei; while (angle>=PI.zwei) angle-=PI.zwei; if (angle>=0 && angle=PI.zwei-min && angle=PI.halbe-min && angle=PI.halbe && angle=PI.PI-min && angle=PI.PI && angle=PI.dreihalbe-min && angle=PI.dreihalbe && angle=bojng._fieldHeight()) continue; block.x=(xbl-2)*bojng._blockwidth(); for (int dx=-1; dx<2; dx++) { int x=xbl+dx; block.x+=bojng._blockwidth(); if (x<0 || x>=bojng._fieldWidth()) continue; if (x==0 && y==0) continue; if (ball.intersects(block)) { Rectangle item; if ((item=checkHitInBlock(ball,x,y))!=null) { hits[cnt++]=item; // Rectangle tmp=new Rectangle(ball); // bounceRect(tmp,item,false); } } } } if (cnt==2) { if ((hits[0].x==hits[1].x) || (hits[0].y==hits[1].y)) { System.err.println("double hit!"); bojng.hit(hits[0],this); bojng.hit(hits[1],this); Rectangle tmp=new Rectangle(ball); Rectangle r2=new Rectangle(hits[0]); r2.add(hits[1]); bounceRect(tmp,r2,false); cnt=0; } } if (cnt>1) System.err.println("---------"); double offset=0; while (cnt>1) { System.err.println("ball.bounce: cnt: "+cnt); curTime-=0.1; offset+=0.1; System.err.println("offset: "+offset); calcCurXY(); ball.x=(int)(xcur-sprad); ball.y=(int)(ycur-sprad); Rectangle[] newhits=new Item[9]; int newcnt=0; for (int t=0; t0) { hits=newhits; cnt=newcnt; } else { System.err.println("none left"); cnt=1; } System.err.println("ball.bounce: new cnt: "+cnt); } if (cnt==1) { bojng.hit(hits[0],this); Rectangle tmp=new Rectangle(ball); bounceRect(tmp,hits[0],false); } // Bounce off paddle bounceRect(ball,bojng._paddle(),true); } void bounceRect(Rectangle ball,Rectangle rect,boolean jitter) { if (!ball.intersects(rect)) return; double offset=0; while (ball.intersects(rect)) { curTime-=0.1; offset+=0.1; calcCurXY(); ball.x=(int)(xcur-sprad); ball.y=(int)(ycur-sprad); } int xd=0,yd=0; if (ball.x>=rect.x+rect.width) xd=1; else if (ball.x+ball.height<=rect.x) xd=-1; if (ball.y>=rect.y+rect.height) yd=1; else if (ball.y+ball.height<=rect.y) yd=-1; if (xd!=0 || yd!=0) { if (jitter && yd==-1) { double t=rect.x+rect.width/2-(ball.x+sprad); t/=rect.width; angle-=t; } bounce(xd!=0,yd!=0); curTime=offset; } else { System.err.println("xd==0 && yd==0 !!!!! "+ball+" "+rect); } } Rectangle checkHitInBlock(Rectangle r1,int bx,int by) { Item i=(Item)(bojng.getItem(bx,by)); if (i!=null && i.intersects(r1)) { // bojng.hit(i,this); return i; } return null; } // Ball int sprad; // Radius of sphere (Pixel) double speed=6.0; // Pixel/Tick double angle; // 0=Right, PI/2=Up double xstart,ystart; // Start position of current movement double xspeed,yspeed; // Current speeds (Pixel/Tick) double curTime=0; // Time since xstart/ystart double xcur,ycur; // Current position (Pixel, Center) boolean bounceBottom=false; // Bounce from bottom int speedUpCntr=0; int speedUpTime=10000; // Speed up every ... ms BojngInterface bojng; }