starcraft2日記 bronze(3)

vs Terran @Delta Quadrant

相手は 2 Barracks FE (Fast Expand) というのをやろうとしていたみたい。

とはいえこちらは向こうの出方に関わらず3Barracksごり押しで、普通に押し勝ち。ワンパターンであれなので、そろそろビックリドッキリメカとかも作っていこうかな。操作にも慣れてきたことだし。

vs Terran @Stepps of War

相手も3Barracksだったので進撃隊が殲滅されて即カウンターされて降参。そりゃ同じ戦略をとってたら移動時間の差で攻撃側が負けますわな。相当格上のGoldさんだったのでstimのタイミングとかそもそもの軍量とか全てにおいて負けてたっていうのもあるけど。scanでMM大盛が見えた時点で別の戦法に移行できたらよかったなー。やっぱりメカの練習をするしか。

starcraft2 bronze league (1)

vs Terran @Lost Temple

相手は30戦程しているbronzeの方。vsTということでBanshee超警戒です。何はなくとも偵察なのですが、しかしこのマップは敵陣がどこにあるのかわかりません。SCVを斥侯に出す必要があります。かなり手間取るも、最後の陣地訪問ですぐ隣の丘にいることが判明。Barracksが3つ建った時点で相手陣をscanしたところ、Starportを2つ発見。この人狩る気まんまんだー。あわててEngineering Bayを建設してTurretの準備をします。それからちょっとMMを貯めてから、おそらく防備が手薄であろう内に進行、敵陣坂下にattack move。このうかつな移動が失敗で、移動中崖上Tankにぼかすか撃たれて、攻め込む前からMarine2がお亡くなり、Marauderも瀕死だったりlife半分だったりでぼろぼろです。まあでもまだいけるんじゃないかな?ということで注射の力で坂を駆け上り、封鎖depot破壊前にまずTankを破壊、進入後にscanを使ってcloak Bansheeを打ち落とし相手は投了。研究や兵種を揃えるために量が出せていなかったようで助かりました。以下反省点。

  • Barracks3のタイミングでscanするのはたぶん良い。
  • 今回はコマンドセンターの位置をscanしてたまたまstarportが見つかったが、これは良くない。ちょっと位置を外して陣地内の空き地を見るべき。
  • 結局Turretを建てていない。今回は相手陣への移動中手が開いた隙に建てられるとよかったかなと思う。今までのreplayをみると、だいたいMMの着弾直前にちょうどCloak研究が完了するみたい。
  • 敵陣に近づいたら移動は丁寧に。Tankに撃たれる。
  • 3つ目のBarracksにはTech LabをつけてMarauderを作っていたのですが、Bansheeの気配がしたらReactorをつけてMarineを多めにした方が安定しそう。敵陣のBansheeを打ち落とすMarineの量がぎりぎりだった。
  • Supply Depotを壊すのはけっこうよさそう。最後相手はsupplyが詰まって軍を出せてなかったみたい。

Bronze15にあがりました。わーい。
そういえば最初に相手の方から「Im probably bonehoused」と言われたのですが、どういう意味なんでしょうか。骨でできた家に住んでるの?

はじめてのstarcraft2

civ5も200時間以上やってそろそろ飽きたなーということで、世界的に大人気のRTS、starcraft2をやりました。多少でもアクション性のあるゲームはかなり苦手なので上手なプレイは見込めませんが、ランクマッチがしっかりしていてプレイ人口も多いと言う事なので、下手なりに楽しめるのではないかという目論見です。
まずはシングルのキャンペーンを通してやろうと思ったものの、10話くらいでやめ。英語わかんないだもん。私も英語が全く駄目なわけではないのですが、表現が砕けているからなのか、さっぱり話が追えません。もういい。
ということで、さっそくマルチで世界に挑戦。の前に、なにをすればいいのかさっぱりわからないので、webで予習。種族はさっきキャンペーンで使ったTerran。調査の結果、一番操作が簡単そうな3barracksでMM(Marine,Marauder)プッシュ、という定石を覚えることにしました。civ4で例えると斧ラッシュみたいな位置にある戦術です。

この動画を参考に、AI相手に10回ほど練習。SCVを欠かさず生産、兵を途切れさせず、supplyをミスらず、とやるのは初心者にはかなり難しいです。terranの科学力でsupplyの自動設置くらいやってくれてもいいのにねー。動画では7分頃に人口50に達すると言っているんですが、私がやると8分近くになります。まあでもその程度で上出来かな。hard AI相手には常勝、very hard相手だと押し切れずぐだぐだ、といったところです。OKOK。マルチプレイボタンを押すと、まず最初に各々の実力にあったリーグに配属するため、5戦placement matchと呼ばれる腕試し戦をやるとのこと。もちろん本気で勝ちにいきます!

