今回の目的

 シンプルな記憶実験(単語自由再生)を作成することを目的とします。具体的には,単語をランダムな順に呈示し,その後,自由再生を行ってもらうというものです。自由再生は配布した回答用紙に行ってもらうこととします。

デモ

 完成版を以下のURLからお試しいただけます。なお,データ保存はできません。

 memoryExperimentDemo

1. アウトライン

 最初に実験のアウトラインを考えてから,コードを書くことが重要です。特に複雑な実験を作成する場合は,アウトラインを十分に練ることが重要です。

1-1. 今回のアウトライン

 実験は以下のようなブロックを順番に実施することにしました。

  1. 「ようこそ」画面
  2. 学習段階
    • 「注視点→単語」という試行を複数回,繰り返す
  3. 自由再生段階
    • 1分間,覚えた単語を回答用紙(これは物理的な紙を用意します)に書いてもらう画面を呈示
  4. 「終わり」画面

1-2. 必要なパーツ(試行)

 アウトラインを元に,各段階にどのようなパーツ(試行)が必要かを考えます。以下のパーツが必要です。パーツをどのように組み合わせるかは,作成しながら考えることにします。

  1. 「ようこそ」画面
  2. 注視点
  3. 単語
  4. 自由再生(1分間)
  5. 「終わり」画面

2. セットアップ

 今回の実験では,単語を日本語で呈示しますが,jspsychはデフォルトのままだと,日本語が表記されない部分があるため,スタイルシートとプラグインを修正したものを用意しています。以下のmyPlugins.zipをダウンロードし,解凍してください。

http://mklab.info/wp-content/uploads/2020/01/myPlugins.zip

 また,jspsychを以下の公式サイトからダウンロードしてください。執筆時点の最新版(jspysch-6-2)で進行していきますが,適宜,最新版を用いてください。

https://www.jspsych.org/

 つづいて,実験のファイルを入れるためにmemoryExperimentというフォルダを任意の場所に作成してください。このフォルダにjspsych本体のフォルダとmyPluginsフォルダを入れてください。以下のような構成になります。

memoryExperiment
├ jspsych-6-2
└ myPlugins

 次に,エディター(atom,sublimetext,メモ帳など)を立ち上げてください。最初に,jsPsychの基本構造を記述したファイルを作成します。以下のコードをコピーして貼り付けてください。このファイルにindex.htmlという名前をつけてmemoryExperimentフォルダに保存してください。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

  </script>
  <!--ここまで-->
</body>
</html>

現在のmemoryExperimentフォルダは以下のようになります。

memoryExperiment
├ jspsych-6-2
├ myPlugins
└ index.html

実験のコードは,<!--実験-->と書かれた部分に書いていきます。

2-1. myPluginsについて

 myPluginsについて,少しだけ説明します(jspsychにて細かい設定を行いたい場合は,プラグインやスタイルシートの修正が必須なため,詳しくは別ページで紹介予定です)。myPluginsの中には,自作のスタイルシート(jspscyh_mk.css)とフルスクリーン表示用のjspsych-fullscreen.jsを少し修正したjspsych-fullscreen-J.jsが入っています。
 まず,スタイルシート(css)の修正として,OS間で共通したフォントを呈示するため,webフォントであるNoto sans JPを指定するように変更しています。WindowsとMacでは共通するフォントがMSゴシックや游ゴシックしかないのですが,游ゴシックはWindowsとMacではウエイトが異なるのでややこしいのです。
