アンケートの結果,予習希望多数でしたので予習を主体とした内容で進めます.もちろん補習では過去の内容の疑問点などの質問も受け付けます.
前回のプログラム例を示す.
Ball ball0; final float GRAVITY = 9.8 / 60; final float ELAS = 0.98; void setup(){ size(500, 500); ball0 = new Ball(); ball0.x = width / 2; ball0.y = height / 2; ball0.vx = 10; ball0.vy = -10; ball0.d = 50; } void draw(){ background(255, 255, 255); moveBall(ball0); drawBall(ball0); } void moveBall(Ball b){ b.x += b.vx; b.vy += GRAVITY; b.y += b.vy; if (b.x < (b.d / 2)){ b.x = b.d / 2; b.vx = ELAS * -b.vx; } if (b.x > (width - (b.d / 2))){ b.x = width - (b.d / 2); b.vx = ELAS * -b.vx; } if (b.y > height - (b.d / 2)){ b.y = height - (b.d / 2); b.vy = ELAS * -b.vy; } } void drawBall(Ball b){ ellipse(b.x, b.y, b.d, b.d); } class Ball{ float x; float y; float vx; float vy; float d; }
今回注目するのは,moveBall関数とdrawBall関数である.この二つの関数は名前の通り「ボールを動かす」「ボールを描く」という機能を持つ.主語に注目するといずれもボールに関するものである.
よって,この二つの関数もBallクラス(型)に含めてしまえばよりプログラムが見やすく,Ballクラス(型)を再利用しやすくなる.
そこで,メソッドという仕組みによりmoveBall関数とdrawBall関数をBallクラス(型)に組み込む.二つの関数をメソッド化した後のプログラムは以下のようになる.
Ball ball0; final float GRAVITY = 9.8 / 60; final float ELAS = 0.98; void setup(){ size(500, 500); ball0 = new Ball(); ball0.x = width / 2; ball0.y = height / 2; ball0.vx = 10; ball0.vy = -10; ball0.d = 50; } void draw(){ background(255, 255, 255); ball0.move(); ball0.draw(); } class Ball{ float x; float y; float vx; float vy; float d; void move(){ this.x += this.vx; this.vy += GRAVITY; this.y += this.vy; if (this.x < (this.d / 2)){ this.x = this.d / 2; this.vx = ELAS * -this.vx; } if (this.x > (width - (this.d / 2))){ this.x = width - (this.d / 2); this.vx = ELAS * -this.vx; } if (this.y > height - (this.d / 2)){ this.y = height - (this.d / 2); this.vy = ELAS * -this.vy; } } void draw(){ ellipse(this.x, this.y, this.d, this.d); } }
これによりプログラムは,
Ball ball0; final float GRAVITY = 9.8 / 60; final float ELAS = 0.98; void setup(){ size(500, 500); ball0 = new Ball(); ball0.x = width / 2; ball0.y = height / 2; ball0.vx = 10; ball0.vy = -10; ball0.d = 50; } void draw(){ background(255, 255, 255); ball0.move(); ball0.draw(); } ↑ ボールを動かすプログラム −−−−−−−−−−−−−−−−−−−−−−−−−−−− ↓ ボール(Ballクラス(型))を定義するプログラム class Ball{ float x; float y; float vx; float vy; float d; void move(){ this.x += this.vx; this.vy += GRAVITY; this.y += this.vy; if (this.x < (this.d / 2)){ this.x = this.d / 2; this.vx = ELAS * -this.vx; } if (this.x > (width - (this.d / 2))){ this.x = width - (this.d / 2); this.vx = ELAS * -this.vx; } if (this.y > height - (this.d / 2)){ this.y = height - (this.d / 2); this.vy = ELAS * -this.vy; } } void draw(){ ellipse(this.x, this.y, this.d, this.d); } }
として,二つに大きく分離されプログラムの見やすさが向上した.また他のプログラムでボール(Ballクラス(型))を扱いたい場合は,class Ball{...}を利用すればよく,プログラムの再利用が容易となっている.
メソッドの導入により
moveBall(ball0); drawBall(ball0);
は,
ball0.move(); ball0.draw();
となり,プログラムからもball0を動かす,ball0を描くことが明確に分かるようになっている.
ボールを使う側であるsetup関数は以下のように記述されている.クラスの属性を,ボールを使う側のプログラムから直接値を代入したりすることは,プログラムの見やすさからあまり好ましくない.
void setup(){ size(500, 500); ball0 = new Ball(); ball0.x = width / 2; ball0.y = height / 2; ball0.vx = 10; ball0.vy = -10; ball0.d = 50; }
よってアクセサメソッドを導入し,次のように書き換える.
Ball ball0; final float GRAVITY = 9.8 / 60; final float ELAS = 0.98; void setup(){ size(500, 500); ball0 = new Ball(); ball0.setX(width / 2); ball0.setY(height / 2); ball0.setVX(10); ball0.setVY(-10); ball0.setD(50); } void draw(){ background(255, 255, 255); ball0.move(); ball0.draw(); } class Ball{ float x; float y; float vx; float vy; float d; void setX(float x){ this.x = x; } void setY(float y){ this.y = y; } void setVX(float vx){ this.vx = vx; } void setVY(float vy){ this.vy = vy; } void setD(float d){ this.d = d; } void move(){ this.x += this.vx; this.vy += GRAVITY; this.y += this.vy; if (this.x < (this.d / 2)){ this.x = this.d / 2; this.vx = ELAS * -this.vx; } if (this.x > (width - (this.d / 2))){ this.x = width - (this.d / 2); this.vx = ELAS * -this.vx; } if (this.y > height - (this.d / 2)){ this.y = height - (this.d / 2); this.vy = ELAS * -this.vy; } } void draw(){ ellipse(this.x, this.y, this.d, this.d); } }