1戦目 vs Terran @ScrapStation

20戦程度経験した少し先輩のTerranさんが緒戦の相手。このマップは動画で見た記憶があります。それぞれの陣地の直線距離は短いけど、陸路でいくと大きく迂回する必要がある、というところだったはず。戦術固定の私にはその事は大して影響がないのですが、相手の位置が初めからわかっているのですこし安心。偵察SCVを動かしながら他の事するなんてできないですからねー。一応1つ目のsupplyを作ったSCVは相手陣地を覗きに行かせはしますが、見る余裕がないので単なるポーズです。
練習の時と同じようにミネラル不足でbarracksを回せなくなったりしつつ8分弱でMarine8Marauder6を作って幸福注射及びMarauderのスローショット研究を完了、相手陣地に向かいます。道中無害な動物だかロボットだかにうろたえながらも進んだところ、相手陣地の坂下あたりで移動中の敵の集団に遭遇。Marine11Marauder4Tank1SCV1です。こう見るとどちらが勝つのかわからない数字なのですが、相手がattack moveでなく単なるmoveにしていて、かつ気付くのが3-4秒送れたために、注射で素早くなったこちらの軍に1人の被害も出すことなく全軍殲滅できました。そのまま本陣になだれ込んで相手は投了。
相手陣でTankをsiege modeにして構えられてたら押し負けていたかもしれません。2つの研究完了直後に同量の軍で相手坂前にいる、くらいにしないと駄目な気がしますね。

2戦目 vs Terran @BlisteringSands

1度勝ったためか、次はsilverリーグの猛者と勝負です。初期陣の周りが広くて、出口の坂がみつからずかなり焦る。モニタの明るさを上げると暗い未探索部分が見やすくなって良いかもしれません。さっきと同じようにMMを貯めていると、7分弱で相手Mrine6くらいが封鎖した坂下に出現。2人撃破して追い返しました。まだこちらの軍は少なかったので前回同様8分前まで貯めてから相手陣に出撃、している途中で自陣に突如敵のMarine20体が出現。どうやらBlisteringSandsというマップには初期陣脇の草むらで隠れた場所に岩の障害物があって、これを壊すと相手の懐にすばやく飛び込めるようになっているみたいです。そんなの知らないよー。炎上するコマンドセンターと虐殺されるSCVをながめつつ、次にこのマップになったときは草むらにsupplyを建てて視界を確保する事を心に誓いゲーム投了。

3戦目 vs Terran @BlisteringSands

先程と全く同じ組み合わせ、相手のリーグも同じくsilverです。悲劇を繰り返さないために3つ目のsupplyを草陰の奥に置こうとしたところ、敵のSCVが潜んでいたのでMarineで駆除。何をするつもりだったのか。恐ろしい。争いはここまで人の心を醜くしてしまうものなのでしょうか。んで8分くらいまで兵を貯めてプッシュ。道中でリーパーに鉢合わせて撃墜してラッキー。この調子で本陣も落とそー、と坂下で注射を打ってなだれ込んで相手の寡兵を殲滅するも、コマンドセンターを浮かされて止めまではさせず。こちらの残存兵はMarauderばっかりで、対空を打てるMarineがいない。おかしい。とここでそれまで光学迷彩で隠れていたBansheeが突如登場。Marineを殺したのは君かー。残りのMarauderも各個撃破され全滅。んもー。相手の兵はBansheeしか残っていないようなので、こちらはMarineばかり作る。10人くらいで再プッシュしている最中に自陣にBanshee4、守衛のMarine6くらいもあっさり溶ける。支援のscanを受けられない攻撃部隊も迷彩Bansheeの前に全滅。Banshee恐ろしい子。gg

4戦目 vs Zerg @Xel'Naga Caverns

やっとTerran以外とあたりました。このひとはこちらと同じく、placement match中だったみたい。ちょろちょろくるZerglingをぴちゅんぴちゅんしてからMMで押して勝利。ZergさんはMutaliskを少量だしていて、多分それでハラスに来ていればこちらは対処できなくて泥仕合になっていたと思うのですが、本陣が攻められていたので操作が間に合わなかったようです。

5戦目 vs Terran @SteppesOfWar

