11/8の課題について


11/8 課題問題 yukidaruma

上の絵と似ていない絵を描くプログラム Kadai1108 を完成させて下さい(月 と雪ダルマが描かれればどんなものでも合格とします). プログラムはキー'q' を押すと正常終了するようにしてください.

  // AWTを使うので java.awt.*を import する
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;

  // 独立したウィンドウを開くので,
class Kadai1108 extends Frame{
  public Kadai1108(String title){
    super(title);
      // GUI部品と,Event Listenerを関連づける
      // KeyAdapterは,KeyListenerを実装して中身は何もないクラス
      // new クラス名(){} で,「クラス名」の名前のない子クラスを定義すると同時に
      // インスタンスを作る
    addKeyListener(new KeyAdapter(){
      public void keyPressed(KeyEvent e){
	int key=e.getKeyChar();
	System.out.println("keyPressed("+e+","+key+")");
	if(key=='q') System.exit(0);
      }
    });
  }
  public static void main(String[] args){
    Kadai1108 frame=new Kadai1108("Kadai1108");
    frame.setSize(400,400);
    frame.setVisible(true);    
  }
  public void paint(Graphics g){
 // この部分を埋めてください. 
  }
}

解答例(1) paintメソッドのみ
  public void paint(Graphics g){
    g.setColor(Color.black); // 使う色を黒に変更する
    g.fillRect(0,0,400,200);   //上の方を黒くする   
    g.setColor(Color.gray); // 使う色を灰色に変更する
    g.fillRect(0,200,400,400);   //下の方を白くする   
    g.setColor(Color.yellow);//使う色を黄色に変更
    g.fillArc(270,85,70,70,0,360);// 円(月)を描く
    g.setColor(Color.white);//使う色を白に変更
    g.fillArc(50,220,100,100,0,360);// 円(雪だるまの頭)を描く 
    g.fillArc(40,310,120,120,0,360);// 円(雪だるまの胴体)を描く
    g.setColor(Color.black); // 使う色を黒に変更する
    g.fillArc(82,255,9,9,0,360);// 円(雪だるまの左目)を描く    
    g.fillArc(107,255,9,9,0,360);// 円(雪だるまの右目)を描く 
    g.setColor(Color.red);//使う色を赤色に変更
    g.fillArc(94,275,9,9,0,360);// 円(雪だるまの鼻)を描く    
    g.setColor(new Color(150,200,255));//使う色を青っぽい色に変更
    g.fillArc(94,345,9,9,0,360);//胴体の模様を描く
    g.fillArc(94,367,9,9,0,360);//胴体の模様を描く
    g.fillArc(94,389,9,9,0,360);//胴体の模様を描く
  }

解答例(2)
// 040252I XXXXXX
//月の上に佇む雪だるまを描くプログラム。

  // AWTを使うので java.awt.*を import する
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;

class Kadai1108 extends Frame{

  public Kadai1108(String title){
    super(title);

    // GUI部品と,Event Listenerを関連づける
    // KeyAdapterは,KeyListenerを実装して中身は何もないクラス
    // new クラス名(){} で,「クラス名」の名前のない子クラスを定義すると同時に
    // インスタンスを作る
    addKeyListener(new KeyAdapter(){
      public void keyPressed(KeyEvent e){
        int key=e.getKeyChar();
        System.out.println("keyPressed("+e+","+key+")");
        if(key=='q') System.exit(0);
      }
    });
  }

  public static void main(String[] args){
    Kadai1108 frame=new Kadai1108("Yukidaruma");
    frame.setSize(500,600);
    frame.setVisible(true);    
  }

  /* 月形を書くメソッド。始角90度,時計回りに180度に限る。
  x,y 一番上の部分の座標
  r 半径
  h 月の膨らみ程度(-100(満月)から100(新月)まで)
  (本当は,このメソッドを含むGraphicsクラスのサブクラスを作りたかったのですが,
  抽象クラスが何とかというエラーが克服できそうに無いので諦めました。
  Graphicsクラスのgを引数に持つという気持悪さは何とかしたいのですが。 */
  
