「プログラミングお作法」カテゴリーアーカイブ

プログラミングしないでFPS風

UnityのAssetStoreにあるPlaymakerを使って「プログラミングしないでゲーム風のものを作る」その第2弾です。

その前に、、いつものお約束。プログラミングはできるにこしたことがありませんよ〜!数学もね!

さてUnityで超簡単なFPSの骨格を作ってみましょう。

FPSは映像業界にいるとFrame Per Second(1秒あたりのフレーム数)ですが,ゲームの世界でがFirst Person Shooting(一人称視点でのシューティング)のこと.

つまり

  • 一人称視点
  • 撃てる

が要件ですよね.

ということで,ボウリング的な物は5分くらいで作れます.

以下画像はリアルタイム時間で再生されます.

最初に板を置いたり,ピンを並べます。登場するピンにはPhysics(物理演算)を入れて10kgに設定しています.

そしてここからPlaymakerです。(1)カメラにMouseLook2をいれてマウスの方向をカメラが向くようにします.これで一人称視点完了.カメラがマウスの方向を動くようになります。

同じくカメラに別のPlaymakerを入れ,(2)マウスのボタンが上がったら,(3)弾を作成します.

作成した弾を変数に格納しますが,プルダウンメニューから変数が作成できます.これば便利.

そして(3)変数に格納された弾にローカルZ軸に90の加速度を入れボールを射出します.弾には複製可能なPrefabという設定したものを使います.

(4)マウスを押したときの処理で最初に戻しておしまい.

これだけですね.

わずか4工程です。しかもクリックしてただけ、、、

この程度であれば作るのは簡単です.

しかし、作り込んでいくと作成した弾を消す処理や,倒れたピンをどうやって数えるかを考えなくてはなりません.

今回の条件では,ボールに関しては「-y座標になったら消す」でかまいません.ですが,これが山あり谷ありの地形だったらどうします?高さ1000にいて、マイナスになるまではかなり時間がかかります。

さらにはどうやってピンが倒れたって検出すればいいですか?床に接触したら検知?いいえ,ピンが置かれている時すでに接触してるので使えませんね.ピンの角度を検出?それも1つの手段ですね.

もう一つあるとすれは衝突検知エリアを少し上にずらすという方法でしょう.

では,どうやって他のピンではなく床に当たったって検知しますか?つまり単に衝突判定しただけではダメってこと。

こういうふるまいのルールをことをアルゴリズムって言います.

さてこの場合に限っては,タグというものを使います.味方のタグ敵のタグ建物などのタグなどがあります.

当たり判定の要素にタグを使い,味方のタグには当たり判定をしない(傷つけない)ということができるんですね.

こうしたことは比較的簡単に設定できます.でもプログラミングを学びながらアルゴリズムまで考えるのは本当に大変です.

プログラミングはできるだけ楽をしてむしろストーリーや,世界観キャラクタユーザの操作性をどうアルゴリズムに活かすかに時間をかけてみませんか.

だんだんとPlaymakerに慣れてきたら、実際にコードを書いてみましょう。次に何をすればいいのか、参考にできるプログラミングをどんなキーワードで検索すればいいのか自然とわかるようになっているはずです。

ネットワークタイムサーバから時刻もってくる

カウントダウンのアプリなのに,デバイス毎に時刻違うってダメじゃん.

ということで,NTP(ネットワークタイムサーバ)から時刻もってくるの.

NTPについては(ここ)みんなのスマホもこれ時間合ってるんだよ。

これ,コンソールに時刻差出します.(多分コンソールで出る数字はミリ秒)

<!DOCTYPE html>
<html>
<head>
<title>Time</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<!-- metaタグで スマホの挙動を制限している -->
</head>
<body>

<script type="text/javascript">


