だいたい47度

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PageTop

[レビュー]家畜人ヤプーと社畜

2012年に読んだ小説の中でいちばんを選ぶのであれば「家畜人ヤプー」になる。正確には最終巻を読了したのは今年になってしまったのだけど。僕としては、奇書と呼ばれるドグラ・マグラを読んだときより、大きな衝撃だった。

以降、家畜人ヤプーについて書こうと思うが、もし汚物愛好や人体改造を含むグロテスクな描写に忌避感を覚えるのであれば、以下を読む必要はない。あえてグロテスクな描写をしようとは思わないが、家畜人ヤプーを述べる上でそういった描写を割けるのは難しいと思われる。そもそも、そういった描写が苦手な向きには、家畜人ヤプーは面白く無いだろう(というか表紙の時点でアウトだ)。

また多少のネタバレも含むが、本書の圧倒的な内容を前にすれば、下記の文など大した問題ではないであろう。

主題:被虐的世界の描写
家畜人ヤプーは、お話としては未来へのタイムスリップものだ。1960年代の男女カップルが主人公となり、二千年後の3970年へ連れて行かれて、未来世界の習俗に感化されていくという流れである。

しかし、家畜人ヤプーにおいて、タイムスリップおよび主人公たちの冒険は主題ではない。彼らの冒険は全5巻で丸2日も進まないし、そもそも最初の方で結論が示されている。その結論も特に驚くところもない。場面転換や主人公たちの内面変化は激しいが、それでも彼らは狂言回しに過ぎない。

では主題は何かというと、筆者のユートピア世界を詳細に描写することである。

筆者は、白人女性への被虐・隷属願望が非常に強い人間であった。彼は巷間のマゾヒズム小説に納得するものが見つけられず、己の渇望を医すためにユートピア世界を夢想していた。その世界を細部まで仕上げていくためには文字に落としていくことが必要だと考え、筆者が書き上げたのが家畜人ヤプーの世界なのだ(詳細は第5巻に所収されている「普及版あとがき」参照)。

つまり、筆者の夢想する被虐・隷属願望の行き着く先こそ、家畜人ヤプーの世界なのだ。筆者は病的といえるほど世界を隅々まで描画している。彼は「法律・裁判、経済・貨幣・税制、軍隊・警察、教育・医療・協会、演劇・スポーツ……イース世界百般の社会事象に関し」て全て考えており、それを記述しようとしているのだ。

家畜人ヤプーを読んで、筆者の被虐・隷属願望に比べれは、僕が想定する「常識・倫理などを破った世界」など児戯に等しいことを痛感した。完全に想定の範囲を上回る小説だった。

家畜人ヤプーの世界
家畜人ヤプーの舞台である未来世界(=イース世界)には2つの大きな特徴がある。「徹底した人種差別」と「女権専制社会」だ。筆者の白人女性への被虐・隷属願望が正に世界の軸となっている。

まずは「徹底した人種差別」についてだが、基本的には三段階があると考えてもらえば良い。3970年のイース世界では、イギリスが全宇宙を掌握し、白人による支配が行われている。白人の下には、使用人としての黒人、黒奴がいるが、黒奴は半人間として扱われ、人間たる白人とは明確に差別されている。そして、更に黒奴の下にいるのが家畜人ヤプーである。なお、白人・黒奴・ヤプー以外は第三次世界大戦において死滅した。

つまり、白人>黒奴>ヤプーとなっているのだが、このヤプーは実は現代の日本人のことである。イース世界での研究により、日本人は人類でなかったということが分かったため、半人間である黒奴より更に下の家畜、家畜人として扱われることとなったのだ。

ヤプーは人類でなく家畜人であるため、人類=白人の役に立つよう様々な分野に利用される。

ヤプーの使い道の一つは生体家具だ。便器、布団、椅子、机、バスタブ、犬、ハンドバッグ、楽器……など、白人の居住空間のほとんどはヤプーを使った生体家具で占められている。

生体家具となるヤプーは、白人が使いやすいように遺伝子および肉体を改造され、白人が使いやすいように教育されてきている。例えば便器として働くヤプー「セッチン」を例に挙げよう。セッチンは便器として働きやすいように口を裂き、舌を伸ばし、鼻の位置を変え、便座になるよう肩を癌化させて拡大し……といったように改造される。また同時に、便器として働く際のテクニックおよび白人を神と崇める洗脳のための学習を学校で習い、非常に洗練された便器としての奉仕を全力を尽くしておこなうよう仕込まれる。

