Open8
Siv3D v0.6.7 新規追加・更新サンプル
OpenAI API (Chat, Image) を扱う機能
準備: 環境変数 MY_OPENAI_API_KEY
に、自身で発行した OpenAI API キー sk-???...
を設定します(適用には PC の再起動が必要)
Chat(同期、非同期)
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
const String API_KEY = EnvironmentVariable::Get(U"MY_OPENAI_API_KEY");
Print << U"(1) 単一のメッセージに回答";
Print << OpenAI::Chat::Complete(API_KEY, U"日本で一番高い山は?");
Print << U"(2) 会話に回答";
Print << OpenAI::Chat::Complete(API_KEY, {
{ U"system", U"回答はできる限り簡潔にして、末尾に!を付けてください。" },
{ U"user", U"白い食べ物は?" },
{ U"assistant", U"豆腐!" },
{ U"user", U"では黒いのは?" } });
auto task3 = OpenAI::Chat::CompleteAsync(API_KEY, U"JPEG 画像ファイルの拡張子は?");
auto task4 = OpenAI::Chat::CompleteAsync(API_KEY, {
{ U"user", U"PNG の P って何?" },
{ U"assistant", U"Perfect です。" },
{ U"user", U"本当ですか?" } });
while (System::Update())
{
if (task3.isReady()
&& task3.getResponse().isOK())
{
Print << U"(3) 非同期で単一のメッセージに回答";
Print << OpenAI::Chat::GetContent(task3.getAsJSON());
}
if (task4.isReady()
&& task4.getResponse().isOK())
{
Print << U"(4) 非同期で会話に回答";
Print << OpenAI::Chat::GetContent(task4.getAsJSON());
}
}
}
Image(同期)
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
Window::Resize(512, 512);
const String API_KEY = EnvironmentVariable::Get(U"MY_OPENAI_API_KEY");
const Texture texture{ OpenAI::Image::Create(API_KEY,
U"There are tall mountains in the distance. The sky is clear.",
OpenAI::ImageSize512) };
while (System::Update())
{
texture.draw();
}
}
Image(非同期)
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
const String API_KEY = EnvironmentVariable::Get(U"MY_OPENAI_API_KEY");
Array<Texture> textures;
auto task = OpenAI::Image::CreateAsync(API_KEY, U"Mount Fuji has erupted, and volcanic ash is falling on Tokyo.", 4, OpenAI::ImageSize256);
while (System::Update())
{
if (task.isReady())
{
for (const auto& image : task.get())
{
textures << Texture{ image };
}
}
for (size_t i = 0; i < textures.size(); ++i)
{
const double x = (i % 2) * 256.0;
const double y = (i / 2) * 256.0;
textures[i].draw(x, y);
}
}
}
アプリケーションの例
OSC 通信
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
const int16 port = 9000;
OSCReceiver receiver{ IPv4Address::Localhost(), port };
OSCSender sender{ IPv4Address::Localhost(), port };
while (System::Update())
{
if (SimpleGUI::Button(U"Send", Vec2{ 600, 20 }))
{
OSCMessage messsage;
messsage.beginBundle()
.beginMessage(U"/siv3d")
.addInt32(Scene::FrameCount())
.addString(U"Hello")
.addBool(true)
.endMessage()
.endBundle();
sender.send(messsage);
}
while (receiver.hasMessages())
{
const auto message = receiver.pop();
Print << message.addressPattern;
for (const auto& argument : message.arguments)
{
switch (argument.tag)
{
case OSCTypeTag::False:
case OSCTypeTag::True:
Print << argument.getBool();
break;
case OSCTypeTag::Char:
Print << argument.getChar();
break;
case OSCTypeTag::Int32:
Print << argument.getInt32();
break;
case OSCTypeTag::Int64:
Print << argument.getInt64();
break;
case OSCTypeTag::Float:
Print << argument.getFloat();
break;
case OSCTypeTag::Double:
Print << argument.getDouble();
break;
case OSCTypeTag::MIDIMessage:
Print << argument.getMIDIMessage();
break;
case OSCTypeTag::TimeTag:
Print << argument.getTimeTag();
break;
case OSCTypeTag::RGBAColor:
Print << argument.getColor();
break;
case OSCTypeTag::String:
case OSCTypeTag::Symbol:
Print << argument.getString();
break;
case OSCTypeTag::Blob:
Print << argument.getBlob().asArray();
break;
case OSCTypeTag::Nil:
Print << U"Nil";
break;
case OSCTypeTag::Infinitum:
Print << U"Infinitum";
break;
case OSCTypeTag::ArrayBegin:
Print << U"[";
break;
case OSCTypeTag::ArrayEnd:
Print << U"]";
break;
}
}
}
}
}
円を割線で切り取った形を描く関数
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 200, 100 }
.drawSegment(0_deg, 60, ColorF{ 0.9 });
Circle{ 400, 200, 100 }
.drawSegment(30_deg, 60, ColorF{ 0.9 });
Circle{ 650, 200, 100 }
.drawSegment(60_deg, 60, ColorF{ 0.9 });
Circle{ 150, 400, 100 }
.drawSegment(120_deg, 60, ColorF{ 0.25 });
Circle{ 400, 400, 100 }
.drawSegmentFromAngles(60_deg, 240_deg, ColorF{ 0.25 });
Circle{ 650, 400, 100 }
.drawSegmentFromAngles(90_deg, 120_deg, ColorF{ 0.25 });
}
}
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Draw(const Circle& circle, double angle, double height)
{
circle.drawFrame(6);
circle.drawSegment(angle, height, ColorF{ 0.2, 0.4, 0.8 });
double arcAngleHalf = std::acos(1.0 - (height / circle.r));
Line{ circle.getPointByAngle(angle), Arg::angle = (angle + 180_deg), height }
.draw(LineStyle::SquareDot, 6);
}
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Circle circle{ 400, 300, 200 };
double angle = 0_deg;
double height = (circle.r * 0.5);
while (System::Update())
{
SimpleGUI::Slider(U"angle: {:.1f}°"_fmt(Math::ToDegrees(angle)), angle, -2_pi, 2_pi, Vec2{ 20, 20 }, 150, 200);
SimpleGUI::Slider(U"height: {:.1f}"_fmt(height), height, 0, 400, Vec2{ 400, 20 }, 160, 200);
Draw(circle, angle, height);
}
}
長方形を斜め方向のグラデーションで描く関数
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Rect{ 100, 100, 600, 180 }
.draw(Arg::topLeft(0.3, 0.6, 0.9), Arg::bottomRight(1.0));
Rect{ 100, 300, 600, 180 }
.draw(Arg::topRight(0.3, 0.1, 0.3), Arg::bottomLeft(0.8, 0.4, 0.6));
}
}
SimpleMenuBar の項目へのチェック
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Array<std::pair<String, Array<String>>> menus
{
{ U"ゲーム", { U"新規", U"スコア", U"終了" }},
{ U"設定", { U"オプション A", U"オプション B", U"オプション C" }},
{ U"ヘルプ", { U"\U000F0625遊び方", U"\U000F14F7リリースノート", U"\U000F05E6ライセンス" }},
};
SimpleMenuBar menuBar{ menus };
while (System::Update())
{
if (const auto item = menuBar.update())
{
// 「終了」が押されたら
if (item == MenuBarItemIndex{ 0, 2 })
{
return;
}
// 「ライセンス」が押されたら
if (item == MenuBarItemIndex{ 2, 2 })
{
LicenseManager::ShowInBrowser();
}
if (item->menuIndex == 1)
{
// チェック状態を反転する
menuBar.setItemChecked(*item, (not menuBar.getItemChecked(*item)));
}
}
menuBar.draw();
}
}
JSON のバリデーション
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
const JSON json1 = UR"({
"name": "Albert",
"age": 42,
"object": {}
})"_json;
const JSON json2 = UR"({
"name": "Albert",
"age": 42,
"object": {
"string": "aaaa"
}
})"_json;
const JSON json3 = UR"({
"name": "Albert",
"age": 999,
"object": {
"string": "bbbb"
}
})"_json;
const JSONValidator validator = UR"({
"title": "A person",
"properties": {
"name": {
"description": "Name",
"type": "string"
},
"age": {
"description": "Age of the person",
"type": "number",
"minimum": 2,
"maximum": 200
},
"object": {
"type": "object",
"properties": {
"string": {
"type": "string"
}
},
"required": [
"string"
]
}
},
"required": [
"name",
"age",
"object"
],
"type": "object"
})"_jsonValidator;
{
JSONValidator::ValidationError error;
if (validator.validate(json1, error))
{
Print << U"OK";
}
else
{
Print << error;
}
}
{
JSONValidator::ValidationError error;
if (validator.validate(json2, error))
{
Print << U"OK";
}
else
{
Print << error;
}
}
{
JSONValidator::ValidationError error;
if (validator.validate(json3, error))
{
Print << U"OK";
}
else
{
Print << error;
}
}
while (System::Update())
{
}
}
コマンドライン引数を直接取得する関数
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
void Main()
{
int32 argc = System::GetArgc();
char** argv = System::GetArgv();
Print << argc;
for (int32 i = 0; i < argc; ++i)
{
Print << Unicode::Widen(argv[i]);
}
while (System::Update())
{
}
}
アドオンの実行優先度、更新と描画の個別指定
# include <Siv3D.hpp> // OpenSiv3D v0.6.7
struct Addon1 : IAddon
{
bool update() override
{
Print << U"Addon1::update()";
return true;
}
void draw() const override
{
Print << U"Addon1::draw()";
}
};
struct Addon2 : IAddon
{
bool update() override
{
Print << U"Addon2::update()";
return true;
}
void draw() const override
{
Print << U"Addon2::draw()";
}
};
struct Addon3 : IAddon
{
bool update() override
{
ClearPrint();
Print << U"Addon3::update()";
return true;
}
void draw() const override
{
Print << U"Addon3::draw()";
}
};
void Main()
{
Addon::Register<Addon1>(U"Addon1", 100, 300);
Addon::Register<Addon2>(U"Addon2", 200, 200);
Addon::Register<Addon3>(U"Addon3", 300, 100);
while (System::Update())
{
}
}