  public void drawMoon(Graphics g,int x,int y,int r,int h){
    int xs0[] =new int[r*4];
    int ys0[] =new int[r*4];
    double xx=0,yy=r;
    int m;
    //円弧を多角形として描く。
    //右側の円弧
    for(m=0;m< 2*r;m++){
      xs0[m]=(int)(xx+x);
      ys0[m]=(int)(y+r-yy);
      yy=yy-1;
      xx=Math.pow(r*r-yy*yy,0.5);
    }
    //左側の円弧
    for(;m< 4*r;m++){
      xs0[m]=(int)(xx+x);
      ys0[m]=(int)(y+r-yy);
      yy=yy+1;
      xx=Math.pow(r*r-yy*yy,0.5)*h/100;
    }
    //描画
    g.fillPolygon(xs0,ys0,m);

  }

  public void paint(Graphics g){
    int n;
    int m;
    int x,y,xx,yy;
    int r;

    //背景
    g.setColor(new Color(0,15,0)); 
    g.fillRect(0,0,600,600); 
    
    g.setColor(new Color(225,225,255));
    //星(雪?)
    for(n=0;n< 50;n++){
      g.fillOval((int)(Math.random()*400),(int)(Math.random()*400),2,2);
    }

    //月
    for(n=-100;n<=100;n=n+10){
      g.setColor(new Color(205-n/2,205-n/2,180));
      drawMoon(g,200,300,800,n);
    }

    //月面の雪    
    n=0;
    while(n< 150){
      if(n<2){
	x=320;
	y=330;
      }else{
	x=(int)(Math.random()*600-n*2)-100+n*2;
	y=(int)(Math.random()*300)+200;
      }
      if(((x-200)*(x-200)+(y-1100)*(y-1100))<=(800*800)){
	m=0;
	while(m<100){
	  xx=(int)(Math.random()*60+x-30);
	  yy=(int)(Math.random()*60+y-30);	
	  if((xx-x)*(xx-x)+(yy-y)*(yy-y)<900){
	    if(((xx-200)*(xx-200)+(yy-1100)*(yy-1100))<=(801*801)){
	      r=200+(int)(Math.random()*55);
	      g.setColor(new Color(r,r,255));
	      g.fillOval(xx,yy,3,3); 
	      m++;
	    }
	  }
	}
	n++;
      }
    }
    //雪だるまの鼻
    g.setColor(new Color(200,0,0));
    int xs0[]={295,310,310};
    int ys0[]={260,255,265};
    g.fillPolygon(xs0,ys0,3);

    
    //雪だるま本体
    for(n=0;n<5;n++){
      g.setColor(new Color(205+n*10,205+n*10,255));
      g.fillOval(300,240+n,40-2*n,40-2*n);
      g.fillOval(295,270+2*n,50-2*n,50-2*n);
    }
    //雪だるまの帽子
    g.setColor(new Color(100,100,210));
    int xs1[]={310,330,340,300};
    int ys1[]={230,230,250,250};
    g.fillPolygon(xs1,ys1,4);

    //雪だるまの手(箒)
    g.setColor(new Color(150,100,120));
    x=315;y=300;xx=320;yy=280;

    g.drawLine(x,y,xx,yy);
    double k;
    for(k=0;k<20;k++){
      g.drawLine(xx,yy,xx+(int)(30*Math.cos((0.2+k/100)*3.14)),
				   yy-(int)(30*Math.sin((0.2+k/100)*3.14)));
    }
  }
}

解答例(3)
//XXXXXX  XXXXX
//Kadai1108.java
//AWTのテストプログラム
//400x400で月と骸骨型雪だるまを表示
//'q'の入力で終了 

import java.awt.*;

import java.awt.event.*;


