latex 文法まとめ

久しぶりのまとめです。
あまり理系っぽくはないですが、その分色々な事に手を出して毎日充実した生活を送っています。
最近は3DSどうぶつの森が楽しいです。昼間はあまりできないので、夜3:00くらいまで魚を釣って、朝学校に行くときに魚を売りさばく生活をしております//
写真は島でサメを釣り上げたところです笑。

どうぶつの森、最後にやったのが小6とかその辺りなので(そのときはGCだった)、新要素の増えっぷりにビビっています。
パンツも選べるし、ソックスも選べるし、メガネもかけられるし、すごすぎます。
海にも潜れるし、村にも公共事業で色々増やせるし、ネット通信までできるし、面白すぎます。
ちなみに今の格好は白シャツにドアテコっぽいパンツというわりかし夏の自分っぽい格好です。今秋?冬?ですけど。

村の住人、というか動物達も可愛いです(*´ω`*)
ちとせちゃん

人の事をたててくれて、言葉遣いもとっても丁寧で、腰の低い、現実にはいそうでいなさそうな子(*´ω`*)
時々「あの、、いらないかもしれないんですけど、、良かったらこれを。いらなかったら本当捨ててください。。」とか言いながらプレゼントくれるw

しずえちゃん

ネットでも評判のしずえちゃん。タレ目と可愛い笑顔が素敵(*´ω`*)
歩く度にしゃんしゃん鳴る鈴の音もなんか可愛いw
「海に行くついでに貝がらを一つとってきてくれたら嬉しいなー、、あ、すみません。あつかましいですよね。。」
↓貝を拾ってくる
「本当に拾ってきてくれたんですか!ありがとうございます!部屋に飾って大事にします!!」
のコンボにはやられた(*´ω`*) リアクション一つ一つが可愛く、バッファローベル的な可愛さがあるw
詳しくは「しずえさん」で検索!!



さて、閑話休題。閑話長すぎですね。
最近はlatexを使って卒業論文を書いていまして。色々調べながらやっていて、ある程度知識が溜まってきたのでまとめておこうと思います。
ちなみに環境をメモっておくと、mactexshopを入れて、ptexで書いています。
この辺りの環境導入はMac de TeX - 武田のつぶや日記を参考に。
以下に出てくる円記号はmacではバックスラッシュとなります。
また、latexに関する最初に学んでおくべき知識はここでは割愛とします。

プリアンプル部

プリアンプル部(\documentclassより下、\begin{document}より上)に記載しているものをまとめます。

\setlength{\topmargin}{40mm}
\addtolength{\topmargin}{-1in}
\setlength{\oddsidemargin}{27mm}
\addtolength{\oddsidemargin}{-1in}
\setlength{\evensidemargin}{26mm}
\addtolength{\evensidemargin}{-1in}
\setlength{\textwidth}{154mm}
\setlength{\textheight}{214mm}
\setlength{\headsep}{0mm}
\setlength{\headheight}{0mm}
\setlength{\topskip}{0mm}

setlength{}は上から順番に「用紙上の余白」「用紙左の余白(奇数ページ)」「用紙左の余白(偶数ページ)」「本文全体の幅」「本文全体の高さ」「ヘッダーと本文までの高さ」「ヘッダーの高さ」「フッターの高さ」の設定となっています。
addtolength{}は中括弧の引数に指定したもののそれぞれの長さを加えています。
それぞれに使用できる単位はmmやin(インチ)em等です。

他にもプリアンプル部には色々と書いていましたが、後から見返してみて何のための記述なのかわからなかったのでとりあえずメモ的ない身を込めてまるまる載せておきます。

\setlength{\topmargin}{40mm}
\addtolength{\topmargin}{-1in}
\setlength{\oddsidemargin}{27mm}
\addtolength{\oddsidemargin}{-1in}
\setlength{\evensidemargin}{26mm}
\addtolength{\evensidemargin}{-1in}
\setlength{\textwidth}{154mm}
\setlength{\textheight}{214mm}
\setlength{\headsep}{0mm}
\setlength{\headheight}{0mm}
\setlength{\topskip}{0mm}

\usepackage[dvips]{graphicx}
\usepackage{amsmath}

