はてなキーワード: keyとは
初めて増田になりました。
学生の頃にCLANNADのアニメを観て、それは大層泣きました。
シナリオの都合のよさとか、主人公にキツい運命を与えすぎでは?とか、そういう理屈を超越したところにこの作品はあって、京アニは見事にこの物語を演出してみせたと思う。
あの頃は家族とか友達とか人のつながりっていいな、と大まかにはそんな感想だったと思う。
しかし今の私は違う。見終わって、人はなぜこんなにも傷つきながら前を向いて生きなくてはならないのだろうと思った。
いやまあそもそも、5年目にして転職を2回しているような人生なので察してほしい。
働き続けることがこんなにもつらいのだと、布団の中で思う日々だ。
多分この日記を開いてくれた人はCLANNADやリトバスをすでに履修済みだろう。よって割愛する。
私の胸を打ったのは、AFTER STORYに入って、朋也が働き始めたところだ。
卒業後にプーだったことを負い目に感じていた主人公は、自分で仕事をみつけ、住む場所をみつけ、愛する人の5年目の高校生活を支える。
その18歳の岡崎朋也がなんともいじらしく、可愛く、行動してみせた自分がどこか誇らしく瞳が輝くも、あっという間に現実を突きつけられてしまうのだ。
新居に渚を迎えて浮ついた気持ち、職場の先輩の芳野と初めて車で現場に向かったときに、すれ違った家族を窓越しに見送った時の未来を期待する表情。
それがもうたった一日の労働で、家に帰ったら愛する渚の話に耳を傾けられないほど疲れ切ってしまうのだ。
学生時代にはその細やかな描写に気が付かなかった、まったく印象に残っていない。
改めて視聴した今回は、汐をめぐる物語以上に、朋也が働き続ける姿が目に焼き付いて離れないのだ。
本人も作中で話してはいるが、学校生活では友人たちの悩みを解決し、手を差し伸べてよい方向へ導いてきた朋也が、
人を導くことができるという自惚れが、働き始めたことで一瞬で瓦解する。
労働とは、そりゃ楽しいこともあるかもしれないけれど、大多数は生きるために嫌々行っているものだ、
学校が楽しくないからと不良のような生活を送っていたあの朋也が、逃げ出さずに仕事と向き合う姿は、まさしく日本という社会で生きるためには組織に所属して労働しなくてはならないという現実を突きつけてくる。
古河家だって、流行っているパン屋ではないことから、渚や朋也の目にみえないところで重いそろばんをはじいているのだろう。
朋也は渚を失ってからも仕事をしつづけた。本人はそれを汐からの逃避だといったが、生きるためにはお金が必要で、庶民は働かないと生きていけない。
どれほど傷ついても生きることから逃れられないのなら、仕事をしたり、人とかかわって生きていかないといけない。
汐の治療のために仕事をやめた朋也は、汐が亡くなってしまったら、もう死のうと心のどこかで覚悟していたのだろう。(原作で描写あったっけ…)
だから生き続けるための仕事をやめて、それを察した芳野は戻ってくるようにと声をかけた。
5年目に触れたCLANNADは家族っていいなとか楽しい友達が欲しいな、とかCLANNADは人生とかそういうことも感じたけれど。
傷ついた人間もその傷が癒えずとも前を向いて生きろと、そんな空をつかむような悲しいエールを受け取ったのだ。
思いっきり割愛するが、リトバスの主人公は親友たちを一度に失うという大きな傷を負う。
そして彼らが死ぬ運命は避けられぬのだと、その痛みを抱えてまでも生きろと言われる。
物語を通してハートが強くなった理樹は喪失をも受け止めて強く生きようとする。
まあ最終的にはうまいこと物語が展開してハッピーエンドになるのだけれども。
だーまえは何かとプレイヤーたちに強く生きてほしいと願っている気がする。
書を捨て街に出よう、じゃないけれど傷ついても現実逃避せずに真っすぐ生きてね、という応援。
ビジュアルアーツ20周年のイベントで配布された曲なのだが、わざわざイベントに来たような熱心なファンに「僕はもう大丈夫だから 今度はそう、きみが幸せになる番だよ」なんて語りかけてくる。
オタクなんて大小あれども、傷ついて生きてきて、エンタメにそれを救われているような人間ばかりなのだ。
そんなオタクたちに、現実に立ち向かえとスパルタ的に奮い立たせようとする。
あと多くのkey作品は現実から逃げるとBADED行きなのだ、智代ルートなど非常に印象に残っている。
そこまでして、どうして生きていかねばならないのか、、、なんて思う。
俺たちは人生の主人公なのだから、現実から逃げずに、居心地のいい環境を作って、ささやかながら生きがいをみつけて、VAにお布施して生きろと。
才能もない、とりえもない、頭もよくない、覚えも悪い。
ぐずぐずに崩れた自尊心を取り戻す手助けをしてくれる渚や朋也、恭介や理樹、そんな存在は周囲にはいない。
久々にCLANNADを観て、そりゃあもう想像外の感想を抱いたのだ。
現実をまっとうに生きている人々が圧倒的に多い世にこんないじけた文章を残せるのなんてここしかない。
自室に引きこもっていたようにみえた恭介だって、実は虚構世界で四苦八苦していた。己の失敗に落胆してはいても、決して行動をやめていたわけではない。
生きることとは行動なのだと、布団の中でスマホを触るオタクへ作品を通して鼓舞している。
もしもここまで読んでくれた人がいたらありがとう。
サマポケ面白かったから買ってプレイしてね、プレイし終わってたらFD発売か京アニでアニメ化することを一緒に願おうね。
あとVAにできることは、だーまえの後継者を必死に探して育成することか、keyを畳んで新たな才能で作品を作るか、だーまえの治療費を全額出してあげてkeyブランドを守るかだ。
オタクの人ら、70年代から内でも外でもひたすら喧嘩してる連中のあつまりなんですが…。
宮崎駿や高畑勲が組合作って労働争議やったり、庵野秀明らがアマチュアから商業業界に無理くり入り込んだり
ポルノ分野で力をつけてメジャーに乗り込んだり(Keyとかニトロ)、タフな人はたくさんいるんですよね。
もちろん弱い人もいるでしょうが、それはどのような属性の人にもいるかと思われます。
社畜が会社を訴える物語は、経済小説という分野になるのでファンタジー路線のライトノベルには向いてないという話ですよね。
オタクが逃げている、というのは全くそぐわない。やろうと思えばできるけど、市場に対して有効かどうかという問題です。
ほい。なんとなく波長に合わなかった面々も多いのであまり気にしないで欲しい
ただ、"死ねばいいのに"といった非生産的なタグを使ってるidは積極的に非表示にしてる
最近ようやくブコメに生産的なコメントばかり並ぶようになったけどブクマ数2桁くらいの新規idが日々増殖しててなかなか大変
b:id:abcdefghijklmnopqrstuvwxy5
b:id:kimokute-kanenonai-obasan
b:id:sushisashimisushisashimi
ざっくりだし同じこと言ってるところもあるかもしれないけど、自分の解釈はこんな感じ。
・2000年以前は社員数名の弱小エロゲメーカーが小粒の良ゲーを発売できていたが、ボリュームの重厚長大化によって開発期間が長期化、開発費は高騰化し、弱小エロゲメーカーの体力がもたなくなった
・上記に関連して、そもそも小粒のエロゲーなら流通に乗せる必要もなく同人で出せばいいということに気づいた
・2000年移行のファイル共有ソフトのカジュアル化も弱小エロゲメーカーの沈没を加速した
・PS2/PSP(Vita)の頃に全年齢対象版を出す流れがあって割と売れたので、そもそもエロゲである必要があるのか?と気づいた(Key)
http://kazenotori.hatenablog.com/entry/2019/04/14/113600
00年前後が青春ど真ん中だったエロゲヲタのひとりとして衰退理由を一言でまとめると、、、
だと思う。
Leafでいえば『雫』『痕』『To Heart』。Tactics/keyでいえば『MOON.』『ONE』『Kanon』『AIR』『CLANNAD』。TYPE-MOONは『月姫』『Fate/stay night』。エロゲではないけど同人の流れをくんだ『ひぐらしのなく頃に』。
この辺のソフトはプレイヤーを熱くさせ、語りたい欲を大いに刺激し(葉鍵板なんてのもあった)、「これエロゲーじゃないから泣きゲーだから」などという妄言を口走りながら周囲にプレイを勧めさせるだけの力があった(売上だけなら『鬼作』とか『大悪司』も当時強かったけど語るもんでも勧めるもんでもないから伝播力に欠けた)。
これらはざっくり「伝奇/サスペンス」「泣き」に分けることができてそれぞれブームを作ったけど、かなしいかなそれに続くブームはつくれなかったし、フォロワー作品は年を追うごとに小粒化して(初期は『sense off』とか『みずいろ』とか『秋桜の空に』とか『それ散る』とか良質なフォロワー作品がいっぱいあった)エロゲ全体のブームを急速に沈下させた。エロゲの時代は突然やってきてあっというまに終わった。
自滅、というのは言い過ぎかもしれないが、文化として根付かせることができなかった、ぐらいは言ってもいいだろう。
粒が小さくなって新しい体験が提供できなくなったエロゲは世代交代(『恋姫シリーズ』世代はいると思ってる)に失敗したし、熱狂してた連中はエロゲといっしょにオタクを卒業するか新たな最前線へと旅立っていった。
それは『ラグナロクオンライン』/『東方』(ROは2002年開始だけどコミケの流行が葉鍵/型月→RO→東方と変わっていった(型月はしぶとく東方と共存してたような記憶)のは大きなトピック)だったり、ラノベ(西尾維新/『ハルヒ』/『とある』/『ゼロ魔』)だったり、ニコ動/ボカロ+アイマス文化だったりした。
ブームが完全に去った現代はソシャゲ(『艦これ』/『デレマス』/『グラブル』/『FGO』)でゲーム体験を満たしつつエロはその同人で摂取する時代だから本格的にエロゲの出番はないだろう。ニッチな需要は同人エロゲが担っているから尚更だ(『奴隷との生活』はヒットしたなあ)。
1. ラノベ・深夜アニメ・ソシャゲ(あるいはスマホゲー)など他のメディアに客を奪われた。
2. ファイル共有ソフトなどにより海賊版が蔓延して購入者が減った。
3. CDからDVDへの移行、スマホの普及、光学ドライブのつかないノートパソコンの普及など、周辺環境の変化によりプレイヤーが減った。
の4つがかかげられていたけど、
2. は共有ソフト以前にコピー問題があったので要因とまではいえない
3. はスマホの普及以外論外(エロゲをやるためにパソコンを買う・組む連中は多数いた。DVDへの移行なんて屁でもないし、光学ドライブがつかない云々はDL販売とかUSBドライブの存在を無視してる)
4. は正しい。制作コストの増加とプレイコストの上昇は別問題なので切り分ける必要はあるが、これらの問題は大きかった
という所感。
上記以外の理由としてはこのエントリの主張である「オタク系サブカルの最前線という地位を失ったから」と、もうひとつあるとすればスマホの登場による可処分時間の細切れ化。エロゲをやるようなオタクはもともとインターネットとの親和性が高かったわけで、スマホの登場でネットに常時接続する消費スタイルへ移行すると、パソコンに向かってじっくりエロゲをプレイするなんてことが難しくなった面はあると思う(ここに物語の長大化によってプレイコストが上昇した問題がからんでくる)。
まあ同人エロゲもエロゲといえばエロゲだし、DMM GAMESのエロゲも形をかえたエロゲと言えるだろうし(大本のオモコロの記事はまさにその宣伝だ)、FGOもエロゲに含めれば(含めるな)過去最大のエロゲ市場が爆誕してると言えるのかもしれないが。
Q. 「オタク系サブカルの最前線という地位を失ったから」ってそれトートロジーじゃないの?
A. そう見えるかもしらんけど、オタクを熱狂させる弾がなくなったから、という話をしてるつもり。
逆になんで00年前後にそういう作品が雨後の筍のごとくでてきたかというとまあ割と謎なんだけどひとつ言えるとしたら若いクリエイターに申し訳程度のエロさえつけてれば自分のやりたいことをやれる場所だって認知されたことがデカいんじゃないかなーって(日活ロマンポルノみたいなやつって言えば伝わるのかね)。
『Phantom -PHANTOM OF INFERNO-』ってエロゲがある。ニトロプラス(今はたぶん刀剣乱舞で有名)の処女作でシナリオはぶっさん(虚淵玄。今だと『まどマギ』で有名……ってそれももう古いか)。
アメリカに旅行した青年が殺しの現場を見たせいでマフィアに拉致られ暗殺者をやらされるって話なんだけど、ハードボイルド小説か映画かってあらすじでもうエロゲじゃないよね。で、なんとこのゲーム暗殺に使う銃を選べて、なおかつその銃がポリゴンで表現されてた上に、どの銃を選んでもシナリオには一ミリも影響がない、というのが爆笑ポイントで単に作り手がそういうの好きなだけっていう。当時すでにIllusionとかがポリゴンエロゲを世に送り出してたとはいえ銃だけポリゴン表現にしたエロゲって『Phantom』が最初で最後じゃねーかな(ゲームはめっちゃ面白かったよ念の為)。
『雫』だって『新興宗教オモイデ教』のフォロワーだし、菌糸類が菊地秀行とかの影響モロに受けてるの見ても、外の文化にエロをつけてエロゲの流通に乗せる、は所謂たまによくあるってやつだった(そういうのの元祖はたぶん蛭田昌人と剣乃ひろゆき)。
まあ結局売り手も買い手もスケベ心があったんだよな。当時はエロさえ入れてれば一定の購買が見込める市場で、市場が未熟な分、制作コストが安くすんだ。買う方としてもエロがあるだけでオトクな感じがしたし地雷でも許せた(Tony絵に騙されて買った『Partner』ですら俺は許したよ)。上で挙げた諸作が仮に非エロだったらここまで売れてなかったと思うね(『CLANNAD』とか『ひぐらし』は地盤を築いた後だったからヒットした説)。
エロゲ(商業パッケージ)の売上は2015年に底を打っててV字回復しているとか,10年代でも名作はあるとか,本当に崩壊したのはエロゲ批評のコミュニティだとかいう話をすればいいんです? / “エロゲが衰退したのはラノベのせい、、、ではない”
https://twitter.com/nix_in_desertis/status/1117750519840198656
なんだろな,一連の流れを読んでいて思うのは,『千桃』とか『サクラノ詩』とか『金色ラブリッチェ』とは言わんにせよ,『ホワルバ2』とか『はるくる』とか『つり乙』あたりをスルーされると,お前エロゲ追わなくなって10年近くないか感強くて,一気にもにょるんだよな。
https://twitter.com/nix_in_desertis/status/1117753560047898624
こういう論旨を理解せずに訳知り顔するやつが一番むかつくんだよね。
とりあえずエロゲ市場規模は02年の段階で560億(財界さっぽろ)、15年の実績値で150億(矢野総研)。V字回復というからには18年実績値で300億ぐらいに戻してるんだろうな?
そして本稿は00年台前半にエロゲ市場が盛り上がったあと衰退した理由をその当時オタクシーンの最前線をはれる弾がありその後そういうのがなくなったから、に求めてるのであって、それ以降にエロゲとして名作と呼ばれる作品があったかなかったかなんて話は一切していない。
俺が最後にやったエロゲは『もっと!孕ませ!炎のおっぱい異世界エロ魔法学園』(2018年4月27日発売)だ。ゲスパーすんなヴォケ。
またムカつくコメントがついたら全力で殴りに行く。
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // int blocks[100][100]; BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; boxType = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); for(int x = 0 ; x < 100 ; x++) { for (int y = 0; y < 100; y++) { blocks[y][x] = 0; } } if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 100 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } int boxType; BOOL WriteBoxOLDBox() { int width = 24; HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 48)); for (int y = 0; y < 30; y++) { for (int x = 0; x < 8; x++) { if (blocks[y][x] == 0) { continue; } RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); } } DeleteObject(hBrush); return FALSE; } BOOL WriteBox() { WriteBoxOLDBox(); switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } return TRUE; } BOOL WriteBoxZ() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxL() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 246 , 48)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) -1 ; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) -1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxI() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB( 246 , 48 , 48)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); //Rect.left += width; //Rect.right += width; Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL SaveBoxI() { blocks[y ][x] = 1; blocks[y+1][x] = 1; blocks[y+2][x] = 1; blocks[y+3][x] = 1; return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 20) { switch (boxType) { case 0: SaveBoxI(); break; case 1: break; case 2: break; } y = 0; boxType++; if (boxType > 2) { boxType = 0; } } this->WriteBox(); return TRUE; } BOOL OnKey(WPARAM wParam) { if (wParam == VK_LEFT) { x++; } if (wParam == VK_RIGHT) { x--; } return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(wParam); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
テトリス風
落ちてくるブロックの描き方
まずはブロックの種類は3種類
の違いをよく見比べて
自力で違いがわかれば
プログラマーにはなれるとおもう
とはいえ、コレを自力でわかるならもっと儲かる仕事あるとはおもうけどな
BOOL WriteBox() { switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; boxType = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } int boxType; BOOL WriteBox() { switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } } BOOL WriteBoxZ() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxL() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) -1 ; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) -1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxI() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); //Rect.left += width; //Rect.right += width; Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 8) { y = 0; boxType++; if (boxType > 2) { boxType = 0; } } this->WriteBox(); return TRUE; } BOOL OnKey() { x++; return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
第何回だろうな
まだ、何を押してもブロックが右に移動するだけ(右端にいくと左にワープ)
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; Rect.left = 48 * x; Rect.right = 48 * (x+1); Rect.top = 48 * y; Rect.bottom = 48 * (y+1); if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 8) { y = 0; } BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL OnKey() { x++; return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); y = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; Rect.top = 48 * y; Rect.bottom = 48 * (y+1); if (y > 8) { y = 0; } BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
青い■を表示するだけ
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); // メイン メッセージ ループ: while (GetMessage(&amp;msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
次の解説
staticキーワードを付けることで
これでHWNDを通して
static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); // メイン メッセージ ループ: while (GetMessage(&amp;msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } } return TRUE; } BOOL OnPaint() { return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
後に福禄寿と寿老人が加えられ、七福神が誕生することとなった。この際、五福神に福禄寿を加えただけでは六福神になるため、「福」と「禄」を福禄寿とし、「寿」だけを独立させて寿老人を作り、無理矢理七福神としたと伝えられる。
福禄寿と寿老人は神様ではなく仙人であり、元々数合わせ的に参加させられたためか、元禄10年(1697年)の『日本七福神伝』には、「福禄寿の変わりに吉祥天を七福神に加えてもよい」と記され、また享保年間(1716-1735年)の『書言字考』では寿老人に代えて猩猩が七福神の一柱とされている。また、寿老人と福禄寿はともに南極老人星の化身とされることから、この二神は本来同一とみなし、寿老人の代わりに吉祥天や猩猩が入れられた時代もあったといわれている。
私は1990年生まれで高校の時にリアルタイムでハルヒやニコニコ動画に出会った男性です。あまりアニメ全般については詳しくありませんが、私の経験の限りにおいてハルヒについて語ってみます。
ハルヒは当時の印象では「わけがわからないが、とにかく新時代のすごいアニメ」という作品でした。一つ一つの要素を見ると取り立てて珍しいものではないのですが、それらをアレンジするセンスと細部のクオリティがずば抜けていたと思います。
まず、日常系学園ラブコメと高度なSFとを融合させたアニメが珍しかったことは記憶しています。当時の私はスクールランブルやあずまんが大王にハマっていましたし、エヴァンゲリオンやカウボーイビバップも大好きでした。しかし、両者の世界観が融合するような日常系アニメがあり得るとは思ってもいませんでした。その後六畳間の侵略者やニャル子さんなど似たような作品が出てきましたが、少なくとも当時の私にとっては斬新な世界観でした。
もちろん作画も素晴らしかったです。これについて私はほとんど語れませんが、日常系萌え作品であれだけぬるぬると人物を動かしたことには驚きました。それまではロボットや飛行機をどれだけなめらかに動かすのかについては意識してきました。しかし美少女の手足や顔を実写のように丁寧に動かすことについては、ほとんど注目していませんでした。明らかにキャラクターの日常的身体動作を美しく作画する流れは、けいおんやその他の萌えアニメに繋がっていったでしょう。
また、ブログや2chなどでの考察が盛んになったのもこの頃でした。ハルヒは謎が多い設定や話数シャッフルなど、視聴者の探究心を刺激するギミックが多数仕掛けられていました。当時のアニメブログ上では考察記事や参考書籍の一覧があちこちで見られ、2chでは解釈を巡る論争が白熱していました。その後、シュタインズ・ゲートやまどマギでも同じような光景が繰り広げられることになります。
さらにはニコニコ動画やYoutubeの「ハレ晴レユカイを踊ってみた」動画が社会現象になりました。この流行に高校生や大学生の社交的な人々の多くが参加したことの意味は大きかったです。これによって電車男以来続いてきた、社会におけるオタク文化容認の流れが加速することになったと思います。深夜に放送している萌えアニメが、陰気なオタクが見るものから「(女性も含めた)普通の」中高生も楽しめるものに変わる転機でした。
2000年代の京アニは、Key作品のような男主人公ハーレム物から、らき☆すた、けいおんのような百合日常物へと変化していきました。それは2000年代から2010年代にかけてアニメの潮流がエロゲ的な物からラノベ・きらら的な物、オタク的な物からサブカル的な物、男性作家原作から女性作家原作へと変化する動きと重なっているように私には見えました。そういったアニメ界の地殻変動の結節点に存在していたのがハルヒであり、90年代文化の終焉と10年代に続く新たな文化の始まりの両者を象徴するアニメだったのではないかと今にして思うのです。もしかするとハルヒのこうした両義的な立ち位置がフォロワーの少なさに影響しているのかもしれません。
ちなみに2010年前後の私は一連のアニメ業界の流行の変化を「男性向けアニメの少女マンガ化」だと漠然と感じ、個人的にそのことを嬉しく思っていました。というのも私はエロゲに象徴されるようなハーレム系作品が苦手で、少女漫画や百合が大好きだったからです。けいおん以降の百合アニメ全盛のこの10年間は私にとってアニメの黄金期でした。今後、ハルヒやその前後のアニメの潮流は、どのように分析・批評されるのでしょうか?近い内にどなたかが『10年代の想像力』を書かれる日を楽しみにしています。
ちょいちょい分析として抜けてるので勝手に上から目線で補足してみたい。
京アニはハルヒ以前にAIRがあり、加えてもともと人気ラノベのフルメタの二期もやりきり、
人気原作 + 泣き演出 + 作画 という武器の多さもあったと思う。
ラノベ、エロゲ、同人(月姫、ひぐらし)が相互に影響を与えていったというのがある。
メディアミックス読み物コンテンツのアニメ化が色々されてきた頃だった。
今はアニメ界のAKBであるアイドルマスターの楽曲をやっていたMONOKAの人が
まとめの通り社会的な変化が背景にあった。
毎月といってもいいくらい何かしらコンテンツを順繰りに出し続けてた。
・アニメ
・マンガ
・ゲーム
・イベント
今はどの作品も当たり前のようにやりすぎてる手法で麻痺してるけど、
ここまで上手に展開し続けたのは当時少なかったじゃないかな。。
野ブタをプロデュースとか、蹴りたい背中とかもあったからかな、
ほんと純粋に魅力があったよなーと思うわ。
https://ja.m.wikipedia.org/wiki/ポリティカル・コレクトネス
これ見てて思った
性別を限定する職業を男女共通で使えるようにするのもポリコレだが↓のように
職業 伝統的な表現 ポリティカル・コレクトな表現
議長 chairman chairperson または chair
実業家 businessman businessperson
写真家 cameraman Photographer[要検証 – ノート]
英語で見ると男性限定の表現だったものが女性も使えるようになった例が多い
それに対して日本は女性限定の名称が男性も使えるように変更されたものが多い。
カメラマンやビジネスマンキーマンのような海外では既に改定された用語はそのままなのは、日本人はマン=男という意識が薄いからだろうか?
看護士 看護師 2002年、保健師助産師看護師法改正。男性も職業に就いているため。
障碍者 「害」の字が使われていることに不満がある人の感じる悪い印象を回避するため。2001年(平成13年)に東京都多摩市が最初に採用。
助産婦 助産師 2002年、保健師助産師看護師法改正。ただし現行では資格付与対象は女性限定である(同法3条)。
保父 保育士 1999年、児童福祉法改正。男性も職業に就いているため。
キャビンアテンダント (CA) 1996年に日本航空が従来の呼称を廃止。他社も追随した。世界の航空会社では、男性も従事している。
トルコ風呂 ソープランド トルコ人留学生、ヌスレット・サンジャクリの抗議により、1984年に改称。
女優 俳優 男優という言葉があるのにもかかわらず、男性のみに俳優という肩書が使われることが多いため。
メクラフランジ 閉止フランジ JISなども改正済み 英語ではblank flange・blind flangeなどと云い、JISでも記号はBLと残る