Goku Engine 0.1.1リリース: Quasar Questアップデートでの新機能と改善点



こんにちは、親愛なる友人たち、エキサイティングなアップデートをお伝えできて、とても嬉しいです。日本語を学んでコミュニケーションをより良くするために努力していますが、言語のミスを犯すかもしれませんので、その点をお詫び申し上げます。ご理解いただき感謝しています。

また、前回の[Qiita](https://qiita.com/ladroid/items/affc1949286ff7affed0)での記事に対する関心とサポートに心から感謝申し上げます。このプロジェクトに興味を持っていただけることは、本当に素晴らしいことです。

さて、大きなニュースに移りましょう！

## 公式ウェブサイトがオープンしました！

私たちの公式ウェブサイト、Goku Engine <https://gokuengine.com/> がオープンしました！ Gokuに関する最新のニュースやアップデートをすべて共有する場所です。ウェブサイトのソースコードも[GitHub](https://github.com/ladroid/goku-website)で見ることができます。現在、ブログは英語でありますが、日本語や他の言語を追加する作業を進めています。良いニュースは、メインページはすでに日本語で利用可能で
あることです！

また、私はGokuエンジンを使用したゲームの制作に取り組んでおり、この楽しいプロジェクトについても近々お知らせします。

さて、最新のGokuアップデート、バージョン0.1.1、Quasar Questと名付けられたものについて話しましょう。

## Quasar Questの新機能

以下は、Goku 0.1.1の新機能と改善点です：

**より良いアニメーションクラス**:

リファインされたAnimationクラスにより、キャラクターのアニメーションが簡単になりました。 1つのPNGファイルから行を設定できるようになり、テクスチャを別々のPNGにスライスする煩わしいプロセスにさようならを告げることができます。

| 前                                                                                                                                                                                                                                                                                                                                                                                                                                       | 後                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| ```// creating several times same animation but for left, right,etc.<br>let mut player_right = GameObject::new(texture_manager, Vector2(50, 50));<br>player_right.load_texture(Path::new("character_walk_anim_right.png"), 30, 30, 150)?;<br>let mut player_left = two_d::GameObject::new(texture_manager, nalgebra::Vector2::new(50, 50));<br>player_left.load_texture(std::path::Path::new("character_walk_anim_left.png"), 16, 18, 150, 0)?;``` | ```let mut player = two_d::GameObject::new(texture_manager, nalgebra::Vector2::new(50, 50));<br>player.load_texture("idle", std::path::Path::new("character_idle_anim.png"), 16, 18, 150, 0)?;<br>player.load_texture("walk_down", std::path::Path::new("character_walk_anim.png"), 16, 18, 150, 0)?;<br>player.load_texture("walk_up", std::path::Path::new("character_walk_anim.png"), 16, 17, 150, 1)?;<br>player.load_texture("walk_right", std::path::Path::new("character_walk_anim.png"), 16, 17, 150, 2)?;``` |   |
|                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |

毎回テクスチャをいくつかの別々の部分に切り取り、変数`player_left, player_right, etc.`を作成する必要はありません。今ではタグを追加し、そのタグを通じてアニメーションを作成することが可能です。1つの同じテクスチャに複数のタグを付けることができます。

**PointLightの完璧さ**:

改善されたPointLight機能を使用して、シーンを効果的に照らすことができます。

![Point light](https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/point_light.png)

コードサンプル:

```rust
let mut light_spot_texture = texture_creator.load_texture("point_light.png")?;
let light = two_d::PointLight::new(
    nalgebra::Vector2::new(400.0, 300.0),
    100.0,
    0.6,  // 強度: 0.0 (オフ) から 1.0 (最大強度)
    sdl2::pixels::Color::RGB(255, 255, 255)  // 純白の光のための白色。これは変更可能です！
);

....

// 各ライトをライトテクスチャにレンダリングする
window.canvas.with_texture_canvas(&mut darkness_texture, |canvas| {
    // 暗闇のために半透明の黒でテクスチャをクリアする
    canvas.set_draw_color(sdl2::pixels::Color::RGBA(0, 0, 0, 150));
    canvas.clear();
    
    // 各ライトをこの暗いテクスチャにレンダリングする
    light.render(canvas, &mut light_spot_texture);
})?;

// メインシーンにライトテクスチャをブレンドするためにブレンドモードをModに設定します
// そして、ライティング効果を得るために、ブレンドモードを設定し、darkness_textureをメインキャンバス上にレンダリングします
window.canvas.set_blend_mode(sdl2::render::BlendMode::Mod);
window.canvas.copy(&darkness_texture, None, None)?;
window.canvas.set_blend_mode(sdl2::render::BlendMode::None);
```

**AmbientLightFilterの追加**:

新しく導入されたAmbientLightFilterを使用して、ゲームの色グラデーションをシームレスに変更し、適切な雰囲気を設定できます。


![Ambient light](https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/ambient_filter.png "Ambient light")

コードサンプル:

```rust
// 変数を定義する
let mut light_texture = texture_creator.create_texture_streaming(None, 800, 600)?;
light_texture.set_blend_mode(sdl2::render::BlendMode::Add);
let light = two_d::AmbientFilter::new(0.6);  // 1.0は最大強度を意味します

....

// レンダリング
// 環境色（例：ダークブルー）でライトテクスチャをクリアする
light_texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
    for y in 0..600 {
        for x in 0..800 {
            let offset = y * pitch + x * 4;
            buffer[offset] = 60;       // 青 (Blue)
            buffer[offset + 1] = 0;   // 緑 (Green)
            buffer[offset + 2] = 100;   // 赤 (Red)
            buffer[offset + 3] = 255;             // Alpha
        }
    }
}).unwrap();

// 各ライトをライトテクスチャにレンダリングする
light.render(&mut window.canvas, &mut light_texture);

// メインシーンにライトテクスチャをブレンドするためにブレンドモードをModに設定する
window.canvas.set_blend_mode(sdl2::render::BlendMode::Mod);
window.canvas.copy(&light_texture, None, None)?;
window.canvas.set_blend_mode(sdl2::render::BlendMode::None);
```

**Spot Light**:

この新機能を使用して、必要な場所にスポットライトを当て、シーンの雰囲気とリアリズムを強化します。

<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/spot_light_1.png" alt="drawing" width="200" height="200">
<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/spot_light_2.png" alt="drawing" width="200" height="200">
<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/spot_light_3.png" alt="drawing" width="200" height="200">
<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/spot_light_4.png" alt="drawing" width="200" height="200">

コードサンプル:

```rust
let mut spotlight_texture = texture_creator.load_texture("spot_light.png")?;
let spotlight = two_d::SpotLight::new(
    nalgebra::Vector2::new(400.0, 300.0),
    nalgebra::Vector2::new(0.0, -1.0),   // 上向きに指している
    45.0,                                // 45度のコーン
    200.0,
    0.6,
    sdl2::pixels::Color::RGB(255, 255, 255)
);
let mut darkness_texture = texture_creator.create_texture_target(None, 800, 600)?;
darkness_texture.set_blend_mode(sdl2::render::BlendMode::Mod);

....

// 各ライトをライトテクスチャにレンダリングする
window.canvas.with_texture_canvas(&mut darkness_texture, |canvas| {
    // 暗闇のために半透明の黒でテクスチャをクリアする
    canvas.set_draw_color(sdl2::pixels::Color::RGBA(0, 0, 0, 150));
    canvas.clear();
    
    // 各ライトをこの暗いテクスチャにレンダリングする
    spotlight.render(canvas, &mut spotlight_texture);
})?;

// メインシーンにライトテクスチャをブレンドするためにブレンドモードをModに設定します
// そして、ライティング効果を得るために、ブレンドモードを設定し、darkness_textureをメインキャンバス上にレンダリングします
window.canvas.set_blend_mode(sdl2::render::BlendMode::Mod);
window.canvas.copy(&darkness_texture, None, None)?;
window.canvas.set_blend_mode(sdl2::render::BlendMode::None);
```

**ボタンデザインの選択**:
丸みを帯びたボタンまたは丸みを帯びていないボタンの選択により、ゲームのインターフェイスに完璧なタッチを加え、UIをあなたの好みに合わせてカスタマイズできます。

<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/button_rounded.png" alt="drawing" width="145" height="75">
<img src="https://raw.githubusercontent.com/ladroid/goku-website/main/article_assets/article_2/button_rectengular.png" alt="drawing" width="145" height="75">

コードサンプル 円形のボタン:

```rust
// レイヤー + ボタン
let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;
let mut ui_layer = two_d::Layer::new();
// フォントをロードする:
let font_path = std::path::Path::new("ARIALUNI.TTF");
let font_size = 24;
let font = std::sync::Arc::new(sdl2::ttf::Sdl2TtfContext::load_font(&ttf_context, font_path, font_size)?);
let text_box = std::rc::Rc::new(two_d::TextBox::new("Hello, world".to_lowercase(), font, sdl2::rect::Rect::new(50, 20, 120, 50)));
let button = std::rc::Rc::new(two_d::Button::new(text_box.clone(), 
sdl2::pixels::Color::RGB(123, 23, 56), 
sdl2::rect::Rect::new(50, 20, 120, 50), (0, 0), 10, 
Box::new(|| {
    println!("Button pressed!");
}),));
ui_layer.add_button(button.clone());

....

ui_layer.render(&mut window.canvas)?;
```

コードサンプル 長方形のボタン (最後の値（イベントの前）を0に設定する以外はすべて同じ):

```rust
// レイヤー + ボタン
let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;
let mut ui_layer = two_d::Layer::new();
// フォントをロードする:
let font_path = std::path::Path::new("ARIALUNI.TTF");
let font_size = 24;
let font = std::sync::Arc::new(sdl2::ttf::Sdl2TtfContext::load_font(&ttf_context, font_path, font_size)?);
let text_box = std::rc::Rc::new(two_d::TextBox::new("Hello, world".to_lowercase(), font, sdl2::rect::Rect::new(50, 20, 120, 50)));
let button = std::rc::Rc::new(two_d::Button::new(text_box.clone(), 
sdl2::pixels::Color::RGB(123, 23, 56), 
sdl2::rect::Rect::new(50, 20, 120, 50), (0, 0), 0, 
Box::new(|| {
    println!("Button pressed!");
}),));
ui_layer.add_button(button.clone());

....

ui_layer.render(&mut window.canvas)?;
```

**Profiler**:

Simple Profilerを使用して、ゲームを最適化し、パフォーマンスを分析および最適化するのに役立てます。

コードサンプル:

```rust
let mut profiler = two_d::Profiler::new();

....

// メインループ内
profiler.update(current_frame_time);
```

**キーボード用のGEvent**:

GEventへの移行により、キーボードイベントの処理がより効率的になり、プレイヤーにとってスムーズなインタラクションが確保されています。

**ダイアログシステムの改善**:

強化されたダイアログシステムを使用して、プレイヤーに魅力的な物語を提供し、レンダリングと描画をサポートすることで、テキストの追加も可能になりました。

コードサンプル:

```rust
let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;
let mut dialogue_box = two_d::DialogueBox::new();
// フォントをロードする:
let font_path = std::path::Path::new("ARIALUNI.TTF");
let font_size = 24;
let font = std::sync::Arc::new(sdl2::ttf::Sdl2TtfContext::load_font(&ttf_context, font_path, font_size)?);
let text_box = std::rc::Rc::new(two_d::DialogueTextBox::new(Some("Charlie".to_string()), "Hello, world".to_lowercase(), font, sdl2::rect::Rect::new(50, 500, 100, 80)));
dialogue_box.add_text(text_box);

....

// 何らかのイベントでダイアログボックスをアクティベートする
dialogue_box.activate();

// あなたのメインループ内で、他の要素をレンダリングする前または後に:
if dialogue_box.is_active {
    dialogue_box.render(&mut window.canvas)?;
}
```

**さらに多くの例**:

改善された例と追加の例を通じて、Gokuの機能を通じて可能性の拡がった領域を探索します。

## まとめ
これらの新しい変更により、Gokuは皆さんのゲーム開発の冒険のためのさらに優れたツールになることを願っています。 Quasar Questは、日々Gokuを向上させる多くのステップのうちの1つに過ぎません。この旅が私たちに何をもたらすのかを見るのが楽しみであり、将来さらに多くのアップデートを共有することを楽しみにしています。 皆さんのサポートはこのプロジェクトにとって非常に意味があり、Gokuで素晴らしいゲームを作成する皆さんのことを待ちきれません。これからもアップデートをお楽しみに、そしていつものように、幸せなゲーム開!

--- 

P.S.：例のファイルが.txt形式である現状について謝罪いたします。私はコアの改善に重点を置いていたため、それらを.rs形式に切り替える時間がほとんどありませんでした。でも心配しないでください、それはやるべきことのリストに載っています！さらに、いくつかのGUIのアップデートが予定されており、Gokuをさらにユーザーフレンドリーで直感的にするためです。

[GitHub](https://github.com/ladroid/goku) | [公式ウェブサイト Goku](https://gokuengine.com/) | [ドキュメンテーション](https://lados-organization.gitbook.io/goku/v/goku-game-engine_jp/)