コンテンツにスキップ

15.配列を使おう1(一次元配列)

1.配列とは

配列(はいれつ) というのは、たくさんのデータが入るケースのような変数のことです。配列を使うと、データをまとめて扱えて便利です。

// 配列の例
String[] fruits = {"Apple", "Orange", "Banana"};

この例では、 fruits という名前の文字列型の配列を用意し、 "Apple""Orange""Banana" の三つのデータを入れています。 String(ストリング) というのは文字列という意味です。

2.配列の宣言と初期化

配列を使うときには、ほかの変数と同じように、まず 宣言(せんげん) をします。また、 初期化(しょきか) といって、いくつデータが入るかを決める必要があります。

配列の宣言のしかた

// 配列の宣言
データ型 [] 変数名;

ふつうの変数と違い、データ型の後に[]をつけます。

// 配列の宣言の例
int[] numbers;
String[] cars;

ここでは、int(整数)型の numbers という名前の配列と、String(文字列)型の変数 cars を定義しています。

配列の初期化のしかた

配列を使う前に初期化していくつデータが入るかを決めます。初期化するときには、new(ニュー) を使います。

// 配列の初期化の例
numbers = new int[3];
cars = new String[5];

この例では、変数 numbers は3つのデータが入るようになり、 cars には5つのデータが入れられるようになります。中身は空です。

宣言と初期化を一緒に行う

宣言と初期化はいっしょにすると便利です。

int[] numbers = new int[3];
String[] cars = new String[5];

3.配列にデータを入れる

配列を作ったら、データを入れましょう。

String[] robots = new String[3];
robots[0] = "Gundam"; // 1番目の要素。
robots[1] = "Doraemon"; // 2番目の要素。
robots[2] = "Atom"; // 3番目の要素

[] の中に数字を入れて、データを入れる場所を指定します。この数字のことを 添え字(そえじ) と呼びます。添え字は 0から始まる ことに注意してください。

間違った添え字

robots[3] = "Macross"; // エラー!!

robots[3] は「配列robotsの4番目の要素」を意味しています。robotsは3個しか定義されいないので、4番目にアクセスしようとするとエラーになります。

初期化時に中身をいちどに入れる

配列の宣言時に最初からデータを入れてしまうやり方があります。この場合、データを{}で囲みます。データが変わらないときはこのやり方が便利です。

int[] numbers = {7,5,3};
String[] cars = {"bmw", "toyota","honda","mazda","suzuki"};

4.おみくじ

ここからは、配列を実際に使ってみます。配列は、 同じものがたくさんあるとき に使うと便利です。

// おみくじ
size(300,300);
textSize(48);
String[] luck = {"Very Good", "Good", "Bad"};
int result = (int) random(3);
text(luck[result], 30, 100);

配列に "Very Good""Good""Bad" の3つを入れておき、実行するたびに乱数を使ってどれか1つを画面に表示します。

random(3) で、0から2までの数字がランダムに選ばれますが、float(小数)型であるため、そのままでは配列の添え字に使えません。配列の添え字には、int(整数)型にする必要があります。float(小数)型をint(整数)型に変更するには キャスト(型変換) という方法を使います。

// キャストの書き方
int(変換したい値)

小数を整数にキャストすると、小数点以下が切り捨てられます。キャストはfloat型からint型への変換だけではなく色々ありますので、調べてみると良いでしょう。

5.ボール落下

次は、少し難しい例です。ボールキャッチゲームなどでボールがたくさん出てくるようにします。ここでは、単純化のためにボールが落ちてくるだけのサンプルを作ります。課題集の課題「複数のボールキャッチゲームを作ってください」でキャッチする部分も含めたゲームの作成に挑戦してみてください。

配列を使わないボール落下

まず、配列を使わないでやったらどうなるかを見てみましょう

ボールがひとつのとき

