Created
May 20, 2015 01:24
-
-
Save wx257osn2/03070a196bea3c541901 to your computer and use it in GitHub Desktop.
ねるねるねるね with Direct2D1.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <will/_2dim.hpp> | |
#include <will/com.hpp> | |
#include <vector> | |
#include <cstdint> | |
#include <cmath> | |
#include <d2d1.h> | |
std::int64_t timer; | |
double w, h; | |
static const double neData[] = {55.741471, 10.28401, 4.79822, 0.021, 9.59645, 0.0421, 14.394669, 0.0631, -5.261209, 4.31419, -10.522419, 8.62839, -15.783629, 12.94258, 0, 0, 6.37659, -4.48255, 13.70019, -2.33598, 3.661809, 1.07329, 5.271739, 2.856843, 5.934649, 4.458883, 0.66292, 1.60204, 0.37881, 3.022567, 0.25254, 3.369807, -0.25254, 0.69448, -0.78921, 5.65708, -9.733549, 6.74007, -4.62955, 0.56055, -5.44009, -1.65231, -5.36171, -2.81243, 0.11817, -1.74924, 1.20883, -3.06318, 3.54164, -3.04376, 2.10739, 0.0175, 3.04624, 1.34161, 3.63023, 2.19392, 0.584, 0.85232, 0.72605, 1.81512, 0.97859, 2.85684}; | |
static const double ruData[] = {47.547019, 15.301239, 3.78807, -0.0421, 7.57615, -0.0842, 11.36422, -0.12627, -3.40926, 5.3033, -6.81853, 10.6066, -10.22779, 15.9099, 4.12479, -3.43031, 8.0286, -6.13457, 12.69003, -9.34391, 0, 0, 4.54569, -3.12515, 6.69227, -3.4724, 3.77923, -0.61136, 5.3033, 2.58852, 5.3033, 2.58852, 0, 0, 1.76776, 2.65165, 0.31567, 9.65958, -1.45209, 7.00794, -7.00793, 4.48255, -7.00793, 4.48255, -1.53407, -0.82854, -1.8324, -2.22846, -0.44195, -3.78807, 0, 0, 1.95718, -2.58851, 5.99779, -0.94702, 4.04061, 1.6415, 5.93464, 3.15673, 5.93464, 3.15673}; | |
static const double stick[] = {52.534649, 9.619129, 0, 26.01143, 0, 26.01143, 0, 26.01143}; | |
will::two_dim::xy<double> stickRu = {42., -30.}; | |
will::two_dim::xy<double> fuPos ={-120. / 2, -75. / 2}; | |
int dataSize = 10; | |
double time = 0.; | |
int sendRu = 0; | |
int curRu = -5; | |
double pumpPos = 0; | |
int u = 4; | |
int pushed = -1; | |
//static const double sPos[] = {w - 125, w - 120, w - 120}; | |
//public var sName : Array = ["Perfect", "Cool", "Good"]; | |
bool next = false;//Ne.Ru | |
will::com_ptr<ID2D1SolidColorBrush> brush; | |
class path_geometry{ | |
will::com_ptr<ID2D1PathGeometry> path; | |
ID2D1GeometrySink* sink = nullptr; | |
public: | |
explicit path_geometry(ID2D1PathGeometry* p):path(p){} | |
path_geometry& operator=(ID2D1PathGeometry* p){path = p;return *this;} | |
void reset(){path.reset();} | |
template<typename F> | |
HRESULT operator()(const D2D1_POINT_2F& point, F&& f, D2D1_FIGURE_BEGIN beg = D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END end = D2D1_FIGURE_END_OPEN){ | |
auto hr = path->Open(&sink); | |
if(FAILED(hr)) | |
return hr; | |
sink->BeginFigure(point, beg); | |
f(sink); | |
sink->EndFigure(end); | |
return sink->Close(); | |
} | |
ID2D1PathGeometry* get(){return path.get();} | |
}geometry{nullptr}; | |
will::com_ptr<ID2D1SolidColorBrush> create_solid_color_brush(ID2D1HwndRenderTarget* rt, const D2D1_COLOR_F& col, const D2D1_BRUSH_PROPERTIES& prop = D2D1::BrushProperties()){ | |
return will::com_create_resource<ID2D1SolidColorBrush>([&](ID2D1SolidColorBrush** x){return rt->CreateSolidColorBrush(col, prop, x);}); | |
} | |
path_geometry create_geometry(ID2D1Factory* rt){ | |
return path_geometry{will::com_create_resource<ID2D1PathGeometry>([&](ID2D1PathGeometry** x){return rt->CreatePathGeometry(x);})}; | |
} | |
double linear(double a, double b, double g){ | |
return a * (1 - g) + b * g; | |
} | |
void drawNeru(ID2D1HwndRenderTarget* rt, double x, double y, double s, double g, float stroke_width){ | |
double dx = x + (fuPos.x + linear(neData[0], ruData[0], g))*s; | |
double dy = y + (fuPos.y + linear(neData[1], ruData[1], g))*s; | |
double cx = 0, cy = 0; | |
geometry(D2D1::Point2F(dx, dy), [&](ID2D1GeometrySink* sink){ | |
for (int i = 2; i < 2 + dataSize * 6; i += 6){ | |
sink->AddBezier(D2D1::BezierSegment( | |
D2D1::Point2F(dx + (cx + linear(neData[i ], ruData[i ], g))*s, | |
dy + (cy + linear(neData[i + 1], ruData[i + 1], g))*s), | |
D2D1::Point2F(dx + (cx + linear(neData[i + 2], ruData[i + 2], g))*s, | |
dy + (cy + linear(neData[i + 3], ruData[i + 3], g))*s), | |
D2D1::Point2F(dx + (cx + linear(neData[i + 4], ruData[i + 4], g))*s, | |
dy + (cy + linear(neData[i + 5], ruData[i + 5], g))*s))); | |
cx += linear(neData[i + 4], ruData[i + 4], g); | |
cy += linear(neData[i + 5], ruData[i + 5], g); | |
} | |
}); | |
rt->DrawGeometry(geometry.get(), brush.get(), stroke_width); | |
} | |
void drawStick(ID2D1HwndRenderTarget* rt, double x, double y, double s, float stroke_width){ | |
double dx = x + (fuPos.x + stick[0])*s; | |
double dy = y + (fuPos.y + stick[1])*s; | |
geometry(D2D1::Point2F(dx, dy), [&](ID2D1GeometrySink* sink){ | |
sink->AddBezier(D2D1::BezierSegment( | |
D2D1::Point2F(dx + stick[2 ]*s, | |
dy + stick[2 + 1]*s), | |
D2D1::Point2F(dx + stick[2 + 2]*s, | |
dy + stick[2 + 3]*s), | |
D2D1::Point2F(dx + stick[2 + 4]*s, | |
dy + stick[2 + 5]*s))); | |
}); | |
rt->DrawGeometry(geometry.get(), brush.get(), stroke_width); | |
} | |
struct Ru{ | |
double x, y, tx; | |
int p; | |
double grade = 0.; | |
bool onStick; | |
will::two_dim::xy<double> stickP = { 0, 0 }; | |
Ru(double x, double y, int p) :x(x), y(y), tx(x), p(p){} | |
void draw(ID2D1HwndRenderTarget* rt){ | |
brush->SetColor(D2D1::ColorF(0, 0.3f)); | |
rt->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(x - 30, y - 13), 80, 20), brush.get(), 0.f); | |
brush->SetColor(D2D1::ColorF(0)); | |
drawNeru(rt, x, y, 4, grade, 12.f); | |
if (onStick) | |
drawStick(rt, x + stickP.x, y + stickP.y, 4, 12.f); | |
brush->SetColor(D2D1::ColorF((0 + 64 * grade) / 256.f, (64 - 64 * grade) / 256.f, (0 + 64 * grade) / 256.f)); | |
drawNeru(rt, x, y, 4, grade, 6.f); | |
if (onStick){ | |
brush->SetColor(D2D1::ColorF((64 * grade) / 256.f, (0) / 256.f, (64 * grade) / 256.f)); | |
drawStick(rt, x + stickP.x, y + stickP.y, 4, 6.f); | |
} | |
} | |
void tick(int i){ | |
tx = (p - i) * 140 + w - 385; | |
x += (tx - x) / 4.0; | |
if (onStick){ | |
grade += (1 - grade) / 4.0; | |
stickP.x += (0 - stickP.x) / 4.0; | |
stickP.y += (0 - stickP.y) / 4.0; | |
} | |
} | |
/*public function mkC(r:int, g : int, b : int) :int{ | |
return r * 65536 + g * 256 + b; | |
}*/ | |
}; | |
std::vector<Ru> rus; | |
extern "C"{ | |
void __stdcall construct(ID2D1Factory* factory, ID2D1HwndRenderTarget* rt){ | |
/*tef.defaultTextFormat = new TextFormat("Arial", 30, 0xffffff); | |
tef.defaultTextFormat.align = "center"; | |
tef.x = w - 135; | |
tef.y = 300; | |
tef.width = 100; | |
tef.height = 100; | |
tef.text = "Test"; | |
tef.alpha = 0; | |
addChild(tef);*/ | |
const RECT r = [&]{ | |
RECT r; | |
GetWindowRect(rt->GetHwnd(), &r); | |
return r; | |
}(); | |
w = r.right - r.left; | |
h = r.bottom - r.top; | |
//w = 456.f; | |
//h = 456.f; | |
stickRu = {42., -30.}; | |
fuPos ={-120. / 2, -75. / 2}; | |
dataSize = 10; | |
sendRu = 0; | |
curRu = -5; | |
pumpPos = 0; | |
u = 4; | |
pushed = -1; | |
next = false;//Ne.Ru | |
rus.reserve(10); | |
for (int i = 0; i<10; ++i){ | |
rus.emplace_back(w + 100, h / 2, sendRu); | |
++sendRu; | |
} | |
brush = create_solid_color_brush(rt, D2D1::ColorF(D2D1::ColorF::White)); | |
geometry = create_geometry(factory); | |
} | |
void __stdcall run(std::int64_t timer){ | |
::timer = timer; | |
pumpPos += (0 - pumpPos) / 4.0; | |
//tef.alpha += (0 - tef.alpha) / 8.0; | |
while (rus.size()<10){ | |
rus.emplace_back(w + 100, h / 2, sendRu); | |
++sendRu; | |
} | |
if (timer % 30 == 0) | |
++curRu; | |
else if (timer % 60 == 15){ | |
pumpPos = h / 12 + h / 3; | |
u = 0; | |
} | |
for (auto it = rus.begin(); it != rus.end(); ++it){ | |
if (it->x < -100){ | |
it = rus.erase(it); | |
continue; | |
} | |
if (u == 3 && !it->onStick){ | |
if (w - 110 < it->x && it->x < w - 100 && pushed != it->p){ | |
it->onStick = true; | |
it->stickP.x = stickRu.x; | |
it->stickP.y = stickRu.y; | |
pushed = it->p; | |
int cu = std::abs(it->x - (w - 105)); | |
//tef.x = sPos[Math.floor((cu + 1) / 2)]; | |
//tef.text = sName[Math.floor((cu + 1) / 2)]; | |
//tef.alpha = 1; | |
} | |
else if (w - 165 < it->x && it->x < 45){ | |
pushed = it->p; | |
//tef.x = w - 115; | |
//tef.text = "Bad"; | |
//tef.alpha = 1; | |
} | |
} | |
it->tick(curRu); | |
} | |
++u; | |
} | |
void __stdcall render(ID2D1HwndRenderTarget* rt){ | |
rt->Clear(D2D1::ColorF(D2D1::ColorF::White)); | |
//spr.graphics.beginFill(0xffffff); | |
//spr.graphics.drawRect(0, 0, w, h); | |
brush->SetColor(D2D1::ColorF(0x602f00)); | |
rt->FillRectangle(D2D1::RectF(0.f, h / 2 + 40, w, h / 2 - 40), brush.get()); | |
brush->SetColor(D2D1::ColorF(0x854720)); | |
rt->FillRectangle(D2D1::RectF(0, h / 2 + 50, w, h / 2 - 50), brush.get()); | |
rt->DrawLine(D2D1::Point2F(w - 90, 0), D2D1::Point2F(w - 90, pumpPos + h / 6), brush.get(), 12.f); | |
brush->SetColor(D2D1::ColorF(0x0)); | |
drawNeru(rt, 100, 100, 2, (std::sin(timer / 4) + 1) / 2 * 1.2, 6.f); | |
for(auto&& x : rus) | |
x.draw(rt); | |
} | |
void __stdcall destruct(){ | |
geometry.reset(); | |
brush.reset(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment