【プログラムnsa6.java】**************************

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;


class Calculator{
	double dPics(int x1,int y1,int x2,int y2){
		int dx=x2-x1;
		int dy=y2-y1;
		return Math.sqrt(dx*dx+dy*dy);
	}
	
	double dPics(Point p1,Point p2){
		return dPics(p1.x,p1.y,p2.x,p2.y);
	}	
	
	double dCount(double speed,int x1,int y1,int x2,int y2){
		return dPics(x1,y1,x2,y2)/(speed * Math.sqrt(2.0));
	}
	
	double dCount(double speed,Point p1,int x,int y){
		return dCount(speed,p1.x,p1.y,x,y);
	}
	
	double dCount(double speed,Point p1,Point p2){
		return dCount(speed,p1.x,p1.y,p2.x,p2.y);
	}
	
	double[] iPics(double speed,int x1,int y1,int x2,int y2){
		double count=dCount(speed,x1,y1,x2,y2);
		double xi=(x2-x1)/count;
		double yi=(y2-y1)/count;
		double ar[]={xi,yi};
		
		return ar;
	}
	
	double[] iPics(double speed,Point p1,Point p2){
		return iPics(speed,p1.x,p1.y,p2.x,p2.y);
	}
	
		
}

class MovingCharacter extends Calculator{
	Point p;
    int mode;
	int r;
	boolean start;
	boolean arrive;
	double speed;
	double dx,dy,tx,ty;
	Color color;
	int clw,clh;
	int rw,rh;
	
	MovingCharacter(){
		start=false;
		arrive=false;
		mode=0;
		dx=0;dy=0;tx=0;ty=0;
	}
	
	/*
	boolean reachArea(MovingCharacter mc){
		if(mc.p.x>=(p.x-rw/2) && (p.x+rw/2)>=mc.p.x && mc.p.y>=(p.y-rh/2) && (p.y+rh/2)>=mc.p.y){
			return true;
		}
		return false;
	}
	*/
	
	int punchNum(MovingCharacter mc){
		int i1=0,i2=0;
		
		if(mc.p.x<(p.x-rw/2))i1=1;//もっと左
		if((p.x+rw/2)<mc.p.x)i1=2;//もっと右
		if(mc.p.y<(p.y-rh/2))i2=10;//早すぎる
		//if((p.y+rh/2)<mc.p.y)i2=20;//遅すぎる
		if((p.y)<mc.p.y)i2=20;//遅すぎる
		
		return i1+i2;
		
	}
	
	
	
	double[] moveCount(Point p1,Point p2){
		return iPics(speed,p1.x,p1.y,p2.x,p2.y);
	}
	Point move(Point p1,Point p2){
		if(!start){
			double[] ar=moveCount(p1,p2);
			dx=ar[0];
			dy=ar[1];
			tx=p1.x;
			ty=p1.y;
			p.setLocation(p1);
			start=true;
		}
		else if(Math.abs(tx-p1.x)>=Math.abs(p2.x-p1.x) && Math.abs(ty-p1.y)>=Math.abs(p2.y-p1.y)){
			dx=0;dy=0;
			arrive=true;
		}
		else if(!arrive){
			tx+=dx;
			ty+=dy;
			p.setLocation(tx,ty);
		}
		
		
		
		return p;
	}
	Point action(Point p1,Point p2){
		return p;	
	}
}
	

class Ball extends MovingCharacter{
	Ball(){
		p=new Point();
		start=false;
		arrive=false;
    	r=4;
		speed=2.5;
		color=Color.white;
		clw=6*r;
		clh=6*r;
		mode=0;
	}

	Point action(Point p1,Point p2){
		if(arrive){
			start=false;arrive=false;
		}
		
		p=move(p1,p2);
		return p;
			
	}
	
}

class Keeper extends MovingCharacter{
	boolean punch;
	Keeper(){
		punch=false;
		p=new Point();
		start=false;
		arrive=false;
		r=5;
		speed=1;
		color=Color.red;
		clw=60*r;
		clh=2*r;
		rw=35;
		rh=35;
		
	}
	
	Point action(Point p1,Point p2){//左右に動く
		if(arrive){
			mode+=1;
			start=false;
			arrive=false;
		}
		if(mode%2==1){
			p=move(p2,p1);
		}
		else{
			p=move(p1,p2);
		}
		return p;
	}
	
}	


class Line{
	final int w=3;	
	final Color lcolor=Color.white;
}
/*
class coach{
	Image im;
	String[] words;
	coach(){
		
	}
}

*/

public class nsa6 extends java.applet.Applet implements Runnable{
	
	final int w=680;
	final int d=1050;//グランド、縦105m×横68m
	
	final int gw=74;//ゴールポストの内側が7.32m
	final int gd=15;
	final int ccr=92;//センターサークルの半径9.15m
	final int cpr=5;//センターマークの半径
	final int pmr=1;//ペナルティーマークの半径
	final int car=10;//コーナーアークの半径1m
	//final int car=100;//コーナーアークの半径1m
	
	
	