他の使い道としては、燃料、食料、革……などあらゆる分野でヤプーは活躍している。イースの科学を持ってすれば、遺伝子的・外科的改造は勿論、寿命と引き換えに身体を極端に小さくすることや、使用者の脳波を受信して行動するようにすることもできるため、様々な分野に特異的なヤプーを作ることができるのだ。ヤプーの総数は非常に多いので、新種の構築のために幾らヤプーが死んでも構わないし、使っているものも要らなくなったら気軽に廃棄処分できる。

上記数段落では簡潔に留めたが、「家畜人ヤプー」本文中ではヤプーの使い道ひとつひとつが詳細に記述してあることは付記しておく。

イース世界のもう一つの特徴は「女権専制社会」だ。イース世界では、現在の男性主導の社会から女性主導の社会に切り替わり、労働をするのは女性の仕事、家を守るのが男性の仕事となっている。女々しいと雄々しいの意味合いが逆になっているのだ。例えば、黒奴の半人間はデミ・ウーマンと読む。

この「女権専制社会」の成立にもヤプーの一種、子宮畜(ヤプム)が大きく関わっている。ヤプムとは代理出産の腹となるためのヤプーである。白人女性が妊娠すると、その子種を極小畜(身長を極度に縮められたヤプー)が子宮の中に入っていって回収し、ヤプムの腹に移し替える。ヤプムはそのまま子供を腹にいれて育て、出産の際にはハラキリをして子供を取り出す(白人の子供がヤプーの産道を通るのはおかしいため)。

ヤプムにより白人女性が妊娠から実質的に開放された結果、女性による社会進出=女権革命が起こって女権専制社会が成立したわけである。

以上のようにして「徹底した人種差別」と「女権専制社会」という軸ができ、筆者の白人女性への被虐・隷属願望を表す世界の基本となっている。基本と書いたのは、上述した内容から更に隷属していく運命が待っているからであるが、それは本書を読んだときのお楽しみとしよう。

被虐・隷属願望において、自分が苦痛を感じることは大事であるが、その理由が相手への奉仕であることの方がより大事である。ともすると、衝撃の大きさからヤプーが踏みにじられていることだけに着目しがちではあるが、それだけでは片手落ちであり、あくまでも白人の心地良い生活のためであることを理解しなくてはならない。奉仕のためという前提があるからこそ、白人・黒奴・ヤプーを含む複雑な社会システムが詳細に構築されているのだ。

苦痛を伴う奉仕に喜びを
この小説が最初に発表されたのは1956年。その当時、この小説は筆者の欲望の具現化であると共に、現実の風刺と読むことができた。それもあって幾らかの人たちには受けたようである。

2012年の僕が読むと、西洋大国に蹂躙される日本という絵面にはピンと来ないが、「社畜」人ヤプーという言葉が何となく浮かんできた。

ヤプーは、自分の仕事は誰の仕事よりも尊いものであると信じてやまない。たとえ食べられるヤプーでも、白人(神)の身体の一部になれるなんて!という喜びでいっぱいのまま食べられていく。痛くても喜びが上回るのだ。白人の方も、ただヤプーを利用するのではなく、本人たちが満足して奉仕するように仕向けるべきだ(慈恵主義)、そうすることでより良い奉仕を受けられると考えている。

そこかしこにあるこの描写を見たとき、僕は、あまり面白くもない仕事を自分を騙して素晴らしいものだと思い込み、身体を壊してでもやっている社会人を想起してしまった。外の世界を見ることさえ知らない人を、忙しいことを求めている人を。

世界を描ききっている小説に触れると、人は自分の世界を投影してしまうのかもしれない。


家畜人ヤプー〈第1巻〉 (幻冬舎アウトロー文庫)家畜人ヤプー〈第1巻〉 (幻冬舎アウトロー文庫)
(1999/07)
沼 正三

商品詳細を見る

余談だが、石ノ森章太郎の漫画も出ているらしい。どうやって漫画化したのだろう……。読んでみようかな。

スポンサーサイト

PageTop

キモくて面白いボールを買ったよ メッシュスクイシーボール

やばいものを手に入れてしまった。

下の画像のボールである。手のひら大のゴムっぽい材質のボールの周りに、ネットがかぶさっている。なんの変哲もないボールに見えるが、ちょっと握ってみると……。


動画をみてもらうと分かるように、とてもキモいことが起こる。最初だけでもキモいのに、戻るときにプツプツ戻っていくのがまたキモい。とてもハマる。

このボールはメッシュスクイシーボール(Mesh Squishy Ball)というボールで、ビレッジバンガードで500円くらいで売ってた。買った当初はちょっと力を入れないとニュってならないのだけど、遊んでいるうちに柔らかくなっていく。幾つか色があるのだけど、ムラサキのが気に入ったのでそれにした。

12個セットってお前……、って思ったけど1個でも売ってた。アメリカで大人気!とかがB級っぽくて好き。

★何コレ!?日本初上陸、アメリカで超人気!★メッシュスクイシーボールMeshSquishyBall★【ブルー&ネオンイエロー】ストレス解消ボール!★何コレ!?日本初上陸、アメリカで超人気!★メッシュスクイシーボールMeshSquishyBall★【ブルー&ネオンイエロー】ストレス解消ボール!
MeshSquishyBall

商品詳細を見る


メッシュスクイシーボール【Mesh Squishy Ball】12個セットメッシュスクイシーボール【Mesh Squishy Ball】12個セット
不明

商品詳細を見る

PageTop

Objective-Cの乱数作成はarc4random_uniform

Objective-Cで乱数を発生させたい時があります。その方法の比較。

rand()を使う
一番単純な方法としてはrand()を使います。rand()で乱数を発生させ、MAX_NUMのmodをとることでMAX_NUM未満の乱数を取得するわけです。

rand() % MAX_NUM;
例)rand() % 3 + 1 →1から3までの乱数を取得

ただし、この方法で実装すると実行するたびに毎回同じ乱数が発生します。そのため、乱数の初期値を修正する下記の方法をとることが多いです。

srand(time(NULL));//現在の秒数を元に初期値を修正
rand() % MAX_NUM


arc4random()を使う
Objective-Cでは便利な関数としてarc4random()があります。これを使うと乱数の初期化が要りません。

((int) arc4random()) % MAX_NUM;

ただし、arc4random()の返り値はunsignedの値(u_int32_t)なので、intにキャストしてあげないと想定していない数値が取れてしまうことがあります。ここに気をつけないと、配列からランダムに中身を取り出そうとしてINDEX範囲外を取得してしまいランタイムエラー、なんてことになります。

また、実はarc4random()はランダム性に少しバイアスが掛かっています。arc4random()は0から2^32-1の値を返すため、それの法をとる際に微妙にランダム性が崩れるのです(modulo bias:0から10の値をとるランダム値のモジュロ7の法をとると、0-3の出現割合は4-6の二倍になりますね)。ただし、MAX_NUMが2の累乗であれば完全にランダムとなります。

arc4random_uniform()を使う
arc4random()のランダム性のずれを補正したのが、arc4random_uniform()です。

(int) arc4random_uniform(MAX_NUM);

ただしMacOS10.7以上、iOS4.3以上が要求されます。最新のXcodeだとiOS4.3以降対象のアプリしか作れないので、基本的にはarc4random_uniformを使うべきだと思います。

詳解 Objective-C 2.0 第3版詳解 Objective-C 2.0 第3版
(2011/12/28)
荻原 剛志

商品詳細を見る

PageTop

Box2Dでbody破壊後もsprite画像を描画(cocos2d)

cocos2dのBox2Dで、PhysicsSpriteのbodyをDestroyした後も画像を描画したいときについて。

前提 PhysicsSpriteとは
PhysicsSpriteは、物理シュミレーションを行うbodyにSprite画像を貼り付け、bodyが動くのにあわせてSpriteも動くようにする便利なクラスです。cocos2DのBox2Dプロジェクトを作成すると自動的に生成されます。

bodyに画像がついていく動きはnodeToParentTransformで実装されています。PhysicsSpriteにsetPhysicsBodyでセットしたbodyにあわせて画像が動きます。worldをstepさせるだけで画像の回転やら移動やらを良い感じにやってくれるので、非常に便利です。

PhysicsSpriteは本来CCSpriteの子クラスですが、僕はCCSpriteを継承させたGameSpriteというクラスを作り、それを継承させてPhysicsSpriteを作る形にしています。GameSpriteクラスは、アニメーションや状態の遷移などをしやすくしたクラスでLearning Cocos2Dから学びました。詳しくは過去記事参照。CCSpriteの子・孫クラスなのでCCSpriteBatchNodeで管理します。

Body破壊後に画像を描画する方法
ゲームを作っているうちに、PhysicsSpriteのbodyを破壊しながらも、画像は表示したいことがあります。例えば、敵を倒したとき、bodyはすぐに消して(破壊して)ゲームに影響を与えないようにしつつ、画像はCCBlinkで点滅させながらFadeOutしたいときなどです。