\makeatletter
\long\def\@makecaption#1#2{%
\vskip\abovecaptionskip
\iftdir\sbox\@tempboxa{#1\hskip1zw#2}%
\else\sbox\@tempboxa{#1 #2}%
\fi
\ifdim \wd\@tempboxa >\hsize
\iftdir #1\hskip1zw#2\relax\par
\else #1 #2\relax\par\fi
\else
\global \@minipagefalse
\hbox to\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\vskip\belowcaptionskip}
\makeatother

\usepackage〜は画像を扱うために必要という事はわかるんですが、、後は何でしょうね。
この設定で、一行あたりの字数が35〜45字、一ページあたりの行数が30〜40行という条件を満たす事ができる。
(うちの卒論のフォーマットがそうだったので参考までに)

数式

数式モード
上は行中に数式をうめこむ場合。下は別行にして数式をうめこむ場合(通常数式番号がふられる)。

$〜$
\begin{equation} 〜 \end{equation}

分数
この場合a/b。

\frac{a}{b}

下付き文字(上)と下付き文字(下)
この場合a^2x_1
複数文字を上付きや下付きにしたい場合{}でかこめばよい(例:a^{x + 2}、x_{y - 1}...)。

a^2
x_1

ルート
この場合ルート2。

\sqrt{2}

様々な記号
上から順番に「∈」「<」「{」「}」「Κ(ギリシャ文字)」「π」「°」「σ」「∞」

\in
\le
\left\{
\right\}
\kappa
\pi
\cric
\sigma
\infty

箇条書き
\item[]の括弧内でどのように番号や記号をそれぞれの項の最初に書くか指定する。

\begin{itemize}
\item [(1)] 適当な線分を描画する
\item [(2)] 1.元の線分を原点を中心として1/3する。

2.元の線分を原点を中心として1/3し、元の線分の長さの2/3だけ平行移動する。
\item [(3)] 得られた2つの線分に対してそれぞれ同様の処理を施す
\item [(4)] それらを繰り返す
\end{itemize}

こんな感じになる。

行列式
\begin{split}〜\end{split}で複数行にわたる数式である事を示す。後述する「\begin{eqnarray}」でも複数行の数式を扱う事ができるが、これなら式番号を複数行の数式のちょうど真ん中に書く事ができる。
\begin{array}〜\end{array}で配列である事を示し、行列式をうまく表現している。
\begin{array}の後の{ccc}は三列の行列で、それぞれの要素を中央揃え(「c」enter)である事を示している。左揃えなら「l」、右揃えなら「r」。
それらの配列を先ほどの「{}」を使って囲み行列としている。
配列の列を変えるときは間に「&」を挟み、行を変えるときは「\\」を挿入する。
途中の「&=」は数式が複数行に渡る際に「=」で数式の位置を揃える事を示す。

\begin{equation}
\begin{split}
\left(
\begin{array}{c}
x_1 \\
y_1 \\
1
\end{array}
\right)
&=
\left(
\begin{array}{ccc}
1/3 & 0 & 0\\
0 & 1/3 & 0\\
0 & 0 & 1
\end{array}
\right)
\left(
\begin{array}{c}
x_0 \\
y_0 \\
1
\end{array}
\right)
\\
\left(
\begin{array}{c}
x_2 \\
y_2 \\
1
\end{array}
\right)
&=
\left(
\begin{array}{ccc}
1/3 & 0 & 0\\
0 & 1/3 & 0\\
0 & 0 & 1
\end{array}
\right)
\left(
\begin{array}{ccc}
1 & 0 & 2x_0\\
0 & 1 & 2y_0\\
0 & 0 & 1
\end{array}
\right)
\left(
\begin{array}{c}
x_0 \\
y_0 \\
1
\end{array}
\right)
\end{split}
\end{equation}

こんな感じになる。

複数行に渡る数式モード
何も手を加えないと複数行全てに式番号がつく。
式番号をつけたくなければ、\nonumberと記述する。
行が変わるところで\\、縦をそろえたいものを&で囲む。

\begin{eqnarray}
3 - 3x = 3 - \left\{a_2(\frac{1}{3}) + a_3(\frac{1}{3})^2 + ・・・\right\}
&=& 1 - a_2(\frac{1}{3}) - a_3(\frac{1}{3})^2 - ・・・\nonumber\\
&=& (2 - a_2)(\frac{1}{3}) + (2 - a_3)(\frac{1}{3})^2 + ・・・
\end{eqnarray}

極限
limの下の矢印は \to で表す事ができる。無限大は上述。

\begin{equation}
L_\infty = \lim_{n \to \infty} L_n = \infty
\end{equation}

こんな感じ。

ただし、行中でlimを使おうとしてもn→0みたいなのがlimの下に来ず、ずれて表示される。
気に入らない人は次のようにする。\displaystyleを使うときちんと表示される。

$\displaystyle A_\infty = \lim_{n \to \infty} A_n = 0$

場合分けを含む数式
場合分けをする場合数式に大きい中括弧みたいなのが欲しくなります。その場合はequationとarrayを使って次のようにします。

\begin{equation}
x_{n + 1} = \left\{
\begin{array}{cc}
ux_n & (x_n \leq 0.5) \\
u(-x_n + 1) & (x_n > 0.5)
\end{array}
\right.
\label{tentmap}
\end{equation}

こんな感じになります。

その他

その他(主にページの体裁を整えるもの)のlatexコードをまとめます。

章立て
上から章、節、項。

\chapter{章名}
\section{節名}
\subsection{項名}

ページ番号をつけたくないページに記述する

\thispagestyle{empty}

引数に指定した長さ(縦)の空白を挿入する

\vspace{60mm}

中央揃え(上)と右揃え(下)

\begin{center}〜end{center}
begin{flushright}〜end{flushright}

文字サイズ
上から順番に大きくなる。

{\tiny 文字}
{\scriptsize 文字}
{\footnotesize 文字}
{\small 文字}
{\normalsize 文字}
{\large 文字}
{\Large 文字}
{\LARGE 文字}
{\huge 文字}
{\Huge 文字}

強制的に新しいページに改ページ

\newpage

インデントさせない
インデントさせたくない文字の直前につける。

\noindent

目次関連
上は目次にどこまで出力するのか。引数に1を指定する事で「section」までとなる。2にすると「subsection」まで出力できる。
下のもので実際に目次を出力する。(書くだけで目次ができる!!)

\setcounter{tocdepth}{1} 
\tableofcontents

コメント
一行分コメントアウトできる。
個人的な使い方としては%======================とsectionが変わる境目に入力しておき、texファイルを見やすくしている。

%コメントアウトする文字

ページカウントの変更
これを使うと途中でページカウントを1に変えたりできる。
pageの部分を変更する事により、sectionのカウントを変えたりできる。

\setcounter{page}{1}

画像関係
以下の例の場合、「cantole.epsファイル」(この場合のファイルの指定法は相対パス)を「ページ中央」に「横幅100mm」で、「画像の見出しを カントール集合の幾何学的構成法 」として貼り付けている。
また、labelは本文中で図を参照したい際に利用する\ref{}と対応させている。つまりこの場合本文中で\ref{cantole}とすると、自動で図番号が振られ本文中で図2.1のように表示してくれる。

\begin{figure}[h]
\begin{center}
\includegraphics[width = 100mm]{cantole.eps}
\caption{カントール集合の幾何学的構成法}
\label{cantole}
\end{center}
\end{figure}

\section{}で指定しなかったものをsectionとして目次に組み込む方法
うちの場合、付録のchapterでは通常のように「2.2」と指定するのではなく、「付録A」「付録B」と名前をつけるので次のように工夫しました。
まず、

\section*{付録A「アフィン変換」}

のように自動でセクションナンバーがふられるのを防ぎつつ、新しくセクションを作ります。
しかし、これでは目次に表示されないのでその後、

\addcontentsline{toc}{section}{付録A [アフィン変換]}

として、目次に表示する事ができます。

そのまま表示
texではスペースをどんなにうっても半角スペース1つ分しか反映されないので、ソースコードを貼り付ける際は次のようにします。

\begin{verbatim}〜\end{verbatim}

これでインデントなど、きちんと整形されたままきれいなソースコードを貼り付ける事ができます。


とりあえずよく使っているのはこんな感じでしょうか。
texで書いているとプログラムを書いているみたいな気分になって楽しく文章が書けますね。
javaで書いているプログラムの方も色々できてきているので近々まとめてみます。

texでこんなの便利だよ、とか指摘があればコメントがtwitter(id:takedai0313)でお願い致します。
ではしずえちゃんに会ってきます!

Mac de TeX

大学も後期が始まり色々ばたばたとしてきたました。
html5を勉強してみたり、就活イベントのポスター作ったり、javaで研究室用のプログラムを作ったり、アプリケーション用の画像を作ったりと色々と日々勉強させてもらっていますが、なかなかここにまとめるにはいたっていません。徐々にやっていきます。

大学四年の後期と言えば、特に理系の人にとっては、卒論が待ち構えていたりして自分も今まで下書きのようなものを作ってはいましたが本格的にまとめ直してちゃんとしたものを作り始めました。
偏見ではありますが、理系の人は論文を書く際にはtexを使っているイメージがあります。
というか式とか参照が多くてtex使わずにword使うとすごい大変なんじゃないかと思ったりもします。
人によってはプログラムを書いているみたいで嫌いという人もいるかもしれませんが、個人的には逆にあのプログラムを書いている感じがとても楽しいです。

さて、例に漏れず自分自身も下書きのときにもtexを使っていましたが、本格的に始めるにあたって環境を一新し直しました。
もともとwindowsにてeclipseプラグインを入れてeclipselatexを書いていましたが、macに移行しました。
移行にあたって最も手軽な方法で利用したかったので、eclipseではなく、texshopを利用する事にしました。

導入

JIS X0212 for pTeX
このサイトに移動して以下のものをダウンロードします。

  • Drag & Drop UpTeX
  • UpTeX差分ファイル
  • TeXPad alternative (1.3)
  • ESP Ghostscript 7.07.1

Drag & Drop UpTeXはdmgファイルを展開後、UpTeX.appをアプリケーションディレクトリにコピー。
UpTeX差分ファイルを解凍して、UpTeX.app/teTeX/bin/dvipdfmxと差し替えます。
アプリケーションディレクトリにコピーしたUpTeX.appを右クリックして、「パッケージの内容を表示」で上記のファイルを参照できます。
TeXPad alternative (1.3)ファイルも解凍して、UpTeX.app/TeXPad.appと差し替えます。
ESP Ghostscript 7.07.1はdmgファイルを展開後、pkgファイルを実行してインストールを完了します。

続いて以下のサイトにアクセスします。
TeXShop

このサイトで以下のリンク先からtexshopをダウンロードします。

ダウンロードしたらこれもdmgファイルを展開して、アプリケーションディレクトリにコピーします。


続けてtexshopの環境設定を行います。
環境設定を開き、タイプセットタブのスクリプトTex + DVIにします。

続けて内部設定タブのパス設定の(pdf)TeXを/Applications/UpTeX.app/teTeX/binに書き換えます。
さらに同タブ内の「TeX + dvips + distiller」のTeXのところを空欄にして、その下のLatexのところをXtexshopに書き換えます。
最後にBiBTeXエンジンにてbibtexをjbibtex変更します。

これで完了です。

使い方

最後に使い方を。
texshopを開き、環境設定の書類タブのエンコーディングを「Japanese(ShiftJIS)」にします。
そのファイルから新規作成を選び、新しいtexファイルを開きます。

新しく開かれたファイルの上の方にマクロというタブがあるのでそのマクロメニューからHeadings→11pt(or 12pt)→article(or report or book)とたどっていきクリックするだけです。
個々の意味については別の機会にまとめるとして、これで概ね準備が完了しました。

あとは好きなようにファイルをまとめ、最後に適当なディレクトリに保存した後にcommand + tでコンパイルすれば自動的にpdfファイルが作られます。

次回で使ったコマンドやらちょっとしたtips等をまとめてみます。

FractalProgram part1

自分の所属している研究室ではフラクタルについて扱っていたりとか、様々なものを扱っていたりします。
フラクタルとは→フラクタル - Wikipedia
所詮学部で卒業してしまう自分はたいそうな研究はできないですし、もうちょっと違うところに目を向けた方がいいとの思いを勝手に持っていたりするのですが、フラクタルについて最初に知ったときにはなかなか感動してしまいまして。
大学ももう卒業間近にしてそれはどうなの、という感じですがビジュアル的にわかりやすく結果が現れるものにはすごく反応してしまって自分でも色々楽しんでみたいと思ったのは事実でして。

ただ初学者はプログラムを組んでみて色々しないとなかなかすぐには楽しめないという感じなので(とはいえプログラムを組んでやってみるというのは色んな面で勉強になりますし、そもそも探せば簡単に楽しめるプログラムくらいありそうですが)、自分で初学者がすぐに使ってフラクタルを楽しめるようなプログラムをjavaで組んでみようと思い、作ってみることにしました。

今回はそのpart1です。

概要

概要というか、目標。
普通にメニューバーがあって、そこにFileとEditとHelpがあって、Fileから各フラクタルを作成するためのマネジメント画面に移行する事ができて、そこでパラメータをいじる事によってフラクタルを描画する事ができるようなプログラムです。
Editではsaveとpasteがあって描画したフラクタルを画像として保存できるような形がいいです。これはあくまで第二目標という感じですけど。
そしてHelpでは普通にhelpを。

色々大変そうだけどゆっくりのんびり作ってみます。

メニューバーの実装

実装というほどたいそうなものではないけれど。
とりあえず今の段階のメニューの階層は次のような感じにします。

javaでメニューバーを扱うためには JMenuBarクラス を使用するようです。
このJMenuBarクラスのインスタンスの中に自分に必要なメニューを色々組み込んでいくようです。

各メニューはJMenuクラスのインスタンスを作成し、先ほどのJMenuBarクラスのメソッドadd()を使用してJMenuBarクラスに組み込むようです。
さらに各メニューの最下層、つまり「close」だったり、各曲線名のメニューはJMenuItemクラスを使用します。


以上の事を踏まえてざっくりとコードを書いてみます。
通常のGUIプログラムを作成するようにframeを作成してそこにメニューバーを追加するみたいな感じになります。

package source;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class Fractal extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public Fractal(String title){
		setTitle(title);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(10, 10, 500, 500);
		setResizable(false);
		
		JMenuBar menu = new JMenuBar();
		JMenu menuFile = new JMenu("File(F)");
		JMenu menuEdit = new JMenu("Edit(E)");
		JMenu menuHelp = new JMenu("Help(H)");
		
		// 主メニューの追加
		menu.add(menuFile);
		menu.add(menuEdit);
		menu.add(menuHelp);
		
		// 副メニューの追加
		JMenu menuItemNew = new JMenu("New");
		JMenuItem menuItemClose = new JMenuItem("Close");
		menuFile.add(menuItemNew);
		menuFile.add(menuItemClose);
		
		JMenuItem menuItemSave = new JMenuItem("Save");
		JMenuItem menuItemPaste = new JMenuItem("Paste");
		menuEdit.add(menuItemSave);
		menuEdit.add(menuItemPaste);
		
		JMenuItem menuItemExplanatory = new JMenuItem("フラクタルプログラムについて");
		JMenuItem menuItemHelp = new JMenuItem("Help");
		menuHelp.add(menuItemHelp);
		menuHelp.add(menuItemExplanatory);
		
		// サブメニューの追加
		JMenuItem menuItemGasket = new JMenuItem("シエルピンスキーギャスケット");
		JMenuItem menuItemKoch = new JMenuItem("コッホ曲線");
		JMenuItem menuItemJulia = new JMenuItem("ジュリア曲線");
		JMenuItem menuItemLorenz = new JMenuItem("ローレンツ曲線");
		JMenuItem menuItemMandelbrot = new JMenuItem("マンデルブロー集合");
		
		menuItemNew.add(menuItemGasket);
		menuItemNew.add(menuItemKoch);
		menuItemNew.add(menuItemJulia);
		menuItemNew.add(menuItemLorenz);
		menuItemNew.add(menuItemMandelbrot);
		
		// キーボードニーモニックの設定
		menuFile.setMnemonic(KeyEvent.VK_F);
		menuEdit.setMnemonic(KeyEvent.VK_E);
		menuHelp.setMnemonic(KeyEvent.VK_H);
		
		setJMenuBar(menu);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		Fractal frame = new Fractal("フラクタルプログラム");
		frame.setVisible(true);
	}
}

コンストラクタが随分長いような気がしますが、コンパイルして実行したときに次のような画面が出れば成功です。

きちんと、Fileメニューの中のNewにカーソルをあわせると各種メニューが表示されます。

コンストラクタで各種メニューをバーの中に入れて、メニューバーをframeに組み込んでいます。
具体的には setJMenuBar(menu) でJMenuBarクラスのオブジェクトであるmenuオブジェクトをframeにセットしています。
今回はなんとなく画面サイズが変更されない方が都合がいいと思ったので、setResizable(false)としています。
他はひたすらメニューを組み込んでいます。

一つ目新しいのはキーボードニーモニックの設定というものです。
これはいわゆるショートカットキーです。
setMnemonic()メソッドで設定する事ができます。
引数にはKeyEventを設定する事ができます。
例えば、VK_Fというのは alt + Fキー です。

フラクタルプログラムについて画面の作成

続いて各種描画処理を実装していきます。しかし、如何せん勉強不足で何から手をつけていいやら。
一番簡単そうなフラクタルプログラムについて、という画面を作ってみます。
いわゆる自己紹介的な画面です。
メニューのHelp-フラクタルプログラムについて というメニューをクリックする事により、新しいframeが作成され、そこに色々文章が書いてあり、そのframeのバツボタンをクリックするとその画面のみ終了するという感じにします。
それとついでにcloseメニューを選択したときにプログラムが終了するようにも設定しておきます。

ここですべき事はいくつかあって、まずメニューをクリックするとイベントが発生するようにしなければいけないこと。そしてそのイベントを受けて新規frameを作成するということ。そのframeの終了処理を加えるということ。
ざっくりというとこの三つでしょうか。
メニューアイテムにイベントリスナを登録するためには addActionListener()メソッド を用います。
今回はこの引数にthisを指定して、同じクラス内にactionPerformed(ActionEvent e)メソッドを作ります。

それではまたざっくりとコードを作ります。

package source;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class Fractal extends JFrame implements ActionListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public Fractal(String title){
		setTitle(title);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(10, 10, 500, 500);
		setResizable(false);
		
		JMenuBar menu = new JMenuBar();
		JMenu menuFile = new JMenu("File(F)");
		JMenu menuEdit = new JMenu("Edit(E)");
		JMenu menuHelp = new JMenu("Help(H)");
		
		// 主メニューの追加
		menu.add(menuFile);
		menu.add(menuEdit);
		menu.add(menuHelp);
		
		// 副メニューの追加
		JMenu menuItemNew = new JMenu("New");
		JMenuItem menuItemClose = new JMenuItem("Close");
		menuFile.add(menuItemNew);
		menuFile.add(menuItemClose);
		
		JMenuItem menuItemSave = new JMenuItem("Save");
		JMenuItem menuItemPaste = new JMenuItem("Paste");
		menuEdit.add(menuItemSave);
		menuEdit.add(menuItemPaste);
		
		JMenuItem menuItemExplanatory = new JMenuItem("フラクタルプログラムについて");
		JMenuItem menuItemHelp = new JMenuItem("Help");
		menuHelp.add(menuItemHelp);
		menuHelp.add(menuItemExplanatory);
		
		// サブメニューの追加
		JMenuItem menuItemGasket = new JMenuItem("シエルピンスキーギャスケット");
		JMenuItem menuItemKoch = new JMenuItem("コッホ曲線");
		JMenuItem menuItemJulia = new JMenuItem("ジュリア曲線");
		JMenuItem menuItemLorenz = new JMenuItem("ローレンツ曲線");
		JMenuItem menuItemMandelbrot = new JMenuItem("マンデルブロー集合");
		
		menuItemNew.add(menuItemGasket);
		menuItemNew.add(menuItemKoch);
		menuItemNew.add(menuItemJulia);
		menuItemNew.add(menuItemLorenz);
		menuItemNew.add(menuItemMandelbrot);
		
		// キーボードニーモニックの設定
		menuFile.setMnemonic(KeyEvent.VK_F);
		menuEdit.setMnemonic(KeyEvent.VK_E);
		menuHelp.setMnemonic(KeyEvent.VK_H);
		
		// イベントリスナの登録
		menuItemClose.addActionListener(this);
		menuItemExplanatory.addActionListener(this);
		
		setJMenuBar(menu);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		Fractal frame = new Fractal("フラクタルプログラム");
		frame.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent e){
		if(e.getActionCommand() == "フラクタルプログラムについて"){
			explainWindow explainFrame = new explainWindow();
			explainFrame.setVisible(true);
		}else if(e.getActionCommand() == "Close"){
			System.exit(0);
		}
	}
}