	final Color GC=new Color(50,125,50);
	final Color SC=Color.white;
	
	Line li=new Line();
	final Color LC=li.lcolor;
	
	Ball ball=new Ball();
	final Color BC=ball.color;
	int r=ball.r;
	Point bap=ball.p;//******************************************
	
	Keeper kp=new Keeper();
	final Color KC=kp.color;
	int kr=kp.r;
	Point kpp=kp.p;

	
	MovingCharacter[] mca=new  MovingCharacter[2];
	//mca[0]=ball;
	//mca[1]=kp;
	
	int spx;
	int spy;
	int i5=100;
	
	String sk;
	
	
	final Point ps=new Point(100,100);//******************************グランド上のラインの起点
    final Point pe=new Point(ps.x+w,ps.y+d);
	final Point prs=new Point(ps.x+r,ps.y+r);
    final Point pre=new Point(pe.x-r,pe.y-r);
	final Point pce=new Point(ps.x,(prs.y+pre.y)/2);//センターライン
	final Point pccc=new Point(pce.x+w/2,pce.y);//センターマーク
	final Point pglb=new Point(pccc.x-gw/2,pe.y);//ゴール、下、左
	final Point pgrb=new Point(pccc.x+gw/2,pe.y);//ゴール、下、右
	final Point pgelb=new Point(pglb.x-55,pe.y);//ゴールエリア
	final Point pgerb=new Point(pgrb.x+55,pe.y);//ゴールエリア
	final Point ppelb=new Point(pglb.x-165,pe.y);//ペナルティーエリア
	final Point pperb=new Point(pgrb.x+165,pe.y);//ペナルティーエリア
	final Point ppm=new Point(pccc.x,pe.y-110);//ペナルティーマーク
	
	
	Point pks;
	Point pke;
	
	//Thread t_kp=new Thread(this);
	

	Point pbs=new Point(pccc.x,pccc.y);
	Point pbe=new Point(pccc.x+31,pe.y+10);
	Point pbe2=new Point(500,pccc.y);
	
	Thread t_ball=new Thread(this);
	final int STOP_TIME= 10;

	Image ibuff;    /* 裏画面用Image          */
  	Graphics gb;    /* 裏イメージの描画領域用 */
	
	
    public void init() {
    	addMouseListener(new MA(this));
    	addMouseMotionListener(new MMA(this));

    	setBackground(GC);
   		ibuff= createImage(900,1300);     /* 横900×縦1300でImage生成 */
    	gb = ibuff.getGraphics();          /* 裏イメージの描画領域 */
    	gb.setFont(new Font("SansSerif",Font.BOLD,20));
    	
    	pks=new Point(pglb.x,pglb.y);
		pke=new Point(pgrb.x,pgrb.y);
    	kp.p.setLocation(pks);
    	kpp=kp.p;
    }
	
	public void start(){
    	if (t_ball != null) t_ball.start();
	}
	
	public void run() {
    	Thread ct = Thread.currentThread();
    	while (t_ball == ct) {
			repaint(bap.x-12,bap.y-12,ball.clw,ball.clh);
			//repaint();
    		switch(ball.mode){
    		case 0:
    			
    			if(!ball.start){//************************************
    				int x=(int)(1 + Math.random() * gw);
    				x+=(pccc.x-gw/2);
    				pbe.setLocation(x,pbe.y);
    				
    				x=(int)(1 + Math.random() * w);
    				x+=ps.x;
    				pbs.setLocation(x,pbs.y);
    				
    			}
    			
    			bap=ball.action(pbs,pbe);
    			if(ball.arrive)ball.start=false;
    			break;
    		case 1:
    			bap=ball.action(kpp,pbe2);
    			
    			if(ball.arrive){
    				ball.mode=0;
    				ball.start=false;
    			}
    			break;
    		}
      	try {
        	Thread.sleep (STOP_TIME);
      	}
    	catch (InterruptedException e) {}	
    	}
  	}	
		
	public void update(Graphics g) {//**********************************************************
	//	gb.setClip(bap.x-11,bap.y-11,ball.clw,ball.clh);
		paint(g);
  	}	
	