httpObj = new XMLHttpRequest();
httpObj.open("get", "https://ntp-a1.nict.go.jp/cgi-bin/json", true);
httpObj.onload = function(){

	var myData = JSON.parse(this.responseText);
	//var mySt = myData.st;
	var mySt = (myData.st * 1000) - Date.now();
	//var txt = "";
//	for (var i=0; i<myData.weather.length; i++){
//		txt = txt + myData.weather[i].description + "  " + myData.weather[i].main+"<br>" + "<img src=http://openweathermap.org/img/w/" + myData.weather[i].icon + ".png>";
//	}

	console.log(mySt);

}
httpObj.send(null);


</script>



</body>
</html>

で,現時刻との差分ですが

まず,コードの上の方の初期化あたりに

///ネットワーク時刻取得
var mySt;
httpObj = new XMLHttpRequest();
httpObj.open("get", "https://ntp-a1.nict.go.jp/cgi-bin/json", true);//NTPサーバに行って時間取得
httpObj.onload = function(){

	var myData = JSON.parse(this.responseText);//JSONで内容をmyDataに入れる
	mySt = (myData.st * 1000) - Date.now();//IDがstの数字をひっぱってくる.NTPの戻り値は小数点以下3桁まであるので,1000描けてUNIX時間に変更する.ほんでミリ秒の誤差を出す

}
httpObj.send(null);

いれておいて(2行目のvar myStがグルーバル変数になります)

そのあとの日付ほしいところで

var nowDate = new Date(Date.now() + mySt);//ネットワークタイムを利用して時差を埋める

で,日付入れてます.

カウントダウンなので毎回new Date();していますが,本当はこの時刻を100ミリ毎くらい引いていけばいいのですが,元のプログラムを大幅に変更するのがいやだったので,,

ブラウザにデータを保存できるwebstorageのサンプル

ここのサンプルを少し改造しています.

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset=utf-8>
<script>
//変数storageにlocalStorageを格納
var myData = localStorage;//たぶん”localstorage”というのは変えてはいけない

//myDataに保存する
function dataSave() {
  var myKey = document.getElementById("mykey").value;
  var myValue = document.getElementById("myvalue").value;
  myData.setItem(myKey, myValue);
  show_result();
}

//データを消去
function myclear() {
  myData.clear();
 show_result();
}

//保存されているデータをリスト表示する
function show_result() {
 var result = "";
  //保存されているデータの数だけループ
  for(var i=0; i<myData.length; i++){
    //i番目のキーを取得
  //  var k = myData.key(i);
    var calledData = myData.key(i);

    result += calledData + "は" + myData.getItem(calledData) + "です<br>";
  }
  //上のループで作成されたテキストを表示する
  document.getElementById("show_result").innerHTML = result;
}


  // 
  function removeStorage() {
    var key = document.getElementById("sakujoKey").value;
    myData.removeItem(key);
    key = "";
    show_result();
  }

</script>
<title>Web Storage サンプル</title>
</head>
<body onload="show_result();"><!-- ←ここで結果を自動表示させている-->
<p>
キー:<input id="mykey" type="text">
値:<input id="myvalue" type="text">
<input type="button" value="ストレージに保存" onClick="dataSave()">
</p>
<p>
<div id="show_result"></div>
<input type="button" value="ストレージをクリア" onClick="myclear()">

<input type="button" value="リスト表示" onClick="show_result()">
<br />
削除するキー:<input id="sakujoKey" type="text">
  <button id="button" onclick="removeStorage()">このキーを削除</button>
</p>
</body>
</html>

このデータは共有できるので,同じサーバ(で判別している)であれば別のページからでもこのデータをみられる.

そこで,書き込み用ページと,読み出しようページを分けて,普段は読み出し用ページ,特別な時に書き込みようページへ移動してデータを追加というのも可能です.

データはクリア以外にも,キーワードを指定して削除という方法があります.

「削除するキー」の横に削除したいキーワードを入れて,削除ボタンを押すと,そのキーと値が削除されます.

なお,同じキーの場合は,上書きされますので,日付などで固有化させてください.

例えば,「2014年11月電気代」という風に.