class explainWindow extends JFrame{
	private static final long serialVersionUID = 1L;
	
	public explainWindow(){
		setTitle("フラクタルプログラムについて");
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
		setBounds(30, 60, 400, 400);
		setResizable(false);
		
		// text表示
		JTextPane text = new JTextPane();
		text.setText("フラクタル初学者用のプログラムです。\nフラクタルやカオスといったそれぞれの持つ性質や形を実感する事ができればとの思います。");
		text.setEditable(false);
		text.setFocusable(false);
		StyledDocument doc = (StyledDocument)text.getDocument();
		SimpleAttributeSet attr = new SimpleAttributeSet(); // 行間を詰める用
		StyleConstants.setLineSpacing(attr, -0.2f);
		StyleConstants.setAlignment(attr, 10);
		doc.setCharacterAttributes(0, 300, attr, true);
		getContentPane().add(text);
	}
}

では実際に起動してみます。起動画面こそ変わりませんが、メニューバーのHelpからフラクタルプログラムについて、というメニューを選択すると以下のような画面が表示されます。

またこの説明画面のバツボタンを押すとこの画面のみ消えるはずです。
さらにメニューのcloseを選択するとプログラムが終了するはずです。


コードを見ていきます。
今回はイベントリスナを設定するのでFractalクラスにimplements ActionListenerとしておきます。
また上記の通り、menuItemClose.addActionListener(this);とmenuItemExplanatory.addActionListener(this);で各メニュー画面にイベントリスナを登録しています。
イベントリスナを登録したので対応するメソッドをOverrideします。
今回はactionPerformed(ActionEvent e)メソッドです。