    public void paint(Graphics g) {
    	
    	gb.setColor(GC);
    	gb.fillRect(0,0,900,1300);
    	gb.setColor(LC);
    	
    	
    	//gb.fillArc(prs.x-(car+li.w)/2,pre.y-(car+li.w)/2,car+li.w,car+li.w,0,90);
    	gb.fillArc(prs.x-car/2-li.w,pre.y-car/2+li.w,car+li.w,car+li.w,0,90);
    	gb.setColor(GC);
    	gb.fillArc(prs.x-car/2-li.w,pre.y-car/2+2*li.w,car,car,0,90);
    	gb.setColor(LC);
    	
    	gb.fillRect(ps.x,ps.y,li.w,d);
    	gb.fillRect(ps.x+w,ps.y,li.w,d+li.w);
    	gb.fillRect(ps.x,ps.y,w,li.w);
    	gb.fillRect(ps.x,ps.y+d,w,li.w);
    	
    	gb.fillArc(ppm.x-ccr,ppm.y-ccr,ccr*2,ccr*2,36,108);//***
    	gb.setColor(GC);
    	gb.fillArc(ppm.x-ccr+li.w,ppm.y-ccr+li.w,(ccr-li.w)*2,(ccr-li.w)*2,35,111);
    	
    	gb.setColor(LC);
    	gb.fillRect(pccc.x-gw/2,pe.y,li.w,gd);//ゴール
    	gb.fillRect(pccc.x+gw/2,pe.y,li.w,gd);//ゴール
    	gb.fillRect(pccc.x-gw/2,pe.y+gd,gw+li.w,li.w);//ゴール
    	
    	gb.fillRect(pgelb.x,pgelb.y-55,li.w,55);//ゴールエリア
    	gb.fillRect(pgerb.x,pgelb.y-55,li.w,55);//ゴールエリア
    	gb.fillRect(pgelb.x,pgelb.y-55,pgerb.x-pgelb.x,li.w);//ゴールエリア
    	
    	gb.fillRect(ppelb.x,ppelb.y-165,li.w,165);//ペナルティーエリア
    	gb.fillRect(pperb.x,pperb.y-165,li.w,165);//ペナルティーエリア
    	gb.fillRect(ppelb.x,pgelb.y-165,pperb.x-ppelb.x,li.w);//ペナルティーエリア
    	
    	gb.fillOval(ppm.x-cpr,ppm.y-cpr,pmr*2,pmr*2);
    	
    	gb.fillOval(pccc.x-ccr,pccc.y-ccr,ccr*2,ccr*2);
    	
    	gb.setColor(GC);
    	gb.fillOval(pccc.x-ccr+li.w,pccc.y-ccr+li.w,(ccr-li.w)*2,(ccr-li.w)*2);
    	
    	
    	gb.setColor(LC);
    	gb.fillOval(pccc.x-cpr,pccc.y-cpr,cpr*2,cpr*2);
    	gb.fillRect(pce.x,pce.y,w,li.w);
       
    	gb.setColor(BC);
    	gb.fillOval(bap.x-r,bap.y-r,r*2,r*2);
    	
    	gb.setColor(KC);
    	gb.fillOval(kpp.x-kr,kpp.y-kr,kr*2,kr*2);
    	//gb.drawRect(kpp.x-kp.rw/2,kpp.y-kp.rh/2,kp.rw,kp.rh);
    	
    	gb.setColor(SC);
    	gb.drawString("bap.x:"+bap.x,200,200);
    	gb.drawString("bap.y:"+bap.y,200,230);
    	gb.drawString("peb.x:"+pbe.x,pglb.x,pglb.y+90);
    	gb.drawString("arrive:"+kp.arrive,200,320);
    	
    	//gb.drawString("Punch! : "+kp.punch,pgelb.x,pgelb.y+50);
    	if(i5==0)sk="ナイスパンチ!!";
    	if(i5==100)sk=" ";
    	if(i5==1)sk="もっと左!!";
    	if(i5==2)sk="もっと右!!";
    	if(i5==10)sk="早すぎる!!";
    	if(i5==20)sk="遅すぎる!!";
    	if(i5==21)sk="遅すぎる!!もっと左!!";
    	if(i5==22)sk="遅すぎる!!もっと右!!";
    	if(i5==11)sk="早すぎる!!もっと左!!";
    	if(i5==12)sk="早すぎる!!もっと右!!";
    	
    	gb.drawString("Punch! : "+sk,pgelb.x,pgelb.y+50);
    	
    	g.drawImage(ibuff,0,0,this);
    	
    }

 	 public void stop(){
    	if(t_ball != null) t_ball = null;
  	}
	
}

class MA extends MouseAdapter{
	nsa6 ap;
	Keeper kp;

	MA(nsa6 ap) {
		this.ap = ap;
		this.kp=ap.kp;
	}

	public void mouseClicked(MouseEvent e){//******************************
		/*
		kp.punch=kp.reachArea(ap.ball);
		*/
		
		ap.i5=kp.punchNum(ap.ball);
		if(ap.i5==0){	
			ap.ball.mode=1;
			ap.ball.arrive=true;
		}
		ap.repaint(ap.pgelb.x-20,ap.pgelb.y,520,520);
		//ap.repaint();
	}
	
}

class MMA extends MouseMotionAdapter{
	nsa6 ap;
	
	MMA(nsa6 ap) {
		this.ap = ap;
	}
	
	
	public void mouseMoved(MouseEvent e){
		
		if(e.getX()<ap.pgelb.x){
			ap.kpp.x=ap.pgelb.x;
		}
		else if(e.getX()>ap.pgerb.x){
			ap.kpp.x=ap.pgerb.x;
		}
		else{
			ap.kpp.x=e.getX();
		}
		//ap.repaint();
		ap.repaint(ap.kpp.x-ap.kp.clw/2,ap.kpp.y-5,ap.kp.clw,ap.kp.clh);
		
	}
}