しかし、単純にbodyの破壊だけを行うとぬるぽで落ちます。nodeToParentTransformではbodyの位置を取得するため、body破壊後に呼び出してはいけません。

対応としては単純で、PhysicsSpriteにbool型プロパティを一つ持たせ、nodeToParentTransformの先頭で確認してあげればいいだけです。bodyの破壊時にはそのプロパティをONにし、以降nodeToParentTransformが空ぶらせてあげる。

-(CGAffineTransform) nodeToParentTransform
{
  if (_isNeedToTransform == NO) return transform_;
 
  //


静的Body注意
実は、b2_staticbodyをdestroyして画像をそのままにしても、落ちません。調べてないですけど、おそらくsleep状態のbodyはnodeToParentTransformが呼ばれないのではないでしょうか。

そのため、僕はゲームをある程度作るまで上記の問題に気づきませんでした。僕が作っていたゲームでは、b2_staticbodyが破壊される時にアニメーションを描画するようにしていましたが、問題なく動きました。一方でdynamicbodyの破壊は同時にvisible = NOとなるようになっていたので、問題の発覚が遅れたのです。

そしてあるとき、とても変な動きに気づきました。b2_staticbodyの破壊をしながら、一秒に数回b2_dynamicbodyをcreateする状況になったとき、b2_dynamicbodyの画像が、破壊されたb2_staticbodyのものになっていたのです。静的なものの画像が、すごい勢いで動きまわってる……。最初はCCSpriteBatchNodeの問題かと思ったのですが、b2_staticbodyとb2_dynamicbodyを別バッチノードに登録しても問題は再発しました。

静的物体のボディに上述の制御をいれたところ、問題が生じなくなりました。具体的な原因はわからないのですが、破壊と生成が同時に起こってbodyのポインタがずれるような形になったのかな。いずれにせよ、bodyがNULLな状態でnodeToParentTransformが呼ばれうるのは良くないです。


なんか最近、書き始めたときの想定と全然違う記事があがるな……。

PageTop

カップルの休日の過ごし方にバドミントンがオススメ

久しぶりに気楽な記事でも。

最近、休日にバドミントンをやったのですけど、カップルの休日の過ごし方としてはかなりイイものだなぁと思いました。

1 男女差が少ない
初心者の場合、バドミントンは男女の体格差に影響を受けにくい競技です。また、女性経験者が多く、女性が男性を引っ張る形になることも多いでしょう(ウチでは正にそう)。

2 共同作業になる
バドミントンはラリーが続くだけで結構面白いものです。ぽん、ぽん、ぽんとつなげていくだけで単純に楽しいのです。相手がミスショットしたときにフォローしつつ、2人で記録を伸ばしていくのはまさに共同作業。

3 準備が少ない
ラリーを続けるだけならネットもいらず、適当にラケットと羽を用意するだけでOKです。ほんの二〜三千円の初期投資で長く遊べます。思ったより全然安かった。場所も、近くの公園でぱっとできます。

SPALDING(スポルディング) DX バトミントンセットSPALDING(スポルディング) DX バトミントンセット
SPALDING(スポルディング)

←2本で2000円くらい。


製造直販シャトルでコスト削減!【バドミントン】シャトルコック!【アヒル羽根使用】初心者向け練習球!FEEL WIN 【ECO】(6個入り)製造直販シャトルでコスト削減!【バドミントン】シャトルコック!【アヒル羽根使用】初心者向け練習球!FEEL WIN 【ECO】(6個入り)
WAGI/FEEL WIN
←600円くらい。

とりあえずわかったコツは、ラケット面とシャトルの両方が視界で一致するまでは面を合わせることに集中し、当たる瞬間にだけラケットを動かすこと。テニスラケットより手元から面までの距離が遠いので、当てることに集中しないと空振りしちゃいます。一方できちんと当てれば簡単にポコーンと飛んでいく。

なかなか2人でできることが見つからなかったのですが、バドミントンはちょっと続きそうです。

PageTop

cocos2dゲームでデータ消去ボタン実装

iPhoneゲームアプリではユーザが自分のセーブデータを消したいときがあります。

データ削除の際には確認表示が必須です。一回のタップで全てのデータが消えてしまうのはあんまりです。

確認表示にはUIKitを使うのが、楽かつ綺麗に思います。前回作成したアプリでは、データ削除ボタンをタップすると別レイヤを呼び出し、そこに確認文言とOK・cancelボタンを作っていました。ゲーム全体の雰囲気を保持したかったのでそうしたのですが、今回UIKitをちょっと試してみたところ意外とキレイにマッチしそうだったので、反省をこめて記事を残します。
data_delete_confirm.png

まず、データ削除ボタンとしてCCMenuItemを作ります。これは単純。タップされた時にshowDataDeleteConfirmViewを呼び出します。

//GameLayer.m
- (CCMenuItem*) createItem {
   CCMenuItemSprite* itemSpr = [CCMenuItemSprite ....];//ボタン作成
   [itemSpr setTarget:self selector:@selector(showDataDeleteConfirmView)];
   return itemSpr;
}

次に、showDataDeleteConfirmViewを実装します。普通に呼ぶだけで確認ポップアップが表示されます。

//GameLayer.m
- (void)showDataDeleteConfirmView {
   UIAlertView* confirmView =
      [[[UIAlertView alloc] initWithTitle: @"データを消していいですか?"
         message: @"消したデータは戻せません。"
         delegate: self
         cancelButtonTitle: @"だめ"
         otherButtonTitles: @"いいよ", nil] autorelease];
   [confirmView show];
}

最後に、UIAlertViewのタップ結果で呼び出される関数を作ります。delegateで設定した先にalertViewを記述します(この例ではGameLayer.m)。NSUserDefaultsのデータ全消去をさせています。

//GameLayer.m
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
   if (buttonIndex==[alertView cancelButtonIndex]) {
      return;
   }
   //データ消去
   NSString* domain = [[NSBundle mainBundle] bundleIdentifier];
   [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:domain];
}