つまり何らかのメニューが選択されたときにこのメソッドが呼ばれるので、この中で何のメニューがおされたのか判断します。
選択されたメニューを取得するメソッドはgetActionCommand()メソッドです。
もし、これが”フラクタルプログラムについて”であればframeを新規作成し、”close”であればSystem.exit(0);として終了します。

新しいframeは別クラスとして作成します。
通常通りJFrameクラスを拡張してのクラス作成です。

このframeではテキストのみの表示となるので、JTextPaneクラスを用います。
また、テキストエディタのように編集できたりする必要もないので、setEditable(false)やsetFocusable(false)メソッドを用いています。
その下のスタイルはうまく適応されていない気もしますが、とりあえずこんな感じでいいでしょう。


とりあえず今回はここまで。
次回は描画処理です。もっと良い書き方があれば教えて欲しいです。

PhoneGap 導入

スマートフォンが一般化してきたことにより、スマートフォンアプリケーションの作成法は様々なものが出ています。
例えば、java+Eclipseでネイティブアプリケーションとして作ったり、ruby+Rhodesでwebアプリケーションのように開発したり、javascript+Titanium Mobileでjavascriptファイルで開発したり。
自分もそんなに詳しくないですが。というかOSによっても言語は変わりますし。
iOSObjective-Cだったり。
個人的な話をすれば、初めて自分で本格的に勉強した言語がjavaだったので、java+Eclipseで勉強した事もありますが結構難しかった印象があります。

なので、今回はPhoneGapを使ったスマートフォンアプリケーション開発を勉強してみようと思います。
もう最近どこに向かいたいのかよくわからなくなっていますが、コードを書いたりそれが動いたりするのを見るのはなんだかとても楽しいので気にせずいきます。

PhoneGapはTitanium Mobileと同様にjavascriptファイルでアプリケーション開発を行う事ができるものです。
本当はTitanium Mobileをdot install様で勉強していこうとも思ったのですが、以前のFacebookアプリケーション開発(facebookアプリ 開発環境構築編 - 武田のつぶや日記)でも参考、というよりほとんど丸読みの日経ソフトウェアにも載っているという事と、折角CAATのおかげでhtml5やら、javascriptの知識も入れているのでそれを生かしてみたいとの思いで今回はPhoneGapを用いてみたいと思います。

日経ソフトウエア 2012年 10月号 [雑誌]

日経ソフトウエア 2012年 10月号 [雑誌]

ちなみにdotinstall様によるTitanium Mobileはこちら。
http://dotinstall.com/lessons/basic_titanium

PhoneGapについて