また,フォントサイズについても,フォントサイズを絶対指定(例えば,16px)にしてしまうと,ディスプレイサイズや画面解像度によって,文字の大きさが著しく異なってしまい,レイアウトが崩れる場合があります。そこで,デフォルトのフォントサイズに,縦の画面解像度の割合を基準とした相対指定であるvhを用いています。もちろん,vhを用いても環境間の差をなくすことはできませんが,画面に占める文字の大きさは統一することができます,同一のディスプレイ環境を構築できる場合には,フォントサイズは絶対指定した方が論文などでは理解してもらいやすいかもしれません。
 これだけフォントを気にするのは,フォントの種類やフォントの大きさといった要素は,単語の情報処理に影響する可能性があるためです。例えばフォントサイズが単語の記憶成績に影響すること(Halmamish, 2018)や可読性の低いフォントの方が処理水準が高く,単語の記憶成績がよいこと(Diemand-Yauman et al., 2011)が知られています。
 もう1つのjspsych-fullscreen-J.jsについてですが,jspsychでフルスクリーン表示を行うためには「許可」が必要となります。そのためにjspsych-fullscreen.jsというライブラリが用意されていますが,このライブラリでは許可を求める文章が英語で表示されます。そこで,日本語でフルスクリーンの許可を問う文章を表示するようにしたものが,jspsych-fullscreen-J.jsです。なお,jspsychによる実験では,基本的には,他の情報からの妨害を防ぐため,フルスクリーンでの実験実施を推奨します。

3. 実験の作成

 それでは,これから,単語の記憶実験プログラムを作成していきましょう。最小限の構成(ようこそ画面のみ)を作成した後に,徐々に他の段階を追加していきましょう。

3-1. ようこそ画面の作成

 まず,実験起動後に表示する「ようこそ」画面を作成しましょう。先ほど作成したindex.htmlをエディターで開いてください。そして,<script type=text/javascript>の下に,以下のコードを書いてみましょう。

//ようこそ画面
var welcome = {
  type: "html-keyboard-response",
  stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
  '<p>表示された単語を覚えていってください。</p>'+
 '<p>後ほど,記憶テストを行います。</p>'+
  '<p>記憶テストに回答できるよう,覚えてください。</p>'+
  '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>'
};

 jspsychでは,各変数(var XXXX)に対して,どのような変数かをtypeで指定し,stimulusで刺激を指定することで,1つの試行やブロック(1つの要素と呼ぶべきかもしれません)を作成していきます。
 今回は,welcomeという名前で,html-keyboard-responseという,キーボード入力を前提とした種類の試行を作成し,そこで呈示する文字をstimulusに記述しています。つまり,このwelcomeという変数は,キーボード入力を受け付ける試行で,かつ,画面にようこそメッセージを刺激として呈示するものになっています。
 このように,jspsychでの実験の作成は,まず試行や刺激を定義する変数を作っていきます(パーツ)。つづいて,どのような順番でこれらの試行を構成するのかを定義します(パーツを組立ていく)。それが//実験を構成からの部分にあたります。
 各パーツを作成する度に組み立てる(timeline.push)することもできますが,パーツの部分と組立ての部分の区別しにくくなり,組立てミス(実験の構成ミス)が生じやすくなります。したがって,パーツごとに作成し,最後に実験を構成する方法を推奨します。

 それでは,実験の構成をしていきましょう。jspsychでは,timelineという実験の流れを表す変数を作成し,timelineに各試行や各ブロックを追加(push)していくことで,実験を構成します。最初にvar timeline = []として,空のtimelineを作成します。つづいて,各段階を追加してきます(今回はようこそ画面1つだけです)。timelineへの追加は,timeline.push(要素名)で可能です。ここでは,ようこそ画面を追加するので,timeline.push(welcome);と記述します。
 そして,最後にjspsychを開始する記述(jsPsych.init以下)を書けば,ようこそ画面を呈示する実験の完成です。なお,このjsPsych.init以下は必ず書かなければならないので,注意してください。

//ようこそ画面
var welcome = {
  type: "html-keyboard-response",
  stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
  '<p>表示された単語を覚えていってください。</p>'+
 '<p>後ほど,記憶テストを行います。</p>'+
  '<p>記憶テストに回答できるよう,覚えてください。</p>'+
  '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>'
};

//実験を構成
var timeline = [];

//各段階を追加
timeline.push(welcome);

