gotutiyan’s blog

競技プログラミングをやったりopenframeworksでお絵かきをしたりしています。

gotutiyan.io

agar.ioというゲームを思い出して作ったのでこの題名に。

小さい円とくっついて成長してくように見えます。画面を覆い尽くすほどの大きさになれば、黒い円が画面を元に戻します。
色は大きい円と小さい円の色を毎回合成しています。(単にHSBのHを取ってきて平均を取っているだけです。これが合成になっているのかはわかりません・・)

bool変数 isAddに関係している処理のおかげで、小さい円が当たれば「じわっ」と円が広がる様子を表現できました。


以下のコードは変数名をかなり雑に書いてしまったので、読みにくいです。時間があればリファクタリングします。
以下、簡単のため、下から出続ける小さい円を「小さい円」
広がっていく大きい円のうち色とりどりなものを「色付き円」
色付き円が広がりきれば出てくる黒い円を「黒い円」と呼ぶことにします。

#include "ofApp.h"
#define rep(i,j,k) for(int i=j;i<k;i++)

int y,speed,ccolorH=255,cccolorH=255;  
int bsize=0,wsize=0; //bsizeが黒い円、wsizeが色付き円の大きさ
bool isBig=false,isAdd=false;
int ct=0;
ofColor c,cc; //cのHSBにおけるHがccolorH, ccにおけるHがcccolorH(ひどい)
void ofApp::setup(){
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    ofSetColor(255);
    ofSetCircleResolution(32);
    c.setHsb(255,255,255);
    cc.setHsb(255,255,255);
    
    y=ofGetHeight()/2;
}

void ofApp::update(){
    
    if(isBig){ //色付き円が画面を覆い尽くしたとき
        bsize++;
        if(bsize>ofGetWidth()/2){  //黒い円が広がって、広がりきったら色々初期化
            wsize=0;
            isBig=false;
            bsize=0;
        }
    }else{  //色付き円がまだ大きくない時
        y-=5;  //小さい円を動かします
        if(y<wsize){   //色付き円と当たれば色を合成して、isAddをtrueに
            y=ofGetHeight()/2;
            isAdd=true;
            ccolorH=ofGetFrameNum()%255;
            c.setHsb(ccolorH,255,255);
            cccolorH=(ccolorH+cccolorH)/2;
            cc.setHsb(cccolorH,255,255);
        }
        
        if(wsize>ofGetWidth()/2-50){ //色付き円が広がりきれば、isBigがtrueに
            isBig=true;
        }
    }
    
    if(isAdd){  //isAddがtrueなら、色付き円を20ピクセル分広げます。
       //素直にwsize+=20と書くと、1フレームで20ピクセル一気に増えるので物足りないです。20フレームかけて1ピクセルずつ広げると良い感じになります。
        wsize++;
        ct++;
        if(ct>20){
            ct=0;
            isAdd=false;
        }
    }
}

void ofApp::draw(){
    ofTranslate(ofGetWidth()/2,ofGetHeight()/2);
    ofSetColor(c);
    ofDrawCircle(0,y,10,10);  //小さい円
    
    ofSetColor(cc);
    ofDrawCircle(0,0,wsize,wsize); //色付き円
    ofSetColor(0);
    ofDrawCircle(0,0,bsize,bsize); //黒い円
}