公式サイトは以下のものです。
PhoneGap
スマートフォンアプリケーション開発において対象のOSによって使用する言語が変わるというのは前述した通りですが、PhoneGapはこの対象OSの差分を吸収してくれます。
具体的にはhtml5を用いてwebアプリのように作成したアプリケーションを同一ファイルを用いてAndroid,iOS,Blackberry,WindowsPhone,Palm WebOS,Bada,Symbianの7つのプラットフォーム上で動作する事ができるようになります。
この各プラットフォームの差分を吸収するという点ではTitanium Mobileと同じなのですが、Titanium Mobileは独自のAPIを用いるのに対して、PhoneGapはHTML5を用います。
そういた点からも今後普及するのはTitanium MobileよりもPhoneGapなのではないかという見方をする人もいます。

それはそうとして、大事なのはHTML5でwebアプリケーションのように作成をするが、PhoneGapを用いる事によりAppStore等でも配布する事ができるようになるという事です。

それでは、PhoneGapの導入を始めます。

Phone Gapの導入

今回はAndroid上で動作するアプリケーションを作成する事を目標に学習します。
アプリケーションは初学者っぽく画面上にHello Worldと表示するアプリケーションを目標にします。

必要となるのは次の二点です。

    • Eclipse(ver3.4以上 androidSDKやAVDは導入済みとします)
    • PhoneGap

EclipseのインストールやSDKの導入等は本題ではないので今回は省略させてもらいます。
それではまず、PhoneGapの公式サイト(PhoneGap)にアクセスします。

上のようなサイトにアクセスできたら、右上にあるDownloadをクリックします。
すると自動的に.zipファイルのダウンロードが開始されます。
少し時間がかかるかもしれませんが、ダウンロードが終わったら、.zipファイルを展開します。

phoneap-phoneap-2dbbdabファイルが展開されます。
中にはchargelogやdocディレクトリ、libディレクトリ等が入っていると思いますが、このlibディレクトリに各OSに対応するライブラリが入っているのでこれらを用います。


それでは実際にアプリケーション開発の手順を踏んでみるとします。
公式リファレンスは以下を見るといいです。
PhoneGap API Documentation

おもむろにEclipseを立ち上げ、新規から新しいプロジェクトを作成します。javaプロジェクトではないので気をつけてください。

プロジェクトの種類からAndroid Application Projectを選択して、次へ進みます。

ApplicationNameとProjectNameとPackageNameを適当に決めます。
PackageNameはアプリケーションごとのユニークな値でidみたいなものです。他に存在しないような名前を付けなければいけません。
通常ドメインのように記載します。
ですが、別に公開したりしないので適当に決めましょう。

その下のbuildsdkはその名前の通り、その下のminimum required sdkは最低限必要なAPIレベルです。
別段意味はないですが、自分のスマートフォンが2.2くらいかなと思ったのでそれくらいにしてます。適当な値に設定してください。

その後のiconの設定やActivityの設定は特にいじる事なく次へと進みます。
最後にActivity nameやlayout nameを適当に決めて、プロジェクトの作成を完了します。

プロジェクトの作成が完了したら、プロジェクト内にassetsディレクトリとlibsディレクトリがある事を確認してください。
Eclipseの左にあるプロジェクト一覧から確認できるはずです。

このassetsディレクトリ内にwwwディレクトリを作成します。
assetsを右クリックして、新規からフォルダーで作成できます。

続いて、ダウンロードしたphonegap内 /lib/android/cordova-2.0.0.jarファイルをlibsディレクトリに、phonegap内 /lib/android/cordova-2.0.0.jsファイルをassets/wwwディレクトリ内にコピーします。
普通に各ファイルを、それぞれのディレクトリにドラッグ&ドロップするだけです。
コピーするかどうかを聞かれるので、コピーを選択します。

続いて同phonegap内の /lib/android/xmlディレクトリを丸ごとresディレクトリ内にコピーします。方法は先程と一緒です。


では次のステップです。
続いてライブラリの追加を行います。
先ほど追加したcordova-2.0.0.jarファイルを右クリックして出てくるメニューの中に、ビルドパスというものがあります。その中のビルドパスの構成というものがあるのでそれを選択します。

出てきた画面のライブラリータブを選択し、Jar追加という右側にあるボタンをクリックして、cordova-2.0.0.jarファイルを選択してライブラリの追加を行います。

ここまでできたらいよいよソースコードをいじります。
まずプロジェクト内のsrcフォルダ内にあるパッケージ内の.javaファイルを表示して次のような処理を行います。

    • import文のところにimport org.apache.cordova.*; を追加する。
    • クラスのextendsがActivityになってるのをDroidGapに変える。
    • onCreate()メソッド内のsetContentView()をsuper.loadUrl("file:///android_asset/www/index.html");に書き換える。

次のような感じになれば大丈夫です。

続いてプロジェクト内にあるAndroidManifest.xmlファイルをいじっていきます。
タグの間に以下のコードをペーストします。

<supports-screens 
    android:largeScreens="true" 
    android:normalScreens="true" 
    android:smallScreens="true" 
    android:resizeable="true" 
    android:anyDensity="true" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />

ただし、どうやらgoogle playに登録する際にはこの複数あるタグのうち使っていないものは削除しておかないとgoogle playに登録する事ができないようです。

さらに同様のxmlファイル内のタグ内に次の一文を加えます。

android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"

最後に画面本体を作成します。
まず、/assets/wwwディレクトリ内にindex.htmlファイルを作成します。
index.htmlファイルの中身は以下のような形です。

<!DOCTYPE HTML>
<html>
<head>
<title>Cordova</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

これで画面にhello worldと表示されるプログラムを作成する事ができました。
全て保存して、実行してみます。このときandroid applicationとして実行するようにします。
以下のような画面が表示されれば成功です。

このindex.htmlファイルをいじったりリンクファイルを用意する事によって、様々なアプリケーションを開発する事ができます。
時間を見つけて何かしら作ってみたいです。

CAAT::Actor(Behavior)

久しぶりのCAATです。
今回はBehaviorについてです。
公式ドキュメントは以下のwebページです。
http://hyperandroid.github.com/CAAT/documentation/tutorials/t2-4.html


公式ドキュメントでは次のような事を言及しています。

Behaviorについて

Actorは自身に適当される事によって自身のビジュアル的な形を変化させる能力を持つが、同時に適当できるスケールやローテーションといった値はひとつだけです。
Behaviorは与えられた時間(これは以前【CAAT::Actor(Life Cycle) - 武田のつぶや日記】のライフタイム内の時間的な意味合いかな)内で、actorインスタンスにアフィン変換を適応する能力を持つ。
したがってBehaviorというのは、フレームタイムーつまりいつbehaviorの適応が始まってどのくらいの時間適応されるのかという時間ーとどんな適応がされるのかという二つによって定義されている。
例えば、0度から360度、2000[ms]から5000[ms]の間回転する、というように。

ここでRotateBehaviorやScaleBehaviorについて重要な事は、setScaleAnchoredやsetRotationAnchoredと同じようにsetAnchorというメソッドを使用する事によってanchorをセットする事ができるようになるという事です。
しかし、後者の二つはanchorをピクセル単位で指定していたのに対してbehaviorはパーセンテージ単位、つまりactorの大きさに対してどのくらいかという指定の仕方をする。


今回はこの程度の文章しかなく比較的わかりは良かったです。

サンプル

今回の完成形は次のような形です。

じっと見ていると気持ち悪くなってきます。
特にゲームっぽくもせず今回は公式リファレンスのサンプルをそのまま使用させていただきました。