//実験開始
jsPsych.init({
  timeline: timeline,
});

 時折でてくる//の部分は,コメントといい,コードとして実行しない部分です。コメントとして,その後に実行する処理の目的や位置づけを記述しておくと,後で見直す時や他の人と共有する際にコードの可読性が高くなります。一手間ですが,できるだけコメントを書いておきましょう。
 また,変数名や関数名をその目的に合った名前にするということもコードの可読性を高める上では重要です。例えば,今回は「ようこそ画面」を格納する変数名をwelcomeにしていますが,もし,これがxという名前にしたとすると,この変数がどのような役割が伝わりません。そのため,変数の位置づけがわかりにくく,混乱を生む原因となってしまいます。

3-1-2.ここまでのまとめ

 ここまでで以下のようなindex.htmlが作成できたはずです。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>',
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>

 ここで一度,index.htmlを保存し,ブラウザで開いてみましょう。どうでしょうか?ようこそ画面は表示されましたか?ようこそ画面は,いずれかのキーを押すと終了するようになっています。

3-1-3. 文字の色や大きさの変更

 さて,次に取り組むのは,文字の色や大きさの変更です。現在,ようこそ画面のメッセージは黒色で表示されていますが,実験に参加してくださった方への感謝を示すため,赤色で表示したい場合を考えます。ここで用いているtypehtml-keyboard-responseというものです。これはHTMLを表示し,キーボード入力を受け付けるという変数になっています。HTMLとはウェブページの表示に使われる言語です。ようこそメッセージはHTMLによって表示されているため,HTMLを装飾するスタイルシート(css)によって,色などの変更が可能です。以下のように記述することで書かれた文字のデザインを変更できます。

//ようこそ画面
var welcome = {
  type: "html-keyboard-response",
  stimulus: '<div style = "color: tomato;"><p>これから,様々な単語が5秒間,表示されます。</p>'+
  '<p>表示された単語を覚えていってください。</p>'+
 '<p>後ほど,記憶テストを行います。</p>'+
  '<p>記憶テストに回答できるよう,覚えてください。</p>'+
  '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p></div>',
};

 ここでは,<div style = "color: tomato">と記述し,文字の色をtomato(赤)に変更しています。スタイルシートの記法については,今回の目的を超えるので詳細な説明は割愛しますが,このように,文字の色の変更などはスタイルシートで行う必要があります。ストループ課題など,色の変更が必要な課題ではスタイルシートの理解がポイントになります。なお,今回は文字の色は操作する必要はないので,黒色のまま進みます。

3-2. 学習段階の作成

3-2-1. 注視点の作成

 次に,様々な実験で用いられる基本的な刺激である注視点を呈示する試行を作成します。ようこそ画面と同じように,html-keyboard-responseというtypeの変数を作成し,刺激に「+」を指定すれば,注視点を表示することができます。ここでは,注視点を大きめに呈示したいのでフォントサイズに4vhを指定しています。

var showFixation = {
  type: "html-keyboard-response",
  stimulus: '<div style = "font-size: 4vh">+</div>
};

 一般的に,注視点は1秒前後の時間は呈示するので,この試行の持続時間をtrial_durationに記述します。ここでは,1秒(1000ms)を呈示するように記述します。なお,ここでの単位はミリ秒(msec)なので注意してください。

var showFixation = {
  type: "html-keyboard-response",
  stimulus: '<div style = "font-size: 4vh">+</div>,
  trial_duration: 1000
};

 これで注視点を呈示できますが,実は,このままでは,1秒が経つためになんらかのキーが入力されると試行が終了してしまいます。html-keyboard-responseはデフォルトでこの設定になっています。そこで,キー入力では次に進まないようにchoices: jsPsych.NO_KEYSを書き加えましょう。これで,設定した時間の長さで呈示後,次に進むようになります。
 いま記述したchoicesは,試行の反応を設定するパラメータになっていますが,ここでは,「反応キーなし」を表すjsPsych.NO_KEYSを指定しています。