// ボールが落ちてくる
float ball_y;
void setup(){
size(600,400);
ball_y = 0;
}
void draw(){
background(200);
ball_y += 5;
if(ball_y > 400){
ball_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(300, ball_y, 20,20);
}

黄色い丸に見立てたボールが落ちてきて、下まで来たらまた上から落ちてきます。ボールは横には動きませんからX座標を300固定にしておき、Y座標を ball_y という変数に入れます。

ボールが5つのとき

今度はボールが5つ落ちてくるものを配列を使わずにふつうの変数だけで作りましょう。

float ball1_y;
float ball2_y;
float ball3_y;
float ball4_y;
float ball5_y;
void setup(){
size(600,400);
ball1_y = 0;
ball2_y = 0;
ball3_y = 0;
ball4_y = 0;
ball5_y = 0;
}
void draw(){
background(200);
ball1_y += 5;
if(ball1_y > 400){
ball1_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(100, ball1_y, 20,20);
ball2_y += 5;
if(ball2_y > 400){
ball2_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(200, ball2_y, 20,20);
ball3_y += 5;
if(ball3_y > 400){
ball3_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(300, ball3_y, 20,20);
ball4_y += 5;
if(ball4_y > 400){
ball4_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(400, ball4_y, 20,20);
ball5_y += 5;
if(ball5_y > 400){
ball5_y = 0;
}
fill(255,255,0);
noStroke();
ellipse(500, ball5_y, 20,20);
}

ボールが5個あるので、それぞれのボールのY座標をあらわす変数を ball1_y から ball5_y まで5つ用意しています。それぞれについてさきほどと同じようにプログラムを書きます。X座標は100ずつ変えています。

配列を使うボール落下

配列を使わないと、5つのボールでもかなり長いプログラムになってしまいました。これを配列を使って書いてみましょう。

float[] ball_y = new float[5];
void setup(){
size(600,400);
for(int i = 0; i < 5; i++){
ball_y[i] = 0;
}
}
void draw(){
background(200);
fill(255,255,0);
noStroke();
for (int i = 0; i < 5; i++){
ball_y[i] += 5;
if(ball_y[i] > 400){
ball_y[i] = 0;
}
ellipse(i*100+100, ball_y[i],20, 20);
}
}

配列を使わない場合と比較するとかなり短くなっています。 中身を見てみましょう。 float[] ball_y = new float[5]; では、5つのデータが入る配列ball_yを定義しています。

// 配列の初期化
for(int i = 0; i < 5; i++){
ball_y[i] = 0;
}

ここでは、for文を使って配列のデータひとつひとつに0を入れて初期化しています。

(応用) ball_y[i] = 0;ball_y[i] = random(400); とするとゲームっぽくなります。

// ボールの表示
for (int i = 0; i < 5; i++){
ball_y[i] += 5;
if(ball_y[i] > 400){
ball_y[i] = 0;
}
ellipse(i*100+100, ball_y[i],20, 20);
}

for文を使っているだけで、変数のときのと同じですね。ellipseの i*100+100 の部分では、それぞれのボールのX座標を100ずつずらしています。( +100 がないとどうなるかは試してみましょう)

6.星スクロール

たくさんの円を星に見立て、右に移動させ横スクロールを表現します。 星は数が多いので配列を使うと便利です。順を追って作り方を見てみましょう。

画像はこちら↓

flying_tento.png

flying_tento.png

星をたくさん出す

まず、最初に星をランダムに並べるプログラムを作ります。

// 星をランダムに並べる
float[] stars = new float[100];
PImage tento;
void setup(){
size(600,400);
for(int i = 0; i < 100; i++){
stars[i] = random(0,600);
}
fill(255);
stroke(255);
tento = loadImage("flying_tento.png");
}
void draw(){
background(0);
for(int i = 0; i < 100; i++){
ellipse(stars[i], i*4,2,2);
}
image(tento,400,175);
}

実行するとこうなります。

setup()部分

// 星をランダムに並べる(setup部分)
float[] stars = new float[100];
PImage tento;
void setup(){
size(600,400);
for(int i = 0; i < 100; i++){
stars[i] = random(0,600);
}
fill(255);
stroke(255);
tento = loadImage("flying_tento.png");
}

まず、星100個のX座標を入れる配列starsを作ります。星は右に動いていくので、Y座標は変わらないためY座標の配列はいりません。 PImage tento はテントの画像を表示するための変数です。 setup() では、for文でそれぞれの星の最初のX座標を決めています。自然な並びになるように random() を使います。 fill(255)stroke(255) で、星のりんかくと中身の色を白にしています。

draw()部分

// 星をランダムに並べる(draw部分)
void draw(){
background(0);
for(int i = 0; i < 100; i++){
ellipse(stars[i], i*4,2,2);
}
image(tento,400,75);
}

ここでは、一個ずつの星を表示しています。星は ellipse で描きます。このとき、X座標は stars の値を使って、Y座標はたてに4ドットおきに均等に置きます。画面の縦の長さが400なので、4ドットおきに表示すればちょうど100個の星が描けます。 テントの画像が星よりも手前に来るように、最後に image() でテント画像を表示します。

星をスクロールさせる

それでは、星をスクロールさせてみましょう。drawの部分を変えます。

// 星をスクロールさせる(draw部分の追加分)
void draw(){
background(0);
for(int i = 0; i < 100; i++){
ellipse(stars[i], i*4,2,2);
stars[i] += 2;
if(stars[i] > width){
stars[i] = 0;
}
}
image(tento,400,175);
}

増やしたのは下の4行です。

// 星をスクロールさせる(draw部分の追加分)
stars[i] += 2;
if(stars[i] > width){
stars[i] = 0;
}

stars[i] += 2; で、星のX座標を増やしています。なので、drawが呼ばれるたびに星が右に2ドットずつ動いていきます。 if(stars[i] > width) で、星が右まで行ったときに星のX座標を0に戻しているので左からまた始まります。

完成版

float[] stars = new float[100];
PImage tento;
void setup(){
size(600,400);
for(int i = 0; i < 100; i++){
stars[i] = random(0,600);
}
fill(255);
stroke(255);
tento = loadImage("flying_tento.png");
}
void draw(){
background(0);
for(int i = 0; i < 100; i++){
ellipse(stars[i], i*4,2,2);
stars[i] += 2;
if(stars[i] > width){
stars[i] = 0;
}
}
image(tento,400,175);
}