[work 3] bouncing ball in a box

[work 3] bouncing ball in a box

Movie

Source code

about

  • ボックス内でボールが跳ね回る
  • ボールの軌跡は30フレーム分だけ描画する
  • だんだんとボールの不透明度が下がる
  • ofRotateで座標系を回転させる

file

  • 上部にあるファイル名が表示されているボタンを押すと、表示されるファイルが切り替わります
  • 別ウィンドウ表示したい時や行番号などが無いRawMode表示したい時は、コード内右上のボタンを押してください(ボタンはマウスオーバーすると表示されます)
#include "ofMain.h"
#include "ofApp.h"

//===========================================
int main( ){

    // 4K:4096x2160
    // 2K:2048x1080
    // FullHD:1920x1080
    // HD:1440x1080
    // HD720p:1280x720
    // DVD:720x480
	ofSetupOpenGL(1280,720, OF_WINDOW);

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp( new ofApp());

}
#pragma once

#include "ofMain.h"
#include "Ball.hpp"

class ofApp : public ofBaseApp{
	public:
    ofApp();
    ~ofApp();
    
		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);
    
private:
    float degX;
    float degY;
    float degZ;
    ofEasyCam cam;
    Ball *ball;
};
#include "ofApp.h"

ofApp::ofApp(){
    ball = new Ball();
    degX = 0;
    degY = 0;
    degZ = 0;
}

ofApp::~ofApp(){
    delete ball;
}

//--------------------------------------------------------------
void ofApp::setup(){
    double fps = 30;
    
    ofBackground(255, 255, 255);
    ofSetBackgroundAuto(true);  // clear frame:true
    ofSetFrameRate(fps);
    
    ball->setup();
}

//--------------------------------------------------------------
void ofApp::update(){
    ball->update();
}

//--------------------------------------------------------------
void ofApp::draw(){
    cam.begin();
    degX += 1;
    degZ += 1;
    ofRotateXDeg(degX);
    ofRotateZDeg(degZ);
    ofSetColor(0, 0, 0);
    ofNoFill();
    ofDrawBox(0, 0, 0, 300);
    ball->draw();
    cam.end();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if (key == 's') {
        /* start */
        std::cout << "record" << std::endl;
        //ir->start();
    } else if (key == 'e') {
        /* stop */
        std::cout << "end" << std::endl;
        //ir->stop();
    } else {
        /* do nothing */
    }
}
#ifndef Ball_hpp
#define Ball_hpp

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

class Ball {
public:
    Ball();
    ~Ball();
    
    void setup();
    void update();
    void draw();
    
private:
    std::deque<ofVec3f> location;
    ofVec3f velocity;
    int lifeTime;
    int radius;
};
#endif /* Ball_hpp */
#include "Ball.hpp"

Ball::Ball()
{
    lifeTime = 30;
    radius = 10;
}


Ball::~Ball()
{
    
}

void Ball::setup()
{
    velocity = ofVec3f(10, 20, 30);
    location.push_front(ofVec3f(0, 0, 0));
    
    for (int i = 0; i < lifeTime - 1; i++) {
        if (location[i].x + velocity.x < -(150 - radius) || (location[i].x + velocity.x > (150 - radius))) {
            velocity.x *= -1;
        }
        if (location[i].y + velocity.y < -(150 - radius) || (location[i].y + velocity.y > (150 - radius))) {
            velocity.y *= -1;
        }
        if (location[i].z + velocity.z < -(150 - radius) || (location[i].z + velocity.z > (150 - radius))) {
            velocity.z *= -1;
        }
        
        location.push_back(location[i] + velocity);
    }
}


void Ball::update()
{
    ofVec3f loc = location.back();
    
    if (loc.x + velocity.x < -(150 - radius) || (loc.x + velocity.x > (150 - radius))) {
        velocity.x *= -1;
    }
    if (loc.y + velocity.y < -(150 - radius) || (loc.y + velocity.y > (150 - radius))) {
        velocity.y *= -1;
    }
    if (loc.z + velocity.z < -(150 - radius) || (loc.z + velocity.z > (150 - radius))) {
        velocity.z *= -1;
    }
    
    location.pop_front();
    location.push_back(loc + velocity);
}


void Ball::draw()
{
    int life = 0;
    for (auto itr = location.begin(); itr != location.end(); itr++) {
        life++;
        ofSetColor(0, 255, 255, (255 / lifeTime) * life);
        ofFill();
        ofDrawSphere((*itr).x, (*itr).y, (*itr).z, radius);
    }
}

Link to the API reference page

ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。

categoryAPI
openframeworksofVec3f
openframeworksof3dGraphics ofDrawSphere