#はじめてのC++【40日目】

# はじめに

openframeworksでクラスを作れました。クラスの便利さを体感しましたが、文章に書き表せるほどまだ理解できていない。

## OF　ブロック崩し

### 実行画面

<img width="1010" alt="スクリーンショット 2019-04-17 21.13.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298612/6b14e21d-778c-05fc-a476-6159320ecb36.png">

### ソースコード

```cpp:Bar.h
#ifndef BAR_H
#define BAR_H

#include <stdio.h>
#include "ofMain.h"


class Bar {
public:
  void init( float _width, float _height, float _speed );//初期化

  void update();//更新
  void display();//描画

  void keyPressed(int key);//キーボードの読み取り

  float xPos;//x座標
  float yPos;//y座標
  float width;//長さ
  float height;//高さ
  float speed;//動く速さ

  bool XPlus = true;//右に進む or 左に進む
//  bool YPlus = false;

};

#endif
```

```cpp:Bar.cpp
#include "Bar.h"
#include "ofMAin.h"

void Bar::init( float _width, float _height, float _speed ){//初期化

  xPos = ofGetWidth() / 2.0;
  yPos = ofGetHeight() *  ( 8.0 / 10.0 );
  width = _width;
  height = _height;
  speed = _speed;

}

void Bar::update(){//バーを動かしたりする
  //xPos += speed;
  if( XPlus && xPos < ofGetWidth()-110 ){
      xPos += speed;
  }

  if( !XPlus && xPos > 0 ){
      xPos -= speed;
  }

}


void Bar::display(){//描画する
  ofRect( xPos, yPos, width, height);
}

void Bar::keyPressed(int key){

  if ( key == OF_KEY_RIGHT  ){//右のキーを押したら右に進む
    XPlus = true;
  }

  if ( key == OF_KEY_LEFT ){//左のキーを押したら左に進む

    XPlus = false;
  }

}
```

```cpp:Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H

#include <stdio.h>
#include "ofMain.h"

class Circle {
public:

  void init( float _y, int _eSize, float _speed ); //初期化するときに使うやつ
  void update();//更新する
  void display();//描画

  //ofVec2f position;//これも使えるかも

  float xPos;
  float yPos;
  float eSize;//円の大きさ
  float speed;

  bool XPlus = true;//衝突判定のときに使う
  bool YPlus = false;

};

#endif
```

```cpp:Circle.cpp

#include "Circle.h"

void Circle::init(float _y, int _eSize, float _speed){
  xPos = ofGetWidth() / 2;//真ん中の位置から始める。
  yPos = _y;//yは宣言時の引数
  eSize = _eSize;
  speed = _speed;//スピードも宣言できる。
}

void Circle::update(){


  if ( xPos > ofGetWidth() ){//壁の衝突判定 //バーとの衝突判定はまだできていない
    XPlus = false;
  }

  if ( xPos < 0 ){
    XPlus = true;
  }

  if ( yPos > ofGetHeight() ){
    YPlus = false;
  }

  if ( yPos < 0 ){
    YPlus = true;
  }


  XPlus ? xPos += speed : xPos -= speed;//壁反射
  YPlus ? yPos += speed : yPos -= speed;//壁反射


}

void Circle::display(){
  ofDrawCircle( xPos, yPos, eSize );//円byouga
}
```

```cpp:ofApp.h
#pragma once

#include "ofMain.h"
#include "Circle.h"
#include "Bar.h"

class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y);
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

		Circle c1;
		Circle c2;

		Bar bar;


};
```

```cpp:ofApp.cpp
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
  
  ofBackground( 255, 255, 255 );
  ofSetCircleResolution(64);
  c1.init(100, 10, 1.0);//y座標,円の大きさ,スピード
  c2.init(200, 15, 3.0);
  bar.init(100,20, 10);//width,height,speed

}

//--------------------------------------------------------------
void ofApp::update(){

  c1.update();
  c2.update();
  bar.update();

}

//--------------------------------------------------------------
void ofApp::draw(){

  ofSetColor(0,0,0);
  c1.display();
  c2.display();
  bar.display();

}


//--------------------------------------------------------------
void ofApp::keyPressed(int key){
 bar.keyPressed(key);
}
```

### 感想

同じクラス内の関数に 変数 を共有できるのがクラスを使うメリットの一つかな。
BallとBarの衝突判定もなんとなく実装できそうな気がする。
それにしても、openframeworksって便利ですね。今は、keyボードからの入力で左右に動かしているけど、OpenCVにたいなの使ってカメラから自分の手を認識してBarを動かすのもやってみたい。

### 参考にしたホームページ

http://r-dimension.xsrv.jp/classes_j/of_class_method/

## ロベールのC++

### template

ずいぶん昔にこのようなコードを書いたことがある。

```cpp

int Abso(int a){
  return a > 0? a : -a;
}

double Abso(double a){
  return a > 0? a : -a;
}
```

この場合は、 `Absの引数` によって実行される関数が変わってくる。
ですが、ほとんど同じ形なので無駄だと思いますよね。こんなときに、 **`template`** を使います！
では、早速使ってみます。

```cpp:template.cpp
#include <iostream>

template <typename TYPE>
  TYPE Abso(TYPE a)
  {
    return a > 0? a : -a;
  }

int main() {
  std::cout << Abso(-5) << std::endl;
  std::cout << Abso(-7.6) << std::endl;
  std::cout << Abso('c') << std::endl;
}
```

```plain:実行結果
5
7.6
c
```
　' c '　もできるのだなぁ。

# 終わりに

おやすみなさい