C++OpenSiv3D入門講座 Vol. 11 演習問題の解答
以下に演習問題の解答例を示す。
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(); } }