サンシャイン牧場用のミクシーアプリを作ってみた
最近、ミクシーのサンシャイン牧場ってゲームにハマっているんですが、その補助ツールを作りたくなり、ミクシーアプリの作り方を勉強してみたので、その記録をメモ。あれこれ検索したところ、以下の手順で作れました。
3ステップで出来るミクシーアプリ
1.ここでデベロッパー登録する。
2.レンタルサーバーに以下のようなファイルを test.xml などにしてアップロードする。
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="任意のタイトル"> <Require feature="opensocial-0.8" /> </ModulePrefs> <Content type="html"> <![CDATA[ hello world!!!(←ココの部分が表示されます) ]]> </Content> </Module>
3.ここからアプリ登録して、こんな感じで↓URLを開いて、「hello world!!!」って出ればオッケーです。
http://mixi.jp/run_appli.pl?id=(あなたのアプリケーションID)&nocache=1
お手軽ですね!!ちなみに自分が作ったサンシャイン牧場用ミクシーアプリはココから登録できます。どうぞご利用ください。
で、作ったものとか
以下にソースコードを公開しときます。Javascript の書き方よくわかってなくて汚いと思いますが、ご了承ください。
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="サン牧成熟シミュレーター"> <Require feature="opensocial-0.8"/> </ModulePrefs> <Content type="html"> <![CDATA[ <style type="text/css"> table.sunboku{ border-top:1px solid #663300; border-left:1px solid #663300; border-collapse:collapse; border-spacing:0; background-color:#ffffff; empty-cells:show; } .sunboku th{ border-right:1px solid #663300; border-bottom:1px solid #663300; color:#330000; background-color:#996633; background-image:url(http://rocky.sakura.ne.jp/mixiapp/table-back.gif); background-position:left top; padding:0.3em 1em; text-align:center; } .sunboku td{ font-size: small; text-align: center; border-right:1px solid #663300; border-bottom:1px solid #663300; padding:0.3em 1em; line-height: 1; } </style> <script type="text/javascript"> // サンシャイン牧場成熟時間ハッシュデータ var hashSunboku = { 'ニンジン': [0.75,0,0], 'かぼちゃ': [7.50,0,0], 'トウモロコシ': [9.00,0,0], 'トマト': [10.50,0,0], 'ナス': [13.00,0,0], 'りんご': [15.50,24.93,0], 'メロン': [17.00,0,0], 'いちご': [24.50,35.53,46.56], 'ブドウ': [27.00,39.15,0], '金糸瓜': [29.00,42.05,55.1], '豌豆': [32.50,47.13,0], 'マンゴ': [33.50,48.58,63.66], 'クワの実': [44.50,64.53,0], 'レモン': [45.50,65.97,86.44], 'レイシ': [46.00,66.7,0], 'メキシコシティー': [47.00,68.15,89.3], 'パラミツ': [48.00,69.6,0], '柿': [49.00,71.05,93.1], 'ハエトリ草': [50.50,73.23,0], '桃': [51.00,73.95,96.9], 'バナナ': [52.00,75.4,0], 'サクランボ': [54.00,78.3,102.6], '蜜柑': [64.00,92.8,0], 'リュウガン': [65.00,94.25,123.5], '紅ナツメ': [66.00,95.7,0], 'シュガーケーン': [67.00,97.15,127.3], 'タンポポ': [50.00,0,0], 'センノウ': [51.00,0,0], 'カラタネオガタマ': [52.00,84.65,0], 'ザクロ': [53.00,86.25,0], 'ハリエンジュ': [54.00,86.94,119.88], '金盞花': [56.00,90.16,124.32], '金魚草': [58.00,93.38,128.76], 'バイオレット': [22.00,0,0], 'ユリ': [20.23,0,0] }; var n = 10; // // n時間後の日付時刻を求める // // 日付型と加算時間からn時間後の日付を求める関数 // date 日付型 // addDays 加算日。マイナス指定でn日前も設定可能 // function calcDate(date, addHours) { var dt = new Date(); dt.setTime(date); var baseSec = dt.getTime(); var addSec = addHours * 3600000; //時間数 * 時間のミリ秒数 var targetSec = baseSec + addSec; dt.setTime(targetSec); return dt; } // Date型を YYYY/mm/dd HH:MM:SS の文字列にする関数 function formatDate(date) { var dt = date.getFullYear() + "/" + zeroUme(date.getMonth() + 1) + "/" + zeroUme(date.getDate()) + " " + zeroUme(date.getHours()) + ":" + zeroUme(date.getMinutes()) + ":" + zeroUme(date.getSeconds()); return dt; } // 二桁の数値をゼロ埋めで文字列化する関数 function zeroUme(num) { var len = 2; var sa = len - (num+"").length; var add0 = ""; if (sa > 0) for (var i=0; i<sa; i++ ) {add0 += "0"; } return (add0 + num); } // 作物成熟時間の表示 function dispRipenessTime(id, name, time) { if (name == "") { return 0; } // 作物の名前から成熟時間を得る // var key = document.getElementById(id).innerHTML; var ts = hashSunboku[name]; // 文字列をパースして日付を得る time = Date.parse(time); var date = new Date(); date.setTime(time); var count = 1; for (var i=0; i < ts.length; i++) { var t = ts[i]; count += 1; if (t == 0) { document.getElementById(id+"time"+count).innerHTML = "-"; } else { var dt = calcDate(date, t); document.getElementById(id+"time"+count).innerHTML = formatDate(dt); } } } // 「植えた」ボタンの処理 function plant(id) { var now = new Date; var obj = document.getElementsByName(id+"combo")[0]; var idx = obj.selectedIndex; var name = obj.getElementsByTagName("OPTION")[idx].firstChild.nodeValue; document.getElementById(id).innerHTML = name; document.getElementById(id+"time1").innerHTML = formatDate(now); dispRipenessTime(id, name, formatDate(now)); // 成熟時間の表示 buttonToggle(id, true); //「植えた」ボタンを非表示 savePlant(id); // 保存 } // ボタン、セレクトボックスの表示・非表示処理 function buttonToggle(id, flag) { var obj = document.getElementsByName(id+"combo")[0]; obj.style.display = (flag==true)? "none" : "inline"; document.getElementById(id+"btn1").style.display = (flag==true)? "none" : "inline"; document.getElementById(id+"btn2").style.display = (flag==true)? "inline" : "none"; } // 保存処理 function savePlant(id) { // 作物の名前を得る var name = document.getElementById(id).innerHTML; name = escape(name); // 日付を得る var time = document.getElementById(id+"time1").innerHTML; time = escape(time); var req = opensocial.newDataRequest(); req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, id, name)); req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, id+"time1", time)); req.send(function(response) { if (response.hadError()) { alert(response.getErrorMessage()); } else { debugprint("保存しました"+id); } }); } // 「収穫」ボタンの処理 function reset(id) { document.getElementById(id).innerHTML = ""; document.getElementById(id+"time1").innerHTML = ""; document.getElementById(id+"time2").innerHTML = ""; document.getElementById(id+"time3").innerHTML = ""; document.getElementById(id+"time4").innerHTML = ""; buttonToggle(id, false); // 収穫ボタンを非表示 savePlant(id); // 保存 } // 保存した作物名・時刻を取得して表示する function loadData() { var req = opensocial.newDataRequest(); var fields = new Array(); for (var i=0; i < n; i++ ) { fields[i*2] = "plant" + (i+1); fields[i*2+1] = "plant" + (i+1) + "time1"; } req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "viewer"); req.add(req.newFetchPersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, fields), "viewer_data"); req.send(function(response) { if (response.hadError()) { alert(response.getErrorMessage()); } else { var myId = response.get("viewer").getData().getId(); var data = response.get("viewer_data").getData(); for (var i=0; i<n; i++) { var name = unescape(data[myId][fields[i*2]]); var time = unescape(data[myId][fields[i*2+1]]); if (name != "undefined" && name !="") { document.getElementById(fields[i*2]).innerHTML = name; document.getElementById(fields[i*2+1]).innerHTML = time; dispRipenessTime(fields[i*2], name, time); buttonToggle(fields[i*2], true); } else { buttonToggle(fields[i*2], false); } } } }); } function createTable() { var str = ''; for (var i=1; i < n+1; i++) { str += '<tbody>'; str += '<tr>'; str += '<td align="right">' + i + '</td>'; str += '<td><div id="plant' + i + '"></div></td>'; str += '<td><div id="plant' + i + 'time1"></div></td>'; str += '<td><div id="plant' + i + 'time2"></div></td>'; str += '<td><div id="plant' + i + 'time3"></div></td>'; str += '<td><div id="plant' + i + 'time4"></div></td>'; str += '<td><select name="plant' + i + 'combo">'; for (var key in hashSunboku) { str += '<option value="' + hashSunboku[key] + '">' + key + '</option>'; } str += '</select><button id="plant'+i+'btn1" onclick="plant(\'plant' + i + '\')">植えた!</button>'+ '<button id="plant'+i+'btn2" onclick="reset(\'plant' + i + '\')">収穫</button></td>'; str += '</tr>'; str += '</tbody>'; } document.write(str); } </script> <body onload="loadData()"> <table class="sunboku"> <tr><th>No.</th><th>種類</th><th>植えた日時</th><th>成熟日時</th><th>二期日時</th><th>三期日時</th><th>操作</th></tr> <script language="javascript" type="text/javascript">createTable();</script> </table> 成熟時間データは、<a href="http://spreadsheets.google.com/pub?key=t8nRmfi-RMX7pCrdMDeKYSw&gid=0">こちら</a>のものを利用させてもらっています。サンクス! </body> ]]> </Content> </Module>
ハマッたこと
ミクシーアプリじゃなくて、javascript の話ですけど、IE で document.write 等を用いて、テーブルを動的に作成する場合、TBODY タグを入れないと表示されなくてハマりました。firefox だと問題ないんですけどね、、、。