配列に入れているので並び替え可能かと思われますが(ソート)その場合は配列への書き込み方法を変更する必要があるかも.

ローカルファイルにデータ保存(実験)

Webアプリで入力を行わせる場合,通常はサーバ側に記録するのですが,それではデータベースが必要となります.

HTML5ではWeb Storageという機能があり,URLに紐付けてデータをブラウザ側に保存できるようです.ユーザの購買傾向を見てお奨め商品を出してくる通販サイトはこの技術を利用しているようです.

参考

このデータは何かの拍子に消える可能性もありますので,通販のお奨め商品といったレベルで重要な要素には使わない方がいいかもしれませんが,データベースを構築するよりは簡単そうです.

「保存するデータを見るのは自分だけ」「単に数値や文字といった軽いデータだけ」であればこの方法を使ってみてください.

つづく(できなかったら消す)

みんなで書き込むーを実現するには

「みんなで書き込む」を実現するには,データベースの構築あたりが必要かと.

PHPを使って,サーバ側に置いた○○.txtを書き換えるスクリプトをコントロールすれば良いかと.

そして,PHP,html,css,javascriptのファイルを組み合わせればできそうです.

ただphpの実行ができるサーバ環境を準備してください.

 

EXCELで配列のデータを作成その2

(その1はこちら

つづいて,ワードを開きペーストします.ペースト時には,指定形式でペーストし,テキスト形式を選択します.

paste1


ペーストされました.このままでは使えませんので,検索置換機能で全てカンマを入力します.

word1


編集の置換をクリックします

word2


置換語の文字列には半角のカンマ,上の検索する文字列フィールドをクリックしてカーソルを移動させ,特殊文字のプルダウンメニューを表示させます

word3


 

段落記号を選択

word4


 

全て置換をクリックします.

これで数字とカンマでできた配列用のデータが作成できました.

 

EXCELで配列のデータを作成その1

時刻表を全て分(0時0分起点)に変換し,配列に入れるデータを作成します.

まずEXCELに時と分を分けて,時刻表のデータをとりいそぎ1件入力します

結果の欄には全てを分に直す式を入力します.

kakezan


 

次に,時刻表を全て入力します

excel2


 

計算結果のセルの右下の黒四角をドラッグして下へ引き延ばします.

excel3

excel4

自動で計算結果が入力されます.

つづく

CSSの例

CSSの例です

今回はクラス名でcssを作成します

文字代入でかなりIDを多用します.このID指定と混乱を避けるためあえてクラスで指定します.

サンプルです.CSSはmycss.cssという名前で,HTMLと同じ階層に保存してください.HTMLの方は好きな名前でかまいません.

@charset "UTF-8";
/*
CSSのコメントの書き方
*/

.cat{/*クラス名の宣言*/
	background: #b3b3b3;/*背景色の設定*/
	border-radius: 10px 10px 10px 10px;/*角を丸める*/
	height: 100px;/*高さは100ピクセル*/
	margin: 40px;/*余白*/
	width: 80%;/*幅はピクセルでも全体に対しての割合でもOK*/
	text-align: center;/*文字の横方向をセンタリング*/
}/*catクラスここまで*/

つづいてHTMLです.

開く際はこのHTMLを開いてください.

<!DOCTYPE html>
<html>
<head>
<link href="mycss.css" rel="stylesheet" type="text/css">
<!-- CSSを読み込む-->

<title>CSSの使い方</title>
<meta charset="UTF-8">
</head>
<body>

<div>ここには表示されない</div>

<div class="cat">ここにはCSSが適用される</div>


</body>
</html>

次のように表示されます.

css

これを応用すると,動くボタンなどが作成できます

CSS デザイン

CSS アニメーション

で検索し,使えそうなクラスを探してみましょう.

ちなみにブロック要素とインライン要素で適用できないCSSもありますので注意を.

アニメーションなど一部機能のうちスマートホンでは,-webkit- を頭につけないと動かないものもあります.

PC版とスマホ版を共用したい場合は,併記しましょう.

配列の例5つ

配列の例を5つあげます

<!DOCTYPE html>
<html>
<head>

<title>外部ライブラリの使い方</title>
<meta charset="UTF-8">
</head>
<body>

<div id="hyouji"></div>
<!--idを探させる場合,探す前にそのID付きのタグを書いておくこと(この場合,下のdocumen.getElementの前ってこと)-->


<script type="text/javascript">

var animal = new Array("豊田市","梅坪","上豊田","浄水","三好ヶ丘","米野木","日進","赤池");//変数に配列を入れ込む.この配列を

//----(1)配列の長さを調べる
var kazu = animal.length;
console.log("長さ"+kazu);//webコンソールで確認
//「長さ8」と表示される

//----(2)配列を検索する(浄水駅が何番目か調べる)
var nanban = animal.indexOf("浄水");
console.log("浄水駅は" + nanban);//webコンソールで確認
//「浄水駅は3」と表示される 実際には4番目ですが,順番は0から始まっている3と表示


//---(3)配列の要素を指定(5番目の駅を表示させる)
var banme = animal[4];//0から始まるので5番目は4です
console.log(banme + "駅です");//webコンソールで確認
//「三好ヶ丘駅です」と表示される


//---(4)(3)の応用(変数eki番目の駅を表示する)
var eki = 5;
var banme = animal[eki];//0から始まるので5番目は4です
console.log(eki + "番目の駅は" + banme + "駅です");//webコンソールで確認
//「"5番目の駅は米野木駅です"」と表示される


//--(5)今17分で,次の電車の時間(22分)を検索する
var jikoku = new Array(10,15,22,29);//rinjiって変数に配列を入れ込む
var mytime = 17;//今の時間を仮に17分とする

function myKensaku(nowTime){
for (i = 0; i < jikoku.length; i++) {//jikokuの要素を1つずつ取り出す.最大値はjikokuの長さまで
   if(nowTime < jikoku[i]){//もしmytime(17分)より大きい要素が入ったら
   nextTram = jikoku[i];//nextTramはその要素ね
   return nextTram;//22がnextTramに入って戻る.returnは処理を止める
   }
   }
   }
mynext = myKensaku(mytime);//変数mynextには,myKensakuを実行した戻り値を入れなさい
var nokorijikan = mynext - mytime + "分残り";//残り時間を変数nokorijikanに入れる
document.getElementById("hyouji").innerHTML = nokorijikan;//ID hyoujiのあるタグを探して,umaを代入せよ.
//「5分残り」表示されます
//---ここまで

</script>


</body>
</html>

 

外部ライブラリを自作して使う

面倒くさい関数は外部ライブラリ化してシンプルにします.

tora.jsという外部ライブラリ(ファイル名はかならずtora.jsに)

function neko(){
var cat = 300;//変数catに300を入れる
return cat;//変数catを返す(返事するってこと)
}

このライブラリは次のhtmlから呼び出します

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="tora.js"></script>
<!-- ここで外部のJavaScriptライブラリを読み込む-->

<title>外部ライブラリの使い方</title>
<meta charset="UTF-8">
</head>
<body>

<div id="hyouji"></div>
<!--idを探させる場合,探す前にそのID付きのタグを書いておくこと(この場合,下のdocumen.getElementの前ってこと)-->


<script type="text/javascript">
var uma = neko();//JavaScriptライブラリを読み込んでおけば,関数(function neko())をいきなり呼び出せる.その結果を変数umaに入れる
document.getElementById("hyouji").innerHTML = uma;//ID hyoujiのあるタグを探して,umaを代入せよ.
</script>


</body>
</html>

tora.jsとこのhtmlファイルは同じ階層に置いてください.

tora.jsで変数に入れた300がhtmlから読み込めていますね.

面倒な処理は外部ライブラリ化すると,htmlの記述も減ってすっきりしますよ〜(整理にもなり,バグの場所も分かりやすくなります)