Created
June 28, 2017 14:34
-
-
Save sknjpn/58d0b5ffde1de91e2331a8c32650ebf6 to your computer and use it in GitHub Desktop.
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 <Siv3D.hpp> // OpenSiv3D v0.1.5 | |
# include <HamFramework.hpp> | |
struct Unit | |
{ | |
Unit(const Vec2& _pos) | |
: pos(_pos) | |
, isPlant(RandomBool(0.95)) | |
, angle(RandomVec2(1.0)) | |
, v(RandomVec2(0.0)) | |
, energy(Random(25, 100)) | |
, timer1(Random(150.0, 300.0)) | |
, target(NULL) | |
{} | |
Unit(const Unit* _u) | |
: pos(_u->pos) | |
, isPlant(RandomBool(0.01) ? !_u->isPlant : _u->isPlant) | |
, angle(RandomVec2(1.0)) | |
, v(RandomVec2(1.0)) | |
, energy(Random(25, 50)) | |
, timer1(Random(150.0, 300.0)) | |
, target(NULL) | |
{} | |
Vec2 pos; | |
bool isPlant; | |
Vec2 angle; | |
Vec2 v; | |
double energy; | |
Unit* target; | |
//AI | |
double timer1; | |
}; | |
void Main() | |
{ | |
Window::SetTitle(L"Lonely Creatures"); | |
Window::Resize(1280, 720); | |
Window::SetBaseSize(Window::Size()); | |
Graphics::SetBackground(Palette::Skyblue); | |
Array<Unit> units; | |
const double width = 64.0; | |
const double sizeX = 512; | |
const double sizeY = 512; | |
for (int i = 0; i < 200; i++) | |
units.push_back(RandomVec2(sizeX, sizeY)); | |
Grid<Array<Unit*>> data(int(sizeX / width) + 1, int(sizeY / width) + 1); | |
Camera2D camera; | |
while (System::Update()) | |
{ | |
for (auto& u : units) | |
{ | |
if (u.isPlant) | |
{ | |
u.energy += 0.1; | |
} | |
else | |
{ | |
if (u.target == NULL) | |
{ | |
u.timer1 -= 1.0; | |
if (u.timer1 < 0) | |
{ | |
u.timer1 = Random(150.0, 300.0); | |
u.angle = RandomVec2(1.0); | |
} | |
} | |
else | |
{ | |
if ((u.target->pos - u.pos).length() < 8.0) | |
{ | |
u.target->energy -= 5.0; | |
u.energy += 1.5; | |
} | |
u.angle = (u.target->pos - u.pos).normalized(); | |
} | |
u.energy -= 0.1; | |
u.v += u.angle*0.05; | |
} | |
u.v /= 1.1; | |
} | |
for (int i = 0; i < units.size(); i++) | |
{ | |
auto& u = units[i]; | |
if (u.energy > 100.0) | |
{ | |
u.energy -= 50.0; | |
units.push_back(&u); | |
} | |
} | |
Erase_if(units, [&](Unit& u) {return u.energy <= 0.0; }); | |
for (auto& p : step(data.size())) data[p.x][p.y].clear(); | |
for (auto& u : units) | |
{ | |
//運動処理 | |
u.pos += u.v; | |
if (u.pos.x < 0) u.pos.x = 0.0; | |
if (u.pos.y < 0) u.pos.y = 0.0; | |
if (u.pos.x > sizeX) u.pos.x = sizeX; | |
if (u.pos.y > sizeY) u.pos.y = sizeY; | |
data[int(u.pos.x / width)][int(u.pos.y / width)].push_back(&u); | |
} | |
for (auto& u1 : units) | |
{ | |
u1.target = NULL; | |
for (int x = Max(0, int(u1.pos.x / width) - 1); x <= Min(int(sizeX / width), int(u1.pos.x / width) + 1); x++) | |
{ | |
for (int y = Max(0, int(u1.pos.y / width) - 1); y <= Min(int(sizeY / width), int(u1.pos.y / width) + 1); y++) | |
{ | |
for (auto& u2 : data[x][y]) | |
{ | |
if (&u1 != u2 && !(u1.pos - u2->pos).isZero()) | |
{ | |
const double length = (u1.pos - u2->pos).length(); | |
if (length < 8.0) u1.v += (u1.pos - u2->pos).normalized()*(16.0 - length)*0.01; | |
if (!u1.isPlant && u2->isPlant && (u1.pos - u2->pos).length() < 16.0 && u1.angle.cross((u2->pos - u1.pos).normalized()) < 0.7) | |
{ | |
if (u1.target == NULL || (u1.pos - u1.target->pos).length() > (u1.pos - u2->pos).length()) u1.target = u2; | |
} | |
} | |
} | |
} | |
} | |
} | |
camera.update(); | |
{ | |
auto t = camera.createTransformer(); | |
for (double x = 0; x <= sizeX; x += width) Line(x, 0, x, sizeY).draw(2, Palette::Gray); | |
for (double y = 0; y <= sizeY; y += width) Line(0, y, sizeX, y).draw(2, Palette::Gray); | |
for (const auto& u : units) | |
{ | |
const double theta = atan2(u.angle.y, u.angle.x); | |
if (!u.isPlant) Circle(u.pos, 24).drawPie(theta + 0.78, 1.57, ColorF(Palette::Red, 0.5)); | |
} | |
for (const auto& u : units) | |
{ | |
const Color& color = u.isPlant ? Palette::Green : Palette::Orange; | |
Line(0.0, 0.0, 8.0, 0.0).movedBy(u.pos.movedBy(-4.0, -6.0)).draw(Palette::Black); | |
Line(0.0, 0.0, u.energy*0.08, 0.0).movedBy(u.pos.movedBy(-4.0, -6.0)).draw(Palette::Yellow); | |
Circle(u.pos, 4).draw(color).drawFrame(1, Palette::Black); | |
} | |
RectF(sizeX, sizeY).drawFrame(0, 2, Palette::Black); | |
} | |
camera.draw(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment