C++OpenSiv3D入門講座 Vol. 11 演習問題の解答

C++OpenSiv3D入門講座

以下に演習問題の解答例を示す。

Vol. 01

演習問題(コンソール)

1問目

ソースコードを開く

#include <iostream>

int main() {
    int input;
    std::cout << "整数値を入力してください:" << std::endl;
    std::cin >> input;//inputに入力された数値を代入
    std::cout << "入力された値は、" << input << "です。" << std::endl;

    return 0;
}

2問目
ソースコードを開く

#include <iostream>

class Vector3 {
public:
    int x, y, z;

    // コンストラクタ
    Vector3(int _x, int _y, int _z) {
        x = _x;
        y = _y;
        z = _z;
    }

    // x, y, zの値を表示
    void show() {
        std::cout << x << "," << y << "," << z << std::endl;
    }

    // x * y * zの値を表示
    void showMultiple() {
        std::cout << x *y* z << std::endl;
    }
};

int main() {
    Vector3 vec3{ 1, 2, 3 };
    vec3.show();
    vec3.showMultiple();

    return 0;
}

演習問題(OpenSiv3D)

1~3問目

ソースコードを開く

# include <Siv3D.hpp>

class Player {
public:
    double x, y, speed;

    Player() {
        x = 320.0;
        y = 240.0;
        speed = 50.0;
    }
    void update() {
        //このフレームで進む距離の計算
        const double delta = Scene::DeltaTime() * speed;

        //上下左右キーで移動
        if (KeyLeft.pressed()) {
            x -= delta;
        }
        if (KeyRight.pressed()) {
            x += delta;
        }
        if (KeyUp.pressed()) {
            y -= delta;
        }
        if (KeyDown.pressed()) {
            y += delta;
        }
    }
    //自機(円)を描画
    void draw() {
        Circle{ x, y, 30.0 }.draw(Color{ 0, 0, 255 });
    }
};

class Enemy {
public:
    double x, y, speed;

    Enemy(double _x, double _y, double _speed) {
        x = _x;
        y = _y;
        speed = _speed;
    }

    void update() {
        //このフレームで進む距離の計算
        const double delta = Scene::DeltaTime() * speed;
        y += delta;
    }
    //敵(円)を描画
    void draw() {
        Circle{ x, y, 30.0 }.draw(Color{ 255, 0, 0 });
    }
};

void Main()
{
    //PlayerとEnemyをインスタンス化
    Player player;
    Enemy enemy{ 480, 0, 50 };

    while (System::Update())
    {
        //移動などの処理
        player.update();
        enemy.update();
        //描写
        player.draw();
        enemy.draw();
    }
}

Vol. 02

ソースコードを開く

#pragma once
# include <Siv3D.hpp> //Vec2型を使うためインクルード

class Player {
public:
    Vec2 pos;
    double speed;
    Player(); 
    void update();
    void draw();
};
#include "Player.h"
//Player.hで<Siv3D.hpp>をインクルードしているので# include <Siv3D.hpp>は必要なし

Player::Player() :
    pos{ 320.0, 240.0 },
    speed{ 50.0 }
{
}

void Player::update() {
    //このフレームで進む距離の計算
    const double delta = Scene::DeltaTime() * speed;

    //上下左右キーで移動
    if (KeyLeft.pressed()) {
        pos.x -= delta;
    }
    if (KeyRight.pressed()) {
        pos.x += delta;
    }
    if (KeyUp.pressed()) {
        pos.y -= delta;
    }
    if (KeyDown.pressed()) {
        pos.y += delta;
    }
}

void Player::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 0, 0, 255 });
}
#pragma once
# include <Siv3D.hpp> //Vec2型を使うためインクルード

class Enemy {
public:
    Vec2 pos;
    double speed;
    Enemy(double _x, double _y, double _speed);
    void update();
    void draw();
};
#include "Enemy.h"
//Enemy.hで<Siv3D.hpp>をインクルードしているので# include <Siv3D.hpp>は必要なし

Enemy::Enemy(double _x, double _y, double _speed) :
    pos{ _x, _y },
    speed{ _speed }
{
}

void Enemy::update() {
    //このフレームで進む距離の計算
    const double delta = Scene::DeltaTime() * speed;
    pos.y += delta;
}

void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
# include <Siv3D.hpp>
# include "Player.h"
# include "Enemy.h"

void Main()
{
    //PlayerとEnemyをインスタンス化
    Player player;
    Enemy enemy{ 480, 0, 50 };

    while (System::Update())
    {
        //移動などの処理
        player.update();
        enemy.update();
        //描写
        player.draw();
        enemy.draw();
    }
}

Vol. 03

演習問題(コンソール)

1問目

ソースコードを開く

#include <iostream>
#include <vector>
int main() {
    std::vector<int> vec;//int型の動的配列
    // 0~9のランダムな10個の数を追加
    for (int i = 0; i < 10; i++) {
        vec.emplace_back(rand() % 10);
    }
    //出力
    for (int i = 0; i < vec.size(); i++) {
        std::cout << vec[i] << " ";
    }
    std::cout << std::endl;
    return 0;
}

2問目

ソースコードを開く

#include <iostream>
#include <vector>

class MyClass {
public:
    int x;
    MyClass(int _x) :
        x{ _x }
    {
    }
    void show() {
        std::cout << "xは:" << x << std::endl;
    }
};

int main() {
    std::vector<MyClass> vec;//MyClass型の動的配列
    // 10個のMyClassインスタンスを作成し、vecに追加
    for (int i = 0; i < 10; i++) {
        vec.emplace_back(MyClass{ rand() % 10 });
    }
    //出力
    for (int i = 0; i < vec.size(); i++) {
        vec[i].show();
    }
    return 0;
}

 演習問題(OpenSiv3D)

1~3問目

ソースコードを開く

#pragma once
#include <Siv3D.hpp>
class Enemy {
public:
    Vec2 pos;
    Vec2 velocity;
    Enemy(Vec2 _pos);
    void update();
    void draw();
};
#include "Enemy.h"
Enemy::Enemy(Vec2 _pos) :
    pos{ _pos },
    velocity{ 0.0, 50.0 }
{
}
void Enemy::update() {
    pos += Scene::DeltaTime() * velocity;
}
//エネミー(円)を描画
void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
# include <Siv3D.hpp>
# include <vector>
# include "Enemy.h"

void Main()
{
    std::vector<Enemy> enemies; //Enemyの動的配列
    enemies.emplace_back(Enemy{ Vec2{ 480, 0 } }); //Enemyの実体を作成してenemiesに追加


    while (System::Update())
    {
        //Zキーが押されたら敵を追加
        if (KeyZ.down()) {
            enemies.emplace_back(Enemy{ RandomVec2(Scene::Size().x, Scene::Size().y) }); //ランダムな座標に敵を生成して追加
        }
        //移動などの処理
        for (int i = 0; i < enemies.size(); i++) {
            enemies[i].update();
        }
        //描写
        for (int i = 0; i < enemies.size(); i++) {
            enemies[i].draw();
        }
    }
}

4問目

ソースコードを開く

#pragma once
#include <Siv3D.hpp>
class Enemy {
public:
    Vec2 pos;
    Vec2 velocity;
    Enemy(Vec2 _pos);
    void update();
    void draw();
};
#include "Enemy.h"
Enemy::Enemy(Vec2 _pos) :
    pos{ _pos },
    velocity{ 0.0, 50.0 }
{
}
void Enemy::update() {
    pos += Scene::DeltaTime() * velocity;
}
//エネミー(円)を描画
void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
#pragma once
#include <vector>
#include <Siv3D.hpp>
#include "Enemy.h"
class EnemyManager {
public:
    std::vector<Enemy> enemies;
    void update();
    void draw();
    void add(Vec2 pos);
};
#include "EnemyManager.h"
void EnemyManager::update()
{
    //Zキーが押されたら敵を追加
    if (KeyZ.down()) {
        add(RandomVec2(Scene::Size().x, Scene::Size().y)); //ランダムな座標に敵を追加
    }

    //メンバのEnemyのupdateを呼ぶ
    for (int i = 0; i < enemies.size(); i++) {
        enemies[i].update();
    }
}
void EnemyManager::draw()
{
    //メンバのEnemyのdrawを呼ぶ
    for (int i = 0; i < enemies.size(); i++) {
        enemies[i].draw();
    }
}
void EnemyManager::add(Vec2 pos)
{
    enemies.emplace_back(Enemy{ pos });
}
# include <Siv3D.hpp>
# include <vector>
# include "EnemyManager.h"

void Main()
{
    EnemyManager enemyManager;
    enemyManager.add(Vec2{ 480, 0 }); //敵を一体追加

    while (System::Update())
    {
        //移動などの処理
        enemyManager.update();
        //描写
        enemyManager.draw();
        
    }
}

Vol. 4

演習問題(コンソール)

ソースコードを開く

#include <iostream>

void twiceRef(int& x) {
    x *= 2;
}


int main() {

    int num = 3;

    std::cout << num << std::endl;

    twiceRef(num);

    std::cout << num << std::endl;

    return 0;
}

演習問題(OpenSiv3D)

ソースコードを開く

#pragma once
#include <Siv3D.hpp>

class Player {
public:
    const double Speed;
    Vec2 pos;
    Player();
    void update();
    void draw();
};
#include "Player.h"

Player::Player() :
    pos{ 320.0, 240.0 },
    Speed{ 50.0 }
{
}

void Player::update() {
    //このフレームで進む距離の計算
    const double delta = Scene::DeltaTime() * Speed;

    //上下左右キーで移動
    if (KeyLeft.pressed()) {
        pos.x -= delta;
    }
    if (KeyRight.pressed()) {
        pos.x += delta;
    }
    if (KeyUp.pressed()) {
        pos.y -= delta;
    }
    if (KeyDown.pressed()) {
        pos.y += delta;
    }
}

void Player::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 0, 0, 255 });
}
#pragma once
#include <Siv3D.hpp>
#include "Player.h"
class Enemy {
public:
    Vec2 pos;
    Vec2 velocity;
    Player* pPlayer;
    Enemy(const Vec2& _pos, Player* ptr);
    void update();
    void draw();
};
# include "Enemy.h"

Enemy::Enemy(const Vec2& _pos, Player* ptr) :
    pos{ _pos },
    velocity{ 0.0, 0.0 },
    pPlayer{ ptr }
{
}

void Enemy::update() {
    //Playerの位置と比較してvelocityを決定(x方向)
    if (pPlayer->pos.x > pos.x) {
        velocity.x = 50.0;
    }
    else if (pPlayer->pos.x < pos.x) {
        velocity.x = -50.0;
    }
    else {
        velocity.x = 0;
    }

    //Playerの位置と比較してvelocityを決定(y方向)
    if (pPlayer->pos.y > pos.y) {
        velocity.y = 50.0;
    }
    else if (pPlayer->pos.y < pos.y) {
        velocity.y = -50.0;
    }
    else {
        velocity.y = 0;
    }

    //移動
    pos += Scene::DeltaTime() * velocity;
}

void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
#include <Siv3D.hpp>
#include "Player.h"
#include "Enemy.h"

void Main()
{
    Player player; //Playerをインスタンス化
    Enemy enemy{ Vec2{ 480, 0 }, &player }; //Enemyをインスタンス化、playerのポインタを渡す

    //メインループ
    while (System::Update())
    {
        //移動等の処理
        player.update();
        enemy.update();
        //描写
        player.draw();
        enemy.draw();
    }
}

Vol. 5

1問目

ソースコードを開く

#include <iostream>

int mySquare(int x) {
    std::cout << "int型のmySquareが呼ばれました" << std::endl;
    return x * x;
}

float mySquare(float x) {
    std::cout << "float型のmySquareが呼ばれました" << std::endl;
    return x * x;
}

double mySquare(double x) {
    std::cout << "double型のmySquareが呼ばれました" << std::endl;
    return x * x;
}


int main() {
    int x = 1;
    float y = 0.5;
    double z = 2.1;
    std::cout << mySquare(x) << std::endl;
    std::cout << mySquare(y) << std::endl;
    std::cout << mySquare(z) << std::endl;
}

2問目

ソースコードを開く

#include <iostream>

class Vector2 {
public:
    int x, y;

    Vector2() :
        x{ 0 },
        y{ 0 }
    {
        std::cout << "引数なしのコンストラクタが呼ばれました" << std::endl;
    }

    Vector2(int _x, int _y) :
        x{ _x },
        y{ _y }
    {
        std::cout << "引数ありのコンストラクタが呼ばれました" << std::endl;
    }

    ~Vector2() {
        std::cout << "デストラクタが呼ばれました" << std::endl;
    }
};

int main() {
    std::cout << "メイン関数に入りました" << std::endl;
    Vector2 point1;
    Vector2 point2{ 2, 3 };
    std::cout << "メイン関数を抜けました" << std::endl;
}

Vol. 6

演習問題(コンソール)

ソースコードを開く

#include <iostream>
#include <vector>

class MyClass {
public:
    int a;
    int b;

    MyClass(int _a, int _b) :
        a{ _a },
        b{ _b }
    {
    }
};

int main() {
    std::vector<MyClass> vec;

    for (int i = 0; i < 10; i++) {
        vec.emplace_back(MyClass{ rand() % 10, rand() % 10 });
    }

    for (auto iter = vec.begin(); iter < vec.end(); iter++) {
        std::cout << "(" << iter->a << ", " << iter->b << "), ";
    }

    std::cout << std::endl;

    auto iter = vec.begin();
    while (iter < vec.end()) {
        if (iter->a < iter->b) {
            iter = vec.erase(iter);
        }
        else iter++;
    }

    for (auto iter = vec.begin(); iter < vec.end(); iter++) {
        std::cout << "(" << iter->a << ", " << iter->b << "), ";
    }

    std::cout << std::endl;
}

演習問題(OpenSiv3D)

ソースコードを開く

#pragma once
#include <Siv3D.hpp>
class Enemy {
public:
    Vec2 pos;
    Vec2 velocity;
    Enemy(const Vec2& _pos);
    void update();
    void draw();
};
# include "Enemy.h"
Enemy::Enemy(const Vec2& _pos) :
    pos{ _pos },
    velocity{ RandomVec2(50.0) }
{
    // RandomVec2(double length)
    // 半径length(今回は5.0)の2次元ベクトルを返す
}
void Enemy::update() {
    pos += Scene::DeltaTime() * velocity;
}
void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
# include <Siv3D.hpp>
# include <vector>
# include "Enemy.h"

void Main()
{
    std::vector<Enemy> enemies; //Enemyの動的配列
    //5つの要素を追加する
    for (int i = 0; i < 5; i++) {
        //ランダムな位置に敵を生成
        enemies.emplace_back(Enemy{ RandomVec2(Scene::Size().x, Scene::Size().y) });
    }

    while (System::Update())
    {
        //移動などの処理
        auto iter = enemies.begin();
        while (iter != enemies.end()) {
            iter->update();
            //問題3のシーン外に出たかどうかの条件文
            if ((iter->pos.x < 0) || (iter->pos.x > Scene::Size().x) || (iter->pos.y < 0) || (iter->pos.y > Scene::Size().y)){
            //if (iter->pos.y > 480) {  //問題2ならこちらの条件文
                iter = enemies.erase(iter);
            }
            else {
                iter++;
            }
        }
        //描写
        for (auto iter = enemies.begin(); iter != enemies.end(); ++iter) {
            iter->draw();
        }
    }
}

Vol. 7

演習問題(コンソール)

1問目

ソースコードを開く

#include <iostream>

int main() {

    auto twice = [](int x) {
        return x * 2;
    };

    int num = 3;

    std::cout << twice(num) << std::endl;

    return 0;
}

2問目

