動きを導入・失敗編

Since 2003.04.30  

このような解説の場合、「こうすれば動く」という説明はありますが、「こうしたら失敗する」という説明は無いのが多いです。
今回は、やってはいけないプログラムを書いてみます。

連続して点滅させる=ループを使う

夜空の星は輝きます。「輝く」というのはキラキラするということ。だから、星のイメージを点滅させようと考えます。
点滅させるには、「背景色で塗りつぶす」「星を描く」を繰り返せばよいはずです。次のようなコードです。

g.fillRect(0, 0, dim.width, dim.height);
g.drawImage(starimage, 0, 0, this);
g.fillRect(0, 0, dim.width, dim.height);
g.drawImage(starimage, 0, 0, this);
g.fillRect(0, 0, dim.width, dim.height);
g.drawImage(starimage, 0, 0, this);
g.fillRect(0, 0, dim.width, dim.height);
g.drawImage(starimage, 0, 0, this);
以下、繰り返し

このまま書こうとすると、延々と書かなければなりません。このような時の為にプログラミング言語には必ず「ループ(反復処理)制御文」が用意されています。Java には、while文、do文、for文の3種類あります。while文を使うとプログラムコードは、次のようになります。

while (条件) {
    g.fillRect(0, 0, dim.width, dim.height);
    g.drawImage(starimage, 0, 0, this);
}

今回のプログラムでは、イメージファイルを取得できたときは、無限に繰り返す様、条件を設定しています。( 7行目、34行目)
HTMLファイルも書き換えて実行してみます。

画像キャプチャソフトを使って画面をコピーすると、上記のような2種類の画面になっていることがわかります。実際に実行された方は「うそぉ!」という感想でしょう。 どのように見えるかは、ここでは詳しく書きません。実際に体験してください。
Windows2000、WindowsXPをお使いの方は、HTMLファイルを表示させた状態でタスクマネージャを開いてみてください。
タスクバー右クリック・・・タスクマネージャ・・・パフォーマンス
次のように CPU使用率が 100% に振り切っているはずです。

最初に書いたように、このプログラムは、「やってはいけない失敗プログラム」です。
何がいけないのかというと、 CPUを 100% 使い切ることです。くれぐれもこのプログラムを長時間実行させないでください。設計の悪いコンピュータの場合には、CPU が熱暴走します。CPUを 100% 使い切ることは、どのような場面でもいけないということではありません。実時間処理の厳しいロボット制御などでは使われます。
何が失敗かというと、人間の視覚特性を無視していることです。扇風機が回転数によって止まっているように見えるのと同じ原理です。
解決策は次回回しとして、ここではループ文の解説を行います。

while文、do文、for文

-while文do文for文
構文 while(式)
    文;
do
    文;
while(式)
for(初期化 ; テスト ; 増分)
    文;
while(式) {
    文;
}
do {
    文;
} while(式)
for(初期化 ; テスト ; 増分) {
    文;
}
動作 式を評価
false の場合は終り
true の場合は文を実行
式の評価に戻る
文を実行
式を評価
false の場合は終り
true の場合は文の実行に戻る
初期化実行
テストを評価
false の場合は終り
true の場合は文を実行
増分実行
テストの評価に戻る

上側の構文は、ループ本体が単独文のときに使用できます。ループ本体が複数の文から構成されるときは下側の構文のように「{」と「}」で囲まなければなりません。下側の構文しか使わない人もいるはずです。

while文、do文の式は省略できません。他言語の場合は省略可能なものも有るのですが、その場合は無条件無限ループになるので、Javaでは許さないのでしょう。(true と書けば同じなのですが)
for文の、初期化、テスト、増分は、それぞれ省略可能です。(文法上全部省略も可能です。無限ループになる)
いずれも、ループ本体の文は省略できません。何も実行させない場合でも、空文(「;」のみ)を置かなければなりません。実質上、デバッグの時以外、ループ本体を空文にするのは無駄でしょう。

while文が、最も基本的な構文です。
do文の場合は、ループ本体は必ず1回は実行されます。while文、for文の場合は、最初の評価で false であれば、ループ本体は1回も実行されません。
do文は、あまり使われません(私の場合、他言語も含めて一度も使ったことがありません)。評価には、実行可能かを判定する場合も多いからでしょう。実行不能なら実行できませんから。
for文は、次のようにwhile文に変換できます。

初期化;
while(テスト) {
    文;
    増分;
}

反対に、while文を for文に変換することもできます。

for( ; 式; ) {
    文;
}

私は、ほとんどの場合、for文を使っています。

ソースコード

java/net/sys5jp/basic/Star2.java

1 package net.sys5jp.basic;
2
3 import java.applet.*;
4 import java.awt.*;
5
6 public class Star2 extends Applet {
7     boolean runnable = true;
8     Color backcolor = new Color(0, 0, 0);
9     Image starimage;
10     Dimension dim;
11
12     private Color getColorParameter(String param) {
13         String value = getParameter(param);
14         try { return new Color(Integer.parseInt(value, 16)); }
15         catch(Exception e) { return null; }
16     }
17
18     public void paint(Graphics g) {
19         dim = getSize();
20         g.setColor(backcolor);
21         while (runnable) {
22             g.fillRect(0, 0, dim.width, dim.height);
23             g.drawImage(starimage, 0, 0, this);
24         }
25     }
26
27     public void init() {
28         Color color;
29         if((color = getColorParameter("backcolor")) != null) {
30             backcolor = color;
31         }
32         try { starimage
33                 = getImage(getDocumentBase(), getParameter("starimage")); }
34         catch(Exception e) { runnable = false; }
35         setBackground(backcolor);
36     }
37 }

java/html/Star2.html

<html>
<head>
<style>
body {background-color:rgb(0, 0, 0);
    color:rgb(255, 255, 255)}
table {text-align:center;
    margin:10px 10px}
td {padding:5px 10px}
</style>
</head>
<body>
<table>
<tr><td>
<applet code="net/sys5jp/basic/Star1.class"
    codebase="../"
    width=30 height=30>
        <param name="starimage" value="../images/Star30.png">
</applet>
</td><td>
<applet code="net/sys5jp/basic/Star2.class"
    codebase="../"
    width=30 height=30>
        <param name="starimage" value="../images/Star30.png">
</applet>
<tr><td>
Star1.class
</td><td>
Star2.class
</td></tr>
</table>
</body>
</html>

トップヘ 目次ヘ 前ヘ 次ヘ