ソースコード

<!DOCTYPE HTML PUBLIC "-//W3c//DTD HTML 4.01 Transitiional//EN"
"http://www.w3.org/TR/html4/loose,dtd">
<html>
	<head>
		<title></title>
	</head>

	<body>
		<div><canvas id="_c4"></canvas></div>
		<script type="text/javascript" src="../../../hyperandroid-CAAT-f7d1a87/build/caat.js"></script>
		<script type="text/javascript">
			(function( ){
				var _director_4 = new CAAT.Director().initialize(
					600,
					250,
					document.getElementById('_c4'));

				var _scene_4 = _director_4.createScene();

				var anchor = [
					0,0,	.50,0,	 1.00,0,
					0,.50,	.50,.50, 1.00,.50,
					0,1.00,	.50,1.00, 1.00,1.00,
					];
					
				var i;

				for(i=0;i<9;i++){
					var _scene_4_rotating_actor_background = new CAAT.Actor().
						setLocation(50+50*(i%3), 35+50*((i/3)>>0)).
						setSize(30, 30).
						setFillStyle('#ffffff').
						setStrokeStyle('#000000').
						enableEvents(false);

					_scene_4.addChild(_scene_4_rotating_actor_background);

					var _scene_4_rotating_actor = new CAAT.Actor().
						setLocation(50+50*(i%3), 35+50*((i/3)>>0)).
						setSize(30, 30).
						setFillStyle('#ff0000');

					var _scene_4_rotating_behavior = new CAAT.RotateBehavior().
						setCycle(true).
						setFrameTime(0, 2000).
						setValues(0, 2*Math.PI, anchor[i*2], anchor[i*2+1]);

					_scene_4_rotating_actor.addBehavior(_scene_4_rotating_behavior);
					_scene_4.addChild(_scene_4_rotating_actor);

					var _scene_4_scaling_actor = new CAAT.Actor().
						setLocation(300+60*(i%3), 30+60*((i/3)>>0)).
						setSize(30, 30).
						setFillStyle('#ff00ff');

					var _scene_4_scaling_behavior = new CAAT.ScaleBehavior().
						setCycle(true).
						setFrameTime(0, 2000).
						setValues(.5, 1.5, .5, 1.5, anchor[i*2], anchor[i*2+1]).
						setPingPong();

					_scene_4_scaling_actor.addBehavior(_scene_4_scaling_behavior);
					_scene_4.addChild(_scene_4_scaling_actor);
				}
				
				CAAT.loop(20);
			 })();
		</script>
	</body>
</html>

ソースも今回はとりたてて気になるところもないでしょうか。
通常どおりDirectorを作成してSceneを作成してそこにActorを追加していきます。
配列変数anchorはanchorの位置をそれぞれ指定しています。個人的には二重配列にすればよいのではないかとも思いましたが、今回はサンプルコードのままです。
公式リファレンスではこの値が微妙におかしいので注意が必要です。公式リファレンス通りの値を使用すると相当荒ぶったサンプルができます。

その後for文で、四角形を9つずつ作成しています。
最初の変数_scene_4_rotating_actor_backgroundは回転する四角形の後ろに白い四角形を9つ配置するものですが、今回のように背景が白い場合は見えないのでいらなかったですね。
そして、それぞれの四角形に対してbehaviorを作成して適応しています。
このあたりはtransformationとあまり変わらない気もしますが。

actorに対してaddBehaviorメソッドで振る舞いを追加する感じですね。とてもわかりやすいです。


今回はあまり目新しい感じではありませんでした。
次回はCAATの続きか、あるいはスマートフォンアプリの開発の導入に入るかもしれません。

facebookアプリ 開発編

前回facebookアプリ 開発環境構築編 - 武田のつぶや日記開発環境を整えたので、いよいよ開発のほんちゃんに入ります。
まずはインストールした各ライブラリを利用できるようにすると共に各ライブラリの使い方を確認します。
最初はsilexです。
silexを使った場合、最初にリクエストが来るのはhtdocs/sillshindan.localhost/web/index.phpファイルです。
なのでこの中身を確認します。

<?php

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->get('/hello', function() {
    return 'Hello!';
});

$app->run();

こんな感じになっているはずです。
require_once〜でautoload.phpファイルを読み込み、その後Silex\Applicationオブジェクトを作り、app変数に格納します。
$app->get〜のところでは、http://skillshindan.localhost/helloにアクセスした際にはHello!と返すという処理を行なっています。
前回の最後にアクセスして確認しました。最後のrun()は実際に処理を実行するための命令です。
この__DIR__というのは現在のディレクトリという意味です。

ではこれをベースにして次のように書き換えます。

<?php
require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();
/*
$app->get('/hello', function() {
    return 'Hello!';
});
*/

$app->register(new Silex\Provider\TwigServiceProvider(), array(
	'twig.path' => __DIR__.'/../views',
));

$app->match('/', function() use($app){
	return $app['twig']->render('test.html');
});

$app->run();

まず、さきほどのget〜のところは/*〜*/でコメントアウトし(削除してもいいですがどこまで動いているのか確認するためにいつでもgetを使えるよう残してあります)、その後作ったApplicationオブジェクトにTwigを使えるように登録します。それが$app->register以下です。連想配列で'twig.path'にtwigのテンプレートを保管する場所を示しています。この場合は/skillshindan.localhost/ディレクトリにviewsディレクトリを作成して、そこにtwigファイルを入れていきます。
その後、http://skillshindan.localhost/というアクセスでトップページを表示したいので、match('/')としています。
このアクセスがあったときの処理がreturn以下で、twigオブジェクトを作成して、renderというメソッドでviewsディレクトリにあるtest.htmlを描画しています。

では、続いてtwigを使用するためにtwigのライブラリを読み込む処理を加えます。
ここが本当にわかりませんでした。これだけで2日くらい悩み続けました。おかげで色々脱線し結構新しい知識も増えましたが。
まず、自分が学習していた本には/vendor/autoload.phpに以下のように記載すると書いてありました。

$loader->add('Twig_', __DIR__.'/twig/lib');

しかし、これだとエラーが出てファイル自体を読み込む事ができませんでした。
続いて色々なサイトを確認してみてindex.phpのregisterのところに加えるというやり方を発見したので、次のように/web/index.phpを次のように編集しなおしました。

$app->register(new Silex\Provider\TwigServiceProvider(), array(
  'twig.path'       => __DIR__ . '/views',
  'twig.class_path' => __DIR__ . '/silex/vendor/twig/lib', //加えたのはこの部分
));

日本語ドキュメントにもこのやり方は書いてありましたし、いけると思いましたが、うまくいきませんでした。
さきほどのhelloアクセスもできなくなります。このtwig.class_pathの部分をコメントアウトするとhelloは表示しますが。
日本語版ではなく、英語版の公式ドキュメントを確認してみるとclass_pathみたいなパラメータについての記載はありませんでした。

で、よく考えてみるとこの$loaderという変数はどっからきているのか、となりよく見てみるとautoload.phpを見てみると、さらにautoload_real.phpを読み込んでいる。
という事でこのvendor/composer/autoload_real.phpファイルを確認してみたらありました!$loader変数がたくさん!
というわけで、$loader->register();の前に先ほどの一行

$loader->add('Twig_', __DIR__.'/twig/lib');

を加えます。

で、最後にテスト用のtest.htmlを作ります。
とその前にテスト用に先ほどのweb/index.htmlファイルに二行を加えて次のようにします。

