LoginSignup
12
14

More than 5 years have passed since last update.

openFrameworksで3D空間上にライフゲームを描画する

Last updated at Posted at 2015-09-25

イベント映像を制作する際になにかしらサイバーっぽいアニメーションを使いたかったため、
openFrameworksにて3D上に平面のライフゲームを描画させました。

lifeGameObject.h

#pragma once
#include "ofMain.h"

class lifeGameObject {
public:
    void setup(ofPoint center, int xChellCount,int yChellCount);
    void update();
    void draw();
private:
    ofPoint center; //中央の座標
    int xChellCount; // 横のセル数
    int yChellCount;  // 縦のセル数
    bool aliveNow[100][100];
    bool aliveNext[100][100];
    ofPlanePrimitive plainPrimitive;
};

と宣言し、

lifeGameObject.cpp
#include "lifeGameObject.h"

void lifeGameObject::setup(ofPoint _center, int _xChellCount,int _yChellCount) {
    center = _center;
    xChellCount = _xChellCount;
    yChellCount = _yChellCount;
    plainPrimitive = ofPlanePrimitive(8, 8, 2, 2);

    // ライフゲームの最初のデータはランダムとしました
    for (int i = 0; i < xChellCount; i++) {
        for (int j = 0; j < yChellCount; j++) {
            aliveNow[i][j] = ((int)ofRandom(2))%2;
            aliveNext[i][j] = false;
        }
    }
}

void lifeGameObject::update() {
    // 各セルに対し判定を行う
    for (int i = 0; i < xChellCount; i++) {
        for (int j = 0; j < yChellCount; j++) {
            // 自分の周囲の生存セル数を取得
            int aliveCount = (int)aliveNow[i-1][j-1] + (int)aliveNow[i-1][j] + (int)aliveNow[i-1][j+1] + (int)aliveNow[i][j-1] + (int)aliveNow[i][j+1] + (int)aliveNow[i+1][j-1] + (int)aliveNow[i+1][j] + (int)aliveNow[i+1][j+1];
            if (aliveNow[i][j] == true) { // 現在生存している場合
                if (aliveCount == 2 || aliveCount == 3) {
                    aliveNext[i][j] = true; // 2か3であれば生存
                    continue;
                }
            } else { // 現在死亡している場合
                if (aliveCount == 3) { // 3であれば誕生
                    aliveNext[i][j] = true;
                    continue;
                }
            }
            aliveNext[i][j] = false;
        }
    }
    for (int i = 0; i < xChellCount; i++) {
        for (int j = 0; j < yChellCount; j++) {
            aliveNow[i][j] = aliveNext[i][j];
        }
    }
}

void lifeGameObject::draw() {
    ofSetColor(255);
    for (int i = 0; i < xChellCount; i++) {
        int xPosition = center.x + (i-xChellCount/2) * 10;
        for (int j = 0; j < yChellCount; j++) {
            int yPosition = center.y + (j-yChellCount/2) * 10;
            if (aliveNow[i][j] == true) {
                plainPrimitive.setPosition(xPosition, yPosition, center.z);
                plainPrimitive.draw();
            }
        }
    }
}

あとは呼び出し元から lifeGameObjects.setup(ofPoint(0,0,0), 100, 100); といった形で宣言してやり、updateとdrawを適宜呼び出せば動きます。

スクリーンショット 2015-09-25 12.01.27.png

C++とoFへの理解がまだ薄いせいか、かなり冗長なコードとなってしまいました。

12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14