ソースコードを開く

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec;

    // vectorに0から9の数を入れる
    for (int i = 0; i < 10; i++) {
        vec.emplace_back(i);
    }

    //表示
    for (auto i = vec.begin(); i < vec.end(); ++i) {
        std::cout << *i << " ";
    }
    std::cout << std::endl;

    // 2の倍数を後ろに詰め、削除
    auto rmvIter = std::remove_if(vec.begin(), vec.end(), 
        [](int i) {return i % 2 == 0; }
    );
    vec.erase(rmvIter, vec.end());

    //表示
    for (auto i = vec.begin(); i < vec.end(); ++i) {
        std::cout << *i << " ";
    }
    std::cout << std::endl;

    return 0;
}

演習問題(OpenSiv3D)

ソースコードを開く

#pragma once
#include <Siv3D.hpp>

class Enemy {
public:
    Vec2 pos;
    Vec2 velocity;
    Enemy(const Vec2& _pos);
    void update();
    void draw();
};
# include "Enemy.h"

Enemy::Enemy(const Vec2& _pos) :
    pos{ _pos },
    velocity{ RandomVec2(50.0) }
{
    // RandomVec2(double length)
    // 半径length(今回は50.0)の2次元ベクトルを返す
}

void Enemy::update() {
    pos += Scene::DeltaTime() * velocity;
}

void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
# include <Siv3D.hpp>
# include <vector>
# include <algorithm>
# include "Enemy.h"

void Main()
{
    std::vector<Enemy> enemies; //Enemyの動的配列
    //5つの要素を追加する
    for (int i = 0; i < 5; i++) {
        //ランダムな位置に敵を生成
        enemies.emplace_back(Enemy{ RandomVec2(Scene::Size().x, Scene::Size().y) });
    }

    while (System::Update())
    {
        //移動などの処理
        for (auto iter = enemies.begin(); iter != enemies.end(); ++iter) {
            iter->update();
        }
        //画面外に出た敵を削除
        auto rmvIter = std::remove_if(enemies.begin(), enemies.end(),
            [](const Enemy &e) {
                return (e.pos.x < 0) || (e.pos.x > Scene::Size().x) || (e.pos.y < 0) || (e.pos.y > Scene::Size().y);
            }
        );
        enemies.erase(rmvIter, enemies.end());
        //描写
        for (auto iter = enemies.begin(); iter != enemies.end(); ++iter) {
            iter->draw();
        }
    }
}

Vol. 8

ソースコードを開く

#pragma once
# include<Siv3D.hpp>

class Player
{
public:
    Vec2 pos;
    double speed;
    Player(const Vec2& _pos, double _speed);
    void update();
    void draw();
};
#include "Player.h"

Player::Player(const Vec2& _pos, double _speed) :
    pos{ _pos },
    speed{ _speed }
{
}

void Player::update() {
    //このフレームで進む距離の計算
    const double delta = Scene::DeltaTime() * speed;
    //上下左右キーで移動
    if (KeyLeft.pressed()) {
        pos.x -= delta;
    }
    if (KeyRight.pressed()) {
        pos.x += delta;
    }
    if (KeyUp.pressed()) {
        pos.y -= delta;
    }
    if (KeyDown.pressed()) {
        pos.y += delta;
    }
}

void Player::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 0, 0, 255 });
}
#pragma once
#include <Siv3D.hpp>

class Enemy {
public:
    enum Kind {
        Straight,
        Sin,
        Round
    };
    Kind kind; //種類
    Vec2 pos; //座標
    Color color; //色
    double t; //円軌道のための変数
    Enemy(Kind _kind, const Vec2& _pos);
    void update();
    void draw();
};
# include <cmath>
# include "Enemy.h"
# include "GameManager.h"

Enemy::Enemy(Enemy::Kind _kind, const Vec2& _pos) :
    kind{ _kind },
    pos{ _pos },
    t{ 0 }
{
    //kindによって色を変更
    switch (kind)
    {
    case Enemy::Kind::Straight:
        color = Color{ 255, 0, 0 };
        break;
    case Enemy::Kind::Sin:
        color = Color{ 255, 165, 0 };
        break;
    case Enemy::Kind::Round:
        color = Color{ 246, 152, 150 };
        break;
    default:
        color = Color{ 255, 0, 0 };
        break;
    }
}

void Enemy::update() {
    //kindによって動きを変更
    switch (kind) {
    case Enemy::Kind::Straight:
        //自機に向かって直進
        if (gameManager.player.pos.x < pos.x) {
            pos.x -= Scene::DeltaTime() * 50.0;
        }
        else if (gameManager.player.pos.x > pos.x) {
            pos.x += Scene::DeltaTime() * 50.0;
        }
        if (gameManager.player.pos.y < pos.y) {
            pos.y -= Scene::DeltaTime() * 50.0;
        }
        else if (gameManager.player.pos.y > pos.y) {
            pos.y += Scene::DeltaTime() * 50.0;
        }
        break;
    case Enemy::Kind::Sin:
        //sin軌道
        pos.x += Scene::DeltaTime() * 60.0;
        pos.y += Scene::DeltaTime() * 500.0 * std::cos(pos.x / 10.0);
        break;
    case Enemy::Kind::Round:
        //円軌道
        t += Scene::DeltaTime() * 2.0;
        pos.x -= Scene::DeltaTime() * 100.0 * std::sin(t);
        pos.y += Scene::DeltaTime() * 100.0 * std::cos(t);
        break;
    default:
        break;
    }
}

void Enemy::draw() {
    Circle{ pos, 30.0 }.draw(color);
}
#pragma once
# include<vector>
# include"Enemy.h"

class EnemyManager
{
public:
    std::vector<Enemy> enemies;
    EnemyManager(int num);
    void update();
    void draw();
};
#include "EnemyManager.h"


EnemyManager::EnemyManager(int num)
{
    //numで指定された数要素を追加
    for (int i = 0; i < num; i++) {
        //ランダムの種類とランダムの座標で敵を生成
        enemies.emplace_back(Enemy{ (Enemy::Kind)(rand() % 3) , RandomVec2(800, 600) });
    }
}

void EnemyManager::update() {
    //Enemyそれぞれのupdateを呼ぶ
    for (auto iter = enemies.begin(); iter != enemies.end(); ++iter) {
        iter->update();
    }
    //画面外に出た敵を削除
    auto rmvIter = std::remove_if(enemies.begin(), enemies.end(),
        [](const Enemy& e) {
        return (e.pos.x < 0) || (e.pos.x > Scene::Size().x) || (e.pos.y < 0) || (e.pos.y > Scene::Size().y);
        }
    );
    enemies.erase(rmvIter, enemies.end());
}

void EnemyManager::draw() {
    //Enemyそれぞれのdrawを呼ぶ
    for (auto iter = enemies.begin(); iter != enemies.end(); ++iter) {
        iter->draw();
    }
}
#pragma once
# include <vector>
# include "Player.h"
# include "EnemyManager.h"

class GameManager
{
public:
    Player player;
    EnemyManager enemyManager;
    GameManager();
    void update();
    void draw();
};


extern GameManager gameManager;
#include "GameManager.h"

GameManager::GameManager() :
    player{ Vec2{ 400.0, 300.0 }, 50.0 },
    enemyManager{ 10 }
{

}

void GameManager::update() {
    //それぞれのupdateを呼ぶ
    player.update();
    enemyManager.update();
}

void GameManager::draw() {
    //それぞれのdrawを呼ぶ
    player.draw();
    enemyManager.draw();
}

GameManager gameManager;
# include <Siv3D.hpp>
# include "GameManager.h"

void Main()
{
    while (System::Update())
    {
        gameManager.update();
        gameManager.draw();
    }
}

Vol. 9

演習問題(コンソール)

ソースコードを開く

#include <iostream>
#include <vector>

class MyClass {
public:
    int a;

    MyClass(int _a) :
        a{ _a }
    {
    }
};

int main() {
    std::vector<MyClass*> vec;

    // 適当な数でMyClassを追加
    for (int i = 0; i < 10; i++) {
        vec.emplace_back(new MyClass{ rand() % 10 });
    }

    // vectorの中身を表示
    for (const auto& i : vec) {
        std::cout << i->a << " ";
    }
    std::cout << std::endl;

    // 5以下の要素を削除
    auto it = vec.begin();
    while (it != vec.end()) {
        if ((*it)->a <= 5) {
            delete* it;
            it = vec.erase(it);
        }
        else {
            it++;
        }
    }

    // vectorの中身を表示
    for (const auto& i : vec) {
        std::cout << i->a << " ";
    }
    std::cout << std::endl;

    return 0;
}