$app->get('/', function() use($app) {
  $variables['test1'] = 'これはテストです。';
  $variables['test2'] = array('テスト1', 'テスト2', 'テスト3');

  return $app['twig']->render('test.html', $variables);
});

そして、test.htmlを次のように記載して、/views/ディレクトリにtest.htmlとして保存します。

<html>
	<head>
		<meta charset="utf-8" />
		<title>title</title>
	</head>
	<body>
		<h1>テスト</h1>
		<p>{{ test1 }}</p>
		<ul>
			<!--{% for test in test2 %}-->
			<li>{{ test }}</li>
			<!--{% endfor %}-->
		</ul>
	</body>
</html>

MAMPでサーバを起動して、hosterでホストファイルを適当してhtpp://skillshindan.localhostとうつと次のような画面が表示されれば成功です。

この画面が出たときの感動といったらありませんでした。
ここまで来ればあとは本当にあと少しです。がしがしいきます。

まず、今回は各質問にyes noで答えて最後に診断結果が出るというものなので、質問を9つと結果を6つ配列で用意します。
それが次のコードです。

<?php
$questions = array(
	1 => array(
		'body'		=> '正直勝つ事よりも負ける事の方が多い',
		'next_yes'	=> 4,
		'next_no'	=> 2,
	),
	2 => array(
		'body'		=> '能力で格好良いと思うのは「目」に関する能力だ',
		'next_yes'	=> 5,
		'next_no'	=> 3,
	),
	3 => array(
		'body'		=> '能力の格好良さは「強さ」だけではないと思う',
		'next_yes'	=> 6,
		'next_no'	=> 5,
	),
	4 => array(
		'body'		=> 'いかに勝つかよりもどう負けるかが重要だと思う',
		'next_yes'	=> 7,
		'next_no'	=> 5,
	),
	5 => array(
		'body'		=> '人知れず努力をする事が好きだ',
		'next_yes'	=> 8,
		'next_no'	=> 7,
	),
	6 => array(
		'body'		=> 'なんの助けを借りずに自分の力で問題を解決したい',
		'next_yes'	=> 9,
		'next_no'	=> 8,
	),
	7 => array(
		'body'		=> '失恋をしたら相手の事を全て忘れる',
		'next_yes'	=> 'A',
		'next_no'	=> 'B',
	),
	8 => array(
		'body'		=> '人が自分の事をどう見ているかが気になる',
		'next_yes'	=> 'C',
		'next_no'	=> 'D',
	),
	9 => array(
		'body'		=> '完璧主義である',
		'next_yes'	=> 'E',
		'next_no'	=> 'F',
	),
);

$results = array(
	'A' => 'Aタイプの君にぴったりなのは「大嘘憑き(オールフィクション)」だぜ。傷ついても傷ができた事自体を無かった事にしちゃうんだぜ。全く君は根っからの過負荷だな。',
	'B' => 'Bタイプの君には「五本の病爪(ファイブフォーカス)」がぴったりかな。病気にしたり、病気を治したりと便利なスキルなんだぜ。今は赤さんに貸してるんだけどね。',
	'C' => 'Cタイプの君にぴったりなのは「欲視力(パラサイトシーイング)」だね。この前まで善吉君に貸してたんだけど。他人の視界をのっとれるスキルだぜ。そんなに自分の顔がきになるかい?',
	'D' => 'このDタイプの人間にぴったりなのは「知られざる英雄(ミスターアンノウン)」だぜ。正確にはスキルじゃないんだけど、相手から見えなくなるスキルくらい僕だって持ってるんだぜ',
	'E' => 'そんなEタイプにぴったりなスキルは「完成(ジ・エンド)」なんだぜ。どんな事でも自分で完璧に仕上げちゃうぜ。このスキルを使ってフラスコ計画を完成させればよかったぜ。',
	'F' => 'Fタイプの君にぴったりなのは「愚行権(デビルスタイル)」かな。運にも主人公補正にも頼らず自分の力で進みたい君にぴったりなんだぜ。まぁ読み方はどうかと思うんだけどね。',
);

このファイルをdata.phpという名前で/skillshindan.localhost/ディレクトリに保存します。
少しこのファイルを見ていきます。
質問の項目を$questions変数に配列で、結果を$results変数に配列で用意しています。
例えば$questions変数の連想配列1には質問1の内容がさらに連想配列で記載されています。
'body'に質問の内容、next_yesにyesを選んだ場合の次の質問番号、next_noにはnoを選んだ場合の次の質問番号を格納しています。
$results変数の方も同じでAタイプには、、という感じで配列を組み込んでいます。

続いて実際にアプリを作成するために/web/index.phpを次のように編集します。

<?php

require_once __DIR__.'/../vendor/autoload.php';
require __DIR__.'/../data.php';

$app = new Silex\Application();
/*
$app->get('/hello', function() {
    return 'Hello!';
});
*/

$app->register(new Silex\Provider\TwigServiceProvider(), array(
	'twig.path' => __DIR__.'/../views',
));

$app->match('/', function() use($app){
	return $app['twig']->render('index.html');
});

$app->run();

変更したのは、requireで先ほど作成したdata.phpを読み込み、http://skillshindan.localhostでアクセスした際に読み込むファイルをindex.htmlに変更した事です。

続いて、/vendor/autoload.phpファイルのrequire_once〜の下に次の一行を加えます。

require_once __DIR__.'/facebook-php-sdk/src/facebook.php';

これで、facebook sdkを読み込む事ができるようになりました。

それでは実際にindex.htmlというトップページを作りtwigで読み込めるようにします。
/views/ディレクトリにindex.htmlという名前で以下のコードを保存します。

{% extends 'base.html' %}

{% block content %}
	<div class="hero-unit start-unit">
		<h1>めだかボックス:スキル診断</h1>
		<p>安心院さんが既存のスキルを一つ付与してくれるそうだ</p>
		<p>あなたにぴったりなスキルはなんだろう</p>
		<p><a href="q/1" class="btn btn-primary">診断を始める&raquo;</a></p>
	</div>
{% endblock %}

一見htmlファイルのようじゃないかもしれませんが、これがテンプレートエンジンを使用するという事です。
つまりこのコードで言えば、base.htmlというテンプレートの{% block content %}〜{% endblock %}で囲まれた部分をこのファイルの{% block content %}〜{% endblock %}で囲まれた部分で書き換えるという事です。

テンプレートエンジンを使った事が無かったのでこういう考え方はおぉ、と少し感動してしまいました。

続いてそのベースとなるbase.htmlファイルを作って、同じく/viwes/ディレクトリに保存します。
以下がそのコードです。

<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>title</title>
		<link href="/assets/bootstrap/css/bootstrap.css" rel="stylesheet">
		<link href="/assets/css/style.css" rel="stylesheet">
	</head>
	<body>
		<div class="container">
			{% block content %}
			{% endblock %}
		</div>

		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
		<div id="fb-root"></div>
		<script>
			window.fbAsyncInit = function(){
				FB.init({
					appId		: '作成したアプリID',
					status		: true,
					cookie		: true,
					xfbml		: true
				});
				FB.Canvas.setAutoGrow();

				{% block fb_javascript %}{% endblock %}
			};

			(function(d){
				var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
				if(d.getElementById(id)){return;}
				js = d.createElement('script');
				js.id = id;
				js.async = true;
				js.src = "//connect.facebook.net/ja_JP/all.js";
				ref.parentNode.insertBefore(js, ref);
			}(document))
		</script>
	</body>
