プログラミングを春休みの自由研究にしてみる 4日目
六花です。
https://komochiduki.net/ikupro/2020/03/03/245/の続き、4日目です。
シリーズリスト :
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/
タイピング練習を約束はしたものの、今日は折り紙の練習に専念したかったらしく全く手つかずでした。
まあこの歳でプログラミングを受け入れるとは思ってもいなかったので、多少他のことがやりたくなって離れることくらいは些事でしょう。
私が講義がてら全部打ち込むというのも、この年齢の子に対する教育という点では良いかもしれませんが、折角頑張って勉強しているのだから、「私が作ったよ!」と胸を張って他の人に見せられるようになってほしいかなと思います。
そのためにはどうしてもタイピング練習は外せないので、今日もタイピングを一時間ほど練習してから作業の続きにとりかかりました。
前日は横移動ができるようになったので、今日は重力の概念を導入してジャンプを実装することにします。
接地判定はとりあえず適当にy=定数のところに置くことにします。
今回の作業の一番の問題は「位置」「速度」「加速度」を理解してもらうところです。
そもそも、小数も負の数も座標もここ数日で知ったばかりの子に教えるものではないというのは重々承知なのですが、これがないとジャンプの挙動なんて全く理解できないのでやるしかありません。
色々手を変え品を変え説明した結果、娘の理解は以下の通りでした。
・位置:今ある場所
・速度:位置を変えるもの
・加速度:速度を変えるもの
・速度と加速度の向きが同じならどんどん早くなっていく
・速度と加速度の向きが反対ならどんどん遅くなっていく
翌日訊ねてみて、大体同じ答えが返ってきたらもう言うことはないです。完璧でした。
後は実際にジャンプ処理を実装してみて、無限ジャンプしないために「状態」という情報を持つことの意味を説明し、その過程でわざとxとyを書き間違え、その原因を推察させてみました。
次はいよいよステージの作成に取り掛かるのですが、さすがにそれは大仕事で、それを完遂するには時間が足りなかったため、また明日ということになりました。
最後に、ステージ1の最初から最後までと、スタッフロールだけは完成させようね、と改めて約束しました。
最終的には、私がなるべく関与せずに娘一人でソースを書ききることを目標にしたいです。
月末までにそれを達成しようとすると、私はあと一週間くらいしか手伝うことができません。
最初はステージ3まで決める気合の入れぶりでしたが、「ゲームの完成度を上げる」ことは主目的ではないので、諦めるべきかなと思います。
↓今日遊んだソースコード
#include "DxLib.h"
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_状態 状態;
};
struct s_ステージ
{
};
struct s_敵
{
};
// プログラムは 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; // ソフトの終了
}