上の絵と似ていない絵を描くプログラム Kadai1120 を完成させて下さい(月 と雪ダルマが描かれればどんなものでも合格とします). プログラムはキー'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){ // この部分を埋めてください. } }
public void paint(Graphics g){ System.out.println("paint("+g+") is called"); g.setColor(Color.black); g.fillRect(0,0,400,400); g.setColor(Color.yellow); g.fillOval(70,40,50,50); g.setColor(new Color(230,230,230)); g.fillRect(0,200,400,400); g.setColor(new Color(170,170,170)); g.fillOval(220,300,150,50); g.fillOval(280,325,120,40); int[] xs={355,400,400,390}; int[] ys={365,382,345,340}; g.fillPolygon(xs,ys,4); g.setColor(Color.white); g.fillOval(180,180,150,150); g.fillOval(195,80,120,120); g.setColor(new Color(190,190,250)); g.fillOval(200,185,132,145); g.fillOval(212,90,102,115); g.setColor(Color.red); int[] xs0={235,275,285,225}; int[] ys0={35,35,95,95}; g.fillPolygon(xs0,ys0,4); g.setColor(new Color(200,0,0)); int[] xs1={250,275,285,240}; int[] ys1={35,35,95,95}; g.fillPolygon(xs1,ys1,4); g.setColor(Color.red); g.fillOval(235,30,40,10); g.setColor(Color.cyan); g.drawArc(225,75,60,40,180,180); g.setColor(new Color(200,0,0)); g.fillRect(245,113,20,4); }
public void paint(Graphics g){ int i,j; // 空のグラデーション for(i=0;i<250;i++){ g.setColor(new Color(0,0,100-i/4)); g.drawLine(0,i,400,i); } // 月を描画 g.setColor(new Color(255,255,192)); g.fillOval(0,80,300,300); // 地のグラデーション for(i=250;i<=400;i++){ g.setColor(new Color(i-200,i/2-100,0)); g.drawLine(0,i,400,i); } // 円を重ねることで雪だるまの腹部を描画 g.setColor(new Color(200,200,200)); g.fillOval(200,250,120,120); g.setColor(new Color(210,210,210)); g.fillOval(202,252,110,110); g.setColor(new Color(220,220,220)); g.fillOval(205,255,100,100); g.setColor(new Color(230,230,230)); g.fillOval(210,260,80,80); // 同様に胸部を描画 g.setColor(new Color(200,200,200)); g.fillOval(210,200,100,100); g.setColor(new Color(210,210,210)); g.fillOval(212,202,90,90); g.setColor(new Color(220,220,220)); g.fillOval(215,205,80,80); g.setColor(new Color(230,230,230)); g.fillOval(220,210,60,60); // 同様に頭部を描画 g.setColor(new Color(200,200,200)); g.fillOval(205,130,110,110); g.setColor(new Color(210,210,210)); g.fillOval(207,132,100,100); g.setColor(new Color(220,220,220)); g.fillOval(210,135,90,90); g.setColor(new Color(230,230,230)); g.fillOval(215,140,70,70); // 長方形で脚を描画 for(i=0;i<2;i++){ for(j=0;j<3;j++){ g.setColor(new Color(120,120,240)); g.fillRect(180+110*i,240+j*10,50,5); g.setColor(new Color(60,60,120)); g.fillRect(182+110*i,242+j*10,48,3); } } // 長方形で触角を描画 for(i=0;i<2;i++){ g.setColor(new Color(240,120,120)); g.fillRect(240+40*i,100,3,40); g.setColor(new Color(120,60,60)); g.fillRect(241+40*i,101,2,39); } // 眼を描画 for(i=0;i<2;i++){ g.setColor(Color.black); g.fillOval(235+35*i,160,15,15); g.setColor(Color.white); g.fillOval(238+35*i,163,4,4); } // 口を描画 g.setColor(new Color(192,48,144)); g.fillOval(250,190,20,30); // // 蛇足とはこのことであろう。 // }
/* 月に向かって飛びはねる雪だるまを描きました。 雪だるまの軌道は,初めから計算で求めたのではなく, 試行錯誤で結果的にこの数値に落ち着きました。 三日月も,現場合わせのわりにはうまく描けたと思います。*/ public void paint(Graphics g){ /*背景の作成*/ for(int n = 0 ; n < 70 ; n++){ g.setColor(new Color(0,0,70-n)); g.fillRect(0,5*(n+1),400,7); } g.setColor(Color.white); g.fillRect(0,350,400,60); /*三日月の作成 (三日月の影のなかにはグラデーションをいれることができませんでした。)*/ g.setColor(Color.yellow); g.fillArc(350,100,40,40,240,180); g.setColor(Color.black); g.fillArc(323,83,60,60,285,100); /*飛びはねる雪だるまとその残像の作成*/ for(int i = 0 ; i < 5 ; i++){ g.setColor(new Color(215+10*i,215+10*i,215+10*i)); g.fillOval(40+31*i,234+6*(4-i)*(4-i),60-4*i,40+2*i); g.setColor(Color.black); g.drawArc(40+31*i,234+6*(4-i)*(4-i),60-4*i,40+2*i,0,360); g.setColor(new Color(215+10*i,215+10*i,215+10*i)); g.fillOval(45+30*i,214+6*(4-i)*(4-i),50-4*1,30+2*i); g.setColor(Color.black); g.drawArc(45+30*i,214+6*(4-i)*(4-i),50-4*1,30+2*i,0,360); g.setColor(Color.black); g.fillArc(75+31*i,224+6*(4-i)*(4-i),8,8,30,300); } }
/* 無駄なものが多いプログラムになってしまった 目とかマフラーとかを何でプログラムで描こうとしたんだろ… 変数の宣言の仕方にまるで一貫性が無い模様 設定: 雪だるまが月を見上げている図 とりあえずグラデーションをたくさん使った */ // 制(上下)限のある数値を作るメソッド public int myNum(int upnum, int downnum, int num){ num = Math.min(num,upnum); num = Math.max(num,downnum); return num; } /* 雪を適当に降らせるメソッド。おかげでrepaint()が呼び出されるたびに 雪の位置が変わってたり… 配列変数に格納しろ、と言いたい*/ public void snow(Graphics g, int kyori) { Random rdm = new Random(); int i, j, x, y; // kyori は小さい方が遠い for (i=0; i< Snows; i++){ // 課題の番号をシード値にしたが // たいした意味は無い x = rdm.nextInt(1120+i*kyori)/3; y = rdm.nextInt(1120-i+kyori)/3; g.setColor(Color.white); g.fillArc(x-3/2*kyori, y-3/2*kyori, 2*kyori, 2*kyori, 0, 360); // 雪の降る場所をこれで調べた。 // System.out.println(x+","+y); } } public void paint(Graphics g){ // この部分を埋めてください. // とにかくfor文ではi,jを使おうと決心 int i, j; int red, green, blue; int xValues[] = {170, 170, 167, 142, 142, 145}; int yValues[] = {320, 323, 323, 298, 295, 295}; int xValues2[] = {169, 169, 166, 141, 141, 144}; int yValues2[] = {321, 324, 324, 299, 296, 296}; // 背景を黒で塗りつぶす g.setColor(Color.black); g.fillRect(0, 0, 400, 400); // お月様の描画 for (i=0; i<=20; i++){ /* RGBの値を決定してグラデーションを起こす 後から考えてみるとグラデーションのキレをちょっと変えた ぐらいでは見た目が殆ど変わらなかった*/ red = myNum(255,0, (int)Math.sqrt(i*6400)); green = myNum(255,0, (int)Math.sqrt(i*6400)); blue = myNum(160,0, (int)(Math.sqrt(i*6400)/1.5)); g.setColor(new Color(red, green, blue)); g.fillArc(MoonX-(R-i), MoonY-(R-i), 2*(R-i), 2*(R-i), 0, 360); } // 雪 snow(g,1); // 帽子 for(i=0; i<20; i++){ g.setColor(new Color(200-i*7,200-i*7,200-i*7)); g.drawArc(167, 235+i, 73, 68, 15+i/4, 150-i/2); } // 雪だるま様(face) for(i=0; i<40; i++){ j = 255 -i / 2; g.setColor(new Color(j, j, j)); g.fillArc(165+i*3/4, 245+i*2/3, 80-i, 70-i*7/8, 0, 360); } // 雪だるま様(body) for(i=0; i<40; i++){ j = 255 -i*5/4; g.setColor(new Color(j, j, j)); g.fillArc(150+i*3/4, 300+i*3/4, 110-i, 110-i, 0, 360); } // ボタン for(i=0;i<2;i++){ g.setColor(new Color(80, 40, 20)); g.fillArc(190, 300+i*20, 13, 8+i, 0, 360); g.setColor(new Color(140, 80, 40)); g.fillArc(189, 299+i*20, 13, 8+i, 0, 360); } // 目 for(i=0; i<6; i++){ j = 100 -i*10; g.setColor(new Color(j, j, j)); g.fillArc(205+i*3/4, 253+i*3/4, 15-i, 13-i, 0, 360); } for(i=0; i<6; i++){ j = 100 -i*10; g.setColor(new Color(j, j, j)); g.fillArc(179+i*3/4, 256+i*3/4, 12-i, 11-i, 0, 360); } g.setColor(Color.white); g.fillArc(215, 254, 3, 3, 0, 360); g.fillArc(188, 257, 3, 3, 0, 360); g.setColor(new Color(150, 150, 150)); g.drawArc(202, 252, 20, 15, 20, 120); g.drawArc(178, 255, 16, 14, 60, 120); g.setColor(Color.black); g.drawArc(202, 253, 20, 15, 20, 120); g.drawArc(178, 256, 16, 14, 60, 120); // 口 g.setColor(new Color(255, 150, 150)); g.fillArc(197, 277, 3, 7, 0, 360); g.setColor(new Color(190, 190, 190)); g.drawArc(197, 277, 3, 7, 135, -180); // ポッ(頬です) for(i=0; i<4; i++){ g.setColor(new Color(222+i*8,222,222)); g.fillArc(220+i/2, 270+i/2, 9-i, 4-i*6/10, 0, 360); g.setColor(new Color(233+i*6,233,233)); g.fillArc(175+i/2, 272+i/2, 8-i, 4-i*6/10, 0, 360); } // マフラー for(i=14; i>=0; i--){ g.setColor(new Color(i*6+25, (15-i)*5+15, (15-i)*4+15)); g.drawArc(219+i, 285-i/3, 20, 80, 135, -45); g.drawArc(219+i-1, 285-i/3, 20, 80, 135, -45); } for(i=14; i>=0; i--){ g.setColor(new Color((15-i)*6+25, i*5+15, i*4+15)); g.drawArc(214+i, 280+i/3, 20, 80, 135, -45); g.drawArc(214+i-1, 280+i/3, 20, 80, 135, -45); } for(i=0; i<10; i++){ g.setColor(new Color((10-i)*10+15, i*7+10, i*5+10)); g.drawArc(114, 285+i, 180, 180, 65+i/4, 55-i/2); } for(i=0; i<10; i++){ g.setColor(new Color(i*10+15, (10-i)*7+10, (10-i)*5+10)); g.drawArc(114, 285+(i+10), 180, 180, 65-i/4, 55+i/2); } for(i=14; i>=0; i--){ g.setColor(new Color(i*6+25, (15-i)*5+15, (15-i)*4+15)); g.drawArc(219+i, 285-i/3, 20, 80, 90, -135); g.drawArc(219+i-1, 285-i/3, 20, 80, 90, -135); } for(i=14; i>=0; i--){ g.setColor(new Color((15-i)*6+25, i*5+15, i*4+15)); g.drawArc(214+i, 280+i/3, 20, 80, 90, -135); g.drawArc(214+i-1, 280+i/3, 20, 80, 90, -135); } // 腕と手 g.setColor(new Color(150,80,0)); g.fillPolygon(xValues, yValues, 6); g.setColor(new Color(100,50,0)); g.fillPolygon(xValues2, yValues2, 6); for(i=0; i<20; i++){ j = 255 -i*2; g.setColor(new Color(j, j, j)); g.fillArc(127+i*3/4, 280+i*3/4, 25-i, 25-i, 0, 360); } // 結局月にかぶっても目立たない最小サイズになってしまった snow(g,1); // 最後に地面でも描く g.setColor(new Color(150,150,150)); g.fillArc(-100, 375, 600, 400, 0, 360); } // オプション課題でダブルバッファリングでもしようか… //public void update(Graphics g){ //paint(g); //}
// 無理のある背景を書いた。グラデーションと言えなくもない。が、見ていてかえって不快。 public void paint(Graphics g){ // この部分を埋めてください. for(int l=0 ; l<=132 ; l=l+1){ for(int k=0 ; k<=400 ; k=k+1){ g.setColor(new Color((3*l+(l+1)*k)%255, (3*l+2*(l+1)*k)%255, (3*l+3*(l+1)*k)%255)); g.drawRect(3*l, k,0,0); g.setColor(new Color((3*l+1+2*(l+1)*k)%255, (3*l+1+3*(l+1)*k)%255, (3*l+1+(l+1)*k)%255)); g.drawRect(3*l+1, k,0,0); g.setColor(new Color((3*l+2+3*(l+1)*k)%255, (3*l+2+(l+1)*k)%255, (3*l+2+2*(l+1)*k)%255)); g.drawRect(3*l+2, k,0,0); } } //座標 (3l,k) の色が ( 3l+(l+1)k , 3l+2(l+1)k , 3l+3(l+1)k ) //座標 (3l+1,k)の色が ( 3l+1+2(l+1)k , 3l+1+3(l+1)k , 3l+1+(l+1)k ) //座標 (3l+2,k)の色が ( 3l+2+3(l+1)k , 3l+2+(l+1)k , 3l+2+2(l+1)k) //但し255を越えたら0に戻る。 g.setColor(Color.white); g.fillOval(90,250,220,100); g.fillOval(150,225,100,50); g.setColor(Color.red); g.fillOval(170,245,10,10); g.fillOval(230,245,10,10); g.drawOval(165,240,20,20); g.drawOval(225,240,20,20); g.setColor(Color.yellow); g.fillOval(170,270,60,60); g.setColor(Color.white); g.fillOval(185,270,30,30); g.setColor(Color.black); g.drawString("What does this painful background mean ?",85,300); g.drawString("Moon",186,330); }
//雪ダルマということですので、少し凝って雪を降らせてみました。 //実行すると4秒弱のアニメーションが見られます。 //アニメーション中は外部からの入力を受け付けないのが問題点です。 //また、マシンスペックによっては相当ちらつきます。 //sleepの使い方も今一わからずに使っているため、他にも問題があるかも知れません。 public void paint(Graphics g){ System.out.println("paint("+g+") is called"); //黒を選択 g.setColor(Color.black); //背景を塗り潰す g.fillRect(0,0,400,400); //少し暗めの白を選択 g.setColor(new Color(225,225,225)); //地面を塗り潰す g.fillRect(0,300,400,100); //以下雪を降らせるアニメーションを含むループ for(int i=0;i<=110;i++){ //jは雪のy座標 int j=4*i; //白を選択 g.setColor(Color.white); //雪が画面の外に出たときの処理 if(j>390) j=j-390; //直径10ピクセルの円(雪) g.fillOval(20,j,10,10); //他の雪のためにjを元に戻す if(i>=98)j=4*i; //以下、降り始める位置と時間を少しずつずらして22個の雪を降らせている //雪が画面の外に出たときの処理 if(j>410)j=j-390; if(i>5){ g.fillOval(240,j-20,10,10); } //他の雪のためにjを元に戻す if(i>=103)j=4*i; //雪が画面の外に出たときの処理 if(j>430)j=j-390; if(i>10){ g.fillOval(120,j-40,10,10); } //他の雪のためにjを元に戻す if(i>=108)j=4*i; if(i>15){ g.fillOval(320,j-60,10,10); } if(i>20){ g.fillOval(60,j-80,10,10); } if(i>25){ g.fillOval(220,j-100,10,10); } if(i>30){ g.fillOval(30,j-120,10,10); } if(i>35){ g.fillOval(280,j-140,10,10); } if(i>40){ g.fillOval(110,j-160,10,10); } if(i>45){ g.fillOval(210,j-180,10,10); } if(i>50){ g .fillOval(340,j-200,10,10); } if(i>55){ g.fillOval(200,j-220,10,10); } if(i>60){ g.fillOval(40,j-240,10,10); } if(i>65){ g.fillOval(125,j-260,10,10); } if(i>70){ g.fillOval(250,j-280,10,10); } if(i>75){ g.fillOval(50,j-300,10,10); } if(i>80){ g.fillOval(300,j-320,10,10); } if(i>85){ g.fillOval(190,j-340,10,10); } if(i>90){ g.fillOval(130,j-360,10,10); } if(i>95){ g.fillOval(260,j-380,10,10); } if(i>100){ g.fillOval(80,j-400,10,10); } if(i>105){ g.fillOval(360,j-420,10,10); } if(i>110){ g.fillOval(20,j-440,10,10); } //Snowクラスのオブジェクトを作成 Snow s; s=new Snow(); //アニメーションさせるために、33msの間sleep。一応秒間30フレームです s.waiting(); //黒を選択 g.setColor(Color.black); //iが110になるまでは以下を再描画する if(i!=110){ //背景を塗り潰す g.fillRect(0,0,400,300); //少し暗めの白を選択 g.setColor(new Color(225,225,225)); //地面を塗り潰す g.fillRect(0,300,400,100); //暗めの茶色を選択 g.setColor(new Color(110,55,10)); //長方形に塗り潰す(木の幹) g.fillRect(225,295,30,35); //暗めの緑を選択 g.setColor(new Color(45,150,45)); //ポリゴンを塗り潰す(木) int[] xs1={185,220,200,225,215,240,265,255,280,260,295}; int[] ys1={295,240,240,190,190,145,190,190,240,240,295}; g.fillPolygon(xs1,ys1,11); //少し暗めの白を選択 g.setColor(new Color(220,220,220)); //楕円を塗り潰す(雪ダルマの体) g.fillOval(240,290,80,80); //楕円を塗り潰す(雪ダルマの頭) g.fillOval(245,230,70,70); //白っぽい黄色を選択 g.setColor(new Color(255,255,200)); //円弧を塗り潰す(月) g.fillArc(50,40,60,60,60,180); //少し暗めの赤を選択 g.setColor(new Color(230,30,30)); //ポリゴンを描画(雪ダルマの頭のバケツの輪郭) int[] xs2={270,290,320,310}; int[] ys2={231,200,215,251}; g.drawPolygon(xs2,ys2,4); //ポリゴンを塗り潰す(雪ダルマの頭のバケツ) g.fillPolygon(xs2,ys2,4); //少し明るい黒を選択 g.setColor(new Color(10,10,10)); //楕円を塗り潰す(雪ダルマの両目) g.fillOval(255,260,8,8); g.fillOval(282,265,8,8); //ポリゴンを塗り潰す(雪ダルマの眉毛) int[] xs3={282,284,295,293}; int[] ys3={260,255,258,263}; g.fillPolygon(xs3,ys3,4); int[] xs4={255,257,268,266}; int[] ys4={254,249,252,257}; g.fillPolygon(xs4,ys4,4); //ポリゴンを塗り潰す(雪ダルマの鼻) int[] xs5={268,270,268,266}; int[] ys5={269,270,280,279}; g.fillPolygon(xs5,ys5,4); //楕円を塗り潰す(雪ダルマの口) g.fillOval(265,284,9,4); //茶色を選択 g.setColor(new Color(140,80,20)); //ポリゴンを塗り潰す(雪ダルマの手) int[] xs6={300,320,320,323,340,328,350,325,301}; int[] ys6={310,300,280,298,282,299,302,302,313}; g.fillPolygon(xs6,ys6,9); int[] xs7={245,240,225,238,232,242,250,245,248}; int[] ys7={310,298,295,295,280,295,285,298,307}; g.fillPolygon(xs7,ys7,9); //長方形を塗り潰す(家) g.fillRect(20,220,160,120); //長方形を塗り潰す(家の窓) //黄色を選択 g.setColor(Color.yellow); g.fillRect(60,240,40,20); g.fillRect(110,240,40,20); g.fillRect(60,270,40,20); g.fillRect(110,270,40,20); //くすんだ白を選択 g.setColor(new Color(200,200,200)); //ポリゴンを塗り潰す(屋根) int[] xs8={0,100,200}; int[] ys8={220,160,220}; g.fillPolygon(xs8,ys8,3); } } }
//長方形,楕円,多角形の塗り潰しによって三日月と雪だるまの絵を描いた。 //for文を利用してグラデーションを描いた。 public void paint(Graphics g){ // この部分を埋めてください. for(int h = 0;h<400;h++){ for(int i = 0;i<400;i++){ int z =(int) Math.sqrt((h-68)*(h-68)+(i-68)*(i-68)); g.setColor(new Color(118-z/4,118-z/4,118-z/4)); g.fillRect(i,h,1,1); } } for(int j = 0;j<=100;j++){ g.setColor(new Color((int)255-j*3/2,(int)255-j*3/2,(int)255-j*13/10)); g.fillRect(0,300+j,400,1); } g.setColor(Color.black); g.fillOval(300,335,200,30); g.setColor(new Color(200,100,0)); int[] x0 = {270,220,220,270}; int[] y0 = {290,240,250,300}; g.fillPolygon(x0,y0,4); g.setColor(Color.white); g.fillOval(250,250,100,100); g.fillOval(260,190,80,80); g.setColor(Color.yellow); g.fillOval(50,50,36,36); g.setColor(new Color(119,119,119)); g.fillOval(50,50,30,30); g.setColor(Color.black); g.fillOval(265,215,10,10); g.fillOval(295,215,10,10); g.setColor(new Color(255,100,0)); g.fillOval(280,223,10,10); int[] x1 = {285,285,240}; int[] y1 = {223,233,238}; g.fillPolygon(x1,y1,3); g.setColor(new Color(50,230,255)); g.fillOval(265,195,70,15); int[] x2 = {275,325,335,265}; int[] y2 = {165,165,202,202}; g.fillPolygon(x2,y2,4); g.fillOval(275,160,50,10); g.setColor(new Color(30,30,30)); g.drawOval(275,160,50,10); g.setColor(new Color(200,100,0)); int[] x3 = {330,380,380,360,375,375,355,330}; int[] y3 = {290,240,250,270,285,295,275,300}; g.fillPolygon(x3,y3,8); g.fillOval(328,290,4,10); g.fillOval(218,240,4,10); g.setColor(new Color(120,80,0)); g.fillOval(378,240,4,10); g.fillOval(373,285,4,10); g.setColor(Color.white); g.fillOval(15,76,4,4); g.fillOval(78,63,4,4); g.fillOval(109,99,4,4); g.fillOval(309,68,4,4); g.fillOval(388,94,4,4); g.fillOval(208,77,4,4); g.fillOval(150,200,4,4); g.fillOval(339,140,4,4); g.fillOval(280,180,4,4); g.fillOval(155,149,4,4); g.fillOval(50,200,4,4); g.fillOval(80,270,4,4); g.fillOval(170,260,4,4); g.fillOval(128,254,4,4); g.fillOval(220,190,4,4); g.setColor(Color.black); g.drawString("ARE YOU HAPPY ???",52,352); g.setColor(Color.red); g.drawString("ARE YOU HAPPY ???",50,350); }
解答例(2)は地面,空,雪だるまだけでなく手足にもグラデーションをつけて いる点などは凝っています.ただし,ところどころインデントがずれている点 が気にかかります.
解答例(4)は他の人と気合いの入り方が違う感じですね.drawArcだけでマフ ラーを描いてしまうとは.ただ感心するばかりです.
解答例(6)はアニメーションを実現しようとしていますが,paintの中で sleepするというのは,正しい AWTの使い方ではないので(偶然動く処理系はあっ ても),正しいアニメーションの実現法はこの講義でやります.
以下の人は,レポート提出プログラム(/home/ktanaka/bin/report1120)の起 動の際に間違ったウィンドウをキャプチャーしてしまった人です.この人たち は再提出してください.