silverの人。2戦目と同じような流れでした。相手本陣をほぼ壊滅させるもcloak Bansheeに手も足も出ず、隠し2ndを作っていた向こうの勝ち。無駄にぐだぐだして30分も付き合わせてしまいました。すいません。

placement match結果

2勝3敗、silverには勝てないね、ということでBronzeリーグ60に配属されました。2勝もできて自分では満足です。試合内容を反省すると、まず2戦目で出た各マップへの対応。これは数をこなして慣れるしかないでしょう。それと、Banshee対策。1戦目の人もreplayをみるとCloak Bansheeをだそうとしているようでした。おそらくこの腐敗した世界ではBansheeによる初心者狩りが横行しています。これを返せるテクニックが急務です。

  • 偵察をきちんとする。BansheeはStarport+Tech Labが必要なのでチェック
  • Bansheeの匂いがしたらEngineering Bayを用意してMissile Turretを建てる
  • その場合相手の兵は少ないはずなのでプッシュを早める
  • プッシュ時にscanできるようにエネルギーをとっておく

この対応でいきたいと思います。うまくscan範囲にStarportが入らないと対応できない気がしてならない。うーん、その頃はSCVもMarineにやられちゃうだろうし。まあそこは頑張るってことで。Bronzeのみんなよろしくね。

ニコニコ動画のスクリプト

ニコニコ動画では、動画再生時に実行されるスクリプトを動画の投稿者が書くことができます。この言語は「ニコスクリプト」とか「ニワン語」などと呼ばれるようです。
ニコニコ動画まとめwikiを見ると仕様がだいたいわかります。

webで知ったwikiに載ってない機能など

関数定義 def

def(format, )

  • def_kari に似ていますが、関数名を文字列ではなくそのまま指定するのと、引数に名前をつけられるところが異なります。
  • ex. "I'm Jon(8)."が表示されます。
0::/def(say(name,age), dt("I'm " + name + '(' + age + ').'))
0::/say('Jon',8)
  • 関数を再帰させるにはdef_kariでは駄目で、defを使う、っぽい。ex. "123456789"が表示されます。
0::/str=""
0::/def(fn(n),if(n<10,then:str+=n;fn(n+1)))
0::/fn(1)
0::/dt(str)
ループ while_kari

while_kari(評価式, )

  • 評価式が真の間を実行します。いわゆるwhile文です。
  • ex. "123456789"が表示されます。
0::/str=''
0::/i=0; while_kari(++i<10, str+=i)
0::/dt(str)
代入 :=
  • ローカル変数を定義します。def, def_kari で定義した関数がローカル変数のスコープになるようです。
  • 代入 = を関数内で使用した場合、変数が外側のスコープで定義されていた場合はその変数に代入、未定義の場合はローカル変数として定義されるようです。
drawShape 制限数

けっこう厳しいです。

スクリプトで何を作るか、について

一人でやるゲームを作っても、他の人のコメントがただのノイズになってしまい、ニコニコ動画を使う意味があまりありません。通常の動画にちょこっとお楽しみ機能としてつける程度ならありでしょうが。タイムラグがあっても成り立つ多人数参加型のなにかを考える必要があるでしょう。

javascriptで非同期処理、の続き

http://d.hatena.ne.jp/sunpro/20100501/1272696997

Concurrent.Threadはちょっと大技すぎる、ということで素直にfunctionをchainさせることにします。MooToolsのChainをつかうとこんな感じに。

// イベントをこんな風に書きたい、というのが目的
function playTutorial() {
    message('歩きます。');        // メッセージwindowが開き、クリックすると次に進む
    walk();                       // プレイヤーが歩く。アニメーションが終わると次に進む
    message('歩きました。');
}

var sequence = new Chain();
function chain(fn) {
    sequence.chain(fn);
}
function next() {
    sequence.callChain();
}

function message(msg) {
    document.body.innerHTML = msg;
    document.onclick = function() {
        document.onclick = null;
        next();
    };
}
function walk() {
    var fx = new Fx({ duration: 5000 });
    fx.set = function(now) {
        var text = 'walking';
        for (var i = 0; i < now; i++) {
            text += '.';
        }
        document.body.innerHTML = text;
    };
    fx.start(0, 5).chain(next);
}
['message', 'walk'].each(function(fn) {
    var orig = window[fn];
    window[fn] = function() {
        chain(orig.pass(arguments));
    };
});

// 実行
playTutorial();
next();

値を参照する時にfunctionで包むなどしないといけなくて煩雑な点は妥協する。実際に使うには、sequenceをコールスタックみたいに階層的にする必要があるだろう。