演習問題(OpenSiv3D)

ソースコードを開く

#pragma once
#include <Siv3D.hpp>
class Enemy {
public:
    static const double Radius;
    Vec2 pos;
    Vec2 velocity;
    Enemy(const Vec2& _pos);
    void update();
    void draw();
};
# include "Enemy.h"
const double Enemy::Radius = 30.0;
Enemy::Enemy(const Vec2& _pos) :
    pos{ _pos },
    velocity{ RandomVec2(50.0) }
{
}
void Enemy::update() {
    pos += Scene::DeltaTime() * velocity;
}
void Enemy::draw() {
    Circle{ pos, Radius }.draw(Color{ 255, 0, 0 });
}
# include <Siv3D.hpp>
# include <vector>
# include "Enemy.h"

void Main()
{
    std::vector<Enemy*> enemies; //Enemy型ポインターの動的配列
    //5つの要素を追加する
    for (int i = 0; i < 5; i++) {
        //ランダムな位置に敵を生成
        enemies.emplace_back(new Enemy{ RandomVec2(Scene::Size().x, Scene::Size().y) });
    }

    while (System::Update())
    {
        //移動などの処理
        auto iter = enemies.begin();
        while (iter != enemies.end()) {
            (*iter)->update();
            //シーン外に出たかどうかの条件文
            if (((*iter)->pos.x < 0) || ((*iter)->pos.x > Scene::Size().x) || ((*iter)->pos.y < 0) || ((*iter)->pos.y > Scene::Size().y)){
                delete* iter;
                iter = enemies.erase(iter);
            }
            else {
                iter++;
            }
        }
        //描写
        for (const auto& e : enemies) {
            e->draw();
        }

    }

    //各要素をdelete
    for (const auto& e : enemies) {
        delete e;
    }
}

Vol. 10

演習問題(コンソール)

ソースコードを開く

# include<iostream>
# include<vector>

class IAnimal {
public:
    double weight;//重さ
    IAnimal(double w) :
        weight{ w }
    {
    }
    virtual void talk() = 0;
    virtual ~IAnimal() = default;
};
class Dog : public IAnimal {
public:
    Dog(double w) :
        IAnimal{ w }
    {
    }
    void talk() override {
        std::cout << "わんわん 重さは:" << weight << std::endl;
    }
};
class Cat : public IAnimal {
public:
    Cat(double w) :
        IAnimal{ w }
    {
    }
    void talk() override {
        std::cout << "ネコチャン 重さは:" << weight << std::endl;
    }
};
class Dialga : public IAnimal {
public:
    Dialga(double w) :
        IAnimal{ w }
    {
    }
    void talk() override {
        std::cout << "グギュグバァッ!!! 重さは:" << weight << std::endl;
    }
};
int main() {
    std::vector<IAnimal*> animals; //IAnimalのポインタの動的配列

    //それぞれのクラスのインスタンスを生成
    animals.emplace_back(new Dog(12.0));
    animals.emplace_back(new Cat(4.5));
    animals.emplace_back(new Dialga(683.0));

    //一つのループでそれぞれの型のtalk()を呼び出し
    for (auto&& a : animals) {
        a->talk();
    }
}

演習問題(OpenSiv3D)

ソースコードを開く ソースが多いため、vol. 8との変更・追加されたファイルのみ記載する。なお、Enemy.hとEnemy.cppは削除されている。

#pragma once
#include <Siv3D.hpp>

class IEnemy
{
public:
    Vec2 pos; //座標
    IEnemy(const Vec2& _pos) : //コンストラクタ
        pos{ _pos }
    {
    }
    virtual void update() = 0; //純粋仮想関数
    virtual void draw() = 0; //純粋仮想関数
    virtual ~IEnemy() = default; // 仮想デストラクタ
};
#pragma once
#include "IEnemy.h"

