[work 103] ひらがなのタイル
![[work 103] ひらがなのタイル](https://i0.wp.com/tsukuru.hayato-works.com/wp-content/uploads/2019/10/outFrameImg0000-2.png?fit=1024%2C576&ssl=1)
Movie
Source code
about
- 上下左右に動くひらがなのタイル
file
- 上部にあるファイル名が表示されているボタンを押すと、表示されるファイルが切り替わります
- 別ウィンドウ表示したい時や行番号などが無いRawMode表示したい時は、コード内右上のボタンを押してください(ボタンはマウスオーバーすると表示されます)
#include "ofMain.h"
#include "ofApp.h"
//================================
int main( ){
// 4K:4096x2160
// 2K:2048x1080
// FullHD:1920x1080
// HD:1440x1080
// HD720p:1280x720
// DVD:720x480
// setup the GL context
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 "Tile.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:
std::shared_ptr<Tile> tile;
};
#include "ofApp.h"
ofApp::ofApp(){
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(255);
ofSetBackgroundAuto(true);
ofSetVerticalSync(true);
tile = make_shared<Tile>();
tile->setup();
}
//--------------------------------------------------------------
void ofApp::update(){
tile->update();
}
//--------------------------------------------------------------
void ofApp::draw(){
tile->display();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 's') {
ofImage img;
img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
img.save("screenshot.png");
}
}
#ifndef Tile_hpp
#define Tile_hpp
#include <stdio.h>
#include "ofMain.h"
struct TileSettings {
int col;
int row;
ofVec2f from;
ofVec2f to;
ofVec2f current;
ofVec2f dir;
bool wrap;
ofColor color;
ofTexture tex;
};
enum MoveDir {
TILE_UP = 0,
TILE_DOWN,
TILE_LEFT,
TILE_RIGHT,
TILE_PAUSE
};
struct Command {
MoveDir dir;
std::vector<int> pos;
};
class Tile {
public:
Tile();
~Tile();
void setup();
void update();
void display();
private:
void setTo(MoveDir dir, std::vector<int> position);
int colMax, rowMax;
float tileSize;
std::vector<TileSettings> tile;
std::list<Command> cmd;
};
#endif /* Tile_hpp */
#include "Tile.hpp"
#include <codecvt>
Tile::Tile()
{
}
Tile::~Tile()
{
}
void Tile::setup()
{
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
std::u32string str = U"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん";
ofTrueTypeFontSettings settings("font/HiraginoProNW4.ttc", 30);
settings.addRanges(ofAlphabet::Japanese);
settings.contours = true;
ofTrueTypeFont font;
font.load(settings);
colMax = 5;
rowMax = 5;
tileSize = 100;
for (int i = 0; i < colMax; i++) {
for (int j = 0; j < rowMax; j++) {
TileSettings ts;
ts.col = i;
ts.row = j;
ts.from = ofVec2f(tileSize / 2 + (tileSize * i), tileSize / 2 + (tileSize * j));
ts.to = ts.from;
ts.current = ts.to;
ts.dir = ofVec2f(0, 0);
ts.wrap = false;
ts.color = ofColor(ofRandom(255), ofRandom(255), ofRandom(255));
int idx = (int)ofRandom(str.size());
std::string conv = converter.to_bytes(str.at(idx));
ts.tex = font.getStringTexture(conv);
tile.push_back(ts);
}
}
}
void Tile::update()
{
int step = ofGetFrameNum() % (int)ofGetTargetFrameRate();
if (step != 0) {
for (TileSettings &ts : tile) {
ofVec2f to;
ofVec2f d;
if (ts.wrap) {
to = ts.from + ts.dir * tileSize;
} else {
to = ts.to;
}
d = to - ts.from;
float scale = ofMap(step, 0, (int)ofGetTargetFrameRate() - 1, 0, 1);
ts.current = ts.from + d * scale;
}
} else {
// set next position
Command c;
float p = ofRandom(1);
if (p < 0.25) {
c.dir = TILE_UP;
} else if (p < 0.5) {
c.dir = TILE_DOWN;
} else if (p < 0.75) {
c.dir = TILE_LEFT;
} else {
c.dir = TILE_RIGHT;
}
std::vector<int> pos;
if (c.dir == TILE_UP || c.dir == TILE_DOWN) {
std::vector<int> col;
for (int i = 0; i < colMax; i++) {
col.push_back(i);
}
pos = col;
} else {
std::vector<int> row;
for (int i = 0; i < rowMax; i++) {
row.push_back(i);
}
pos = row;
}
int size = (int)ofRandom(1, pos.size());
for (int i = 0; i < size; i++) {
int idx = (int)ofRandom(1, pos.size());
c.pos.push_back(pos.at(idx));
pos.erase(pos.begin() + idx);
}
setTo(c.dir, c.pos);
}
}
void Tile::display()
{
ofRectangle window;
window.setFromCenter(ofGetWidth() / 2, ofGetHeight() / 2, colMax * tileSize, rowMax * tileSize);
ofVec2f offset = ofVec2f(window.getTopLeft());
ofPushMatrix();
ofTranslate(offset);
ofFill();
for (TileSettings ts : tile) {
ofSetColor(ts.color);
ts.tex.setAnchorPercent(0.5, 0.5);
ts.tex.draw(ts.current, tileSize, tileSize);
if (ts.wrap) {
ofVec2f from = ts.to - ts.dir * tileSize;
ofVec2f current = from + (ts.current - ts.from);
ts.tex.setAnchorPercent(0.5, 0.5);
ts.tex.draw(current, tileSize, tileSize);
}
}
ofPopMatrix();
// Mask
ofSetColor(255);
ofBeginShape();
ofVertex(0, 0);
ofVertex(ofGetWidth(), 0);
ofVertex(ofGetWidth(), ofGetHeight());
ofVertex(0, ofGetWidth());
ofNextContour(true);
ofVertex(window.getTopLeft());
ofVertex(window.getTopRight());
ofVertex(window.getBottomRight());
ofVertex(window.getBottomLeft());
ofEndShape();
}
void Tile::setTo(MoveDir dir, std::vector<int> position)
{
for (TileSettings &ts : tile) {
ts.wrap = false;
ts.from = ts.to;
ts.current = ts.from;
}
if (dir == TILE_DOWN) { // Down
for (int pos : position) {
for (TileSettings &ts : tile) {
if (ts.col == pos) {
ts.dir = ofVec2f(0, 1);
if (ts.row == rowMax - 1) {
ts.row = 0;
ts.wrap = true;
} else {
ts.row++;
}
ts.to = ofVec2f(tileSize / 2 + (tileSize * ts.col), tileSize / 2 + (tileSize * ts.row));
}
}
}
} else if (dir == TILE_UP) { // Up
for (int pos : position) {
for (TileSettings &ts : tile) {
if (ts.col == pos) {
ts.dir = ofVec2f(0, -1);
if (ts.row == 0) {
ts.row = rowMax - 1;
ts.wrap = true;
} else {
ts.row--;
}
ts.to = ofVec2f(tileSize / 2 + (tileSize * ts.col), tileSize / 2 + (tileSize * ts.row));
}
}
}
} else if (dir == TILE_RIGHT) { // Right
for (int pos : position) {
for (TileSettings &ts : tile) {
if (ts.row == pos) {
ts.dir = ofVec2f(1, 0);
if (ts.col == colMax - 1) {
ts.col = 0;
ts.wrap = true;
} else {
ts.col++;
}
ts.to = ofVec2f(tileSize / 2 + (tileSize * ts.col), tileSize / 2 + (tileSize * ts.row));
}
}
}
} else if (dir == TILE_LEFT) { // Left
for (int pos : position) {
for (TileSettings &ts : tile) {
if (ts.row == pos) {
ts.dir = ofVec2f(-1, 0);
if (ts.col == 0) {
ts.col = colMax - 1;
ts.wrap = true;
} else {
ts.col--;
}
ts.to = ofVec2f(tileSize / 2 + (tileSize * ts.col), tileSize / 2 + (tileSize * ts.row));
}
}
}
} else { // Pause
// do nothing
}
}
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
| category | API/Lib |
| c++ | std::wstring_convert |
| c++ | std::u32string |
| openframeworks | ofTrueTypeFontSettings |
| openframeworks | ofTrueTYpeFont |
| openframeworks | ofTexture |
| openframeworks | ofRectangle |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode