<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>ゲレゲレのブログ</title>
<link>https://ameblo.jp/gere2/</link>
<atom:link href="https://rssblog.ameba.jp/gere2/rss20.xml" rel="self" type="application/rss+xml" />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
<description>吉里吉里（ＴＪＳ２）でゲームを作る過程をロマンチックかつドラマチックにお届します！</description>
<language>ja</language>
<item>
<title>第9回　コリジョン判定！</title>
<description>
<![CDATA[ <p>ども、皆様お久しぶりでございます！</p><p>ゲレゲレです！</p><br><p>違いますって！全然飽きたとかじゃないですって！</p><p>ただちょっと本業の方が忙しくなってしまったのでちょっとお休みしていただけですってば！</p><br><p>…いやーホントに忙しかった。</p><p>堕天使エルギオスを倒して世界を救ったり、秘宝を78個集めて世界を救ったりね！</p><p>まったく。オレがいないと世界はすぐピンチに陥るからさぁ。</p><br><p>さて、では行きますか。</p><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><p>第９回です！</p><br><p>つーことで今回はコリジョン判定です。</p><p>コリジョン判定ってのはオブジェクト同士が接触したかどうかをチェックするってことです。</p><p>マリオが敵と接触すると一機死ぬ、とか</p><p>マリオがジャンプしてブロックを叩く、とか</p><p>叩かれたブロックの上にいた敵はひっくり返る、とか。</p><p>そもそもマリオが地面に立ってる、なんてのにも使います。</p><br><p>今までは毎フレームupdate関数が呼ばれ、その中でキー入力などに応じてキャラクター（と他のオブジェクト）の</p><p>位置、状態の更新をしていました。</p><p>今度はそこにオブジェクトと衝突（コリジョン）しているかチェックを行い、衝突していたら位置の修正、状態の変化</p><p>などを追加します。</p><p>大体こんな感じです。</p><br><p><font color="#008000">方向キーが入力された</font></p><p>→<font color="#ff0000">キャラクター位置の更新</font></p><p>　→<font color="#0000ff">移動先の位置で他のオブジェクトと衝突しているか？</font></p><p>　　→<font color="#ff0000">していたら衝突していない位置に戻す</font></p><p>　　→<font color="#ff0000">していなければそこに移動</font></p><br><p>あるいは、</p><br><p><font color="#008000">方向キーが入力された</font></p><p>→<font color="#ff0000">キャラクター位置の更新</font></p><p>　→<font color="#0000ff">移動先の位置で敵キャラと衝突しているか？</font></p><p>　　→<font color="#ff0000">していたら死にモーション再生</font></p><p>　　→<font color="#ff0000">していなければそこに移動</font></p><br><p>で、当たってるかどうかの判定は</p><p>いろいろあるんですが、とりあえず<font color="#ff0000">四角形同士が重なってるかの判定</font>でいいでしょう。</p><p><font color="#ff0000">右上</font>から当たってるか、<font color="#ff0000">左上</font>から当たってるか、<font color="#ff0000">右下</font>からあたってるか、<font color="#ff0000">左下</font>から当たってるか、</p><p><font color="#ff0000">自分より相手が大きい</font>場合、<font color="#ff0000">自分がすっぽり相手に囲まれて</font>しまっているか、</p><p>逆に<font color="#ff0000">自分より相手が小さい</font>場合、<font color="#ff0000">相手が自分の中にすっぽり入って</font>しまっているか、</p><p>といったあたりをチェックすればOKです。</p><br><p>が、これを<font color="#ff1493">全オブジェクト同士で総当たり</font>チェックするととんでもない回数の計算を</p><p>一フレーム内で行わなければならなくなります。</p><p>上のチェックだと一対一のオブジェクトで6パターンのチェックを行うわけですが、</p><p>対象オブジェクトが自機、敵１０体、弾２０個、障害物２０個なんてものを表示していたとすると</p><p>総当たりでは５１の階乗(約１．５５×１０^６６)回のチェックを行う必要が出てきます。</p><p>１０の６６乗って日本語でなんて言うのか知りませんが、<font color="#ff0000">ともかくあり得ないくらいデカい数字</font>ってことです。</p><p>それに加えて同じフレーム内で画像の再表示やら、音の制御やら通信制御なんかもしなければならないわけで。</p><p>ともかく無駄な処理はできるだけ省きたいわけです。</p><p>ということで工夫が必要なんですが、要するに<font color="#ff0000">不要な判定はやりたくない</font>ということです。</p><p>で、どうするかというと。</p><p>まずは判定の必要なものをグループ分けする、とかですかね。</p><p>今は全オブジェクトを配列に突っ込んでおいて、ループでupdateをかけてるわけですが、</p><p>これをたとえば、プレイヤー配列、敵オブジェクト＆弾配列、障害物配列、自弾配列とかに<font color="#ff0000">分類しておく</font>わけです。</p><p>とすれば、プレイヤーと自弾はあたりをチェックする必要はないですし、敵同士、味方同士なんて</p><p>無駄なチェックする必要はなくなりますよね？</p><p>もちろん仕様次第では必要になる時もありますが、その場合は<font color="#800080">グループ分けを考え直しましょう</font>。</p><br><p>さてさて、<font color="#ff0000">これで万事OK！</font>とおもいきや。これでもまだ無駄が多いわけです。</p><br><p>たとえば<font color="#ff0000">自機が画面左上</font>にいたとき、<font color="#ff0000">画面右側にある敵やら障害物</font>なんてのはチェックするまでもないですよね？</p><p>なので、<font color="#ff0000">画面を分割</font>して、各オブジェクトがどこのエリアにいるかを逐次登録して、各エリアごとにそのエリア内にいる者同士でのみ判定を行うとより<font color="#ff0000">いい感じ</font>になるわけです。</p><p>詳しくは<font color="#ff0000">４分木空間分割</font>（３Dは８分木）でググってくだせい。</p><p>ただ、これはこれでやりゃあいいってもんでもないわけで。</p><p>あんまり細かく分割してもかえって登録の手間が無駄になってしまうし、大きく分割しすぎてもあまり効果がないし。</p><p>ってなわけで実際は扱うオブジェクトの数だとか、大きさ、空間の広さによってどの程度に分割するのが</p><p>最適かという調整が必要になってくるわけですね。</p><br><p>で、ウチの場合なんですけど。</p><p>実はここまで言っといてなんですが、<font color="#ff0000">４分木は使ってません</font>。</p><p>なぜかというと、オレが作りたいのは初代マリオブラザーズ。</p><p>２人対戦だし。敵は一度に２，３匹でいいし。障害物だってせいぜい２０個くらい？</p><p>弾幕シューティングとかじゃないのでそんなにオブジェクト数がないので効果が薄い、</p><p>というか毎フレームごとに移動に伴うセルへの登録、削除のオーバヘッドの方が大きいから。</p><br><p>ま、２０人対戦とかにする時には考え直す必要があるかもですが。</p><br><p>つーことで、今回はグルーピングだけにしておきましたよと。</p><br><p>ではでは、次回、第１０回　敵キャラ（NPC）配置してみる！にてー。</p><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10368875005.html</link>
<pubDate>Tue, 20 Oct 2009 00:54:25 +0900</pubDate>
</item>
<item>
<title>な…なんと、コンテスト中止！？</title>
<description>
<![CDATA[ はいどーも。ゲレゲレですー。<br><br>…いやぁ、ビックリしましたねー。<br><br><font size="4" style="font-weight: bold;"><span style="color: rgb(51, 204, 51);">Ｓｙｎｔｈｅ</span>　第一回ゲームコンテスト</font><font size="4" style="font-weight: bold;"><span style="color: rgb(255, 0, 0);">中止</span>のお知らせ</font><br><br>うええ、マジかよぉ…<br>競争率低そうなので入賞できるかも！とか思っていたのに、<br>そもそも競争にすらならなかったとは…残念だー。<br><br>まぁどっちにしろ自分は間に合ってなかったのであまり関係ないっちゃぁないんですけども！<br>なんというかとりあえずアレですね、いちおう運営様もこれっきりってわけじゃない的なことを<br>お知らせに書いてあった気がするので。<br>締め切りが伸びたと思ってゆっくり進めるとしましょうかね。<br><br>それにしても…ねぇ？<br>さっきちびっとログインして最終的なエントリー状況みてきたんだけどもさ。<br>残念というかやっぱりというか、さっぱりゲーム増えてなかったですわ。<br><br>やっぱあれですよねー。ゲームって作るの時間かかりますもんねー。<br>自分みたいに賞金狙って作り始めたものの結局間に合わなかったって感じの人も<br>けっこーいたりするんかなぁ？<br>ともあれ、せっかく作り始めたことだし、そもそも賞金だけのためにやってたわけでもないし、<br>ってことでひとまず完成を目指そうと。<br><br>そんなこんなでがんばるぞと！<br><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10354445130.html</link>
<pubDate>Thu, 01 Oct 2009 01:43:34 +0900</pubDate>
</item>
<item>
<title>第8回　オブジェクトを増やしてみる！</title>
<description>
<![CDATA[ <p>どうも御無沙汰しております。ゲレゲレです。</p><br><p>ちょっといろいろバタバタありまして更新が滞ってしまっておりました。</p><p>このブログを楽しみにしてくださったいる方、いたらほんと申し訳ないです。</p><p>ちょいちょい不定期になるかもしれませんが、何とか完成まで続けたいと思っておりますです。</p><br><p>ではでは、</p><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><p>第８回です！</p><br><p>さて、今回は予告通りオブジェクトを増やしてみましょう！</p><br><p>とりあえずマリオっぽい感じに土管とかブロックとか背景とか描いて、</p><p>オブジェクトとして配置してみました。</p><p>ということで以下ソース。</p><p>**********************************************************************</p><p>//オブジェクト管理クラス</p><p>class ObjectManager<br>{<br> var objects =  new Array();<br> var win = null;<br> var par = null;<br> function ObjectManager(window, parent)<br> {<br>  //ここで最初に必要なものを設定＆登録<br>  //背景<br>  add(new staticObject(window,parent,"bg.jpg",0,0,800,600,0,0,800,600,0));<br>  <br>  //点数とか<br>  <br>  //プレイヤーキャラクタ<br>  add(new player(window,parent,"test2.png",100,540,50,30,0,0,50,30,100,0,0,1));<br>  <br>  //敵キャラ<br>  <br>  //地面<br>  add(new block(window,parent,0,570,10));<br>  add(new block(window,parent,30,570,10));<br>  add(new block(window,parent,60,570,10));<br>  add(new block(window,parent,90,570,10));<br>  add(new block(window,parent,120,570,10));<br>  add(new block(window,parent,150,570,10));<br>  add(new block(window,parent,180,570,10));<br>  add(new block(window,parent,210,570,10));<br>  add(new block(window,parent,240,570,10));<br>  add(new block(window,parent,270,570,10));<br>  add(new block(window,parent,300,570,10));<br>  add(new block(window,parent,330,570,10));<br>  add(new block(window,parent,360,570,10));<br>  add(new block(window,parent,390,570,10));<br>  add(new block(window,parent,420,570,10));<br>  add(new block(window,parent,450,570,10));<br>  add(new block(window,parent,480,570,10));<br>  <br>  add(new block(window,parent,600,570,10));<br>  add(new block(window,parent,630,570,10));<br>  add(new block(window,parent,660,570,10));<br>  add(new block(window,parent,690,570,10));<br>  add(new block(window,parent,720,570,10));<br>  add(new block(window,parent,750,570,10));<br>  add(new block(window,parent,780,570,10));</p><p>  <br>  //障害物<br>  add(new block(window,parent,100,100,10));<br>  add(new block(window,parent,130,100,10));<br>  add(new block(window,parent,160,100,10));<br>  add(new block(window,parent,190,100,10));<br>  add(new block(window,parent,220,100,10));<br>  add(new block(window,parent,200,200,10));<br>  add(new block(window,parent,230,200,10));<br>  add(new block(window,parent,260,200,10));<br>  add(new block(window,parent,290,200,10));<br>  add(new block(window,parent,320,200,10));<br>  add(new block(window,parent,300,300,10));<br>  add(new block(window,parent,330,300,10));<br>  add(new block(window,parent,360,300,10));<br>  add(new block(window,parent,390,300,10));<br>  add(new block(window,parent,420,300,10));<br> }</p><p> function add(obj)<br> {<br>  //オブジェクトの登録<br>  objects.add(obj);<br> }</p><p> function update()<br> {<br>  for(var i=0; i&lt; objects.count; i++){<br>   objects[i].update();<br>  }<br> }<br>}</p><br><p>//固定オブジェクトクラス</p><p>class staticObject extends Object<br>{<br> var hitAreaType;<br> var hitAreaLeft;<br> var hitAreaTop;<br> var hitAreaHeight;<br> var hitAreaWidth;<br> var animateType;<br> var animateFrameNum;<br> var animateTime;<br> <br> function staticObject(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs)<br> {<br>  super.Object(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs);<br>  show();<br> }</p><p>}</p><br><p>//ブロック</p><p>class block extends staticObject<br>{<br> function block(window, parent, _x, _y, _abs)<br> {<br>  var imgfile = "block.jpg";<br>  var _w=30;<br>  var _h=30;<br>  var _uvx=0;<br>  var _uvy=0;<br>  var _uvw=30;<br>  var _uvh=30;<br>  <br>  super.staticObject(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs);<br> }<br> <br> function update(){<br>  if(!imageLayer.visible){<br>   show();<br>  }<br> }<br>}<br></p><br><p>**********************************************************************</p><p>前回からの変更点は大体こんな感じかな。多分。</p><br><p>で、こんな感じのものになりました。</p><p><br><a href="http://stat.ameba.jp/user_images/20090926/01/gere2/2e/33/j/o0800062910261542286.jpg"><img alt="ゲレゲレのブログ" src="https://stat.ameba.jp/user_images/20090926/01/gere2/2e/33/j/t02200173_0800062910261542286.jpg" border="0"></a><br></p><p>うーん…できたexeをここに添付できないのかなぁ。</p><p>そろそろソース全部貼るのは大変になってきたし…</p><p>でも開発中をSyntheにUPするのもなぁ…</p><br><p>それはさておき、次はどうしようか。</p><p>まぁ、敵かコリジョン判定あたりかな？</p><br><p>そういえば当初目的としておりましたSyntheゲームコンテストですが、いよいよ締め切りが近付いてきましたね。</p><p>マズイ、ひっじょーーにマズイです！</p><p>全然間に合いそうにありません！</p><br><p>とりあえず適当にまとめてエントリーだけしておくか？</p><p>後で完成したらコンテストに関係なく一応UPしなおすとして。</p><br><p>せめて参加賞くらいはくれるかもしれんし…</p><p>うむ！この土日の進捗にかけるしかない！</p><br><p>ではまた！</p>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10350778401.html</link>
<pubDate>Sat, 26 Sep 2009 00:55:14 +0900</pubDate>
</item>
<item>
<title>第7回　クラス設計を考えるpart2</title>
<description>
<![CDATA[ <p>おまたせ！ゲレゲレだよ！</p><br><p>すんません！金曜から諸事情により更新できませんでしたー！</p><p>今日からまたがんばる！</p><br><p>さて、それでは行ってみましょう！</p><br><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><p>第７回です！</p><br><p>ということで、前回に引き続きクラス設計なんですが。</p><p>とりあえず前回の図に従って今までのコードをクラス化してみましょう。</p><br><p>基本的には、</p><p>・機能単位でまとめてクラスにする</p><p>・似た機能は共通機能を基本クラスにして、拡張版は継承を使う</p><p>・大きく分けるとオブジェクトとオブジェクト管理クラス、ウィンドウクラス</p><br><p>で、大体こんな感じになりますかねー。</p><p>**********************************************************************</p><p>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br> var timer;<br> var objectManager;</p><p> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br>  Plugins.link("wuvorbis.dll");//ogg再生用プラグイン読み込み→吉里吉里では必要、syntheでは不要</p><p>  //オブジェクトマネージャーをインスタンス化<br>  objectManager = new ObjectManager(this, primlayer);</p><p>  //60FPS相当のスパンで登録されているオブジェクトの状態更新処理を行う<br>  timer = new Timer(objectManager, "update");<br>  timer.interval = 16;//約60fps<br>  timer.enabled = true;</p><p>  //ウィンドウ表示<br>  visible = true;<br> }<br>}</p><p><br>class ObjectManager<br>{<br> var objects =  new Array();<br> var win = null;<br> var par = null;<br> function ObjectManager(window, parent)<br> {<br>  //ここで最初に必要なものを設定＆登録<br>  //背景<br>  <br>  //点数とか<br>  <br>  //プレイヤーキャラクタ<br>  add(new player(window,parent,"test2.png",100,570,50,30,0,0,50,30,100,0,0,1));<br>  <br>  //敵キャラ<br>  <br>  //地面<br>  <br>  //障害物</p><p> }</p><p> function add(obj)<br> {<br>  //オブジェクトの登録<br>  objects.add(obj);<br> }</p><p> function update()<br> {<br>  for(var i=0; i&lt; objects.count; i++){<br>   objects[i].update();<br>  }<br> }<br>}</p><p><br>class Object<br>{<br> var imageLayer;<br> var win;<br> var par;<br> var x;<br> var y;<br> var w;<br> var h;<br> var uvx;<br> var uvy;<br> var uvw;<br> var uvh;<br> var abs;</p><p> function Object(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs)<br> {<br>  win = window;<br>  par = parent;<br>  x = _x;<br>  y = _y;<br>  w = _w;<br>  h = _h;<br>  uvx = _uvx;<br>  uvy = _uvy;<br>  uvw = _uvw;<br>  uvh = _uvh;<br>  abs = _abs;<br>  imageLayer = new Layer(win, par);<br>  imageLayer.loadImages(imgfile);<br>  imageLayer.setPos(x, y);<br>  imageLayer.setSize(w, h);<br>  imageLayer.imageLeft = uvx;<br>  imageLayer.imageTop = uvy;<br>  imageLayer.visible = false;<br>  imageLayer.absolute = abs;<br> }</p><p> function show(){<br>  imageLayer.visible = true;<br> }</p><p> function hide(){<br>  imageLayer.visible = false;<br> }</p><p> function update()<br> {<br> }</p><p>}</p><p>class character extends Object<br>{<br> var dir;<br> var status;<br> var life;<br> var imageCounter;<br> var speed;<br> var ay;</p><p> function character(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs, _dir, _status, _life, _imageCounter)<br> {<br>  dir    = _dir;  //キャラクターの向き　0:→　1:←<br>  status   = _status; //キャラクター状態　　0:通常<br>  life   = _life; //キャラクター生命値<br>  speed   = 4;  //キャラクターの横方向への移動速度<br>  ay    = 0;  //キャラクターの縦方向への移動速度<br>  imageCounter = _imageCounter; //アニメーションのコマ数<br>  super.Object(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs);<br> }<br>}</p><p>class player extends character<br>{<br> var jump;<br> <br> function player(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs, _dir, _status, _life)<br> {<br>  jump = 0;<br>  super.character(window, parent, imgfile, _x, _y, _w, _h, _uvx, _uvy, _uvw, _uvh, _abs, _dir, _status, _life);<br>  show();<br> }<br> <br> function update()<br> {<br>  //キーボードで入力されたキーを取得して画像の位置を移動<br>  //←キーが押されてたら<br>  if(System.getKeyState(VK_LEFT)){<br>   //キャラがウィンドウの左端を超えてなければ右に移動<br>   if(x &gt; 0){<br>    x -= speed;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = 0;<br>   }<br>  }<br>  //→キーが押されてたら<br>  else if(System.getKeyState(VK_RIGHT)){<br>   //キャラがウィンドウの右端を超えてなければ左に移動<br>   if(x &lt; (win.primlayer.imageWidth - imageLayer.width)){<br>    x += speed;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = win.primlayer.imageWidth - imageLayer.width;<br>   }<br>  }<br>  <br>  //spaceキーが押されたら<br>  if(System.getKeyState(VK_SPACE)){<br>   //ジャンプ中でなければ<br>   if(jump!=1){<br>    jump = 1;<br>    ay += 30;<br>   }<br>  }<br>  //ジャンプ中<br>  if(jump == 1){<br>   //上昇中<br>   if(ay &gt; 0){<br>    y = y - ay;<br>    ay -= 2;<br>   }<br>   //下降中<br>   else{<br>    //着地前<br>    if(y &lt; 570){<br>     y = y - ay;<br>     ay -= 2;<br>    }<br>    //着地<br>    else{<br>     ay = 0;<br>     y = 570;<br>     jump=0;<br>    }<br>   }<br>  }<br>  //位置更新<br>  imageLayer.setPos(x, y);</p><p><br>  <br>  //画像のアニメーション<br>  //uvをずらしてパラパラマンガ<br>  //アニメーション(3コマ)は16fpsだと速すぎる<br>  //20分の1くらいがいい感じ？<br>  if(jump == 0){//ジャンプ中は止める<br>   imageCounter++;<br>   if(imageCounter &gt; 20){<br>    if(imageLayer.imageTop&gt;-60){<br>     imageLayer.imageTop -= 30;<br>    }else{<br>     imageLayer.imageTop = 0;<br>    }<br>    imageCounter = 0;<br>   }<br>  }<br>  <br> }<br>}<br></p><p>**********************************************************************</p><p>はい、そんなわけで、いつも通りこのコードもそのまま使えるですよ。</p><br><p>というわけで、動かしてみた人はわかると思いますが、できたものは第5回と同じものになります。</p><p>クラスという単位でバラバラにされてますが、コード自体は第5回の物とほとんど同じですよね。</p><p>ちょっと違うのは、ObjectManagerの存在でしょうか。</p><br><p>今まではMainWindowに直接持たせていた画像（キャラクタ）と、その動きに関する処理などを</p><p>objectクラスとしてまとめたので、それを操作するクラスですね。</p><p>部品とその使い手の関係になります。</p><p>できたもの自体は変わらないのですが、この構造にすることであとあと拡張がしやすくなってくるわけです。</p><br><p>というわけで、次回はオブジェクトを増やしてみる！にします！</p><p>ではでは本日はこれにて。</p><br><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10342826956.html</link>
<pubDate>Tue, 15 Sep 2009 01:24:51 +0900</pubDate>
</item>
<item>
<title>第6回　クラス設計を考える！</title>
<description>
<![CDATA[ <p>ども！ゲレゲレだよ！</p><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><p>第6回です！</p><p>ずっと一個の関数に処理を追加していたのでそろそろソースが見づらくなってきたと思います。</p><p>え。初めからソースが汚い？うるさいうるさいうるさい！このバカ犬ぅぅぅぅ！</p><br><p>と、いうわけで。</p><p>今日はクラス設計をちょいと考えたいと思います。</p><p>まず、ここで最終的に作ろうと思っているのは上のタイトルにもあるとおり、マリオですよね。</p><p>ということで、マリオを作るのに必要な要素を考えます。</p><br><p>まず、ウィンドウがいりますよね。で、その上に背景を表示して、点数とか文字とか残機が出て、マリオがいます。</p><p>あと、敵も出てきますね。それとブロック(床)とか水道管とか地面かな。あ、あとPOWブロックか。</p><p>だいたい、こんなもんでしょう。</p><br><p>で、これらを全部部品として考えて、似てるものは似てる部分をまとめます。</p><p>すると大体こんな感じになりました。</p><p><br><a href="http://stat.ameba.jp/user_images/20090910/22/gere2/e4/e8/j/o0500050010250950853.jpg"><img alt="ゲレゲレのブログ" src="https://stat.ameba.jp/user_images/20090910/22/gere2/e4/e8/j/t02200220_0500050010250950853.jpg" border="0"></a><br>はい。わかります？これがクラス図ってやつです。</p><p>だいぶ簡略化してますが、大体こんなもんです。</p><p>で、これがプログラムの大体の設計図になるわけですわ。</p><p>もちろんこれが唯一の正解ってわけじゃないですが、こんなもんでいいのではないかと。</p><br><p>一応説明しますと、</p><br><p>まず、図中のオレンジの四角がクラスを表しています。</p><p>これがプログラムの部品です。</p><br><p>でもって、その上に重なって書いてある文字がクラスの名前です。</p><p>とりあえず適当に決めました。</p><br><p>で、それぞれの間にある矢印がお互いの関係を表しています。</p><p>よく見ると2種類ありますよね？</p><p>先が◆になってるやつと普通の→。</p><p>もちろんちゃんと意味がありまして。</p><br><p>まず、先が◆になってるやつ。</p><p>こいつはコンポジションっていうんですが、簡単に言うと</p><p>「矢印の元にあるものは矢印の先にあるものの部品です。」</p><p>という意味です。</p><br><p>次に普通の→。</p><p>これが継承ってヤツです。</p><p>これは、「矢印のもとにあるものは矢印の先にあるものの拡張版です。」</p><p>という意味です。</p><p>つまり、同じものを指してるやつらは同じ機能、特徴を持っているよ。ということです。</p><p>似てるけどちょっと違うものについて、わざわざ同じような処理をいちいち書くのは効率が悪いですよね？</p><p>なので、共通部分はまとめてしまっているわけです。</p><br><p>今回まとめたのは主に表示するモノのです。</p><p>つまり、マリオとか敵とかブロックとかですね。</p><p>これらはみんなウィンドウ上に絵を表示しますよね。</p><p>なので、これらの共通点として絵を表示する、という機能を持ったクラスをobjectクラスとして定義しました。</p><p>で、これを継承するのですが、マリオや敵は動きますが、水道管や地面、ブロックは動きませんよね？</p><p>なので、前者の機能をcharacterクラス、後者の機能をstaticObjectクラスとしてまとめます。</p><p>さらに、マリオはボタン入力で動かせますが敵は好きには動かせません。</p><p>なので、この違いをplayerクラス、enemyクラスとして分けました。</p><p>staticObjectの方も同様に、</p><p>ブロックは下からたたかれると変形して上にいる敵をひっくり返せますが、地面は変形しません。</p><p>なので、blockクラスとgroundクラスとして分けました。</p><p>POWブロックはblockクラスの継承にするか、内部で別処理にするかって感じですかね。</p><br><p>で、それらのオブジェクトを部品として持ち管理するのがobjectmanagerクラス、</p><p>さらにそれを持っているのがMainWindowクラスでその親クラスはTJS2標準のWindowクラス</p><p>というつもりで設計しました。</p><p>って実はこの辺はSyntheのサンプルをみて真似ただけなんですけど。</p><br><p>大体そんな感じですかね。</p><p>まだ背景とか点数とか漏れてるものがいくつかありますが、このあたりは適当に。</p><br><p>ではでは次回はこんな感じの設計を踏まえて、今までのソースを組み直してみましょう。</p><p>ということで、今日はここまで！</p><br><p>次回、クラス設計を考える！part2　でお会いしましょう！</p><br><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10340004185.html</link>
<pubDate>Thu, 10 Sep 2009 23:57:47 +0900</pubDate>
</item>
<item>
<title>第5回　キャラをジャンプさせてみる！</title>
<description>
<![CDATA[ <p>おっす！オラ、ゲレゲレ！</p><br><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><br><p>第5回です！</p><br>前回、キー入力でキャラクターを上下左右に動かせるようにしたので、<br><p>今回はそれをちょっと応用してキャラクターをジャンプさせてみます。</p><br><p>ということで、サンプルソース。</p><p>**********************************************************************</p><p>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br> var timer;<br> var objectManager;<br> var commondata;<br> var imageLayer;//画像レイヤー<br> var imageCounter;//画像のアニメーション時間調節用カウンター<br> var jump;<br> var ay;<br> var speed;<br> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br>  Plugins.link("wuvorbis.dll");//ogg再生用プラグイン読み込み→吉里吉里では必要、syntheでは不要<br>  //ウィンドウ表示<br>  visible = true;</p><p>  //画像を表示<br>  imageLayer = new Layer(this, primlayer);<br>  imageLayer.loadImages("test2.png");<br>  //画像表示位置(左上がx=0,y=0)<br>  var x=100;<br>  var y=570;<br>  imageLayer.setPos(x, y);<br>  //画像表示エリアサイズ設定(w:幅、h:高さ)<br>  var w=50;<br>  var h=30;<br>  imageLayer.setSize(w, h);<br>  //画像ファイル内の使用領域(UV)設定(左上がx=0,y=0)<br>  var uvx=0;<br>  var uvy=0;<br>  imageLayer.imageLeft = uvx;<br>  imageLayer.imageTop = uvy;<br>  //表示状態(true:表示、false:非表示)→このパラメータを書き換えることで表示／非表示の切り替えをする<br>  imageLayer.visible = true;<br>  //描画優先順(複数の画像を重ねて表示した場合、この値が大きい方が手前に表示される)<br>  var abs=100;<br>  imageLayer.absolute = abs;<br>  //画像アニメーションタイミング調整用カウンターを初期化<br>  imageCounter = 0;<br>  <br>  //キャラクターのジャンプ状態初期化<br>  jump=0;<br>  //キャラクターの加速度初期化<br>  ay=0;<br>  //キャラクターの左右への移動速度<br>  speed=4;</p><p>  //windowのupdate関数を実行<br>  timer = new Timer(this, "update");<br>  timer.interval = 16;//約60fps<br>  timer.enabled = true;</p><p> }</p><p> function update(){<br>  //キーボードで入力されたキーを取得して画像の位置を移動<br>  var x = imageLayer.left;<br>  var y = imageLayer.top;</p><p>  //←キーが押されてたら<br>  if(System.getKeyState(VK_LEFT)){<br>   //キャラがウィンドウの左端を超えてなければ右に移動<br>   if(x &gt; 0){<br>    x -= speed;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = 0;<br>   }<br>  }<br>  //→キーが押されてたら<br>  else if(System.getKeyState(VK_RIGHT)){<br>   //キャラがウィンドウの右端を超えてなければ左に移動<br>   if(x &lt; (primlayer.imageWidth - imageLayer.width)){<br>    x += speed;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = primlayer.imageWidth - imageLayer.width;<br>   }<br>  }<br>  <br>  //spaceキーが押されたら<br>  if(System.getKeyState(VK_SPACE)){<br>   //ジャンプ中でなければ<br>   if(jump!=1){<br>    jump = 1;<br>    ay += 30;<br>   }<br>  }<br>  //ジャンプ中<br>  if(jump == 1){<br>   //上昇中<br>   if(ay &gt; 0){<br>    y = y - ay;<br>    ay -= 2;<br>   }<br>   //下降中<br>   else{<br>    //着地前<br>    if(y &lt; 570){<br>     y = y - ay;<br>     ay -= 2;<br>    }<br>    //着地<br>    else{<br>     ay = 0;<br>     y = 570;<br>     jump=0;<br>    }<br>   }<br>  }<br>  //位置更新<br>  imageLayer.setPos(x, y);</p><p><br>  <br>  //画像のアニメーション<br>  //uvをずらしてパラパラマンガ<br>  //アニメーション(3コマ)は16fpsだと速すぎる<br>  //20分の1くらいがいい感じ？<br>  if(jump == 0){//ジャンプ中は止める<br>   imageCounter++;<br>   if(imageCounter &gt; 20){<br>    if(imageLayer.imageTop&gt;-60){<br>     imageLayer.imageTop -= 30;<br>    }else{<br>     imageLayer.imageTop = 0;<br>    }<br>    imageCounter = 0;<br>   }<br>  }<br> }</p><p>}</p><br><p>//ここからメイン処理<br>//まずwindowクラスをインスタンス化<br>var window = new MainWindow();</p><br><p>**********************************************************************</p><p>前回と同様、↑のコードをstartup.tjsって名前で保存して、50x90pixの3コマの画像</p><p>（ここではtest2.pngって名前にしてます）を用意すれば吉里吉里でもSyntheの</p><p>ゲームツールでも動作確認できますよ。</p><br><p>さて、それでは解説ー。</p><p>まず、ジャンプするってことは地面が必要ですね。そして重力があるということです。</p><p>なので、それらをコードで表現しなければなりません。</p><p>まず地面ですが、ここではウィンドウの下端を地面と見立てます。</p><p>なので、キャラクターの登場位置を地面の位置に設定します。（33，34行目）</p><p>で、前回書いたキー入力の処理ですが、重力がありますので、↑キーで浮くのはおかしいですよね？</p><p>なので上下キーの処理を削除してしまいました。</p><p>代わりに、95行目のspaceキーが押されたときの処理を追加します。</p><p>ここにジャンプの処理を書きます。</p><p>ここからは物理（の初歩）の話になるのでアレルギーがある人はちょっと我慢してくだせい。</p><br><p>横方向の移動は今まで通り等速直線運動でもまあ違和感ないのでいいとして、</p><p>（ってこれもホントは徐々に加速とかしたほうがそれっぽくなるんですが）</p><p>ジャンプについてはそうもいきません。</p><p>なんかふわーって浮いてるように見えてしまいますよね？</p><p>なので、ボタン押した瞬間に上向きの初速を設定して、時間がたつごとに</p><p>下向きの加速度（重力）によって減速させて行き、やがて速度がマイナスになると</p><p>下向きに移動しはじめ、地面に触れたら速度を0に戻す。</p><p>という処理にします。</p><br><p>実際に画面上の1pixを何mかに仮定して、重力加速度を9.8m/s^2とした場合に…</p><p>とかやると意外とうまくいかないものなので、この辺はいい感じに動くように</p><p>適当な値に調整します。</p><br><p>でもってジャンプ中状態フラグ(var jump)ってのをわざわざ持たせたのは、</p><p>空中でspaceキー入力を受け付けないようにするためです。</p><p>こうしないと押しっぱにしてたらやっぱりふわーって浮いてってしまうからね。</p><br><br><p>まあ説明としてはこんなもんなんですが、わかりにくかったかな？</p><p>数式とかださないで説明しようとがんばったつもりなんですが…</p><p>もしかしてかえって伝わらなかったかも…</p><br><p>ともあれ今日はここまで！</p><p>なんかあったらコメントくださいませー</p><br><p>そろそろソースが長くなってきたので、ちゃんと処理を分けましょう！</p><p>というわけで予定通り次回はクラス設計をちょっと考える！にします。</p><p>ではまたー。</p><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10339293715.html</link>
<pubDate>Thu, 10 Sep 2009 00:08:18 +0900</pubDate>
</item>
<item>
<title>第4回　キャラを移動させる！</title>
<description>
<![CDATA[ <p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><br><p>第4回です！ゲレゲレです！</p><br><p>さて今日は、キャラクターを動かす！です。</p><p>キーボードからの入力でキャラクターを操作できるようにしてみます。</p><br><p>今回は方向キーで上下左右に動くようにしてみます。</p><p>ではでは、サンプルソース。</p><p>**********************************************************************</p><p>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br> var timer;<br> var objectManager;<br> var commondata;<br> var imageLayer;//画像レイヤー<br> var imageCounter;//画像のアニメーション時間調節用カウンター<br> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br>  Plugins.link("wuvorbis.dll");//ogg再生用プラグイン読み込み→吉里吉里では必要、syntheでは不要<br>  //ウィンドウ表示<br>  visible = true;</p><p>  //画像を表示<br>  imageLayer = new Layer(this, primlayer);<br>  imageLayer.loadImages("test2.png");<br>  //画像表示位置(左上がx=0,y=0)<br>  var x=100;<br>  var y=200;<br>  imageLayer.setPos(x, y);<br>  //画像表示エリアサイズ設定(w:幅、h:高さ)<br>  var w=50;<br>  var h=30;<br>  imageLayer.setSize(w, h);<br>  //画像ファイル内の使用領域(UV)設定(左上がx=0,y=0)<br>  var uvx=0;<br>  var uvy=0;<br>  imageLayer.imageLeft = uvx;<br>  imageLayer.imageTop = uvy;<br>  //表示状態(true:表示、false:非表示)→このパラメータを書き換えることで表示／非表示の切り替えをする<br>  imageLayer.visible = true;<br>  //描画優先順(複数の画像を重ねて表示した場合、この値が大きい方が手前に表示される)<br>  var abs=100;<br>  imageLayer.absolute = abs;<br>  //画像アニメーションタイミング調整用カウンターを初期化<br>  imageCounter = 0;<br>  <br>  //windowのupdate関数を実行<br>  timer = new Timer(this, "update");<br>  timer.interval = 16;//約60fps<br>  timer.enabled = true;</p><p> }</p><p> function update(){<br>  //キーボードで入力されたキーを取得して画像の位置を移動<br>  var x = imageLayer.left;<br>  var y = imageLayer.top;</p><p>  //↑キーが押されてたら<br>  if(System.getKeyState(VK_UP)){<br>   //キャラがウィンドウの上端を超えてなければ上に移動<br>   if(y &gt; 0){<br>    y -= 1;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    y = 0;<br>   }<br>  }<br>  //↓キーが押されてたら<br>  else if(System.getKeyState(VK_DOWN)){<br>   //キャラがウィンドウの下端を超えてなければ下に移動<br>   if(y &lt; (primlayer.imageHeight - imageLayer.height)){<br>    y += 1;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    y = primlayer.imageHeight - imageLayer.height;<br>   }<br>  }<br>  //←キーが押されてたら<br>  else if(System.getKeyState(VK_LEFT)){<br>   //キャラがウィンドウの左端を超えてなければ右に移動<br>   if(x &gt; 0){<br>    x -= 1;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = 0;<br>   }<br>  }<br>  //→キーが押されてたら<br>  else if(System.getKeyState(VK_RIGHT)){<br>   //キャラがウィンドウの右端を超えてなければ左に移動<br>   if(x &lt; (primlayer.imageWidth - imageLayer.width)){<br>    x += 1;<br>   }<br>   //超えてたらそのまま<br>   else{<br>    x = primlayer.imageWidth - imageLayer.width;<br>   }<br>  }<br>  //位置更新<br>  imageLayer.setPos(x, y);</p><p><br>  <br>  //画像のアニメーション<br>  //uvをずらしてパラパラマンガ<br>  //アニメーション(3コマ)は16fpsだと速すぎる<br>  //20分の1くらいがいい感じ？<br>  imageCounter++;<br>  if(imageCounter &gt; 20){<br>   if(imageLayer.imageTop&gt;-60){<br>    imageLayer.imageTop -= 30;<br>   }else{<br>    imageLayer.imageTop = 0;<br>   }<br>   imageCounter = 0;<br>  }<br> }</p><p>}</p><br><p>//ここからメイン処理<br>//まずwindowクラスをインスタンス化<br>var window = new MainWindow();</p><p>**********************************************************************</p><p>前回と同様、↑のコードをstartup.tjsって名前で保存して、50x90pixの3コマの画像</p><p>（ここではtest2.pngって名前にしてます）を用意すればＯＫ！</p><br><p>試してみましたか？動いたでしょ？</p><br><p>では、解説行きまーす。</p><p>まず、今回追加した処理はupdate関数の中身です。</p><p>前回説明したとおり、timerがupdateって関数を定期的に実行するので、この関数の中で</p><p>「キーが押されてたら○○する」みたいな処理を書けばいいってわけ。</p><p>ということで、62行目以降が方向キーに対応した処理になってます。</p><p>第2回でも言ったかもですが、ウィンドウ内では上を原点としてるので</p><p>縦方向は下側に行くほど座標を＋方向にずらします。</p><p>で、→キー押されたらxに座標を＋ってだけやってると画面外に出てもそのまま進んでいってしまいます。</p><p>なので、とりあえずウィンドウの端にぶつかったら止まるような処理を入れておきました。</p><br><p>こんな感じでいいですかね？</p><p>ここがわかんない！とかこうした方がいいよ！とかあればコメントしてくれるとうれしいです！</p><p>ではでは、今日はこの辺で。</p><p>次回は今回のをちょっと応用して、キャラをジャンプさせてみる！にしますー。</p>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10338568929.html</link>
<pubDate>Tue, 08 Sep 2009 23:59:22 +0900</pubDate>
</item>
<item>
<title>第3回　アニメーションさせる！</title>
<description>
<![CDATA[ <p>まいど！ゲレゲレどすー！</p><br><p>何作るか決めました！</p><p>オンライン対戦で、それなりに簡単に作れそうで、モチベーションが持続しそうなネタ…</p><p>ってことで<font color="#0000ff" size="5">マリオブラザーズ（ファミコン）</font></p><p>これをネット対戦できるようにしたいと思います。</p><p>ああ、もちろん素材とかパクんないっすよ。</p><p>いただくのはゲームデザインのみ！</p><p>というわけで、今回から</p><p><font color="#fa8072" size="3">吉里吉里でオンラインゲームを作ろう！（仮）</font></p><p>改め</p><p><font color="#fa8072" size="5">吉里吉里でオンライン対戦マリオブラザーズを作ろう！</font></p><p>にします！！</p><br><p>つーことでね、今後は以下の感じで進めていこうかと。</p><p>・キー入力で動かす</p><p>・ジャンプとかさせてみる</p><p>・クラス設計を見直す</p><p>・コリジョン判定</p><p>・UIとか諸々</p><p>・オンライン機能</p><br><p>…なんですか？「クラス設計は初めにするもの」ですって？</p><p>それは正しい！だがしかし、いきなりそんなのつまらないでしょ？</p><p>とりあえずなんとなく形にしてみてモチベーション上げる！</p><p>これけっこー大事なことですよ！</p><p>というわけで、とりあえずなんかキーボードのキー押したらキャラクターらしきものが</p><p>画面を動き回るまではこのまま行きます。</p><br><p>そんなわけで今回はアニメーション。</p><p>例によってサンプルソースがこれ。</p><p>***********************************************************************</p><p>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br> var timer;<br> var imageLayer;//画像レイヤー<br> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br>  Plugins.link("wuvorbis.dll");//ogg再生用プラグイン読み込み→吉里吉里では必要、syntheでは不要<br>  //ウィンドウ表示<br>  visible = true;</p><p>  //画像を表示<br>  imageLayer = new Layer(this, primlayer);<br>  imageLayer.loadImages("test2.png");<br>  //画像表示位置(左上がx=0,y=0)<br>  var x=100;<br>  var y=200;<br>  imageLayer.setPos(x, y);<br>  //画像表示エリアサイズ設定(w:幅、h:高さ)<br>  var w=50;<br>  var h=30;<br>  imageLayer.setSize(w, h);<br>  //画像ファイル内の使用領域(UV)設定(左上がx=0,y=0)<br>  var uvx=0;<br>  var uvy=0;<br>  imageLayer.imageLeft = uvx;<br>  imageLayer.imageTop = uvy;<br>  //表示状態(true:表示、false:非表示)→このパラメータを書き換えることで表示／非表示の切り替えをする<br>  imageLayer.visible = true;<br>  //描画優先順(複数の画像を重ねて表示した場合、この値が大きい方が手前に表示される)<br>  var abs=100;<br>  imageLayer.absolute = abs;<br>  <br>  //windowのupdate関数を実行<br>  timer = new Timer(this, "update");<br>//  timer.interval = 16;//約60fps<br>  timer.interval = 160;//約6fps<br>  timer.enabled = true;</p><p> }</p><p> function update(){<br>  //とりあえず画像のアニメーション<br>  //uvをずらしてパラパラマンガ<br>  if(imageLayer.imageTop&gt;-60){<br>   imageLayer.imageTop -= 30;<br>  }else{<br>   imageLayer.imageTop = 0;<br>  }<br> }</p><p>}</p><br><p>//ここからメイン処理<br>//まずwindowクラスをインスタンス化<br>var window = new MainWindow();</p><p>***********************************************************************</p><p>こいつをstartup.tjsって名前で保存して、それと同じディレクトリに</p><p>幅50pix、高さ90pix(高さ30pixの3コマ)の画像を用意し、吉里吉里かSynthe(<a href="http://www.synthe-web.jp/">http://www.synthe-web.jp/</a>)の</p><p>ゲームツールで読み込むと動きます。</p><br><p>んでは解説。</p><p>そもそもアニメーションというのはですね、要はパラパラマンガなんです。</p><p>何コマ化の画像を用意して、一コマずつ順番に表示していくことで動いて見えるわけですね。</p><p>ということで、まず5行目！</p><p>var timer;</p><p>って変数がありますね？</p><p>これがタイマーです。</p><p>こいつを使って定期的に画面の再描画をさせます。</p><p>その際に、画像を差し替えればアニメーションが実現できるってわけです。</p><br><p>で、そのタイマーはどう使うかというと、45行目ですね。</p><p>//windowのupdate～</p><p>ってとこから下でタイマーの設定をしています。</p><p>Timerクラスの詳しい説明はTJS２のリファレンス(<a href="http://www.ultrasync.net/dee/kr2helps/tjs2doc/contents/">http://www.ultrasync.net/dee/kr2helps/tjs2doc/contents/</a>)に</p><p>まかせますが、ここでは１６０msごとにupdateって関数を呼び出すように設定しています。</p><p>16msで約60fps、つまりテレビ放送と同じなんですが、これで3コマをアニメーションさせてみたら</p><p>速すぎたのでとりあえず1/10の6fpsにしときました。</p><p>ここの数値を変えてお好みの速さにするといいと思いますよ。</p><br><p>で、updateって関数。</p><p>前回のソースにはそんなものなかったですよね？</p><p>なので、作ります。</p><p>53行目の</p><p>function  update(){</p><p>から61行目の</p><p>｝</p><p>までがupdateって関数です。</p><p>ここでやっているのがパラパラマンガのコマ送りの処理ですね。</p><p>呼び出されるたびに表示する画像を次のコマに差し替えています。</p><br><p>といったところで今日はここまで。</p><p>次回はキー入力でキャラクタを動かす！です。</p><br><p>ではまたー。</p>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10337943892.html</link>
<pubDate>Mon, 07 Sep 2009 23:50:17 +0900</pubDate>
</item>
<item>
<title>第2回　画像を表示させる！</title>
<description>
<![CDATA[ <p>どうも！ゲレゲレです！<br><br>さて、<font size="5"><span style="COLOR: rgb(250,128,114)">吉里吉里でオンラインゲームを作ろう！（仮）</span></font><br>です！<br><br>今日は「第2回　画像を表示させる！」です！<br>あいかわらず漠然と「オンラインゲーム」と言ってるだけで何を作るか決めかねているのですが…<br>ともあれ、何を作るにしても画像は表示しますよね！ということで。<br><br>で、例によってサンプルコードそれっぽい部分をパクって来て前回のソースに移植したのがコレ。<br><br>******************************************************************************<br>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br> var imageLayer;//画像レイヤー<br> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br><br>  //ウィンドウ表示<br>  visible = true;</p><p>  //画像を表示<br>  imageLayer = new Layer(this, primlayer);<br>  imageLayer.loadImages("test1.png");<br>  //画像表示位置(ウィンドウの左上がx=0,y=0、右下がx=800,y=600)<br>  var x=100;<br>  var y=200;<br>  imageLayer.setPos(x, y);<br>  //画像表示エリアサイズ設定(w:幅、h:高さ)<br>  var w=50;<br>  var h=30;<br>  imageLayer.setSize(w, h);<br>  //画像ファイル内の使用領域(UV)設定(左上がx=0,y=0)<br>  var uvx=0;<br>  var uvy=0;<br>  imageLayer.imageLeft = uvx;<br>  imageLayer.imageTop = uvy;<br>  //表示状態(true:表示、false:非表示)→このパラメータを書き換えることで表示／非表示の切り替えをする<br>  imageLayer.visible = true;<br>  //描画優先順(複数の画像を重ねて表示した場合、この値が大きい方が手前に表示される)<br>  var abs=100;<br>  imageLayer.absolute = abs;</p><p> }<br>}</p><br><p>//ここからメイン処理<br>//まずwindowクラスをインスタンス化<br>var window = new MainWindow();</p><p><br><br>******************************************************************************<br><br>これと、幅50pix高さ30pixの適当な画像ファイルを作ってtest.pngって名前で保存したものを<br>同じディレクトリにおいとけばおｋ。<br><br>さあ実行してみよう！<br>ね？表示されたでしょ？<br><br>つーわけで解説しちゃいます。</p><br><p>まず5行目</p><p>var imageLayer;//画像レイヤー</p><p>これをMainWindowクラスのメンバに追加しました。</p><p>あとでクラス設計をちゃんとしないとなーとか思いつつ、とりあえず今日のところは</p><p>とにかく画像が表示されるってことが目標なので直で追加しました。</p><p>うん、今度なおす！</p><br><p>で、この画像レイヤーに画像ファイルを読み込んで表示させる設定が22行目の</p><p>  imageLayer = new Layer(this, primlayer);</p><p>から下です。</p><p>設定内容は…ま、ソース内のコメントに書いてあるので大体わかりますよね？</p><p>注意しなきゃいけないのは、</p><p>座標系が左上を原点(0,0)としてるので縦方向が画面下方向に行くほど＋ってことかな。</p><p>あとは、visible=true;とか？</p><p>これはJavaScriptを書いたことがある人ならわりとおなじみかなと思うんだけど。</p><p>要するに素の要素が見えるか見えないかっていう設定で、</p><p>初期設定ではこれがfalse(見えない)になってるのでtrue(見える)にしときます。</p><br><p>今日はだいたいこんなもんかなー。</p><p>ではではまた明日！</p><p>今回画像を表示したので、次回は「アニメーションさせる！」にしようかな！</p><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10335395694.html</link>
<pubDate>Fri, 04 Sep 2009 15:14:17 +0900</pubDate>
</item>
<item>
<title>第1回　とりあえずウィンドウ出す!</title>
<description>
<![CDATA[ <p>どうもゲレゲレです！<br><br>そんなわけで<br><font size="5"><span style="color: rgb(250, 128, 114);">吉里吉里でオンラインゲーム作ろう！（仮）</span></font><br>です。<br><br>記念すべき第1回のテーマは「とりあえずウィンドウ出す！」です。<br><br>さて、どうしたもんかと。<br>よし、Synthe（http://www.synthe-web.jp）からいい感じのサンプルDLしてきてそれベースに作ろう！<br>ということで「ババぬきっ」と、「あばたーちゃっと」をDL。<br>で、何を作るにしてもとりあえずウィンドウは出すだろうということで、サンプルのコード削って<br>ウィンドウ出すだけのシンプルなコードにしてみました。<br><br>*****************************************************************************<br><br>//メインウィンドウクラス<br>class MainWindow extends Window<br>{<br> var primlayer;<br></p><p> function MainWindow()<br> {<br>  super.Window();<br>  <br>  // 下敷き(プライマリレイヤ)<br>  add(primlayer = new Layer(this, null));<br>  primlayer.left = primlayer.top = 0;<br>  //ウィンドウのサイズを設定(800x600pix)<br>  primlayer.imageWidth = 800;<br>  primlayer.imageHeight = 600;<br>  primlayer.setSizeToImageSize();<br>  setInnerSize(primlayer.width, primlayer.height);<br>    //ウィンドウ表示<br>  visible = true;<br> }<br>}</p><br><p>//ここからメイン処理<br>//まずwindowクラスをインスタンス化<br>var window = new MainWindow();<br><br>*****************************************************************************<br></p><p>はい、こんな感じです。</p><p>これをstartup.tjsって名前で保存して吉里吉里なりSYNTHEのゲームツールなりで実行すると</p><p>幅800ピクセル高さ600ピクセルのウィンドウが表示されます。</p><br><p>これで終わるとさすがにひどいですかね？</p><p>まぁこの辺はおまじないでいいんじゃないかなーと思ったりもするんですが…</p><p>ではちょっとだけ解説。</p><br><p>まず最初のclass～ってとこ</p><p>ここの下の行の</p><p>｛</p><p>から、下から5行目の</p><p>｝</p><p>までがウィンドウクラスの定義です。</p><p>もともとTJS2に用意されているWindowクラスを継承してMainWindowクラスってのを定義してるわけ。</p><p><br></p><p>その下にあるvar～ってヤツが変数宣言。</p><p>メンバ変数ってやつだね。</p><p>とりあえず今は下地のレイヤーを持たせただけ。</p><p><br></p><p>んで、その下にあるfunction～ってとこからが関数。</p><p>これはクラス名と同じ名前（MainWindow）なのでコンストラクタってヤツです。</p><p>クラスが実体化される時に自動で一回だけ実行される関数、なのでここに初期化処理を書いとくわけ。<br></p><p>ここでは下地レイヤーのサイズを８００ｘ６００に指定しただけだけども。</p><br><p>で、最後のvar window=～ってやつがメイン処理。</p><p>メイン処理っつってもこのクラスを実体化するだけなのでこれ1行。</p><br><p>さっきも言ったけどここはおまじないみたいなもんだと思うので、もうコピペでいいですたぶん。</p><p>この辺詳しく説明するとJavaScriptの文法とかオブジェクト指向とは？とか解説しなきゃなんないけど</p><p>それ無理。ってことでご勘弁を。</p><p>もっと実際の動きにつながるような、いわゆるゲーム的な処理の部分になったら</p><p>もうちょっとまともな解説できんじゃないかなと思うのでいましばらくは辛抱してくだされ。</p><br><p>ということで今日はここまで！</p><p>次回は「画像を表示させる！」にしましょう！これも何作るにしても必要なので！</p><p>で、肝心のどんなゲーム作るのか？はそのうち決めます！</p><p>目標ないとモチベーション下がるので！！</p><br><p>ではまた！</p><br>
]]>
</description>
<link>https://ameblo.jp/gere2/entry-10335070538.html</link>
<pubDate>Fri, 04 Sep 2009 00:06:54 +0900</pubDate>
</item>
</channel>
</rss>