class StraightEnemy :
    public IEnemy
{
public:
    StraightEnemy(const Vec2& _pos);
    void update() override;
    void draw() override;
};
#include "StraightEnemy.h"
#include "GameManager.h"

StraightEnemy::StraightEnemy(const Vec2& _pos) :
    IEnemy{ _pos }
{
}

void StraightEnemy::update() {
    //自機に向かって直進
    if (gameManager.player.pos.x < pos.x) {
        pos.x -= Scene::DeltaTime() * 50.0;
    }
    else if (gameManager.player.pos.x > pos.x) {
        pos.x += Scene::DeltaTime() * 50.0;
    }
    if (gameManager.player.pos.y < pos.y) {
        pos.y -= Scene::DeltaTime() * 50.0;
    }
    else if (gameManager.player.pos.y > pos.y) {
        pos.y += Scene::DeltaTime() * 50.0;
    }
}

void StraightEnemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 0, 0 });
}
#pragma once
#include "IEnemy.h"
class SinEnemy :
    public IEnemy
{
public:
    SinEnemy(const Vec2& _pos);
    void update() override;
    void draw() override;
};
#include "SinEnemy.h"

SinEnemy::SinEnemy(const Vec2& _pos) :
    IEnemy{ _pos }
{
}

void SinEnemy::update() {
    //sin軌道
    pos.x += Scene::DeltaTime() * 60.0;
    pos.y += Scene::DeltaTime() * 500.0 * std::cos(pos.x / 10.0);
}

void SinEnemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 255, 165, 0 });
}
#pragma once
#include "IEnemy.h"
class RoundEnemy :
    public IEnemy
{
public:
    double t;
    RoundEnemy(const Vec2& _pos);
    void update() override;
    void draw() override;
};
#include "RoundEnemy.h"

RoundEnemy::RoundEnemy(const Vec2& _pos) :
    IEnemy{ _pos },
    t{ 0 }
{
}

void RoundEnemy::update() {
    //円軌道
    t += Scene::DeltaTime() * 2.0;
    pos.x -= Scene::DeltaTime() * 100.0 * std::sin(t);
    pos.y += Scene::DeltaTime() * 100.0 * std::cos(t);
}

void RoundEnemy::draw() {
    Circle{ pos, 30.0 }.draw(Color{ 246, 152, 150 });
}
#pragma once
# include<vector>
# include"IEnemy.h"

class EnemyManager
{
public:
    std::vector<IEnemy*> enemies;
    EnemyManager(int num);
    void update();
    void draw();
};
#include "EnemyManager.h"
#include "StraightEnemy.h"
#include "SinEnemy.h"
#include "RoundEnemy.h"

EnemyManager::EnemyManager(int num)
{
    //numで指定された数要素を追加
    for (int i = 0; i < num; i++) {
        //ランダムの種類とランダムの座標で敵を生成
        switch (rand() % 3) {
        case 0:
            enemies.emplace_back(new StraightEnemy{ RandomVec2(800, 600) });
            break;
        case 1:
            enemies.emplace_back(new SinEnemy{ RandomVec2(800, 600) });
            break;
        default:
            enemies.emplace_back(new RoundEnemy{ RandomVec2(800, 600) });
            break;
        
        }
    }
}

void EnemyManager::update() {
    //Enemyそれぞれのupdateを呼ぶ
    for (auto&& e : enemies) {
        e->update();
    }
    //画面外に出た敵を削除
    auto iter = enemies.begin();
    while (iter != enemies.end()) {
        //シーン外に出たかどうかの条件文
        if (((*iter)->pos.x < 0) || ((*iter)->pos.x > Scene::Size().x) || ((*iter)->pos.y < 0) || ((*iter)->pos.y > Scene::Size().y)) {
            delete* iter;
            iter = enemies.erase(iter);
        }
        else {
            iter++;
        }
    };
}

void EnemyManager::draw() {
    //Enemyそれぞれのdrawを呼ぶ
    for (auto&& e : enemies) {
        e->draw();
    }
}

C++OpenSiv3D入門講座