</html>

最初に画面の体裁を整えるためにbootstrapとstylesheet.css(まだ作成していない)を読み込んでいます。
その下に先ほど出た{% block content %}〜{% endblock %}があり、さらにその下の処理は全てfacebookのシェア機能を処理するためのものです。

そして最後にstylesheet.cssファイルを作成し、/web/assets/css/ディレクトリに保存します。
コードは次の通りです。

body {
	padding-top: 60px;
}
.container {
	width: 760px;
}
.start-unit {
	background-color: #ccddff;
}
.start-unit h1 {
	font-size: 48px;
}
.start-unit p {
	margin: 15px;
}
.start-unit .btn {
	padding: 10px 30px;
	font-size: 20px;
	line-height: normal;
	border-radius: 5px;
}
.result {
	padding: 20px 40px
}
.hide {
	display: hidden;
}

ここまでできたらトップページが表示されるはずです。
http://skillshindan.localhostにアクセスしてみましょう。
次のような画面が表示されれば成功です。

まだトップ画面しか表示されません。この後、各質問ページや解答ページを表示できるようにしましょう。

質問ページにはhttp://skillshindan.localhost/q/{質問番号}というアドレスでアクセスできるようにします。
まず/web/index.phpファイルの$app->run();の前の行に次のコードを追加します。

$app->match('q/{qid}', function($qid) use($app, $questions, $results){
	if(isset($questions[$qid])){
		return $app['twig']->render('question.html', array(
			'question' => $questions[$qid],
		));
	}elseif(isset($results[$qid])){
		return $app['twig']->render('result.html', array(
			'result_type'	=> $qid,
			'result'		=> $results[$qid],
		));
	}else{
		$this->abort();
	}
});

これで/q/{qid}というアクセス({qid}は質問id)がきたときには質問ページであるquestion.htmlを、/issetというアクセスのときには解答ページであるresult.htmlを表示するようになります。
それぞれの.htmlファイルには配列を渡してページ表示の手助けとしています。

続いて質問ページを作ります。
/views/ディレクトリにquestion.htmlファイルを次のように作成します。

{% extends 'base.html' %}

{% block content %}
	<div class="page-header">
		<h1>めだかボックス:スキル診断</h1>
	</div>
	<div class="transit">
		<h2>{{question.body}}</h2>
		<p>ボタンを押してください</p>
		<div>
			<a href="/q/{{question.next_yes}}" class="btn btn-large btn-primary">yes</a>
			<a href="/q/{{question.next_no}}" class="btn btn-large btn-danger">no</a>
		</div>
		<br>
		<div>
			<a href="/" class="btn">トップに戻る</a>
		</div>
	</div>
{% endblock %}

同様に解答ページを同じ場所にresult.htmlという名前で以下のコードで作成します。

{% extends 'base.html' %}

{% block content %}
	<div class="page-header">
		<h1>スキル診断 - {{result_type}}タイプ</h1>
	</div>
	<h2>きみは{{result_type}}タイプだぜ</h2>
	<div class="alert alert-box alert-info result">
		<h3>{{result}}</h3>
	</div>
	<div>
		<a href="#" class="btn btn-primary btn-fb-share">Facebookでシェア</a>
		<a href="/" class="btn">トップに戻る</a>
	</div>
{% endblock %}

{% block fb_javascript %}
	$(function(){
		$('.btn-fb-share').click(function(e){
			FB.ui({
				method: 'feed',
				// link: '(アプリのURL)',
				name: 'name',
				caption: '{{result_type}}タイプ',
				description: '{{result}}'
			},
			function(response){
			});
			e.preventDefault();
		});
	});
{% endblock %}

どちらもテンプレートエンジンを使用しています。

これで質問ページも解答ページも使えるようになりました。

では最後にページをタブに組み込みます。(実際には行いませんでしたが)
https://facebook.com/add.php?api_key=App ID&pages=1にアクセスすると(App IDは自分のIDと置き換える)、アプリを追加するか聞かれるので追加します。
これで終わりです。
新しいfacebookページに組み込みたければ事前にページを作っておきます。


長かったですがこんな感じです。
最後に自分の作ったスキル診断の結果を全て見せて終わりとします。
善吉君

めだかちゃん

日之影先輩

安心院さん

赤さん

球磨川くん

こんな感じでした。

facebookアプリ アプリ登録編

前回でMAMPの導入が済んだので、facebookアプリの開発環境を整えて、開発してみます。
最初に目標を明確にしておきますが、今回作成するアプリはよくある診断アプリです。まぁ初めてという事で、もちろん内容は変えますが雑誌の通り作ってみましょう。
内容としては「めだかボックス」のスキル診断アプリでも作ってみます。
いくつかの質問にyes,noで答えていき、最後に安心院さんにぴったりのスキルを6つの中から選んでもらうという感じです。
大好きです、めだかボックス

めだかボックス 1 (ジャンプコミックス)

めだかボックス 1 (ジャンプコミックス)

ただし、実際にfacebookに組み込むところまでは行いません。
著作権的にもどうかと思いますし、こんな拙いアプリをって感じでもあるので。
機会を見てちゃんと組み込めるようにしたいです。
ただし、実際にfacebookページを開設して、諸々っていうのはやります。勉強になると思うので。

実際に使うものを最初に確認します。

こんな感じでしょうか。bootstrap以外は使った事がないのでドキドキしますね。

まず、facebookの開発者ページからアプリの登録を行います。
https://developers.facebook.com/apps

facebookにログインしていないと色々聞かれるかもしれませんが、ログインすると下のようなページが出ます。

右上に「新しいアプリを作成」というボタンがあるので、これを押します。
すると、下図のようなダイアログが表示されるので各スペースを埋めます。

App Nameはその名の通り、アプリの名前です。ここでは「めだかボックス」スキル診断にします。
App Namespaceはアプリの名前空間であり、ユニークな値でないといけません。
三つめのチェックボックスはHerokuというサービスを使うかどうかを聞いているのでここではチェックを外しておきます。
Herokuは無料のホスティングサービスで、自前のサーバがない場合に有効そうなので今度使ってみたいです。

ここまで入力して続行を押すと専用のアプリページが表示されます。

最初の画面にアプリのIDとパスワードが表示されています(画像では塗りつぶしをしています)。このIDやらパスワードは流出しないようにきちんと保管しておきます。
ではもう少しアプリの設定を行なっていきます。

今回はfacebookページに「タブ」という形でアプリを埋め込んでいくので、「アプリをfacebookに結合する方法を選択」から各項目を記載します。

まずページタブ名は普通にアプリの名前です。
page tab urlはアプリの最初の画面が表示されるURLですが、今回はhttp://skillshindan.localhost/でログインしたときに、トップ画面が表示されるようにするのでそのようなURLを記載します。
その下のsecure page tab urlはssl対応のurlを記載します。ここでは上記のアドレスのhttpの部分をhttpsに変えただけのものを記載します。
page tab edit urlは飛ばし、最後にpage tab widthをnormalとします。画面は広い方がいいですしね。
これでアプリの結合法の編集を終えたので、変更を保存ボタンを押して変更を保存します。

最後に開発中のアプリを開発者にしか閲覧できないように基本設定のところの一番最後にあるSandbox Modeを有効にしておきます。
これを有効にしておけば開発中のアプリケーションが他の人に見られる事はありません。

長くなりそうなので、一旦ここまでにします。