var showFixation = {
  type: "html-keyboard-response",
  stimulus: '<div style = "font-size: 4vh">+</div>',
  trial_duration: 1000,
  choices: jsPsych.NO_KEYS
};

 これで,注視点を呈示する試行の完成です。最後に,この試行が終わった後に少しブランク画面を表示するようにしておきましょう(刺激が間隔を経ずに連続して呈示されると,見にくい場合があるためです)。いわゆる試行間間隔であるInter Trial Interval(ITI)を設けるというわけです(注視点は刺激と捉えれば刺激間間隔ですが)。
 jspsychではpost_trial_gapに時間を指定することで,試行終了後にブランク画面を表示できます。ここでは,0.5秒(500ms)を設定してみます(注:注視点が消失すると注視点への注意が解放されてしまうので,実際にはあまり注視点の後にはブランクは設けないかもしれません)。

var showFixation = {
  type: "html-keyboard-response",
  stimulus: '<div style = "font-size: 4vh">+</div>',
  trial_duration: 1000,
  choices: jsPsych.NO_KEYS,
  post_trial_gap: 500
};

 つづいて,作成した注視点をタイムラインに追加しましょう。timeline.push(showFixation)を実験の構成に追加します。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '本実験にご参加いただき,ありがとうございます。',
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(fixation);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>
3-2-2. 単語の呈示

 注視点につづいて,実験のメインとなる学習単語を呈示する試行を作成しましょう。ここでも,html-keyboard-responseを用いて,単語を呈示する試行を作ります。「リンゴ」という単語を5秒間呈示し,覚えてもらう試行を作ります。注視点のように,呈示時間を5秒(trial_duration: 5000),キーによる反応なし(choices: jsPsych.NO_KEYS)を指定しておきます。

var showLearningWord = {
  type: "html-keyboard-response",
  stimulus: '<div style = "font-size: 4vh;">リンゴ</div>',
  trial_duration: 5000,
  choices: jsPsych.NO_KEYS,
  post_trial_gap: 500
}

 そして,単語を呈示する試行もtimelineに追加(timeline.push(showLearningWord))します。ここまでのindex.htmlは,以下のようになります。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>',
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //単語を呈示
    var showLearningWord = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh;">リンゴ</div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    }

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(showFixation);
    timeline.push(showLearningWord);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>
3-2-3. 注視点と単語をまとめた試行を作成

 さて,ここまでで注視点と単語呈示という2つのパーツを作成できました。現状では,注視点と単語呈示は独立していますが,実験において,「注視点→単語」を1つの試行としてまとめる必要があります。そこで,「注視点→単語呈示」という順で2つの試行を格納する変数を新たに作成します。ここでは,learningPhaseという名前の変数で,2つの試行を格納します。timeline: [x,y,...]として,各試行の意図した順番通りに(x,y, …)記述していきます。
 このような入れ子構造は,少しわかりにくいかもしれません。イメージ的には,ご飯(showFixation)と鮭(showLearningWord)をおにぎり(learningPhase)としてまとめるという感じです。つまり,構造としては,以下のようになります。

learningPhase
├ showFixation
└ showLearningWord