class Kadai1108 extends Frame{
  public Kadai1108(String title){

    super(title);

    addKeyListener(new KeyAdapter(){
      public void keyPressed(KeyEvent e){
        int key=e.getKeyChar();
        System.out.println("keyPressed("+e+","+key+")");
        if(key=='q') System.exit(0);
      }
    });
  }
  public static void main(String[] args){
    Kadai1108 frame=new Kadai1108("Kadai1108");
    frame.setSize(400, 400);
    frame.setVisible(true);    
  }
  public void paint(Graphics g){
    
    //背景色
    g.setColor(Color.black);
    g.fillRect(0, 0, 400, 400);

    //月の描画
    g.setColor(new Color(255, 200, 0));
    g.fillOval(210, 90, 180, 180);
    g.setColor(Color.black);
    g.fillOval(210, 110, 140, 140);
    g.setColor(Color.red);
    int[] xs = {350, 330, 350};
    int[] ys = {175, 185, 185};
    g.fillPolygon(xs, ys, 3);
    g.drawLine(348, 200, 368, 200);
    g.setColor(Color.blue);
    g.drawLine(348, 160, 368, 160);

    //地面の描画
    g.setColor( Color.gray );
    g.fillRect( 0, 350, 400, 50 );

    //骸骨のオブジェクトを生成し描画
    Skeleton s = new Skeleton( 20, 35, g );
    s.drawSkeleton();
 
  }
}
    //骸骨のクラス

class Skeleton {
  
  int x, y;
  Graphics g;

  public Skeleton(int x0, int y0, Graphics g0){
    x = x0;
    y = y0;
    g = g0;
  }

  public void drawSkeleton(){
    g.setColor( Color.white );
    g.fillRect( x, y+75, 10, 40 );      //右前腕
    g.fillRect( x+160, y+75, 10, 40 );  //左前腕
    g.fillRect( x+60, y+65, 50, 100 );  //体
    g.fillRect( x+10, y+65, 40, 10 );   //右二の腕
    g.fillRect( x+120, y+65, 40, 10 );  //左二の腕 
    g.fillRect( x+60, y+185, 10, 50 );  //右腿
    g.fillRect( x+100, y+185, 10, 50 ); //左腿
    g.fillRect( x+60, y+255, 10, 50 );  //右すね
    g.fillRect( x+100, y+255, 10, 50 ); //左すね
    g.fillRect( x+50, y+305, 20, 10 );  //右足
    g.fillRect( x+100, y+305, 20, 10 ); //左足
    g.fillOval( x+55, y, 60, 60 );      //頭
    g.fillOval( x, y+115, 10, 10 );     //右手
    g.fillOval( x+160, y+115, 10, 10 ); //左手
    g.setColor( Color.red );            
    g.fillOval( x, y+65, 10, 10 );      //右肘
    g.fillOval( x+160, y+65, 10, 10 );  //左肘
    g.fillOval( x+50, y+65, 10, 10 );   //右肩
    g.fillOval( x+110, y+65, 10, 10 );  //左肩
    g.fillOval( x+60, y+170, 10, 10 );  //右足のつけね
    g.fillOval( x+100, y+170, 10, 10 ); //左足のつけね
    g.fillOval( x+60, y+240, 10, 10 );  //右膝
    g.fillOval( x+100, y+240, 10, 10 ); //左膝
    g.setColor( Color.black );
    g.fillOval( x+65, y+10, 18, 18 );   //右目
    g.fillOval( x+87, y+10, 18, 18 );   //左目
    int[] xs = { x+80, x+85, x+90 };
    int[] ys = { y+35, y+30, y+35 };
    g.fillPolygon(xs, ys, 3);           //鼻
    g.drawLine( x+85, y+50, x+85, y+60 );   //口
    g.drawLine( x+75, y+50, x+75, y+57 );
    g.drawLine( x+95, y+50, x+95, y+57 );
  }
}

すべての画像ファイル

講評

こちらで想定した解答は,解答例(1)のように描画のためのメソッドを続けて 呼ぶというものですが,がんばって楽しいプログラムを作ってくれた人もいま した.その中から2点,解答例(2),(3)として紹介します.

解答例(2)に「本当は,このメソッドを含むGraphicsクラスのサブクラスを作 りたかったのですが, 抽象クラスが何とかというエラーが克服できそうに無い ので諦めました。Graphicsクラスのgを引数に持つという気持悪さは何とかし たいのですが。」とありましたが,Graphicsクラスのサブクラスを作成したと しても,paintの引数として渡ってくるgとそのクラスとの間の関係は親子関係 ではなく兄弟になってしまうので,解決することはできません.gを引数とし て引き回すのは面倒かもしれませんが,慣れてください.


オプション課題