2013年12月23日月曜日

Chromeの拡張機能試してみた. 2

ただGoogleトップに飛ぶだけでは面白くないので…


Chromeの拡張機能試してみた. 2


今回はできることいろいろ見てみる回

0. 前回のmanifest.json

{
 "manifest_version": 2, // マニフェストのバージョン. 2にしないと怒られる
 "name": "my extention", // name. 表示される名前でもある
 "version": "1.0",  // アプリversion. 更新があったらあげていく.
 "description": "my first extention", // 説明.
 "icons": {    // iconの設定. サイズごとに設定できる
  "16": "icons/icon.png",
  "48": "icons/icon.png"
 }, 

 "browser_action": {  // ツールバー右上に表示するのに必要な設定. Chrome4からのAPIで、それ以前のものでは使えない。
 "default_icon": "icons/icon.png", //表示するアイコン
     "default_title": "titil test", // 説明. 右上にアイコンを出す場合はホバーするとみられる
     "default_popup": "htmls/popup.html" // 右上に表示されたアイコンを押した際に出るhtmlの指定. 

}
こんな感じ

1. バッジテキスト


右上アイコンにこんなことできます


1-1. 準備

まずはmanifestの準備
"background": {   // 裏で動く機能について書く場所
 "scripts": ["js/background.js"]
}

これをmanifestに追加。","に注意。 backgroundは表に見えない処理を書く場所。そこにscriptを宣言しておく。
ついでに該当ファイルを用意。

1-2. script実装


そして登場するのが
chrome.browserAction
クラス?

参考

要するに browser_actionに対していろいろできるメソッドを持つ。

今回はこんなのをチョイス
// バッジの文字を指定.日本語は不可. 4文字まで
chrome.browserAction.setBadgeText({text:"TEST"});

// バッジの色を指定. RGBA
chrome.browserAction.setBadgeBackgroundColor({color:[125,230,200,255]});

// clickイベント. browser_action.default_popupがあると負けるので注意
chrome.browserAction.onClicked.addListener(
 function(tab){
  alert("test alert");
 }
);

この3つ。概要はコメントで記載の通り。 特にclickイベントはbrowser_action.default_popupがあると宣言順などに関わらず負けるっぽい。使う場合は要注意。

これをbackground.jsに記載して リロード

すると


クリックも合わせてこんな感じ。


2. 今開いているページへの操作

そろそろ面白くなってまいりました
前準備として、1.の実行のために browser_actionのdefault_popupを外していた場合、元に戻しておくこと。

2-1. permissionの設定

いくら拡張とはいえ、あんまりポンポンいじれてしまうのは問題。なので必要な権限だけ付与してやる必要がある。

manifest.jsonで以下を宣言する。
 "permissions": [ // 権限付与の設定
  "tabs", "http://*/*"
 ]

権限に関わるものを宣言する場所。","区切りで並べていく。
内容としては、
tabs : タブに関する操作(移動、作成等)
http://*/* : 自分以外のリソースを使う宣言. この場合は、「httpスキーマである全てのドメイン、パスのものを使う」になるかと。httpsの何かを使うなら、新たに同様な宣言が必要。「現在開いているページ」の情報にアクセスしたいなら必要。基本この2つはセットになるのかねヽ('A`)ノ

2-2. scriptの準備

popup.html(アイコンを押したら出てくる領域)lがインターフェースになるため、まずは操作用のボタンを仕込む
今回はお手本通り、「いま開いているページの背景色を操作」する
<div id="red">to Red</div>
<script src="../js/colorscript.js"></script>
なんの変哲もないdiv。これにclickイベントを載せるscriptを続けて宣言してやる。もちろん中に書いてもいいけど…分けたいね(・д・`)

colorscript.jsを作成する。プロジェクトフォルダ内なら場所に制限は特にない。
function changeColor(color){
 chrome.tabs.executeScript(null,{
  "code" : "document.body.style.backgroundColor='" + color + "'"
 });
}

document.getElementById('red').onclick = function(){
 changeColor('red');
}

ポイントは1. 同様に用意されている、chrome.tabsクラス? タブ操作にまつわるメソッドがいっぱいなのは名前から明らか。
今回は指定したscriptをタブ内で実行する、executeScriptを使用。 実行する内容自体は至極単純で、背景色に引数の色を指定してね、というだけの内容。
これを、#redクリック時に発動するようイベントを乗っけてやるだけ。

全部終わったらまた拡張機能タブからリロード。


3. 実際にやってみる

3-1. 実行

適当なページを開いたら、右上のアイコンをクリック。まずはポップアップ出てますか?
ポップアップが出たら今度は to Redをクリック。するとbodyに background-colorが設定されているはず。
ちなみにポップアップのところで右クリック→要素を検証 すると、ポップアップ部分のデベロッパーツールが開いてくれる。scriptのエラーなんかのチェックに使えるのでぜひ多用するべし。

3-2. 一工夫

実際に色が変わったらここで一工夫。わざわざ開く→押す なんてめんどくさい手間をかけずにアイコンクリックで何とかしたい場合。
1.でいじった background の部分を利用する。

まずmanifest.jsonのbrowser_actionから、default_popupの項を削除。これでポップアップは開かないはず。
さらに backgeoundを1.の状態に再現、動作を確認する。
大丈夫そうなら、background.jsのchrome.browserAction.onClicked.addListener()を用いる。1-2.で既に入れている場合、現在alertが入っている部分に、changeColorメソッドの中身をまるっとブチ込む。
chrome.browserAction.onClicked.addListener(
function(){
 chrome.tabs.executeScript(null,{
  "code" : "document.body.style.backgroundColor='red'"
 });
);

とかなるかと。
これでリロードし、アイコンをクリックすると、同じように赤い背景になるはず。目に優しくない(⊃д⊂ )


ここまでのフォルダ構成

ChromeExt━ ┳━manifest.json
                   ┃
                   ┣━js┳━background.js
                   ┃     ┗━colorscipt.js
                   ┃
                   ┣━htmls━popup.html
                   ┃
                   ┗━icons━icon.png







こんな感じ?ヽ('A`)ノ


参考: ドットインストール

2013年12月9日月曜日

Chromeの拡張機能試してみた

ずっとやろうやろう思ってできていなかったので


Chrome拡張の自作

まぁ別に「こんな機能が作りたい!」なんてのはないので、ベースになる部分ができたらまずは満足。

0. 必要なもの

GoogleChrome
Javascritpの知識
htmlの知識?
なんか適当にエディタ

1. フォルダ準備

まずはプロジェクトフォルダの作成。場所は自由。めんどいのでデスクトップに作るズボラっぷり。
フォルダ名も特に制約っぽい制約もない?別にどこかに表示されるでもなし。
たぶんパッケージ名になるのだろうと予想。

2. ファイル作成

1で作ったフォルダの中でいろいろファイルを作る。まずはmanifest.json。これが無いと始まらない。
その名の通りjson形式での記入。うだうだコードを書かなくていいのは素晴らしいとおもう(小並感)

必要なファイルごとに追ってみる。

2-1. manifest.json

必須ファイル。先述の通りjsonで書く設定ファイル。アイコンの指定や使うファイル等はこいつが持ってる。

簡単にコード-A

{
 "manifest_version": 2, // マニフェストのバージョン. 2にしないと怒られる
 "name": "my extention", // name. 表示される名前でもある
 "version": "1.0", // アプリversion. 更新があったらあげていく.
 "description": "my first extention", // 説明文.
 "icons": {    // iconの設定. サイズごとに設定できる
  "16": "icons/icon.png",
  "48": "icons/icon.png"
 }, 
 // コード-Bに続く
}

まずは基本の宣言。 manifest_versionは拡張機能作成全体に言えることみたいなので、とりあえず2に。
ほかは表示の問題。コード的にはエラーを起こしたりはしないが、nameに関しては必須事項らしい。

簡単にコード-B

{
  // コード-Aから
 "browser_action": {
  // ツールバー右上に表示するのに必要な設定. Chrome4からのAPIで、それ以前のものでは使えない。
  "default_icon": "icons/icon.png", //表示するアイコン
  "default_title": "titil test",  // 説明. 右上にアイコンを出す場合はホバーすると見られる
  "default_popup": "htmls/popup.html" // 右上に表示されたアイコンを押した際に出るhtmlの指定. 
 }
}

この辺りから実用的な設定。拡張を有効にすると出てくる右上アイコンの設定についてのお話。
iconとtitleはともかく、問題はpopup。アイコンクリック時に出るアレはここの中で作る。

manifest.jsonについてはひとまずはこの辺。

2-2. html

簡単にコード-B 中に出てきたhtmlを作成。
<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8">
 </head>
 <body>
  <div class="main_contents">
   <span>Hello, World! <a href="http://www.google.co.jp" target="_blank">Google検索</a></span>
  </div>
 </body>
</html>

ただHello, World!と Google検索 というリンクが並んでいるだけのページ。 拡張で使うのにGoogleへのリンクなのはキニシナイ
とりあえずはシンプルにこれだけ。これをmanifest.jsonのパスに合うように、1で作ったフォルダ内に配置する。

ChromeExt(1のフォルダ)━ ┳━manifest.json
                                      ┃
                                      ┣━htmls━popup.html
                                      ┃
                                      ┗━icons━icon.png

現在こんな感じなはず。

3. 登録

準備ができたらいよいよ配置してみる。機能はとりあえず二の次。

まずは設定を開く。メニューから開くのが楽かと。
設定タブが新たに出てきたら、今度は左側の「拡張機能」を選択。
デベロッパーモードのチェックボックスにチェックを入れたら、
「パッケージ化されていない拡張機能を読み込む」を選択、ディレクトリが選択できるので、 1で作成したディレクトリを選択すると、拡張機能の一覧に追加されて



こうなるはず。icon設定していないのがバレバレである。なんか見えちゃいけないものがちらほらあるので塗りつぶし。ヽ('A`)ノ 
エラーなんかはここに出てくる。修正したら下の リロード を押せばOK。簡単。
ここに登録できたら、右上に注目。ちゃんと「有効」になっていれば設定したアイコンがいるかと。


押せばこうなるはず。 もちろんGoogle検索 を押せばGoogleトップへ。


今回はこんなところで。∩( ・ω・)∩




参考: ドットインストール

2013年11月26日火曜日

スマートフォン上での inputタグとキーボードの関係

よくある疑問
スマホで入力フォームタップしたときに立ち上がるキーボードって制御できないの?

結論としては制御はできません。但し、type属性に対応した初期キーボードの設定はOS側?でされているので、そちらでひっかけることはできるっぽい。

スマートフォン上での inputタグとキーボードの関係

正確には文字列を打ち込むタイプのinput
具体的には

input type="text"
input type="search"
input type="number"
input type="tel"
input type="email"
input type="password"
input type="url"


だいたいこんな感じ。他にもdatetimeなどもあるけど、端末やOSによってはテキストでない入力方法もあったりするので却下。

さてこの状態で、実際にスマートフォンからタップしてもらえるとわかるが、
各inputタップ後最初に起動するのは、

text        → デフォルト
search     → デフォルト
number    → 数字入力
tel          → 電話番号入力
email       → 英字
password → 英字
url          → デフォルト

となるかと。 要するに、だいたいデフォルトなわけで。(「デフォルト」 はデフォルトに設定されているキーボードタイプ)
きちんと入力させたいものに合わせてtypeを設定してやると、ユーザー的にはキーボード切り替えの手間は省ける。

ただし落とし穴があり、上記で 「デフォルト」 としたものは、タップしたとき必ずデフォルト設定キーボードが登場するわけではない。
たとえば上記であれば、

① type="text" のinputをタップし、数字キーボードに切り替えた後、
② type="search"をタップしてみる。

するとデフォルトが数字キーボードでもない限りデフォルトキーボードが出てくるはずなのだが…

答えは 「数字キーボードが居座り続ける」

そもそもキーボードの入れ替え自体が発生しない。

ただし、今度は
① type="text" のinputをタップし、数字キーボードに切り替えた後、
② type="email"をタップ、さらに数字キーボードに切り替えておく
③ またtype="text" のinputのうち、どれかをタップすると…

答えは 「デフォルトキーボードが立ち上がる」

自由すぎる…orz

また、 「数字だけを入力させたいんだ!」 ってところには type="tel"をわざと仕込んでやる、なんて手法もあるが、そのあたりでバグが一つ。

iOS5において、type="number"の 仕様 として、

① 「0930」など、"0"から始まる数字は、 valueにおいても0をないものと扱い、 例ならば「930」と認識する
② 3ケタごとに、「123,456,789」のように、","を入れて表示する。但しこちらは表示だけで、valueに影響は与えない。

という仕様がある。そのため、「電話番号入力」や「パスコード入力」のように、先頭の0を認めるものに対して type="number"を使うと正しく値が取れなくなる。




なお、iOS6からは治っている模様。 不評だったんだね…(・ω・`)

2013年10月31日木曜日

cssの強さ

ふと気になったのでまとめてみる

css強さ選手権

1. そもそも強さって?

基本的にhtmlやjavascript等は, 後に書いたものが優先されて反映される. cssも同様なのだが, たとえば

<div class="test_1" id="mytest_1">
    テスト1
</div>
<style>
    #mytest_1{color: red;}
    .test_1{color: blue;}
</style>

このように書いたとき, どちらも同じdivを指すため, 基本にのっとれば文字は, あとに指定した通り青くなるはず
しかし,

テスト1

赤くなる( ゚д゚ )

これが, 強さによってcssが上書きされる現象である.

2. 強さの順位

では順位はどうなっているのか

順位名前
1位直書き<div style="width: 100%"></div>
2位id#id
3位class.class
3位属性セレクタimg[alt]
3位疑似クラスli:first-child
6位要素名body
7位全選択*

だいたいこんな感じ
但し単体での強さでの話
組み合わせることで
<div class="test_2" id="mytest_2">
    テスト2
</div>
<style>
    div.test_2{color: red;}
    .test_2{color: blue;}
</style>

テスト2

あとに書いたはずの青ではなく, 先に書いた赤になる. これは, それぞれの指定が
赤 → 要素名(6位) + クラス名(3位)
青 → クラス名(3位)
となっており、より多く条件を付けた方が強く反映されるのである.

ちなみに強さを重ねて同列だった場合は…?

<div class="test_3 test_4" id="mytest_3">
    テスト3
</div>
<br />
<style>
    .test_3.test_4{color: red;}
    .test_3[id]{color: blue;}
</style>
テスト3

赤 → クラス名(3位) + クラス名(3位)
青 → クラス名(3位) + 属性セレクタ(3位)
とした実験。結果は下に書いた青の勝利


最後の実験。classを重ねたらidに勝てるのか?

<div class="test_4 test_5 test_6 test_7 test_8 test_9 test_10" id="mytest_4">
    テスト4
</div>
<style>
    #mytest_4{color: red;}
    .test_4{color: blue;}
    .test_4.test_5{color: blue;}
    .test_4.test_5.test_6{color: blue;}
    .test_4.test_5.test_6.test_7{color: blue;}
    .test_4.test_5.test_6.test_7.test_8{color: blue;}
    .test_4.test_5.test_6.test_7.test_8.test_9{color: blue;}
    .test_4.test_5.test_6.test_7.test_8.test_9.test_10{color: blue;}
    .test_4.test_5.test_6.test_7.test_8.test_9.test_10[id]{color: blue;}
</style>
結果は…



テスト4


…うん(・ω・`)
まず一番強いやつがさらっていくんだね…


3. おまけ

それでも上の奴に勝ちたい、そんなcssに最終兵器。

<div class="test_11" id="mytest_5">
    テスト5
</div>
<style>
    #mytest_5{color: red;}
    .test_11{color: green!important}
</style>
idとclassの一騎打ち。但しclassには
!important
が設定されている。これが切り札。
テスト5
と、クラスによる指定にも関わらず緑になっている。後に設定したimportantのおかげだけど、あくまで最終手段。これは、

<div class="test_12" id="mytest_6">
    テスト6
</div>
<style>
    #mytest_6{color: red;!important}
    .test_12{color: green!important}
</style>
テスト6
からわかる通り、強さの順位どうこうをなくし、単純に書かれた順に上書きになっていく模様。

ちなみに
<div class="test_13" id="mytest_7">
    テスト7外
<div class="test_14" id="mytest_8">
    テスト7
</div>
</div>
<style>
    #mytest_7{color: red;!important}
    .test_14{color: green}
</style>

テスト7外
テスト7
さすがに親の影響より、直接指定されたものが優先されるみたい。


css等はこの場で実験もできるから面白い+(・ω・0)*

2013年9月26日木曜日

302を飛ばさない「リダイレクト」

なんか引っかかったのでメモメモφ(・ω・ )

302を飛ばさないでリダイレクトみたいな動きをするタグ


とあるページの通信を調べていたところ, 明らかにリダイレクトじみた動きをしているのに ステータスコード302が見当たらないと調べていたところ, 何やら変なタグを発見

<head>
<meta http-equiv="Refresh" content="0; URL=urlstring">
</head>
ヘッダにこんなのがいる真っ白なページを挟んでました
http-equiv="Refresh" は httpヘッダに refresh属性を仕込む宣言. もう一つの属性 contentと合わせて用いる. 内容はページのリフレッシュを行うことの宣言. なのでこれを仕込んでおくと自動でページを再読み込みしてくれる.
参考

content="0; URL=urlstring" が, リフレッシュまでの時間と, リフレッシュ後のURLの設定. 時間の単位は秒. この urlstringにリダイレクト先のURLを設定することで, 設定秒後に設定したURLにジャンプしてくれる.

移転したサイトの元サイトなんかに、メッセージとkのタグを仕込んでおくと, ユーザーを自動で移転先のページに運ぶ, なんてのが一般的な使い方らしい.





ちょっと予想外だったのでびっくりした(・ω・`)

2013年8月19日月曜日

Sublime Text2使ってみた -前篇-

さすがにメモ帳レベルのテキストエディタでHTMLを書くのは限界なので…('A`)

Sublime Text2使ってみた

1. インストール

まずはここからバージョン, bitに合わせてダウンロードからインストール. 特にインストール項目を設定することもないかも.
Sublime Text2は, 初期状態のままではほぼ空っぽな状態. なので自分でカスタムしてやる必要がある.
ちなみに 3もベータ版だけど出ている模様.

2. 準備

A. Packageのインストール準備
様々カスタムしていく準備を行う. Packageとは要するにプラグイン. 
まずは View→Show Console でコンソールを開く. 出てきたウィンドウのうち, 上が表示エリア, 下が入力エリア. 間違って表示エリアに入力しようとして, 「入力できない(・д・`)」とかググらないように. 自分だけか…('A`)

コンソールには以下をコピペ.
import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp) if not os.path.exists(ipp) else None;open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())
実行すると Packageをインストールするためのプラグイン「Package Control」をインポートする. 終わったら再起動. たまにこいつが突然消えることがある. よくわからないヽ('A`)ノ

B. 日本語化
有志の方が用意してくれたファイルを使って, 一部ではあるが日本語化ができる.
詳しくはこちら

C. ユーザ設定
Preference → Setting - Userを選択し, 出てくる設定ファイルにJSON形式で入力していく. フォントサイズや行間距離, 空白の表示方法等色々設定できる.
設定内容は以下のようなものが…
キー値バリュータイプデフォルト値内容
font_sizenumber11そのままの通り, 表示するフォントサイズの意. デフォルトは(おそらく)11
line_numbersbooleantrue左側の行番号の表示/非表示の切り替え.
gutterbooleantrue左側の行番号を表示している部分(ガーターと呼ぶらしい)自体の表示/非表示. ↑をfalseにするならこっちごとfalseにしてしまった方がいいかも?
marginnumber?ガーターとテキスト部の間の距離の指定. 負の値も設定可能.
fold_buttonsbooleantrue関数などの塊を"折りたたむ"機能のON/OFF. OFFにするとその分ガーターも狭まる.
fade_fold_buttonsbooleantrue↑の折りたたみ機能を 常時表示/カーソルを当てたときに表示 を切り替える. わかりにくい!って人はfalseにすると常に出ている.
rulersnumber[]縦にガーターの横に出ているようなラインを引く機能. 20と設定すれば, 半角で20文字入力した位置に, 縦にラインが引かれる. インデント揃える時などに? ","区切りで複数指定することも可能.
tab_sizenumber4Tabキーを1回押したときに表示されるスペースの量の設定. 10に設定すれば, Tabキー1回で半角スペース10個分進む. インデント幅にも影響する.
translate_tabs_to_spacesbooleanfalseTabキーを押した際に, Tab文字ではなくスペースを入力する. 削除しようとするとなぜか出力した分全てが削除される.
use_tab_stopsbooleantrue↑の"なぜか"の答え. こちらもfalseにしてやると, 削除する際スペース1個ずつ削除するようになる.
auto_match_enabledbooleantruetrueにしておくと, "("などを入力したとき, 自動で閉じる方も入力してくれる. 逆にこれが鬱陶しいなら falseで.
match_bracketsbooleantruetrueにしておくと, "("や")"にカーソルを合わせると, 対応するものに下線を引いてくれる.
…多いってばよorz
ちらっと上げようとしたのにキリが無いのでこのへんで.


ちょっと長くなってきたので続きは次で

2013年7月31日水曜日

ドロップキャップっていうらしい

こういうの


パラグラフの先頭文字だけ大きくするcss

といっても別に cssのプロパティであるわけではなく, 「先頭の文字」を指定して,  font-sizeを大きいものを設定してやるだけ. 

<div class="test1">
    といっても別に cssのプロパティであるわけではなく, font-sizeを先頭の文字だけ大きいものを設定してやるだけ.
</div>
<style>
.test1:first-letter{
    font-size: 3.0em;
    float: left;
    line-height: 1;
}
.test1{
    font-size: 1.0em;
}
</style>
コード的にはこんな感じ. ポイントは疑似要素 :first-letter. これで「最初の文字」を指定している.
ちなみに float: left;, line-height: 1;は演出用. これがないと,

たとえば------------------------------------------------改行した際に, こんな感じに次の行にいってしまう---------------------





じつはこんな要素指定していないのに一文字だけデカく表示されるバグのことを調べているときに見つけたのは内緒. しかもそのバグとは全く関係なかったし…(・ω・`).

2013年7月30日火曜日

selectタグで詰まった話

selectタグをいじってる際,  スマホ上での見せ方で詰まったのでメモメモφ(・ω・ )

selectタグの高さとスマートフォン

selectタグを使ってドロップダウン?な選択をさせたい, といった時, なんか(表示領域)小さいね, といった一言から始まった問題.

問題点は「selectタグの領域に heightがうまくかからない端末がある」 といった現象.





<select class="face_collection">
<option>ヘ(゚∀゚ヘ)アヒャ </option>
<option>∩( ・ω・)∩</option>
<option>ヽ(;´Д`)ノタスケテ~</option>
</select><br />
<br />
<style>
.face_collection{
height: 40px;
}
</style>

PCで見ればなんら問題なくなんか太いドロップダウンメニューができるはず.
但し, このページを, おそらくAndroid4.1系のデフォルトブラウザで見ていただければわかるはず.

「別に太くなんて無いんだけど…(・д・`)」

iPhoneや Android2.x系では太くなるのに, なぜか Android4.1系では太く表示してもらえない.
また, 太くならないのはデフォルトブラウザでのみらしく,  Chromeであれば "少し"太く見える.
一体なんなんだか…('A`)









まぁ font-sizeを大きくしてやれば, それに合わせて大きくなるんですがね( ´_ゝ`)

2013年7月22日月曜日

cssのアニメーション

jQueryのfadeやらなにやら, アニメーションを表現するものの中には機種依存を起こす物がちらほら. そんななか, 「cssの animationを使えばなんとかなるよー」ということなのでやってみた.

cssでアニメーション

1. やりたいこと

いわゆるフェードイン/アウト. しかしjQueryの.fade系は機種依存起こすかも, だとか. なので cssの animationで, cssのプロパティの opacityを操作する. 

( ゚д゚ )
おわかりいただけただろうか…

2. アニメーション内容の宣言

いじるのは css. jsはあくまで addClassしてクラスを切り替えるだけ. この切り替えられたクラスに合わせて cssで表現してやると, 再利用性は格段にアップするはず.

用意するコードはいつもとはちょっと異なり, 「アニメーションの動作内容」の部分と「作ったアニメーションを使うことを宣言する」部分に分けられる. 要するにアニメーションメソッドを作って, それを呼び出す, みたいな流れ.
<div class="testface">
( ゚д゚ )
</div>

上の例の場合は, まずはフェードするアニメーションを作成する.
@-webkit-keyframes anime1 {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-moz-keyframes anime1 {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
注意点としては, レンダリングエンジンごとに用意してやる必要があること. Chromeや Safariなら webkit. firefoxならmoz.
上が webkit用, 下は moz用の宣言. 中身を変えてしまうと当然動きも変わってしまうから注意. コピペ推奨.
1行目がレンダリングエンジンの設定と そのアニメーションの名前. 名前は自由に設定できるので, わかりやすい名前を付けてやろう.
2行目から4行目は, 開始の状態. この場合は 「opacity: 0;」透明度100%状態からスタート, となる.
そして5行目から7行目が終わりの状態.  「opacity: 1;」透明度0%状態となり, 完全に出現した状態となる.
この fromと toは, それぞれ 0%, 100%と書くこともでき, また 33%等, 途中の状態も設定できる.
これでアニメーションの内容は宣言できた. 割と簡単.

3. アニメーションの実行を宣言

アニメーションを作ったら, それを付与してやる. この時いろいろプロパティがあり, これがまたいろいろ悩ませてくれる. 

.testface{
    color: red;
    -webkit-animation: anime1 2s linear infinite alternate;
    -moz-animation: anime1 2s linear infinite alternate;    
}
color: red;はキニシナイ. webkit, moz用に2つ設定. 内容は同じ.
最初の anime1は 2.で設定したアニメーションの名前.  ここでどのアニメーションを使うか宣言する.
2s は「2秒」. アニメーション1周期を何秒で描画するか, を設定する.
linearはアニメーション方法の指定, この場合は fromから toまで一定の速度で変化する方法. 他にもいろいろ.
infiniteは描画回数. 単に 6など数字を入れればその回数描画してくれる. この場合は無限回の指定.
alternateはアニメーション方向. 要するに fromから toへアニメーションするか, その逆に toから fromへアニメーションするか, といった設定. alternateは「奇数回目は from→ to, 偶数回目は to→from」という特別な設定. 例にあるとおり, from→ to→ from→ toと, アニメーションの設定を行き来してくれる.
他にも, アニメーションの開始を遅らせるプロパティなども. これらをセットしたら準備OK.


ちなみに opacityをいじっていたところを marginをいじるように変更すれば, こんなものもcssだけでできる.↓

ガクガク (((( ゚д゚ ;)))) ブルブル



参考

2013年7月17日水曜日

javascriptでもEnum型

以前javaのEnumをまとめたけど
javascriptでもやる機会があったので

javascriptでもEnum型

やり方は簡単.

var counter = {
    a: 0,
    b: 1,
    hoge: 10,
}
シンプル. これを呼びだすのも,
console.log("counter is " + counter.a);
// or
console.log("counter is " + counter["hoge"]);
なにがおいしいかって, 後から追加も楽なこと.
たとえば,
<div class=".hoge">
    <ul id="animal">
        <li></li>
        <li></li>
    </ul>
    <ul id="fish">
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>
なんていうのがあり, 各 ulの liを順番に表示, 非表示にするようなギャラリーが作りたい, なんて時. 順番に回すのはいいけれど, 今どれが表示されているのか管理したい!でもこの後 ulがどんどん増えて, counterに名前なんて付けてられない!なんて時. あるのかね(・ω・`)
.
$(".hoge ul").each(function(){
    var idName = $(this).attr("id");
    counter[idName] = 1;
});
だいたい想像はつくはず. これで,
    console.log(counter.animal);
    console.log(counter.fish);
でそれぞれのカウンターが用意される. 応用するといろいろできるはず!




ちなみに
window.location
なんてのもこれだったりする.

2013年7月9日火曜日

Selectタグの見た目を変える

なんか面白いものを見つけたので

<select>の見た目を変える


コイツの見た目を変えたい!というお話.
使うプロパティは
appearance
こいつを使う.
とりあえずボタンにしてみる

select{

    /* 見た目をinputのtype=buttonに */
    -moz-appearance: button;
    -webkit-appearance: button;
    appearance: button;

}
この設定をしてやると…

となる. あとはボタンと同じようにデコレーションしてやればいい.
ただPCで見ると, たまに選択肢の描画がなんかおかしい. スマホならそれぞれのダイアログが開くので気にはならないかと.

ちなみに
select{

    /* 見た目をcheckboxに */
    -moz-appearance: checkbox;
    -webkit-appearance: checkbox;
    appearance: checkbox;

}
とかしてみると…



これはひどい…('A`)

2013年7月1日月曜日

cssで吹き出し

なんか面白かったからつい…
というかどういう必要性に駆られて生まれたのかが気になる(・ω・`)

cssで吹き出しを作ろう


たとえばこんな感じ
('A`)




Σ('A`)

構造はこんな感じ

<style>
.fukidashi_outline{
    padding-bottom: 10px;
    position: relative;
}
.fukidashi_msg{
    position: relative;
    background-color: #ccc;
    height: 50px;
    width: 100px;
    color: #3a3a3a;
    padding: 5px;
    border-radius: 10px;
}
.fukidashi_msg:after{
    content: '';
    position: absolute;
    border-top: 10px solid #ccc;
    border-right: 5px solid transparent;
    border-left: 5px solid transparent;
    bottom: -9px;
    left: 6px;
}

</style>

<div class="fukidashi_outline">
    <div class="fukidashi_msg">
        たとえばこんな感じ
    </div>
</div>
メッセージ本体部と, 周りとの距離を測る部分, そこに吹き出しの三角形部分を作る cssを足して吹き出しに見せる. それだけ.シンプルです.

キモは15~23行目. ここで疑似クラスの :afterを用いて三角形を作り, 角を丸めた長方形の下にきれいにつくように配置する.


要するに三角形の位置と向きななわけだ
('A`)




Σ('A`)

三角形を横にするのもシンプル. 斜線を leftと rightで作っていたのを topと bottomに, 上底?を書いていた borderを border-leftにしてやり, 後は位置調整.
<style>
.fukidashi_outline2{
    padding-right: 12px;
    position: relative;
    display: table-cell;
}
.fukidashi_msg2{
    position: relative;
    background-color: #ccc;
    height: 50px;
    width: 100px;
    color: #3a3a3a;
    padding: 5px;
    border-radius: 10px;
}
.fukidashi_msg2:after{
    content: '';
    position: absolute;
    border-left: 10px solid #ccc;
    border-bottom: 5px solid transparent;
    border-top: 5px solid transparent;
    top: 10px;
    left: 110px;
}

.fukidashi_set2{
    display: table;
}

.fukidashi_chara2{
    display: table-cell;
    bottom: 10px;
}
</style>

<br />
<div class="fukidashi_set2">
    <div class="fukidashi_outline2">
        <div class="fukidashi_msg2">
            要するに三角形の位置と向きななわけだ
        </div>
    </div>
    <div class="fukidashi_chara2">
        ('A`)
    </div>
</div>

応用するとこんなことも…
('A`)


参考: CSSだけで簡単に吹き出しを作成する方法4つ!

2013年6月10日月曜日

first-childとかnth-last-child(x)とか

残業万歳!
眠い!∠( ゚Д゚)/気が付いたら6月だ!

cssで詰まったからメモメモφ(・ω・ )

疑似クラス:first-child系を用いた「絞り込み」と勘違い


何番目の要素, ってやつ

<div id ="parent">
<div class="child_node">1番目</div>
<h5>タイトル1</h5>
<div class="child_node">2番目</div>
<div class="child_node">3番目</div>
<h5>タイトル2</h5>
<div class="child_node">4番目</div>
<div class="child_node">5番目</div>
</div>

たとえばこんな構造だったとき. #parentの最初の要素を指定したい!なんて時に使えるのが疑似クラスの :first-child. 読んで字のごとく「最初の子」を指す. また, 逆に「最後の子」を指す :last-childなんてのも.
<style>
#parent{
    background-color: blue;
}

#parent div:first-child{
    background-color: red;
}

#parent div:last-child{
    background-color: red;
}
</style>
試しにこんなスタイルを当ててみる.
1番目
タイトル1
2番目
3番目
タイトル2
4番目
5番目
とまぁ色が変わっているのだが, 問題はここから. 「前から x番目の子」を指す :nth-child(x), 「後ろから x 番目の子」を指す :nth-last-child(x)など, 順番を指定し始めると始まる勘違い. たとえば, 「一番最後の h5を指定したい」, 「上から3番目の child_nodeを指定したい」と思った時に,
<style>
#parent .child_node:nth-child(3){
    background-color: green;
#parent h5:nth-last-child(1){
    background-color: green;
</style>
と正直に指定すると…
1番目
タイトル1
2番目
3番目
タイトル2
4番目
5番目
Σ('A`)
"2番目"に色がつくわh5に色はつかないわ散々なわけで. 原因は出力を見ればだいたいの想像はつくかと.
要するに
#parent .child_node:nth-child(3)
とは,
「id=parentの子の, class=child_nodeの中での3番目のもの」ではなく,
「id=parentの子の中で3番目の子で, かつclass=child_nodeなら」という,
ある意味では確かに「絞り込み」を行っているみたい('A`)ソリャネェヨ

なので結局, 「x番目の子」という, 構造が変わると効果がなくなる不安定な絞り込みには変わりないものだったりするorz.




日本語と英語の解釈の違いみたい(・д・`)

2013年5月9日木曜日

Unityのエディタ拡張 -基礎

なんかUnityではエディタが拡張できることも売りの一つらしい.
そんなこと言われたら手を出すしかないじゃない+(・ω・0)*

Unityのエディタ拡張 -基礎

まずは拡張ウィンドウ作成から

1. 準備

ほとんどいらない. Assetsの下に「Editor」ディレクトリを作るくらい. ちなみに他のところでも, 「Editor」ディレクトリにあれば動くらしい. まぁわかりやすくまとめておくのが吉. 

2. コーディング

他の普通のコードと同じようにC#で書ける. 
using UnityEngine;
using UnityEditor;
using System.Collections;

public class ExpansionPrac : EditorWindow {

 [MenuItem("Window/My Window %i")]
 static void Init(){
  ExpansionPrac window = 
   (ExpansionPrac)EditorWindow.GetWindow(typeof(ExpansionPrac));
 }
}
こんな感じ. なにも表示されないウィンドウを出すだけ.
とりあえず EditorWindowクラスを継承. その際には UnityEditorクラスのインポートを忘れずに.

問題は 7行目. 他ではあまり見ない [ ] を使った宣言. MenuItem()により, メニューに追加する.
引数はその際の配置. この場合はメニューの Window → My Windowをクリックで表示されるようになる. 最後の %i はなんとショートカットキー. この場合は 「ctrl + i」. 他と被ってないか注意.


こうなります.

クリック後, Init()の中でウィンドウを用意する.  EditorWindow.GetWindow()でウィンドウを呼び出してる(らしい). 型はこのクラスの型. このクラス名がウィンドウのタブに出てくるので注意.

3. 実際に呼び出せるようにする

しかしゲームに関係ないのにいつコンパイルするんだろう…とか思ってたら
シーンを再生/停止したとき
スクリプトを編集したとき
にやってくれているらしい. 道理でスクリプト編集から戻ってくるなり「エラーあるぞゴルァ!щ(゚Д゚#щ)」とか怒ってくれるわけだ…
なのであと必要な手順は「Editor」ディレクトリの下に配置しているかということ. ちなみに自分は
Assets/Scripts/Editor/ExpansionPrac.cs
と配置して起動を確認. ただ他でEditorを作成→Scriptsディレクトリ以下に移動 した直後はコンパイルが通っていないのか起動しません(・ω・`) 一度 再生→停止 するなどしてコンパイルしてもらうといいかも.

4. 中身を作ってみる

呼び出してはみたものの…
さみしい(・ω・`)
なので中身を適当に入れてみる.
bool isEditable;
bool childToggleBool = true;
float childSliderFloat = 2.22f;
 
void OnGUI(){
 GUILayout.Label("DispTest", EditorStyles.boldLabel);
 int sw = Screen.width;
 int sh = Screen.height;
 isEditable = EditorGUILayout.BeginToggleGroup("ToggleGroupTest", isEditable);
 childToggleBool = EditorGUILayout.Toggle("childToggle", childToggleBool);
 childSliderFloat = EditorGUILayout.Slider("childSlider", childSliderFloat, -10, 10);
 EditorGUILayout.EndToggleGroup();
}
まさかの OnGUI();
シーン中で使ったようにGUILayout()が使用可能. EditorStylesなんていうフォントなどの仕様のクラスも.
また 7, 8行目のように, カスタムウィンドウの幅/高さを取得することも可能.

9行目からがちょっと独特. EditorGUILayoutなるクラスを使える. 通常よく見る Inspectorなんかで使われている表示はここから取り出せるっぽい. Unityリファレンスマニュアルにある通り, とりあえず Toggleグループを追加してみる. グループの中身になるものを 10, 11行目に宣言し, 12行目の EndToggleGroup()でグループの宣言を閉じる. 閉じなくても今回は問題なく動くのだが, 当然閉じないといつまでもグループの中身を足し続けることに…

10行目は子にもトグルボタンをつけてみる. 特に何もなし.
11行目はスライダ. 3,4つ目の引数がスライダの下限/上限. ちなみに, ここの引数を 7行目で取得した swを使って, -sw/swと入れて, ウィンドウサイズを変えてみるとちょっと面白いことにヘ(゚∀゚ヘ)

ちなみにフィールドにあるのがトグルやスライダの初期値になります.
これを 2. で作ったコードに追加してコンパイルしてもらうと…
出てきた!+(゚∀゚0)*



ちなみにコード全景.
using UnityEngine;
using UnityEditor;
using System.Collections;

public class ExpansionPrac : EditorWindow {

 [MenuItem("Window/My Window %i")]
 static void Init(){
  ExpansionPrac window = 
   (ExpansionPrac)EditorWindow.GetWindow(typeof(ExpansionPrac));
 }
 
 bool isEditable;
 bool childToggleBool = true;
 float childSliderFloat = 2.22f;
 
 void OnGUI(){
  GUILayout.Label("DispTest", EditorStyles.boldLabel);
  int sw = Screen.width;
  int sh = Screen.height;
  isEditable = EditorGUILayout.BeginToggleGroup("ToggleGroupTest", isEditable);
  childToggleBool = EditorGUILayout.Toggle("childToggle", childToggleBool);
  childSliderFloat = EditorGUILayout.Slider("childSlider", childSliderFloat, -10, 10);
  EditorGUILayout.EndToggleGroup();
 }
 
}




今回はここまで.
次はGUI操作でちゃんと編集できるようにしたいなー+(・ω・0)*



参考 : Unityリファレンスマニュアル
         MK Games
         EditorGUILayout

2013年4月30日火曜日

Enumノススメ

ふとしたチャンスで借りて読んだ EffectiveJava. ずっとEnumの使い方を勘違いしていたので矯正を兼ねて
メモメモφ(・ω・ )

Enumノススメ

なんという今更感.
だが, それがいい.

1. Enumって?

日本語に直すと 列挙型. 要するに関連する定数をまとめたもの. もともとは基本的に int値らしい. あらかじめ要素数がわかっている際に効果を発揮し, 別の要素が混ざらなくなる.

たとえば実際 EffectiveJavaにある例から. 
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;

public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;
リンゴ, オレンジの種類を定数にしておきたいとする. なにが困るかというと, たとえば品種改良を表すメソッド
public void breed(int variety1, int variety2){}
なんてのがあったとする. このメソッドは引数の2つの品種を掛け合わせる, なんてメソッドだとした時, ちょっとした問題が発生する.
それは, リンゴ×オレンジなんていう異種交配が始まってしまうパターン.
引数は「intかどうか」しかチェックしないため, 間違って (リンゴ,オレンジ) と別の種類の引数を入れてもコンパイルどころか実行まで通ってしまう. おおこわいこわい.
また, 上記例なら,
APPLE_FUJI == ORANGE_NAVEL
が trueを返すミラクル. これを回避するために, いちいち数値が被っていないかチェックが必要だったりとなかなか骨が折れる.
そこでEnum.

2. Enumの作り方

作り方はいたって簡単. 上記例ならリンゴ, オレンジはそれぞれ別物としてほしいので,
  public enum Apple {
    FUJI, PIPPIN, GRANNY_SMITH;
  }

  public enum Orange {
    NAVEL, TEMPLE, BLOOD;
  }
classや interfaceの代わりに enumを使う, 後は名前を列挙してやる. 「,(カンマ)」区切りで並べ, 必ず最後は「;(セミコロン)」でしめる.
こうすると, たとえばFUJIを呼び出したいなら,
Apple.FUJI
で呼び出せる. こうするとbreedメソッドも
public void appleBreed(Apple variety1, Apple variety2){}
とすれば, このメソッドはリンゴ同士でしかコンパイルが通らなくなる. 比較も,
Apple.FUJI == Orange.NAVEL;
Apple.FUJI == Apple.PIPPIN;
上はそもそも比較するものの型が違うとコンパイルエラーを吐いてくれるし, 下はもちろん falseが返る.
後からの追加も名前を足すだけで, 値の被りは名前の被りだけ気にすればいい.

3. 応用

こんな Enumの作り方もできちゃう.
public enum Skill {
  KAMEHAMEHA("かめはめ波", 1000);

  public String name;
  public int power;

  Skill(String name, int power) {
    this.name = name;
    this.power = power;
  }

  public String toString() {
    return name;
  }

}
唐突すぎる例( ゚д゚ )
たとえばかめはめ波という技の持つデータがすべて定数だった場合. これを Enumを使わずに管理するのはおそらく骨.
String KAMEHAMEHA_NAME ="かめはめ波";
int KAMEHAMEHA_POWER = 1000;
うん. 絶対事故る('A`).

そこで 「Enumにデータと振る舞いを持たせる」 ことをやってみる. KAMEHAMEHAは Skill型なので, 7行目からのコンストラクタが使える. 名前 KAMEHAMEHAが()で引数を持つのは, このコンストラクタを使うため. かめはめ波の powerを取り出したいなら,
int power = Skill.KAMEHAMEHA.power;
で取り出せる. 読みやすいし変にいろいろ参照しなくても OKなのは事故が起きにくいはず.
ちなみに12行目からのtoString()はEffectiveJava第 3章 10項「toStringを常にオーバーライドする」参照. 要するに,
System.out.println(Skill.KAMEHAMEHA);
としたときに, 「かめはめ波」と返ってきてくれた方が, 使う人にも優しい, ということ. 技を増やすときは同じように,
KAMEHAMEHA("かめはめ波", 1000),
TAIYOUKEN("太陽拳", 500);
とでも増やしてやればいい.



他にもメソッド持たせたりさらに応用もあるけどまだここまで.



かめはめ波とか出てきたのはだいたいここのせい.
たまに振り返ると固まっていなかった部分が矯正できて気分がいい+(・ω・0)*








まぁこの固めたのもいつまでもつやら…('A`)

2013年4月26日金曜日

UnityプロジェクトをGitHubで管理 -タスク管理編

なにやらGitHubにはタスク管理チックなことができるらしい, みたいな噂だったので調査.

UnityプロジェクトをGitHubで管理

第2幕

1. Issueの作成

プロジェクトのページに入ったら, 
コイツをクリック. 数字がissueの数を表しているらしい.
クリックすると, そこはIssueの一覧画面. New Issueをクリックして新規作成.

こんな画面になるので, タスク名, 担当者やコメント, フィルター…はヨクワカラナイ('A`)を設定して submit.
これでサクッとできました.

2. Issueの操作

一覧に戻るとグリーンなIssueの一覧. グリーンは Open(まだ残っている)タスクの一覧. Closeのボタンを押すと, こちらは Closed(解決済み)タスク一覧に. まだ解決していないのでリストは空のはず. 
では先ほどのIssueを Closeしてみる. 
CloseしたいIssueをクリックすると, 
こんな画面になるはず, 途中経過のコメントとか書けるのかな… 担当なども変えられる. Closeするなら下の Close. それだけで Closeし, 右上の緑の Openが, 赤い Closeに変わるはず. リストに戻れば, Closedのリストに移動しているのがわかるかと. ClosedのIssueを再 Openすることもも可能. 





とりあえずこんなところ. 
意外と簡単かも+(・ω・0)*



って言ってると爆死するフラグ…('A`)


2013年4月24日水曜日

UnityプロジェクトをGitHubで管理 -Git準備編追記

すっかり忘れてたorz
リポジトリに 「共同開発者」 としてチームメイトを登録しないと書き込みしてもらえない(・ω・`)

UnityプロジェクトをGitHubで管理

前回の追記なのでちょびっと

共同開発者の追加

追加するためにはまずチームメイトが GitHubアカウントを持っていることは必須. 当然か(・ω・`)
追加したいプロジェクトの詳細ページに行き, ヘッダにある Settingsをクリック. 

左側にあるこのリストの Collaboratorsをクリック. 
すると入力フォームと Addボタンが出てくるので, チームメイトのアカウントネームを入力して Addする. 
入力フォームにネームを入力しようとすると, 候補がリストで現れるので, 確認してから Addできる. 間違って関係ない人招かないように…
Addはほぼ一瞬で完了する. Addしたことは相手に GitHubからメールでお知らせしてくれる. 届いてなかったら多分別の人追加してる…カモΣ(||゚Д゚)ヒィィィィ
逆に除名したいときは対象のネームの横の (remove). こちらも一瞬. そしてこちらも GitHubからメールが行く. 追加を誤爆すると 追加時のメール+削除時のメール で2通誤爆メールが届きます. 追加の際は相手のアカウントネームをしっかり確認しましょう(・ω・`)





Collaborators がどこにあるか探してしまったのでメモメモφ(・ω・ )

2013年4月18日木曜日

UnityプロジェクトをGitHubで管理 -Git準備編

仲間内で「Unityで共同開発やろうぜ!(意訳)」な話があがり, 何を作るのか盛り上がったところで問題が一つ.
「リソースの共有どうすんの?」
……(;´Д`)('A`)(・д・`)……

「ま、まぁGitとかあるs」「UnityとGit仲悪かった気が…」
……(;´ω`)('A`)(・ω・`)……

若干先行き不安だけどやってみる

UnityプロジェクトをGitHubで管理

※ 前提条件として「コマンドラインでロクにPCとお話しできない人」の行動ログであることをご理解いただいたうえでお読みください.

1. リポジトリ準備

GitHubにて新しいリポジトリを作成する. アカウントはなければ作りましょう. プライベートなリポジトリを作るのでなければ無料. 逆に作りたいなら月々課金が必要. 世の中金か('A`)
ここ. これをクリックするとリポジトリの名前や設定を決める画面に移行する. 


正直 Repository nameと Publicだけ設定しておけばいいと思う. というかわからないorz 先述の通り Privateなリポジトリを立てるには課金が必要. お支払方法の入力フォームがにょきっと出てくるのでおとなしくPublicで.
Repository nameでエラー(既にある名前を使用しようとしている etc...)にひっかからなければ, 下の緑のボタンがクリックできるようになるので, クリックで決定.


できたできた. ちなみにできたリポジトリに行くとご丁寧にreadmeがおいてある. よんでおくといいかも. ちなみにこの画像の右上の「New repository」 でも新規リポジトリの作成ができます.

2. ローカルの準備

正直こっちがめんどくさかった…というか成功してない…1. でできてたreadmeのコマンドを, ここを参考に打ってみたりしてみたけど…なんか繋がらない…('A`)
そこでふと出てきたのが Github for Windows. うん. にも使って挫折したんだ. しかし衝突しなけりゃ使えたなーと思いひっぱり出し使ってみる. ちなみにここからダウンロードできます. またツールを使うには当然ですが Gitのアカウントが必要. 先に1. を済ませておくとスムーズ.

一番左, 自分のアカウントネームをクリックすると, GitHub上にあるアクセス可能なリポジトリ一覧が登場.  画像は既に cloneしてしまっているのでパソコンアイコンが出ているが, cloneしていないリポジトリには青く cloneのアイコン

こんなのが出てくる. クリックすると設定で指定したディレクトリにリポジトリを cloneしてくれる. 楽だ…
設定は上にある tools → optionから. またアカウントネームからGitHubに飛ぶことも可能. default storage directoryに指定した場所に展開されるので, デフォルトの場所が嫌ならここを変更しよう. 

これでリポジトリをローカルに用意できたはず. ちなみに toolsの隣あたりにある addで, ローカルにディレクトリを用意しつつ GitHubに pushしてくれるみたい. ずるい(・ω・`)

これでバージョン管理が開始できる!+(・ω・0)*

3. 共有

自分で作って自分で拾えるのはいいのさ. 問題は共有. 誰かの作ったリポジトリをいただきたい. 
こんどはふらっと見つけた TortoiseGitなるものを使ってみる. 

準備

ちょっとアレだがここも参考に. 
まずはインストーラをここからダウンロード. bit数は注意. 一緒に下の方にある Japaneseを拾っておくと日本語化できます. 英語苦手('A`)
インストールは基本そのまま Next連打. 途中 Pathの設定の際に,
Run Git from the Windows Command Prompt
を選んでおくと, パスも一緒に通してくれる. 一緒に cmdから gitコマンドが使えるようになった?
インストールが完了したら, 今度は日本語化のインストーラも起動. 特に設定もなくインストールが完了するはず.
最後に適当なディレクトリで右クリックすると,

こんなのがふえているはず(既に日本語化終わってるけど最初は英語のまま)なので, 設定から, General → Language を日本語にして決定すると日本語化完了.
詳しくはここ

Clone

上の画像にもあるけど, まんま Gitをクローン.
ダイアログが出るので, 上の URLに貰いたいリポジトリのURLを入力 → 実行 でOK.
非常に楽.






…たったこれだけだったんだけどなぁ…('A`)
まだUnity関係ないし.

超参考 → こちら
04/24追記・共同開発者の追加 → こちら

2013年4月11日木曜日

Conditionのカスタム

ちょっと前にまとめた Wait.until()と、その引数の condition. あの時まとめた既存の物じゃ, 正直今やってるテストがカバーしきれないと思いカスタムしてみたのでメモメモφ(・ω・ )

Conditionのカスタム


といっても正直コピペなんだけどね…

1. 状況

対処したい状況は, 「画像リソースでチェックボックスを表現してる. しかもAjaxで表示を書き換える仕様」といった状況. 
当然 elementToBeSelected系列は使えないし, stalenessOfもページがリロードされるわけでもないから使えない.

なので, 「チェックされているボックスの画像が, x枚になるまで」待機, みたいな形にしてみた.

2. メソッド

ベースにしたのは titleIs. 一番シンプルだし, 戻り値 Booleanだし.
  public static ExpectedCondition<Boolean> countBy(final By by, final int expectedSize) {
    return new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver driver) {
        return driver.findElements(by).size() == expectedSize;
      }
    };
  }
本当にちょびっとの改造. 引数は Byロケーターと期待する数.
なんてことはなく, titleIsで「タイトルが引数と一致する」という条件を書いてた部分を, 「Byで指定したWebElementの size()が, 引数の expectedSizeに一致する」に書き換えただけ. この程度なら意外と簡単.
ちなみにちゃんとロケーターを引数にして, 中で driver.findElements()で取得しなおしてやりましょう.
WebElementや List<WebElement>を直で渡そうとすると, 取得のし直しがない = ページの方は変更があっても size()変わらない = ちゃんと動かない なんていうただのストッパーが出来上がります.




とまぁこんな風に近いメソッドをひっぱり出してきてちょこっと改造してやるだけでも, 一層テストしやすくなるかも. +(・ω・0)*

2013年4月8日月曜日

Unityゲームを終了する

UnityでAndroidにビルドしていると思うこと
「ホームボタンでしか戻れないうえにバックグラウンドで生きてんの…?」

当然バッテリーはマッハなため非常によろしくない. が, デフォルトではそんな処理はしてくれない.
なのでスクリプトでつける必要があったのでメモメモφ(・ω・ )


Unityゲームを終了する


1. メソッド

Application.Quit();
これだけ.
このメソッドを呼ぶことでアプリケーションは閉じてくれる.

2. 実際に使ってみる

空の GameObjectを作り, GameManagerとでもしておく. 
void Update(){
    if (Application.platform == RuntimePlatform.Android && Input.GetKey(KeyCode.Escape)){
        Application.Quit();
    }
}
こんな内容のスクリプトを作り, GameManagerに持たせてやると, ゲーム中「戻る」キーを押すことでゲームが終了できる.
プラットフォームが Androidであることを確認してるけど, 「戻る」キーとか iPhoneには無いよなぁ….
毎フレーム呼び出すのが気持ち悪いなら何かしらボタンを作って, そこから反応してやると誤爆も少なくなっていいかも.

3(おまけ). ダイアログっぽい何か作ってみた

いいと思ったのでやってみようとした. ただ…ダイアログってどう作るんだ…?3Dには強いが2Dにはいまいち余計な手間がかかってしまうイメージ.

   3-1. 構想

      ヨクワカラナイのでとりあえず構想.
      ダイアログを開くボタンを押す → ダイアログからYesを選ぶ → ゲームが終わる!
      こうしたいなー(・з・)的な簡単な構想. 
      何やらいろいろやり方はアルっぽいけどよくわかんない('A`)
      AssetStoreにありそうだなー…
      ダイアログっぽいものを書く OnGUIを持ったスクリプトを動的に追加することで「ダイアログを開」き, このスクリプトを削除して「ダイアログを閉じ」たい. 
   

   3-2. ダイアログを開くボタン

      とりあえずボタン. これはシンプル.
using UnityEngine;
using System.Collections;

public class ButtonTest : MonoBehaviour {

 public bool isOpened = false;
 
 void OnGUI(){
  float sw = Screen.width;
  float sh = Screen.height;
  
  if (GUI.Button(new Rect(0,0,sw * 3/12,sh/12), "menu") && !isOpened) {
   Debug.Log("push!");
   isOpened = true;
  }
  
 }
}
sw, shはそれぞれ現在のスクリーンの幅/高さを取得. 割合でボタンの座標を決定してやると端末変わった時とかに順応しやすいかと.

ボタンを表示させているのが 7行目, GUI.Button(). なお GUIクラスは OnGUI()メソッド以外から呼ぼうとすると怒られる…(・ω・`)
このメソッドはボタンを作りつつ, 押されたときに trueを返すできる子. 一粒で二度おいしい.
最初の引数で表示位置を, 次の引数でボタンに表示するラベルを宣言. なお Rectについてはこんなのもございます(宣伝)

isOpenedはなんてことはない bool. これで制限をかけて, ボタン連打でダイアログ地獄, なんてのを避ける(予定).
これを空の GameObjectでも作って載せてやり, 実行するとボタンが左上に出るはず.

こんな感じ. なおこの状態で押しても, isOpenedをなんとかする方法がないので, ログは一個しか出てこないハズ.


      3-3. 「ダイアログ」を用意する

ここが一番困った. AndroidのDialogクラスみたいなのは見当たらないし, 仕方ないので別のクラスを自作し, そこでOnGUI()でもしてそれっぽく見せてみる.
using UnityEngine;
using System.Collections;

public class TestDialog : MonoBehaviour {
 
 public ButtonTest test;
 
 void Start(){
  test = this.gameObject.GetComponent<buttontest>() as ButtonTest;
 }
 
 void OnGUI () {
  float sw = Screen.width;
  float sh = Screen.height;
  GUI.Box(new Rect(sw / 3, sh / 3, sw / 3, sh / 3),"TestDialog");
  
  if (GUI.Button(new Rect(sw * 2 / 5, sh * 2/ 5, sw / 5, sh / 10), "yes")) {
                        Debug.Log("quite");
                        test.isOpened = false;
                        Destroy (this);
                        Application.Quit();
  }
  if (GUI.Button(new Rect(sw * 2 / 5, sh * 11 / 20, sw / 5, sh / 10), "no")){
                        Debug.Log("cancel");                        
                        test.isOpened = false;
                        Destroy (this);
  }
 }
}
こんなクラス. このスクリプトを 3-2. で作ったスクリプトを載せた空のオブジェクトに動的にくっつけることで表示させよう, という魂胆. menuボタンのイベントで動的にくっつければ, あたかもボタンでダイアログを開いたように見えるという寸法.

Start()はとりあえず 3-2のスクリプトの取得. isOpenedを書き換えて, 「開きっぱなしの状態」をキャンセルする.
15行目, GUI.Boxで, ただの四角い領域を描画. ついでに"TestDialog"とタイトルっぽく入れてみる.
中にはボタン2つ. yesと noボタン. この yesボタンの if()の中で Application.Quit()でも呼んでやれば目的は達成できるはず. でも実機じゃないと確認できない(・ω・`)
そしてDestroy(this)で このスクリプト を破棄することで, ダイアログ(?)を破棄する. アプリ終了する前に Destroy()しておくべきなのだろうか…

後は3-2の方, ボタンのイベントの中を
if (GUI.Button(new Rect(0,0,sw * 3/12,sh/12), "menu") && !isOpened) {
   Debug.Log("push!");
   this.gameObject.AddComponent<TestDialog>();
   isOpened = true;
  }
と, AddComponent()してやることで, ここで作ったスクリプトを動的に足す.
これで, menuボタンを押すと,
みょん. それっぽいものが出てきてくれました.
Inspectorの方を確認して, 動的にスクリプトが追加されているのも確認しておくといいかも.
ちなみに3-2の方, ボタンの if()文を,
if (!isOpened && GUI.Button(new Rect(0,0,sw * 3/12,sh/12), "menu")) {
   Debug.Log("push!");
   this.gameObject.AddComponent<TestDialog>();
   isOpened = true;
  }
としてみると, ダイアログっぽいものを開く際変化する isOpenedのほうの条件に引っかかるのか, そのあとの条件となっている menuボタン描画メソッドが呼ばれなくなり,

menuボタンが消える. これはこれで使いようがありそうだったのでメモメモφ(・ω・ ).





おまけのが充実してる気がするけど仕様です. ( ´∀`)ノシ キニシナイ

2013年4月3日水曜日

他のGameObjectの持つスクリプトのフィールドを参照する

たとえばライフポイント.
ディスプレイするために表示用クラスで見たいけど, 体力管理としてプレイヤーでも参照したい, でも2か所に持つとかキモすぎる!щ(゚Д゚#щ) 絶対バグる!<(゚Д゚#<)
なんて状態.
なお今回からC#で書いてみます. ほとんど変わらないから問題ないかと.


他のスクリプトのフィールドを参照する


1. 状況

たとえば Playerのタグを持った PlayerObjectがいたとする. 
こいつはこんな LifeManagerという名のスクリプトを持っている. 
public int life = 10;
void Update(){
…
たとえば残りライフを描画する GUIのクラス, LifeMonitorがあったとする.
LifeMonitorは残りライフを表示するために PlayerObjectの残りライフが知りたい.
でもまさかダメージが入るたびに SendMessageメソッドで報告を受けるのもなんかヤダ('A`).
まさか LifeMonitorの方でも同じようにライフを減らすなんてありえない.

たとえばこんなシチュエーション.

2. 対策

LifeMonitorのほうのスクリプトに
GameObject player = GameObject.FindWithTag("Player").gameObject;
LifeManager script = player.getComponent(typeof(LifeManager)) as LifeManager;
int currentLife = script.life;
これで参照できる.
1行目は単純に PlayerのGameObjectを取得しているだけ. やり方は他にもいろいろ.

問題はその下.
1行目で取得した Playerから, コンポーネント名を指定して取得する.
ここが最初の問題.

必要なパーツは2つ. 「型宣言」と「キャスト」. 上記2行目なら,  typeof(クラス名)が型の宣言. as LifeManager がキャスト. 他のやり方もあり,
LifeManager script = (LifeManager)player.getComponent<LifeManager>();
とするパターンも. <LifeManager> で型宣言し, (LifeManager)でキャストするやり方の組み合わせ.
2つのパーツがそろっていればやり方は自由なのだが, 実はUnityScriptなら,
var script: LifeManager = player.getComponent(LifeManager);
とか書けちゃったりする.

あとは3行目のように, 取得したコンポーネントからフィールドの lifeをいただけば一丁上がり.
他のフィールドも同様に参照してやればおk. 意外とイメージはしやすいはず.
まぁディスプレイする側から体力操作し始めるようなことはないだろうけど.

3. 応用?

実は同様に, メソッドの呼び出しも可能. LifeManagerに以下のメソッドを追加してみる.
public void addLife(int inc){
    life += inc;
}
今更だけどたとえが悪かったなぁ…('A`) lifeに引数に指定した incだけ足すだけの簡単なメソッド.
LifeMonitorの方では,
script.addLife(1);
とでもしてやればOK. この後 lifeを読むと, ちゃんと 1加算されている.
戻り値も取り出せるし, 当然複数の引数も渡せる.
また直接,
script.life = 11;
とかぶち込むことも. やりたい放題である.

これらの注意点は,  必ず publicであること. パッケージ分けとかがあるわけではないので, アクセス修飾子に注意. 特に C#のデフォルトは privateな点など, 言語的なところにも注意. protectedも当然NG.

フィールドを参照したい, (基本ないだろうけど)フィールドの値を書き換えたい, 何度も同じスクリプトのメソッドを呼び出したい,戻り値が欲しい, 引数は複数持たせたい!なんて時はこの手法がよろしいのかな?

逆にゲームオーバーのように1回だけ呼べばいいものは, sendMessage()を使えばよろしいかと.





なんか変な文章(・ω・`)

2013年3月21日木曜日

Unity基本メソッド覚書

Unityでいろいろ作っている時に,
「あれってどう実装するんだっけ…」「これ動かすときどこの値をいじるんだっけ…」
なんてことが最近多かったのでメモメモφ(・ω・ )

Unityでスクリプトを書くとき覚えておきたいメソッド-移動と回転-


0. 基本

移動にしても回転にしても, 座標を用いてパラメータをいじるのは基本
var myTransform : Transform = this.gameObject.transform;
ここ.
Hierarchyウィンドウから適当なオブジェクトを選択して, Inspectorを眺めると必ずあるのがこの transform.
位置, 回転, スケールを管理するここはスクリプトからもよくアクセスされる.
スクリプト中で何度もアクセスするようなら, 上記のように変数として持ってしまうのも, 処理の高速化として有効らしい.
ちなみにC#で書くなら, 
Transform myTransform = this.gameObject.transform;
ほぼ変わらない.

1. 移動

ゲーム作成において必須項目. なので「プレイヤーを歩かせる」「足場を動かす」「弾を打ち出す」など, いろいろなところで使う. ちなみにC#でもUnityScriptでもほとんどコードは変わらず. おかげでC#のお勉強にならない…(・ω・`)

・ positionをいじる

myTransform.position = new Vector3( x, y, z);
Vector3型で指定した x, y, zの座標に「ワープ」する.
なので「歩く」モーションなどには向かない.
ヨ○テレ○ートみたいなワープ移動や, ロック○ンの"消える足場"みたいなものなら使えるかもしれないが, 基本移動を表現するには不向き.

・ Translate

myTransform.Translate(Vector3 vec);
Vector3型で指定したベクトル方向に「動かす」メソッド. プレイヤーを歩かせるならこれか.
コード中で使うなら,
var speed: float;
myTransform.Translate(Vector3 vec * speed * Time.deltaTime)
となるかと. Vector3で方向を, speedで移動速度を設定. Time.deltaTimeで環境ごとのフレームレートの差を補完させる. 処理がマシンによってばらばらになるのが嫌なら, つけておくと安心できるかと.
参考

・addForce

これだけちょっと毛色が違う. こちらは
this.gameObject.rigidbody.addForce(Vector3 vec);
Vector3型で宣言した方向に力を加えるメソッド. まずアクセスするのが Transformではなく Rigidbody. これは「Unityが面倒な物理演算を自分でやってくれる」ための重要なコンポーネント. ここにアクセスして, 「力を加えて」動かす.
要するに「物を殴って動かす」ようなもの. このメソッドを呼んだ一瞬は力がかかるけど, 以降は慣性で移動する.
おもに弾丸の発射やピンボールのバンパーなんかに用いると幸せになれるかも.
当然対象に rigidBodyがないとだめ. addしておきましょう.

2. 回転

同じく必須項目. たとえ横スクロールアクションであろうと左右の向きくらいは変えるはず. 「向きを変える」「ターゲットの方向を向く」「軸を合わせる」なんかでいろいろ使う.

・LookAt

var targetTransform: Transform;
myTransform.LookAt(targetTransform);
Transformから直接呼び出すメソッド. シンプルに
「targetTransformに指定したものの方を見る」
というもの.
一見便利なのだが, 問題は myTransformと targetTransformが接近したとき.
「近づく」まではぎりぎり行けるかいけないかはわかれるが, 接触してしまうとかなり猛烈な荒ぶり方をしてしまう.
またこの「見る」は, 全身の正面を targetTransformに向けるので, 両者のサイズ差が大きいと, 見上げる or 見下ろす ような体制になりやすいのが難点.

逆に接近することがないようなもの, 侵入者を照らすサーチライトの光源なんかはこれで十分かと.

・rotation- 1

myTransform.rotation = Quaternion.Euler( x, y, z);
transformのrotationに, オイラー角で指定して角度を入れる. この Quaternionクラスが角度の操作をする時に便利.特に,
myTransform.rotation = Quaternion.AngleAxis( float angle, Vector3( x, y, z));
と, AngleAxisメソッドを使うと便利. これは第一引数に角度を, 第二引数に回転軸を設定して回転させる, というもの. Update()メソッドの中で徐々に角度の部分を増やしてやれば, ゆっくり回転する物体の出来上がり. 変に角度いじるよりわかりやすいかと.
またこれは掛け合わせることで, 複数の軸へのそれぞれの回転量を表すこともできる.
たとえば, 「x軸を軸に45度, y軸を軸に120度回転させた状態」にしたいなら,
myTransform.rotation = Quaternion.AngleAxis( 45, Vector3( 1, 0, 0))
                       * Quaternion.AngleAxis( 120, Vector3( 0, 1, 0));
と, それぞれの条件を書いた式をかけてやるだけでいい. これはわかりやすい.
ただし順序があり, 最後にかけた回転から順に行われるらしく, この場合は
「 y軸を軸に120度回転させてから, x軸を軸に45度回転させる」という順序で回転が行われる. 結果が同じならいいけれども….
たとえば

こんな棒があった時,

上記の y軸 → x軸回転時
その逆 x軸 → y軸回転時
とここまで変わるので注意が必要.

主に回転し続ける足場やカメラなど, 常に角度が変化するものに強い?

・rotation - 2

myTransform.rotation = Quaternion.LookRotation(myTransform.position - targetTransform.position);

いじる場所は一個前と同じ myTransform, 使うクラスも Quaternionとこれまた同じ.
やることは二個前と同じ, 「自分を targetTransformの方に向かせる」 というもの.
では何が違うのかというと, 引数に Vector3クラスが使える という点だろう.
LookAtの際問題になるのが, 両者が接近したとき, と紹介したが, これを回避できるのがコイツ.
やり方は
var vec: Vector3 = myTransform.position - targettransform.position;
vec.y = 0;
myTransform.rotation = Quaternion.LookRotation(vec);
としてやる. 要は両者の y軸(高さ)の差を0としてやれば, 変に上下に傾くことがなくなる.
応用してやれば, myTransformの y = 0の場所から見た方向を向く, などもいじりやすいのが利点. 
2D視点など軸が一ついらないゲームなんかではこっちの方が変な動きをしなくて安心かと. 

・Rotate

myTransform.Rotate( x, y, z);
//or
myTransform.Rotate(Vector3 vec);
こちらは x, y, z の角度をそれぞれ指定して回すメソッド. 角度が完璧に決まっているならこちらのが早い. がやはり徐々に変化させるタイプには向かない.
スポーン時に最初の向きを決めてやったり, マ○オのような2Dスクロールで進行方向を変える時などはこっち?.

最近の○リオはちゃんと振り向きモーションあるけどね(・ω・`).


・おまけ

myTransform.rotation = Quaternion.identity;
回転なしの状態にする = すべての角度を 0 にする.
角度の初期化などに便利?





-移動と回転-とか書いたけどこれは他にもまとめる時がくるフラグなんだろうか…(・ω・`)

2013年3月15日金曜日

Wait.until()で指定できる状態の種類

Selenium2でテストを書いていく際, 何かとお世話になるのが Wait<WebDriver>.until(). 「引数に指定した状態になるまで」待機してくれるのだが, この状態の指定のメソッドが多すぎる上に, いちいち英語読むのがダルげふんげふん説明が単調なのでまとめてメモメモφ(・ω・ )
ちなみに 「何言ってんだコイツ?(・д・`)」と感じられたら, こちらの本家へジャンプ.
またこちらでメソッドの中身を見るのもいいかも.

Wait.until()の指定できる「状態」


1. 準備


・インポートと宣言

import org.openqa.selenium.support.ui.Wait;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;

WebDriver driver = new ChromeDriver();
Wait<webdriver> wait = new WebDriverWait(driver, 10);
まずは準備. newする際に, 待機を指示する WebDriverの指定と, 最大待機時間を宣言. 今回は 10秒を指定. もちろん 10を 20に置き換えれば最大 20秒待機となる. この待機時間を過ぎると,
org.openqa.selenium.TimeoutException
が発生し, テストはそこで failとなる.
逆にこの最大待機時間内に conditionが整えば, わざわざ最大待機時間まで待機せずに先に進んでくれる.
Thread.sleep(10000);
とかするよりよっぽどスマート.


・until

wait.until(ExpectedCondition condition);
wait.until()を呼び出す. この引数に以下に紹介する conditionを設定して渡してやればOK.
たとえば titlesで状態を設定したいなら,
wait.until(titles("期待するタイトル"));
としてやる.
使い方自体はシンプルなのだが, 問題はこの「期待する状態の設定」の方になる.


2. conditionの設定

・titles

public static ExpectedCondition<java.lang.Boolean> titleIs(java.lang.String title)
「ページのタイトルが titleに一致するまで」待機.
・titleContains

public static ExpectedCondition<java.lang.Boolean> titleContains(java.lang.String title)
「ページのタイトルに titleが含まれるまで」待機.
・presenceOfElementLocated

public static ExpectedCondition<WebElement> presenceOfElementLocated(By locator)
「引数に指定した locatorがDOMに現れるまで」待機. ただし待機終了時に, 必ずしもそれが画面に表示されているとは限らない.
・visibilityOfElementLocated

public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator)
↑に近く, 「引数に指定した locatorがDOMに現れるまで」待機.こちらは画面に表示されたうえで, それが0より大きい幅高さを持って存在している状態になるまで待機する.
・visibilityOf

public static ExpectedCondition<WebElement> visibilityOf(WebElement element)
visibilityOfElementLocatedに近いが, こちらは「引数に指定した elementがDOMに現れるまで」待機. ”画面に表示される”の定義も visibilityOfElementLocatedと同じ.
・presenceOfAllElementsLocatedBy

public static ExpectedCondition<java.util.List<WebElement>> presenceOfAllElementsLocatedBy(By locator)
「引数に指定した locatorが, ページ上に少なくとも一つ存在するまで」待機. 見えるかどうかは問わないらしい.
・textToBePresentInElement

public static ExpectedCondition<java.lang.Boolean> textToBePresentInElement(By locator, java.lang.String text)
「引数に指定した textが, 指定した locatorに textとして現れるまで」待機. 要するに指定した locatorでgetText()したら textがとれるようになるまで待機?
・textToBePresentInElementValue

public static ExpectedCondition<java.lang.Boolean> textToBePresentInElementValue(By locator, java.lang.String text)
↑に近いが, こちらは「引数に指定した textが, 指定した locatorの valueとして現れるまで」待機.
・frameToBeAvailableAndSwitchToIt

public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(java.lang.String frameLocator)
「指定した frameLocatorに WebDriverが移動するまで」待機?そもそもframeがよくわかってないし, ここを見た分には, このメソッドでそのまま移動しそうな switchTo()が呼ばれてるけどどういうことなんだろう…
・invisibilityOfElementLocated

public static ExpectedCondition<java.lang.Boolean> invisibilityOfElementLocated(By locator)
今度は「引数に指定した locatorが, 見えなくなるかDOM上からいなくなるまで」待機. "見えなくなる"の定義はないのかな…(・ω・`)
・invisibilityOfElementWithText

public static ExpectedCondition<java.lang.Boolean> invisibilityOfElementWithText(By locator, java.lang.String text)
「 textで指定した要素が, locatorで指定したエレメントから, 見えなくなるかDOM上からいなくなるまで」待機, …でいいのかな.
・elementToBeClickable

public static ExpectedCondition<WebElement> elementToBeClickable(By locator)
「 locatorで指定したエレメントが, 画面上に表示され, かつクリックできる状態になる」まで待機.
・stalenessOf

public static ExpectedCondition<java.lang.Boolean> stalenessOf(WebElement element)
「 elementがDOMに付属しなくなるまで」待機. ページのリロードなどでDOMが置き換わるなどするときに, "指定した elementがDOMからちゃんと消えるまで"待つ, ってこと? 参考
refreshed

public static <T> ExpectedCondition<T> refreshed(ExpectedCondition<T> condition)
このメソッド…無くなってる…?まぁ正直どういう動きか微妙に想像つかないけど(・ω・`)
・elementToBeSelected

public static ExpectedCondition<java.lang.Boolean> elementToBeSelected(WebElement element)
「指定した elementが選択された状態になるまで」待機. チェックボックスとかに使うんだろうけど, どこで判断してるんだろう…
・elementSelectionStateToBe

public static ExpectedCondition<java.lang.Boolean> elementSelectionStateToBe(WebElement element, boolean selected)
ほぼ↑と同じ気が…. 「指定した elementが selectedで指定した状態に選択 された/されていない 状態になるまで」待機. こっちで統一してもいい気がする…. 説明文とかコピペを疑うし…
・elementToBeSelected

public static ExpectedCondition<java.lang.Boolean> elementToBeSelected(By locator)
↑の locator版?「 locatorで指定したエレメントが選択された状態になるまで」待機, 当たりか. 説明すら放棄されましたorz
・elementSelectionStateToBe

public static ExpectedCondition<java.lang.Boolean> elementSelectionStateToBe(By locator, boolean selected)
「 locatorで指定したエレメントの選択状態が, selectedで指定した状態になるまで」待機, でいいのかな? もはや説明不要といわんばかりの勢い
・alertIsPresent

public static ExpectedCondition<Alert> alertIsPresent()
おそらく「アラートが出るまで」待機. 見たまんまでも説明がないと不安になりますよ…('A`)
not

public static ExpectedCondition<java.lang.Boolean> not(ExpectedCondition<?> condition)
シンプルに否定. 「引数に指定した conditionの notの状態になるまで」待機. …ってこのメソッドも無くなってるし( ゚д゚ )使えそうとか思ったのに…(;ω;`)


とりあえず以上. なんか無くなってるのか違うとこ見てるのかわからないのが2つほどあったけど…






枠とか試してみたけど…レイアウトって難しい(・ω・`)

2013年3月13日水曜日

プルダウンメニューをWebDriverに選んでもらう

いわゆる

こーいうの
これをWebDriverに選んでもらいたいけどちょっと詰まったのでメモメモφ(・ω・ )

プルダウンメニューをWebDriverで選択する

たとえば, 
<select name="preview">
    <option value="0">おはよう</option>
    <option value="1">こんにちわ</option>
    <option value="2">こんばんわ</option>
    <option value="3">おやすみ</option>
</select>
こんな <Select>があったとすると
ただの Select- optionのプルダウンメニューならサポートしてくれているらしい.
Select selector = new Selector(driver.findElement(By.name("preview")));
これで準備完了. 試しに 「こんにちわ」 を選びたいなら,
selector.selectByValue("1");
selector.selectByIndex(1);
selector.selectByVisibleText("こんにちわ");
など, optionの value, id, 表示テキストで選択できる親切設計.

…ってこここことかここを参考にしてみたけれど…(・д・`)できない

なんでだろうとみてみると
Element should have been "select" but was "input"
なんて警告.
なんか 「inputよこしてるぞゴルァ!щ(゚Д゚#щ) =3」的な話?

こことか眺めていると, どうやらカスタムしたような<select>には対応していないみたいな空気.
…べつにカスタムしてないと思うんだけどなぁ…(・ω・`)

とか思ってたら原因は
nameで locaterを指定していたら, <select>ではなく別の<input>を指定していた
模様. くだらなすぎる…orz
今一度 classや nameに被りがないかちゃんと確認を…(・ω・`)

ちなみにできないと思って探してみた違うやり方.
WebElement selector = driver.findElement(By.name("preview"));
selector.findElement(By.xpath("//option[@value='1']")).click();
いちおうこれでも選択はできた. できたけど…('A`)
まぁ 最後の手段 的なやり方ってことで…





というかプルダウンメニューがここに貼れたことにびっくり( ゚д゚ )

WebElementをもっと楽に探したい

テストを作っているとよく出てくる問題が
「同じようなタグの要素がいっぱいある…」「どう1個だけを指定したらいいんだ…」
なんて状態. リストが複数あるなかその中の要素を1個だけ選べとか言われても下手するとBy.xpath()使っても20や30も Listになって出てきたり, そもそもリスト以外の要素が引っかかったり…
そんな時だいぶ楽になる要素の探し方.

子要素の探索

要するにリストのように全く同じ要素が複数作成されるときは, 親要素に入れて管理している場合がほとんど(だと思う(・ω・`)). ならば親要素を特定してからその中を探索してやればすっごい楽になるよね!というお話. まぁ単純な話です. ちなみにコード中に出てくる Byについてはこちらにもメモがございます(宣伝
たとえば, 
<div class="parent1">
  <span class="child"></span>
  <span class="child"></span>
</div>
<div class="parent2">
  <span class="child"></span>
  <span class="child"></span>
  <span class="child"></span>
</div>
なんて要素の階層があったとする.
2つ目の divの中の2つ目の spanを探したい時, 直接探そうとするとかなりめんどくさい.
なので,
WebElement parent = driver.findElement(By.className("parent2"));
WebElement child = parent.findElemens(By.className("child")).get(1);
と, 先に親エレメントを特定してから, その下のエレメントを探してやることができる. コード的にだいぶ意味が通りやすくなるはず. なおもちろん driverは WebDriver.
これを「class="child"だけで見れば 4番目だから Listで取得して .get(3)だ!」なんて考えて
WebElement child = driver.findElement(By.className("child")).get(3);
こんなコードを書くとまず他の人には伝わらない. まして上の divに要素増えた時には…
Σ(||゚Д゚)ヒィィィィ

また, まとめて
WebElement child = driver.findElement(new ByChained(By.className("parent2"),By.className("child"))).get(1);
なんていう書き方も. これは
new ByChained(By locator, …)
を用いることで, 順に探している(らしい).


ただ問題はここまでのこと,  By.xpath()を使うとなんかうまくいかない…(・ω・`)なんでだろ







一番楽かつ安定なのは classなりわかりやすくつけて指定してやることなのよね…

2013年3月11日月曜日

見回りをする敵の作成

よくある雑魚敵.
見回りの兵士しかり, ただ歩く雑魚しかり, よくある敵の動きとして決められたポイントを動く敵の動きを組んでみた.
作った段階順にメモメモφ(・ω・ )

見回り兵の動きの作成

1. ターゲットの方を「向く」

今回考えたのが, ターゲットの方を向く → 前進! でシンプルにいけるんじゃね?ということ.
なのでまずは「ターゲット」としたものの方を向くことから
var speed : int;
function walkToTarget(t:Transform){
 var targetVec : Vector3 = t.position;
 targetVec.y = this.gameObject.transform.position.y;
 gameObject.transform.LookAt(targetVec);
 this.transform.Translate(0,0,1 * speed * Time.deltaTime);
}
6行目はまだ見ないで('A`). 引数の tは目標の transform. speedはお好みで. ここに出しておくと Unityの Inspectorですぐいじれるから便利.
3行目で目標の positionを取得. これをtransform.LookAt()に放り込むだけで, 引数に入れた positionの方を向いてくれるから便利. ただしこのままだと, 目標が自分より高い位置にいる場合, 最悪仰向けになるという間抜けさ.
なので 4行目, 見る positionの高さ yを自分の高さにしてやれば, 不自然に仰向けうつ伏せになることはなくなる.
これをUpdate()のなかで呼んで, とりあえず目標の方に「向く」ことができた.

2. 「前進」する. 

わりと大事だと思ってる. 適当な区間を歩かせようとしたとき, 「ここから x歩いたら y度修正して 半径 rの弧のうえを歩くように…」なんて考えたくない('A`) できる限り楽したいのです.
this.transform.Translate(0,0,1 * speed * Time.deltaTime);
さっき見えちゃったけど. transform.Transrate()の引数に Vector3で動く量を指定してやるだけ.
今回はただ前進したいので zだけ増やして残りは 0. speedは1. の通りお好み. Time.deltaTimeはフレームレートの違いを吸収して, 単位時間当たりの変化量を一定にしてくれるらしい. 端末の違いなどで変化が出ないようにするのに非常に役立つ.

ここまでで, あとは適当なところで目標を指定してやれば, そいつを追い続ける動きができる. がそれだと巡回ができない.
なので「巡回のポイントごとにマーカーを置き, そこに到達したら次の目標を指示する」ようにしてやる.

3. マーカーの作成

イメージはカラーコーンか. こいつを作る前に, 1. 2. を載せる敵に Enemyのタグをつける. これで「巡回中の敵がマーカーにたどり着いた」を識別する.
まずはマーカーの GameObjectの作成. これは何でもいいけど, 必ず敵が「到達」できるようにすること. はるか上空にあるマーカーを眺めて荒ぶる兵士とかかわいそうすぎる(;ω;`)
適当に cube当たりをチョイス. 名前を checkPoint1とでもしたら Inspectorを見る.
見えているマーカーを回るならともかく, 基本は何もないだろうし, Mesh Filterの Meshを Noneに. 
Colliderは Is Triggerをチェックしておく. 
こうすることで「トリガー」となり, 物理的な当たり判定が消え, 物が素通りするようになる. 
ただし「衝突した」ことはとれるので, センサーなど目に見えない範囲を作るときに重宝する. 
今回もその恩恵にあやかる. 
準備ができたらスクリプト.
var nextTarget : GameObject;

function OnTriggerEnter(object:Collider){
 if (object.gameObject.tag == "Enemy"){
  object.gameObject.SendMessage("changeTarget",nextTarget);
 }
}
OnTriggerEnter()は引数の「なにか」がトリガーに引っかかったぞ, というメソッド. 何がトリガーの範囲に入ってきても呼ばれる. なのでふるい分けをしてやる.
4行目は, 入ってきた「なにか」のタグを取得し, if文でふるい分ける. 今回は敵が巡回してきたら反応したいので, タグは Enemy.
Enemyが来たらそいつに対し, 5行目の処理. 内容はぶつかってきた objectに対して, 「changeTargetというメソッドを, nextTargetという引数を与えて呼び出せ」ということ. これまた便利.
あとは nextTargetに次に目指してほしいマーカーを入れてやるといい.

4. 目標切り替えの処理

これは単純
var target : GameObject;
function changeTarget(newTarget:GameObject){
 target = newTarget; 
}
これだけ. これを敵の方のスクリプトに持たせる. マーカーではない. このメソッドを持ってマーカーに突っ込むと, 次の目標の支持が飛んでくる寸法.
最後に Inspectorから, 「一番最初に向かう目標のマーカー」を敵の scriptの targetのところに指定してやればいい.

ちなみにこの指定の際,  targetをフィールドに宣言していると, Hierarchyに並んでいるマーカーを, Inspectorの scriptの中に表示されている targetにドラッグ&ドロップしてやるだけでいい.
どこを指定したかがわかりやすいかと.

5. マーカーをばらまく

マーカーをコピーしてばらまくだけ. もちろん「次の目標」はそれぞれに設定しないといけないけど.

これで「適当なポイントを巡回する兵士」みたいな動きができる.
ただこのままだと怪しいやつが目の前を通っても無視するおバカ兵士になってしまう.
のでその辺を足すとより敵っぽくなるかと.




ながなが書いたけどコードにするとめっさ短いのがUnityのいいところ. ∩( ・ω・)∩




2013年3月4日月曜日

RECTの勘違い

ずっと勘違いしたまま何とかやってこれてしまったので
ここらで矯正

Rect()の範囲指定

特にGUIいじるときなんかに登場する, 四角形の範囲を宣言するクラス(?). 
Rect(x,y,width,height)
中の4つの引数で範囲を宣言するのだが, 何と混ざったか4つの引数を

左上(x0,y0)と右下(x1,y1)ととった四角形の2点

Rect(x0,y0,x1,y1)

でとるものとか勘違い.
正解は

Rect(x0,y0,x1-x0,y1-y0)

左上の1点と幅高さで宣言するものとのこと.




どうしてこうなった…(・ω・`)



2013年2月28日木曜日

Cookieをaddして「続きからはじめる」

テスト作成中, ログインフォームをすっ飛ばして途中からテストを開始する準備がしたかったので

addCookieのちっちゃな落とし穴

ログイン情報を Cookieに持たせているので, 途中からはじめるなら
「addCookieとかあったよなー」
import org.openqa.selenium.Cookie;
  @Before
  public void setUp() throws Exception {
        driver.manage().addCookie(new Cookie(key, value));
なんてぼんやりaddしてたら
org.openqa.selenium.WebDriverException: Could not set the cookie (WARNING: The server did not provide any stacktrace information)
なんて怒られた.
どうやら「まだページ準備できてねーよどのページにCookie作る気だよ!щ(゚Д゚#щ)ゴルァ!」
とかいうことらしい.
なので
import org.openqa.selenium.Cookie;
  @Before
  public void setUp() throws Exception {
        driver.get(適当なページ);
        driver.manage().addCookie(new Cookie(key, value));
と, 何かログイン前に入れるトップページあたりを一度表示してやると addできる.
さすがに Googleトップとかに addしても意味無いけど.

これでaddCookieできますた.




Cookieよくわかんね('A`)

2013年2月27日水曜日

衝突を恐れない/考えない git merge

正直ちゃんとできているのかわからない('A`)

git (もちろんコンソールから)いじっている際, gitpushが ![reject]されたときの一連の流れの覚書
メモメモφ(・ω・ )

Git の 「! [rejection] 」への対処法


※あくまで自動マージで対処できる程度の衝突の際の流れです.
※本物の git初心者向けです. 

とりあえず commitしたものをあげましょう. 最初はmasterと緑なmasterですが…
git push
すると突如発生する ! [reject] から始まるエラー報告. どうやら他からも変更来てるよーってことらしい. ここで慌てると平気で1日つぶすようなパニックに見舞われます. 落ち着くことが大事です. まだここはこわくなーい.

Gitには幸い 自動マージ なるものがあり, 簡単な衝突なら自動でマージしてくれます.
まずはマージの準備
git fetch
だいぶ前にわからないと投げたコマンドを使う衝撃たるや('A`)
コイツはリモートの状態を, 別の作業用ブランチに持ってきてくれるコマンドだったらしい. すなわち先ほどの「他からのコード」をとりあえず別の場所に貰ってきてくれるらしい.
この時点で自分の書いてたコードと, fetchが持ってきてくれたブランチの2種類が存在する.
ここが一番混乱する…(・д・`)
ちなみに実行するとmasterと黄色くなっているかと.
git merge orign/master
これで 自分の書いていたコードのほうに, 持ってきたものを自動マージしてくれる. 問題はここで自動マージできていなかったとき. ファイルに差分を挿入してくれるらしいので, どれがぶつかったか確認して直しちゃいましょう. …改行コードの統一とかができていないとこれがとんでもない地獄になりますΣ(||゚Д゚)ヒィィィィ
マージが全て完了したら, おそらくmasterと緑に戻るかと.
もう一度
git push
すると今度はいってくれるはず.


…人数多いとマージ中とかに pushされるのよね…('A`)オマイラ…



AWS CDKで立てたEC2インスタンスのTimeZoneとかいじりたかった話

EC2を立てることはできたけど、立てたインスタンスは UTCのままだし設定ファイルとかいちいちscpしてくるのはダルい。 当初UserDataでなんとかしようとしたものの、「書く量がヤバいしメンテしにくい」と悩んでいたところ見かけたのが  AWS::CloudFormation:...