プログラミングを春休みの自由研究にしてみる 5日目
六花です。
https://komochiduki.net/ikupro/2020/03/04/250/の続き、5日目です。
シリーズリスト :
1日目 : https://komochiduki.net/ikupro/2020/03/01/234/
2日目 : https://komochiduki.net/ikupro/2020/03/03/238/
3日目 : https://komochiduki.net/ikupro/2020/03/03/245/
4日目 : https://komochiduki.net/ikupro/2020/03/04/250/
5日目 : https://komochiduki.net/ikupro/2020/03/04/253/
6日目 : https://komochiduki.net/ikupro/2020/03/09/259/
7、8、9日目 : https://komochiduki.net/ikupro/2020/03/11/263/
10、11、12日目 : https://komochiduki.net/ikupro/2020/03/12/268/
13日目[本編1日目] : https://komochiduki.net/ikupro/2020/03/13/286/
14日目[本編2日目] : https://komochiduki.net/ikupro/2020/03/15/289/
15-21日目[本編3-9日目] : https://komochiduki.net/ikupro/2020/03/21/302/
位置、速度、加速度についてはちゃんと覚えていて、説明してくれました。
何となくでも理解していてくれればゲーム作りには支障ないでしょう。
今日の午前中は頑張ってタイピング練習していました。
速度はともかく、キーの位置は少しずつ覚えているようで、AやPなど端っこにあるキーは「あそこだよね!」と言葉で教えてくれるようになりました。
こういう長い休みは持て余しがちですが、何らかの技術を一から覚えてもらうためにはまとまった時間が欲しいので好機でした。
下の息子は、普段は親しか触らないキーボードをお姉ちゃんが触っているのでちょっと羨ましそうです。(意味は解っていないようなので自分の遊びに戻りましたが)
今日の最初の作業は、ステージ1のマップ作成からでした。
分かりやすいので、マップチップの並びをドット絵として保存する方法で行うことにしました。
作成ツールはEDGEです。
敢えて縦横比が異なる参考画像を私が作り、それを元に娘がドット絵を描きました。
↓娘が作った画像
今度は家族総出で作った敵キャラをどこに配置するかを娘に考えてもらいました。
↓マグネットで書けるお絵描き板での仕様書
今まで説明の仕方に迷って放置していた配列について説明することにしました。
娘は「深く知りたいとき」と「とりあえずそういうことにしておこう」というのが共存できるタイプのようで、配列は大体わかった様子、二次元配列とstd::arrayは「ふーん」くらいの様子でした。
まだ定義しかしていないので、実際に利用するところで説明したいと思います。
明日はマスくんのような構造体を敵のために作ろうか、という話をして作業自体は終了。
娘はその後、後日自分だけでソースコードを書けるようにローマ字の練習を始めました。
基本的に突貫工事というか、すさまじくダイジェストで教えているので、ちゃんと理解しているか不安になることも多々あります。
最低限の質問にはちゃんと答えられているため、とりあえず先に進んでいる状態です。
今回は一か月という期限を切っているので「体で覚えろ」式にならざるを得ません。(あれ、つい最近逆上がりで同じようなことをしたような)
なるべく早く主導権を娘に渡して、わからないことを助言しながらなんとか期限までに作り上げてほしいと願っています。
↓今回終了時点のソースコード。構造体定義辺りが変更されている。
#include "DxLib.h"
#include <array>
struct s_マスくん
{
// 位置(いち)
double x;
double y;
// 速さ(はやさ)、速度(そくど)
double vx;
double vy;
// 加速度(かそくど)
double ax;
double ay;
// 状態(じょうたい)
enum class e_状態 : int { 立ってる, 空中, 水中 };
e_状態 状態;
};
s_マスくん マスくん;
struct s_画面
{
enum class e_状態 : int { タイトル, ステージ選択, アクション, スタッフロール };
e_状態 状態;
};
enum class e_ブロック : int { 空気, 水, 草, 丸太, いちご };
enum class e_敵 : int { 未定義, こぐま, おやぐま, はりせんぼん, くじら };
// もしかしたら必要ないかも
struct s_ブロック
{
};
// どの敵がどこに出てくるか
struct s_敵_配置
{
int x = -1;
int y = -1;
e_敵 敵ID = e_敵::未定義;
};
struct s_敵
{
};
struct s_ステージ
{
// 定義の部分
std::array<std::array<e_ブロック, 16>, 128> ブロックID; // [128][16]の配列、拡張性はない
int スタート位置_x;
int スタート位置_y;
std::array<s_敵_配置, 10> 敵_配置;
// 今の敵の状態
std::array<s_敵, 10> 敵;
};
// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(true); // ウインドウモードで起動
SetWindowStyleMode(7); // 7:最大化ボタンが存在するウインドウモードに変更
SetGraphMode(1920, 1080, 32);
SetWindowSize(1920, 1080); // 初期ウインドウの大きさ
SetWindowSizeChangeEnableFlag(true, true); // ウインドウサイズ変更を可能にする(縦横比変更不可)
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
SetTransColor(255, 255, 255);
SetUsePremulAlphaConvertLoad(true); // 画像を読み込んだ後、乗算済みアルファ画像に変換する設定を有効にする
SetDrawScreen(DX_SCREEN_BACK);//裏画面
// 画像読み込み
int 画像_マスくん_立ち = LoadGraph("../../data/マスくん_立ち.png");
int 画像_マスくんの手 = LoadGraph("../../data/マスくんの手.png");
int 画像_マスくんの手_ドリル = LoadGraph("../../data/マスくんの手_ドリル.png");
マスくん.x = 1920 / 2;
マスくん.y = 1080 / 2;
while (ProcessMessage() != -1)
{
ClearDrawScreen(); // 画面を掃除する
// キーボードの入力を取得する
char keydata[256];
GetHitKeyStateAll(keydata);
if (keydata[KEY_INPUT_RIGHT] == 1)
{
マスくん.x += double(10);
}
if (keydata[KEY_INPUT_LEFT] == 1)
{
マスくん.x -= double(10);
}
if (keydata[KEY_INPUT_UP] == 1 && マスくん.状態 != s_マスくん::e_状態::空中)
{
マスくん.vy -= double(25);
マスくん.状態 = s_マスくん::e_状態::空中;
}
// 重力(じゅうりょく)
マスくん.ay = 9.80665 / double(6);
// 加速度を反映
マスくん.vx += マスくん.ax;
マスくん.vy += マスくん.ay;
// 速度を反映
マスくん.x += マスくん.vx;
マスくん.y += マスくん.vy;
// とりあえず地面
if (マスくん.y >= 1080 / 2)
{
マスくん.y = 1080 / 2;
マスくん.vy = double(0);
マスくん.状態 = s_マスくん::e_状態::立ってる;
}
DrawGraph(マスくん.x, マスくん.y, 画像_マスくん_立ち, true);
ScreenCopy(); // 描画を反映する
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}