- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2016-12-14T19:50:19+09:00","default:kyo-in","kyo-in")
[[プログラミング基礎]]
#author("2016-12-14T20:17:23+09:00","default:kyo-in","kyo-in")
*予習(包含関係) [#u9f6116b]
これまで,クラスの属性にはint,float,booleanなど初めから用意されている型を用いてきた.しかしながら,自分で作ったクラスも型であるので,当然ながらそれもまたクラスの属性の型に利用できる.
例えばこれまで書いてきたボールを例に挙げると,位置(x,y),速度(vx,vy)は2次元ベクトルである.そこで,新たに2次元ベクトルを表すクラス(型)Vector2を作り,それを利用することもできる.
Ball ball0;
final float GRAVITY = 9.8 / 60;
final float ELAS = 0.98;
void setup(){
size(500, 500);
ball0 = new Ball(width / 2, height / 2, 10, -10, 50);
}
void draw(){
background(255, 255, 255);
ball0.move();
ball0.draw();
}
class Vector2{
float x;
float y;
Vector2(float x, float y)
{
this.x = x;
this.y = y;
}
}
class Ball{
Vector2 p;
Vector2 v;
float d;
Ball(float x, float y, float vx, float vy, float d){
this.p = new Vector2(x, y);
this.v = new Vector2(vx, vy);
this.d = d;
}
void move(){
this.p.x += this.v.x;
this.v.y += GRAVITY;
this.p.y += this.v.y;
if (this.p.x < (this.d / 2)){
this.p.x = this.d / 2;
this.v.x = ELAS * -this.v.x;
}
if (this.p.x > (width - (this.d / 2))){
this.p.x = width - (this.d / 2);
this.v.x = ELAS * -this.v.x;
}
if (this.p.y > height - (this.d / 2)){
this.p.y = height - (this.d / 2);
this.v.y = ELAS * -this.v.y;
}
}
void draw(){
ellipse(this.p.x, this.p.y, this.d, this.d);
}
}
以下のようにあるクラスが,他のクラスを属性(メンバ変数)として持つことを''包含関係''と呼ぶ.''has-a関係''とも呼ぶ.
class Ball{
Vector2 p;
Vector2 v;
*カメ(ヒント付き) [#yce1e0ca]
final float turtleD = 100; // 亀の大きさ(甲羅の直径)
Turtle turtle;
void setup() {
size(480, 480);
noStroke();
colorMode(HSB, 360, 100, 100);
turtle = new Turtle(turtleD, width / 2, height - turtleD);
}
void draw() {
background(0, 0, 100);
turtle.drawFigure();
turtle.move();
}
class Turtle {
final float vx0 = 0;
final float vy0 = -0.3;
float x;
float y;
float vx;
float vy;
float d;
Shell shell;
Head head;
Leg[] legs; //足は四本なので素直に配列を使う
Turtle(float d, float x, float y) { // 甲羅の直径と中心の初期位置
this.d = d;
this.x = x;
this.y = y;
vx = vx0;
vy = vy0;
head = new Head(d / 3, 0, - d / 2, x, y);
shell = new Shell(d, 0, 0, x, y);
//足を作る
//足は4本,すべて位置が違うので,インスタンス生成時にはfor文を用いていない
legs = new Leg[4];
legs[0] = ???;
...
legs[3] = ???;
}
void drawFigure() {
head.drawFigure(); // 頭を描画する
shell.drawFigure(); // 甲羅を描画する
//足を描く
for(int i = 0; i < legs.length; i++){
legs[i].drawFigure();
}
}
void move() {
// 上端判定
if (head.getTopY() < 0) {
vy = 0;
}
// 移動
x += vx;
y += vy;
head.move(x, y); // 頭を移動する
shell.move(x, y); // 甲羅を移動する
//足を移動する
for(int i = 0; i < legs.length; i++){
legs[i].move(x, y);
}
}
}
/** 甲羅 */
class Shell {
float d; // 甲羅の直径
float x; // 甲羅の中心のx座標
float y; // 甲羅の中心のy座標
float offsetX; // 体の中心からのx方向のoffset
float offsetY; // 体の中心からのy方向のoffset
Shell(float d, float offsetX, float offsetY, float baseX, float baseY) { //
this.d = d;
this.offsetX = offsetX;
this.offsetY = offsetY;
x = baseX + offsetX;
y = baseY + offsetY;
}
void drawFigure() {
fill(150, 50, 50);
ellipse(x, y, d, d);
}
void move(float baseX, float baseY) {
x = baseX + offsetX;
y = baseY + offsetY;
}
}
/** 頭 */
class Head {
float d; // 頭の直径
float x; // 頭の中心のx座標
float y; // 頭の中心のy座標
float offsetX; // 体の中心からのx方向のoffset
float offsetY; // 体の中心からのy方向のoffset
Head(float d, float offsetX, float offsetY, float baseX, float baseY) {
this.d = d;
this.offsetX = offsetX;
this.offsetY = offsetY;
x = baseX + offsetX;
y = baseY + offsetY;
}
/** 頭頂のy座標を返す */
float getTopY() {
return y - d / 2;
}
void drawFigure() {
fill(50, 50, 70);
ellipse(x, y, d, d);
}
void move(float baseX, float baseY) {
x = baseX + offsetX;
y = baseY + offsetY;
}
}
/*足*/
class Leg {
???
}