と、これだけで実装終了です。簡単ですね。

もし同一レイヤ内にUIAlertViewが複数ある場合は、allertViewの内側で呼び出し元を判別し、処理します。

//UIAlertView呼び出し部分1
UIAlertView* view1 = ......
view1.tag = 1;
[show view1];

//UIAlertView呼び出し部分2
UIAlertView* view2 = ......
view2.tag = 2;
[show view2];

//alertView
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
   if (alertView.tag == 1) {
      //view1の処理
   }
   if (alertView.tag == 2) {
      //view2の処理
   }
}

PageTop

Box2Dの衝突検知b2Contactとb2ContactListener(cocos2d)

Box2Dの物体同士の衝突感知のメモ。

簡易な実装はb2Contact
Box2Dで簡単な衝突感知はb2Contactを使って実装します。

b2ContactEdge* edge = targetBody->GetContactList();
while (edge){
b2Contact* contact = edge->contact;
if (contact->IsTouching()){......}//contactから衝突しているfixtureをGetして必要な処理を行う
edge = edge->next;
}

しかし、b2Contactでは、callの間に衝突したものは検知できません。あるcall後に衝突し、次のcall時には跳ね返って衝突が解除されてしまっていた場合、検知されないのです。それでも問題ないゲームであればb2Contactを使うのが良さそうです。

b2ContactListenerを使った実装
正確に衝突を感知する必要がある場合などは、contact listenerを上書きして使います。

基本的にはこちらを参考にして実装しました。

簡単に中身を説明すると、衝突した物体の組み合わせ全てを構造体MyContactのベクタで管理し、ゲームからはベクタの中身をチェックすることで衝突を感知しています。衝突時(BeginContact)にMyContactを作成しベクタに登録、衝突終了時(EndContact)にベクタから削除というようにしているわけです。

しかし、実際使ってみると、たびたび衝突感知が効いていないようでした。再現条件がわからないのですが、ゲームをしていると数十回に一回くらいの頻度で起こっています。

ちょっと調べてみた結果、ゲームからベクタの中身を走査する前にEndContactされているようでした。考えてみればそうか、b2Contactを使ったのと同じになっているじゃん。

ので、ベクタの中身を消す処理を作って、ゲーム側が走査後にその処理を呼ぶことで対応しました。

//MyContactListener.mm
void MyContactListener::BeginContact(b2Contact* contact) {
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() };
_contacts.push_back(myContact);
}

void MyContactListener::ClearContactsData(){
_contacts.clear();
}

void MyContactListener::EndContact(b2Contact* contact) {
}

//GameLayer.mm
- (void)update:(ccTime)dt{
for(pos = listener->_contacts.begin(); pos != listener->_contacts.end(); ++pos)
{......}//チェック処理

listener->ClearContactsData();
}

うん、これでOK。

Learning Cocos2D: A Hands-On Guide to Building iOS Games with Cocos2D, Box2D, and ChipmunkLearning Cocos2D: A Hands-On Guide to Building iOS Games with Cocos2D, Box2D, and Chipmunk
(2011/07/07)
Rod Wenderlich, Ray Strougo

商品詳細を見る

PageTop
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。