var learningPhase = {
  timeline: [showFixation, showLearningWord]
};

 そして,先ほどのtimeline.push(showFixation)の変わりにこのlearningPhaseを追加します。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>',
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //単語呈示
    var showLearningWord = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh;">リンゴ</div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    }

    //注視点と単語呈示からなる学習段階を作成
    var learningPhase = {
      timeline: [showFixation, showLearningWord]
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(learningPhase);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>

 ここまでの構造をまとめると,以下のようになります。

timeline
├ welcome
└learningPhase
    ├ showFixation
    └ showLearningWord

 では一度,index.htmlを保存し,ブラウザで開いて,テストしてみましょう。

3-2-4. 複数の単語の呈示

 ここまでの作業で,注視点の後に単語を呈示するという学習段階が作成できました。しかし,このままでは,1つの単語だけを覚える学習段階です。つづいて,より多くの単語を呈示するように修正しましょう。
 まず,呈示したい複数の単語から構成される単語リストを作成します。具体的には,wordListという配列を作成し,その中に呈示する単語を格納していきます。wordListは配列なので,[]に中身を記述します。各単語は,{word: 'XXX'}としてwordという名前を与えてそれぞれ指定していきます。このword:という名前は後ほど重要になります。

var wordList = [
  {word: '<div style = "font-size: 4vh;">リンゴ</div>'},
  {word: '<div style = "font-size: 4vh;">ミカン</div>'},
  {word: '<div style = "font-size: 4vh;">キウイ</div>'},
  {word: '<div style = "font-size: 4vh;">イチゴ</div>'},
  {word: '<div style = "font-size: 4vh;">メロン</div>'}
];

 つづいて,単語を呈示するshowLearningWordstimulus:を以下のように修正します。この修正は,刺激に実験(timeline)の進行に従って変化するwordを刺激とすることを表しています。ここではstimulus: jsPsych.timelineVariable('word')と記述を変更します。

//単語呈示
var showLearningWord = {
  type: "html-keyboard-response",
  stimulus: jsPsych.timelineVariable("word"),
  trial_duration: 5000,
  choices: jsPsych.NO_KEYS,
  post_trial_gap: 500
};

 さらに,学習段階を格納した変数であるvar learningPhasetimeline_variables: wordListという記述を追加します。この記述は,実験(timeline)の進行に伴って(もしくはlearningPhaseが実行される度に)wordListという配列から刺激を取ってくるという意味になります。wordListには複数の単語が格納されているので,learningPhaseが実行される度に,単語が1つ選ばれるということになります。なお,特に指定しない場合は,学習段階は単語リストの単語数だけ,「注視点→単語呈示」を繰り返します。つまり,デフォルトでは各単語が1回ずつ呈示されるということです。

var learningPhase = {
  timeline: [showFixation, showLearningWord],
  timeline_variables: wordList
};

 ここまでのコードでは単語の呈示順(厳密にはlearningPhase実行時にwordListから選ばれる単語です)は,格納した順版になっています。すなわち,var wordListの上から順番に単語を呈示します。このままでは,順序効果の影響を除去できないため,単語の呈示順をランダムにするように修正します。jsPsychでは,randomize_order: trueとすることで,ランダムな順番に呈示することができます。なお,より複雑な呈示順(サンプリング方法)の指定は,sampleによって指定できます(今回は説明しません)。

var learningPhase = {
  timeline: [showFixation, showLearningWord],
  timeline_variables: wordList,
  randomize_order: true
};

 ここまでのコードをまとめると以下のようになります。一度,保存し,ブラウザで開いてみましょう。ようこそ画面の後に,単語が5回呈示されるはずです。何回か実行してみて,実行する度に単語の呈示順が異なることを確認してください。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>'
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //単語リスト
    var wordList = [
      {word: '<div style = "font-size: 4vh;">リンゴ</div>'},
      {word: '<div style = "font-size: 4vh;">ミカン</div>'},
      {word: '<div style = "font-size: 4vh;">キウイ</div>'},
      {word: '<div style = "font-size: 4vh;">イチゴ</div>'},
      {word: '<div style = "font-size: 4vh;">メロン</div>'}
    ];

    //単語を呈示
    var showLearningWord = {
      type: "html-keyboard-response",
      stimulus: jsPsych.timelineVariable('word'),
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //注視点と単語呈示からなる学習段階を作成
    var learningPhase = {
      timeline: [showFixation, showLearningWord],
      timeline_variables: wordList,
      randomize_order: true
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(learningPhase);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>

3-3. テスト段階の作成

 単語を学習する段階を作成できたので,次に自由再生を行うテスト段階を作成します。テスト段階は,自由再生の教示文を60秒呈示した後,終了文を呈示するだけで完成です(今回は回答用紙に回答してもらうことを想定しているためです)。学習段階に比べると,易しいコードになるので,説明は割愛し,コードだけを以下に示します。

//自由再生開始
var startFreeRecall = {
  type: 'html-keyboard-response',
  stimulus: '<p>先ほど覚えた単語を思い出し,回答用紙に記入してください。</p>'+
  '<p><br>60秒が経過したら,この画面が切り替わりますので,回答をやめてください。</p>',
  trial_duration: 60000,
  choices: jsPsych.NO_KEYS
};

var stopFreeRecall = {
  type: 'html-keyboard-response',
  stimulus: '<div style = "color: tomato; font-size:4vh;"><p>回答をやめてください。</p></div>',
  trial_duration: 5000,
  choices: jsPsych.NO_KEYS
};

//テスト段階を構成
var testPhase = {
  timeline: [startFreeRecall, stopFreeRecall]
};

3-5. デブリーフィング画面の作成

 いよいよ,最後の段階の作成です。実験終了となるデブリーフィング場面を作成します(この例はデブリーフィングというには無情報すぎますが,この後に口頭で伝えるということで…)。

//デブリーフィング
var debriefPhase = {
  type: 'html-keyboard-response',
  stimulus: '<div style = "color: tomato; font-size:4vh;"><p>これで実験終了です。ありがとうございました!</p></div>',
  trial_duration: 5000,
  choices: jsPsych.NO_KEYS
};

3-6. 実験の構成

 ここまでで作成していたindex.htmlにテスト段階とデブリーフィング段階を追加すると実験の完成です。構造は以下のようになります。

timeline
├ welcome
├ learningPhase
│   ├ showFixation
│   └ showLearningWord
├ testPhase
└ debriefPhase

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>'
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //単語リスト
    var wordList = [
      {word: '<div style = "font-size: 4vh;">リンゴ</div>'},
      {word: '<div style = "font-size: 4vh;">ミカン</div>'},
      {word: '<div style = "font-size: 4vh;">キウイ</div>'},
      {word: '<div style = "font-size: 4vh;">イチゴ</div>'},
      {word: '<div style = "font-size: 4vh;">メロン</div>'},
    ];

    //単語を呈示
    var showLearningWord = {
      type: "html-keyboard-response",
      stimulus: jsPsych.timelineVarialbe('word'),
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    }

    //注視点と単語呈示からなる学習段階を作成
    var learningPhase = {
      timeline: [showFixation, showLearningWord],
      timeline_variables: wordList,
      randomize_order: true
    };

    //自由再生開始
    var startFreeRecall = {
      type: 'html-keyboard-response',
      stimulus: '<p>先ほど覚えた単語を思い出し,回答用紙に記入してください。</p>'+
      '<p><br>60秒が経過したら,この画面が切り替わりますので,回答をやめてください。</p>',
      trial_duration: 60000,
      choices: jsPsych.NO_KEYS
    };

    //自由再生終わり
    var stopFreeRecall = {
      type: 'html-keyboard-response',
      stimulus: '<div style = "color: tomato; font-size:4vh;"><p>回答をやめてください。</p></div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS
    };

    //テスト段階を構成
    var testPhase = {
      timeline: [startFreeRecall, stopFreeRecall]
    };

    //デブリーフィング
    var debriefPhase = {
      type: 'html-keyboard-response',
      stimulus: '<div style = "color: tomato; font-size:4vh;"><p>これで実験終了です。ありがとうございました!</p></div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(learningPhase);
    timeline.push(testPhase);
    timeline.push(debriefPhase);

    //実験開始
    jsPsych.init({
      timeline: timeline,
    });

  </script>
  <!--ここまで-->
</body>
</html>

3-7. データの保存

 今回の実験で呈示順を保存したい場合は,データを保存する記述を追加します。ここでは,ローカル(実施しているパソコン本体)に保存してみます。実験が終了した時(on_finish),データをcsvとして保存するというコードを記述します。なお,この保存方法は対面実験向けのもので,オンライン実験では推奨しません。
jsPsych.data.get().localSave('csv', 'mydata.csv');を実験終了後に実行することで,データを保存するプロンプトが表示され,データをcsv形式で任意の場所に保存できます。

//実験開始
jsPsych.init({
  timeline: timeline,
  on_finish: function()
    {
      jsPsych.data.get().localSave('csv','memoryExpriment.csv');
    }
});

3-8. 完成版

 最終的なコードは以下のようになります。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="generator" content="pandoc" />
  <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="MK lab" />
  <title>Memory experiment</title>
  <link href="myPlugins/jspsych_mk.css" rel="stylesheet" type="text/css">
</head>

<body>
  <!-- 必要なプラグイン -->
  <script src="jspsych-6-2/jspsych.js"></script>
  <script src="jspsych-6-2/plugins/jspsych-html-keyboard-response.js"></script>
  <script src="myPlugins/jspsych-fullscreen-J.js"></script>
  <!-- ここまで -->  

  <!-- 実験-->
  <script type="text/javascript">

    //ようこそ画面
    var welcome = {
      type: "html-keyboard-response",
      stimulus: '<p>これから,様々な単語が5秒間,表示されます。</p>'+
      '<p>表示された単語を覚えていってください。</p>'+
     '<p>後ほど,記憶テストを行います。</p>'+
      '<p>記憶テストに回答できるよう,覚えてください。</p>'+
      '<p><br>準備ができたら,スペースキーを押してください。実験がはじまります。</p>'
    };

    //注視点
    var showFixation = {
      type: "html-keyboard-response",
      stimulus: '<div style = "font-size: 4vh">+</div>',
      trial_duration: 1000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    };

    //単語リスト
    var wordList = [
      {word: '<div style = "font-size: 4vh;">リンゴ</div>'},
      {word: '<div style = "font-size: 4vh;">ミカン</div>'},
      {word: '<div style = "font-size: 4vh;">キウイ</div>'},
      {word: '<div style = "font-size: 4vh;">イチゴ</div>'},
      {word: '<div style = "font-size: 4vh;">メロン</div>'},
    ];

    //単語を呈示
    var showLearningWord = {
      type: "html-keyboard-response",
      stimulus: jsPsych.timelineVarialbe('word'),
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS,
      post_trial_gap: 500
    }

    //注視点と単語呈示からなる学習段階を作成
    var learningPhase = {
      timeline: [showFixation, showLearningWord],
      timeline_variables: wordList,
      randomize_order: true
    };

    //自由再生開始
    var startFreeRecall = {
      type: 'html-keyboard-response',
      stimulus: '<p>先ほど覚えた単語を思い出し,回答用紙に記入してください。</p>'+
      '<p><br>60秒が経過したら,この画面が切り替わりますので,回答をやめてください。</p>',
      trial_duration: 60000,
      choices: jsPsych.NO_KEYS
    };

    //自由再生終わり
    var stopFreeRecall = {
      type: 'html-keyboard-response',
      stimulus: '<div style = "color: tomato; font-size:4vh;"><p>回答をやめてください。</p></div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS
    };

    //テスト段階を構成
    var testPhase = {
      timeline: [startFreeRecall, stopFreeRecall]
    };

    //デブリーフィング
    var debriefPhase = {
      type: 'html-keyboard-response',
      stimulus: '<div style = "color: tomato; font-size:4vh;"><p>これで実験終了です。ありがとうございました!</p></div>',
      trial_duration: 5000,
      choices: jsPsych.NO_KEYS
    };

    //実験を構成
    var timeline = [];

    //各段階を追加
    timeline.push(welcome);
    timeline.push(learningPhase);
    timeline.push(testPhase);
    timeline.push(debriefPhase);

    //実験開始
    jsPsych.init({
      timeline: timeline,
      on_finish: function()
        {
          jsPsych.data.get().localSave('csv','memoryExpriment.csv');
        }
    });

  </script>
  <!--ここまで-->
</body>
</html>

4. うまく動かない場合の対処方法

 コードが正確に書かれているかを確認してください。多いミスは,"",’’,;といった記号の記述抜けです。chromeで実施した場合には,右クリックの「検証」を押すと,どこでエラーが生じているかが表示されます。

5. 演習課題

  1. 注視点の長さを1000msから500msに変更してみよう
  2. 学習単語を果物から動物(ゴリラ,キリン,コアラ,イルカ,タヌキ)に変更してみよう