// 名前 : 高井 佳基 // 学生証番号 : 350526C // 説明 : AWTにより月と雪だるまを描画するプログラム・改3 // 1.月及び雪だるまをドラッグにより移動させる // 2.なにもないところでドラッグすると, ランダムに3色の星を書き込む // 3.Delete ボタンを押すと星が一つ消える // 4.Clear ボタンを押すと星がすべて消える // 5.Checkbox により, 夜と昼を切り替える // 6.昼は月の変わりに太陽が動くが, 固定された月の影に太陽が入ると // 日食が起こる。元に戻すには隠れた太陽を月の外に出す // 7.以上の機能をアプレットとしてブラウザで動くようにした // アプレットを使うため import java.applet.*; // AWTを使うので java.awt.*を import する import java.awt.*; // イベント駆動関係のクラスを用いるため import java.awt.event.*; // Randomクラス, Vectorクラスを用いるために必要 import java.util.*; // "星"のクラスを定義する// class Star{ // x座標, y座標を int で保持する public int st_x,st_y,st_color; // Star のコンストラクタ // Star(x座標,y座標,星の色)と指定する public Star(int sx1,int sy1,int sc1){ st_x = sx1; st_y = sy1; st_color = sc1; } } public class Kadai1209 extends Applet implements ActionListener, ItemListener{ // Star の配列を保持する Vector クラスの変数 starArray の宣言 Vector starArray; // 月や雪だるまのないところでドラッグ中ならば dragging = true // 月の上にマウスカーソルがあれば moon = true // 雪だるまの上にマウスカーソルがあれば snowman = true boolean dragging, moon, snowman; // (x1,y1)が月, (x2,y2)が雪だるまの座標を表す int x1 = 55, y1 = 40, x2 = 230, y2 = 190; // Random に雪を降らせたり, 星の色を決めたりするための // 乱数の元となるオブジェクトを作成 Random r = new Random(); // マウスで月や雪だるまをドラッグする際の相対的な座標を int で保持する int dx, dy; // night = true で夜, false で昼, eclipse = true で日食 boolean night = true, eclipse = false; Image offScreenImage; Graphics offScreenGraphics; public void update(Graphics g){ if(offScreenImage == null){ // offScreenImage に値を入れるので, 次回はif文は成立しない offScreenImage = createImage(400, 400); offScreenGraphics = offScreenImage.getGraphics(); } paint(offScreenGraphics); g.drawImage(offScreenImage, 0, 0, this); } public void paint(Graphics g){ int i; // 遠いものや大きいものから配置する // night = true (夜)のとき if(night){ // 夜の空 g.setColor(new Color(25, 25, 112)); g.fillRect(0, 0, 400, 400); // 星 int size = starArray.size(); if(dragging) size--; for(i = 0; i < size; i++){ Star s = (Star)starArray.elementAt(i); g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this); } if(dragging){ Star s = (Star)starArray.elementAt(size); g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this); } // 三日月 g.setColor(new Color(255, 255, 204)); g.fillOval(x1, y1, 46, 46); g.setColor(new Color(25, 25, 112)); g.fillOval(x1-29, y1-29, 69, 69); // 一面の雪にやや丸い地平線 g.setColor(new Color(245, 255, 250)); g.fillOval(-600, 210, 1600, 360); // 雪だるまの影 g.setColor(new Color(245, 245, 245)); g.fillOval(x2+37, y2+75, 100, 50); // 雪だるま(下) g.setColor(new Color(255, 250, 250)); g.fillOval(x2, y2, 100, 100); // 雪だるま(上) g.fillOval(x2+10, y2-65, 80, 80); // "口" g.setColor(Color.black); g.fillRect(x2+32, y2-18, 19, 3); // "鼻(小枝)" g.setColor(new Color(128, 0, 0)); int[] xs0 = {x2+15, x2+15, x2+40, x2+40}; int[] ys0 = {y2-28, y2-25, y2-25, y2-31}; g.fillPolygon(xs0, ys0, 4); // "帽子(バケツ)" g.setColor(Color.red); int[] xs1 = {x2+35, x2+85, x2+83, x2+53}; int[] ys1 = {y2-63, y2-45, y2-74, y2-84}; g.fillPolygon(xs1, ys1, 4); // Randomに雪を降らせる // (sx, sy) = ((雪のx座標)+10, (雪のy座標)+10) // 10 ずらしているのは左端も自然に描画するため // s_size は雪の大きさを表す for(i = 0; i < 300; i++){ int sx = r.nextInt(420); int sy = r.nextInt(420); int s_size = r.nextInt(5)+3; g.setColor(Color.white); g.fillOval(sx-10, sy-10, s_size, s_size); g.setColor(new Color(230, 230, 250)); g.drawOval(sx-10, sy-10, s_size, s_size); } // 雪だるまの"目" g.setColor(Color.black); g.fillOval(x2+30, y2-45, 6, 6); g.fillOval(x2+50, y2-45, 6, 6); // 説明 g.setFont(new Font("Serif", Font.ITALIC, 11)); g.drawString("You can move the moon or the snowman", 180, 320); g.drawString("by dragging it.", 320, 335); g.drawString("You can create a new star", 180, 350); g.drawString("by dragging any other area.", 255, 365); } // night = false (昼)のとき(通常時) else if(!eclipse){ // 昼の空 g.setColor(new Color(135, 206, 250)); g.fillRect(0, 0, 400, 400); // 太陽 g.drawImage(sun, x1, y1, this); // 昼の月 g.setColor(new Color(240, 248, 255)); g.fillOval(20, 10, 46, 46); g.setColor(new Color(135, 206, 250)); g.fillOval(-9, -19, 69, 69); // 一面の雪にやや丸い地平線 g.setColor(new Color(255, 250, 250)); g.fillOval(-600, 210, 1600, 360); // 雪だるまの影 g.setColor(new Color(230, 230, 250)); g.fillOval(x2+37, y2+75, 100, 50); // 雪だるま(下) g.setColor(new Color(255, 250, 240)); g.fillOval(x2, y2, 100, 100); // 雪だるま(上) g.fillOval(x2+10, y2-65, 80, 80); g.drawImage(sweat, x2+60, y2-40, 15, 20, this); // "口" g.setColor(Color.black); g.fillRect(x2+32, y2-10, 19, 3); // "鼻(小枝)" g.setColor(new Color(128, 0, 0)); int[] xs0 = {x2+15, x2+15, x2+40, x2+40}; int[] ys0 = {y2-20, y2-17, y2-17, y2-23}; g.fillPolygon(xs0, ys0, 4); // "帽子(バケツ)" g.setColor(Color.red); int[] xs1 = {x2+80, x2+140, x2+130, x2+90}; int[] ys1 = {y2+120, y2+120, y2+90, y2+90}; g.fillPolygon(xs1, ys1, 4); // 雪だるまの"目" g.setColor(Color.black); g.fillOval(x2+30, y2-37, 6, 6); int[] xs2 = {x2+25, x2+39, x2+37, x2+23}; int[] ys2 = {y2-40, y2-47, y2-49, y2-42}; g.fillPolygon(xs2, ys2, 4); g.fillOval(x2+50, y2-37, 6, 6); int[] xs3 = {x2+62, x2+48, x2+50, x2+64}; int[] ys3 = {y2-40, y2-47, y2-49, y2-42}; g.fillPolygon(xs3, ys3, 4); // 説明 g.setFont(new Font("Serif", Font.ITALIC, 11)); g.drawString("You can move the sun by dragging it.", 220, 365); } // 日食 else{ // 夜の空 g.setColor(new Color(25, 25, 112)); g.fillRect(0, 0, 400, 400); // 星 int size = starArray.size(); if(dragging) size--; for(i = 0; i < size; i++){ Star s = (Star)starArray.elementAt(i); g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this); } if(dragging){ Star s = (Star)starArray.elementAt(size); g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this); } // 月と太陽 g.setColor(new Color(255, 215, 0)); g.fillOval(x1-2, y1-2, 50, 50); g.setColor(new Color(255, 255, 204)); g.fillOval(20, 10, 46, 46); // 一面の雪にやや丸い地平線 g.setColor(new Color(245, 255, 250)); g.fillOval(-600, 210, 1600, 360); // 雪だるまの影 g.setColor(new Color(245, 245, 245)); g.fillOval(x2+37, y2+75, 100, 50); // 雪だるま(下) g.setColor(new Color(255, 250, 250)); g.fillOval(x2, y2, 100, 100); // 雪だるま(上) g.fillOval(x2+10, y2-65, 80, 80); // "口" g.setColor(Color.black); g.fillRect(x2+32, y2-10, 19, 3); // "鼻(小枝)" g.setColor(new Color(128, 0, 0)); int[] xs0 = {x2+15, x2+15, x2+40, x2+40}; int[] ys0 = {y2-20, y2-17, y2-17, y2-23}; g.fillPolygon(xs0, ys0, 4); // "帽子(バケツ)" g.setColor(Color.red); int[] xs1 = {x2+35, x2+85, x2+83, x2+53}; int[] ys1 = {y2-63, y2-45, y2-74, y2-84}; g.fillPolygon(xs1, ys1, 4); // 雪だるまの"目" g.setColor(Color.black); g.fillOval(x2+30, y2-37, 6, 6); int[] xs2 = {x2+37, x2+23, x2+25, x2+39}; int[] ys2 = {y2-40, y2-47, y2-49, y2-42}; g.fillPolygon(xs2, ys2, 4); g.fillOval(x2+50, y2-37, 6, 6); int[] xs3 = {x2+50, x2+64, x2+62, x2+48}; int[] ys3 = {y2-40, y2-47, y2-49, y2-42}; g.fillPolygon(xs3, ys3, 4); // 説明 g.setFont(new Font("Serif", Font.ITALIC, 40)); g.drawString("eclipse!!!", 130, 275); g.setFont(new Font("Serif", Font.ITALIC, 11)); g.drawString("You can move the sun by dragging it.", 220, 365); } } // 星を1つ消すメソッド public void deleteStar(){ int size; if((size = starArray.size())>0 & (night | eclipse)){ starArray.removeElementAt(size-1); repaint(); } } // 星をすべて消すメソッド public void clearStar(){ if(night | eclipse){ starArray.removeAllElements(); repaint(); } } Button deleteButton, clearButton, exitButton; CheckboxGroup cbg = new CheckboxGroup(); Checkbox nightChkbox, dayChkbox; Image sun, sweat; Image star[] = new Image[3]; // コンストラクタは書かない public void init(){ starArray = new Vector(); dragging = false; setSize(400, 400); int i; for(i = 0; i < 3; i++){ star[i] = getImage(getCodeBase(), "star"+i+".png"); } sun = getImage(getCodeBase(), "sun1.png"); sweat = getImage(getCodeBase(), "sweat.png"); // レイアウトを GridBagLayout に設定し, Button や Checkbox を配置する Panel panel = new Panel(); panel.setLayout(new GridBagLayout()); panel.add(deleteButton = new Button("Delete")); deleteButton.addActionListener(this); panel.add(clearButton = new Button("Clear")); clearButton.addActionListener(this); panel.add(exitButton = new Button("Exit")); exitButton.addActionListener(this); panel.add(nightChkbox = new Checkbox("night", cbg, true)); nightChkbox.addItemListener(this); panel.add(dayChkbox = new Checkbox("day", cbg, false)); dayChkbox.addItemListener(this); setLayout(new BorderLayout()); add(panel,"South"); // サイズを400x400に設定 setSize(400,400); // 表示する. setVisible(true); addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e){ int mx = e.getX(), my = e.getY(); // なにもないところでマウスボタンが押されたら星を一つ追加 // その際, Random に星の色を決める // mc=0,1,2 がそれぞれ黄色, 青色, 赤色に対応 // 月(太陽)や雪だるまの上でマウスボタンが押されたら, // 月や雪だるまに対する相対的な座標を記録する if(night){ if(!moon & !snowman){ int mc = r.nextInt(3); starArray.addElement(new Star(mx, my, mc)); dragging = true; } else if(moon){ dx = mx-x1; dy = my-y1; } else if(snowman){ dx = mx-x2; dy = my-y2; } } else{ if(moon){ dx = mx-x1; dy = my-y1; } } // 再表示をおこなう repaint(); } public void mouseReleased(MouseEvent e){ int mx = e.getX(), my = e.getY(); // マウスボタンが離されたら星の座標及び色を固定する if(night){ if(!moon & !snowman){ Star s = (Star)starArray.elementAt(starArray.size()-1); s.st_x = mx; s.st_y = my; dragging = false; } repaint(); } } }); addMouseMotionListener(new MouseMotionAdapter(){ public void mouseDragged(MouseEvent e){ int mx = e.getX(),my = e.getY(); // マウスのドラッグに合わせて星, 月, 雪だるまを動かす // ドラッグ中は星の色は変えない if(night){ if(!moon & !snowman){ Star s = (Star)starArray.elementAt(starArray.size()-1); s.st_x = mx; s.st_y = my; } else if(moon){ x1 = mx-dx; y1 = my-dy; } else if(snowman){ x2 = mx-dx; // 雪だるまの下の部分が地平線から // はみ出さないようにする if (my > 157+dy) y2 = my-dy; else y2 = 158; } eclipse = false; } else if(moon){ x1 = mx-dx; y1 = my-dy; if(x1 < 21 & y1 < 11){ eclipse = true; } if(eclipse & (x1 > 40 | y1 > 30)){ eclipse = false; } } repaint(); } public void mouseMoved(MouseEvent e){ int mx = e.getX(), my = e.getY(); // マウスカーソルが月の上に入ったら moon = true // 雪だるまの上に入ったら snowman = true if(night){ if(mx > x2 & mx < x2+100 & my > y2-80 & my < y2+100){ moon = false; snowman = true; } else if(mx > x1 & mx < x1+46 & my > y1 & my < y1+46){ moon = true; snowman = false; } else{ moon = false; snowman = false; } } else{ if(mx > x1 & mx < x1+46 & my > y1 & my < y1+46){ moon = true; snowman = false; } else{ moon = false; snowman = false; } } } }); } public void actionPerformed(ActionEvent e){ System.out.println(e); Object source = e.getSource(); if(source.equals(deleteButton)){ deleteStar(); } else if(source.equals(clearButton)){ clearStar(); } else if(source.equals(exitButton)){ // 見かけ上終了 setVisible(false); } } public void itemStateChanged(ItemEvent e){ if(nightChkbox.getState()){ night = true; } else{ night = false; } repaint(); } }