ブロックチェーンゲーム制作チェーン -Minimal Arcade Medal-

ブロックチェーン技術、ゲーム作成のためのコード、ドット絵やアニメーションの作り方を解説するブログです。最終的に記事の内容を組み合わせることで誰でもブロックチェーンゲームが作れるようにしたいです。Micro Arcade MedalというdApps開発中です。

Solidityチートシート :CryptZombies

CryptZombiesを完了しました!


さぁ、スマコンを書こう!と意気込んだものの、
開発中にあれってどう書くんだっけ?となるのが目に見えます。


なので忘れないうちにCryptZombiesに出てきたキーワードまとめます!

contract

pragma solidity ^0.4.19; //solidityのコンパイラのバージョン指定

contract HelloWorld { //contract name {}で作れる

}

struct

struct Person { //struct name {datatype name; datatype name...}
  uint age;
  string name;
}

array

Person[] public people;
//peopleはpublicな変数であり、Person型の配列を確保している
//publicをつけるとgetterが自動で作成される
//people.push(Person(16,"Gyo"))でデータを追加できる

function

function eatHamburgers(string _name, uint _amount) {
//function name(datatype name, datatype name ) returns (datatype) {処理}
//関数から値返すときはreturnsに続けて型を書く
}

event

event IntegersAdded(uint x, uint y, uint result); 
//イベントを定義
//フロントエンドに渡したい値をevent宣言内に記述

function add(uint _x, uint _y) public { 
  uint result = _x + _y;
 
  IntegersAdded(_x, _y, result);
//addが呼ばれたときにイベント発火
// 定義した引数を入れる
  return result;
}

//--------------------

// フロントエンドのjavascript
YourContract.IntegersAdded(function(error, result) { 
//発生したeventはフロントサイドからContract名.Event名でアクセスできる。
//渡された値を使ってコールバック関数で処理を行う。
}

mapping

mapping(address => uint) public accountBalance;
//addressは口座番号のようなもの
//contractにアクセスしているaddressはmsg.senderで参照できる

//accountBalance内には
//{address key: uint value, address key: uint value,,,,}
//keyとvalueのペアが保存される

require & assert

function hoge(string huga) public returns (string) {
 
require(huga == "hugahuga")
//真ならばここから先の関数が処理される
//偽ならばエラーを投げて実行を止める
//ガスの残りは返却される

  return "YES hugahuga";
}

//------------
assert(huga == "hugahuga")

//assertも同じ役割を果たすが、関数呼び出しが失敗した場合、ユーザーにガスの残りを返却しない
//重大な間違いが起こった場合に使用される(uintのオーバーフローなど)

is (継承)

contract Doge {
  function catchphrase() public returns (string) {
    return "So Wow CryptoDoge";
  }
}

contract BabyDoge is Doge {
//ロジック毎にコードを整理するのに便利
//親の変数や関数にアクセス可
// is hoge, hugaで多重継承可

  function anotherCatchphrase() public returns (string) {
    return "Such Moon BabyDoge";
  }
}

import

import "./someothercontract.sol";
//他のファイルからcontractを読み込む
//./は同じディレクトリという意味

contract newContract is SomeOtherContract {

}

storage & memory

Sandwich storage mySandwich = sandwiches[_index];

Sandwich memory anotherSandwich = sandwiches[_index + 1];

//型がstructsやarraysの変数を使用する時に明示する必要あり

//storageはブロックチェーン上に永久格納
//状態変数(関数外で宣言された変数)の場合デフォルでstorage

//memoryは一時的な変数
//関数内で宣言された変数はデフォルトでmemory

view & pure

関数の修飾子
function huga() public view returns(string){}のように書く。
view関数ではデータの編集はできず、読み取り専用となる。
pure関数はアプリのデータにアクセスできない、つまり扱えるデータは引数のみとなる。

private, internal, external & public

関数につけてスコープを設定できる

function huga(string hoge) public {}
のように書く

  • private コントラクト内の別関数からのみ参照可
  • public コントラクト外部・内部どちらからでも参照可
  • internal 上記に加え継承したコントラクトからも参照可
  • external コントラクト外からのみ参照可

interface

contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
//interfaceを書くときは関数の中身は書かない
}

contract MyContract {
  address NumberInterfaceAddress = 0xab38...; 
  // イーサリアム上の別のコントラクトのアドレスが入る
  NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
  // 冒頭で書いたinterfaceを型として変数宣言
//interface(使いたい関数)

  function someFunction() public {
 
    uint num = numberContract.getNum(msg.sender);
    //別contractの関数getNumが使える
  }
}

modifier

//関数修飾子 function hoge(string hoga) public modifier(hoge) {}のように書く
//requireと組み合わせて関数を実行する前に特定の条件を満たしているか確認するとき使える
//引数を修飾する関数から引っ張ってこれる
modifier onlyOwner(string huga) {
    require(msg.sender == owner);
    _; //これを終わりにつけるのを忘れないように!
  }

payable

contract OnlineStore {
  function buySomething() external payable {
    // 0.001 etherが送られたことを確認
    require(msg.value == 0.001 ether);
    //0.001 etherが送られていたら、関数呼び出し元にトークンを譲渡する
    transferThing(msg.sender);
  }
}

//------------------
//web3.js(javascriptフロントエンド)からの関数呼び出し
OnlineStore.buySomething({from: web3.eth.defaultAccount, value: web3.utils.toWei(0.001)})
//valueで0.001etherを指定している

//------------------
contract GetPaid is Ownable { //コントラクトのイーサリアムアカウントからetherを引き出す方法
  function withdraw() external onlyOwner {
    owner.transfer(this.balance);
  }
}

ERC721

ERC721
ユニークで分割できないトークンを作れる。
erc721.solをimportし、以下の関数を実装する必要がある。

function balanceOf(address _owner) public view returns (uint256 _balance);
//addressを受け取り、addressのトークン保有量を返す

 function ownerOf(uint256 _tokenId) public view returns (address _owner);
//トークンIDを受け取り、所有者のaddressを返す

function transfer(address _to, uint256 _tokenId) public;
//送り先addressと送りたいトークンIDを受け取り、トークンを移転する
//送り手が呼び出す

function approve(address _to, uint256 _tokenId) public;
//addressとトークンIDを受けとり、mappingで保存

function takeOwnership(uint256 _tokenId) public;
//msg.senderがトークンを受け取ることを承認((approve))されているか確認し、承認済みの場合はトークンが譲渡される
//受け手が呼びだす

library

//contractを宣言するときのようにlibraryを宣言する
//libraryで記述された全メソッドを特定のデータ型に追加できる

//contract内でlibraryを使う場合、contract内に以下のように書く
using library for uint256


//assertと組み合わせることでオーバーフローやアンダーフロー対策ができる
//異なるデータ型ごとにlibraryを定義する必要がある

natspec

solidityのコミュニティで用いられるコメントのフォーマット。
他の開発者や自分に向けてコントラクトや関数を説明するのに使われる。

//@title
//@author
//@notice
//@param
//@dev

値をゲーム実行中に変更する方法ーCocosCreator

NodeやComponentの値を変更することで、ゲーム内オブジェクトを好きなように操ることができます。


NodeとComponentの値の変更の仕方は2つあります。


1つがPropertiesパネルで値を変更する方法で、
もう1つがコードで動的に変更する方法です。


2つ目の方法は言い換えれば、ゲーム起動中に値を変更するということです。


これはリアルタイムでプレイヤーからのインプットを受け取り、NodeとComponentを生成、変更、削除するという、ゲームを作る上では欠かせない機能です。


そのためにはコード*1からNodeや別のComponentの値を参照しなければいけません。



この記事ではその参照方法をまとめます。

自身が属しているNodeの値を参照する

start: function () {
        var node = this.node;
        node.x = 100;
    }


基本的にComponentとNodeは紐づけられています。


Component自身が紐づけられているNodeを参照する場合


this.nodeを使えば良いです。

同じNodeの、別Componentを参照する


Nodeは複数のComponentを持つことができます。


Componentから同じNodeに属している別のComponentの値への参照を得る場合、


getComponentを使います。

start: function () {
        var label = this.getComponent(cc.Label);
        var text = this.name + ' started';

        // Change the text in Label Component
        label.string = text;
    }


getComponent()の引数にはクラス*2が入ります。

上のケースだとcc.Label Componentを獲得します。


また、引数にComponentの名前*3をとることができます。
これで自らが定義したComponentへの参照を得ることができます。

var rotate = this.getComponent("SinRotate");


該当するComponentがない場合、getComponentはTypeErrorを返します。

別NodeのComponentの値を参照する


敵がプレイヤーの位置を特定して追いかけてくる、といったときに敵NodeからプレイヤーNodeのComponentの値を参照する必要があります。


一番簡単な方法はPropertiesパネルを使う方法です。

cc.Class({
    extends: cc.Component,
    properties: {
        // declare player property
        sprite: {
            default: null,
            type: cc.Node
        },
        obj: {
            default: null,
            type: cc.Node
        },

     ...

    }
});


上のようにtypeがNodeのpropertyを宣言すると、
下の画像のようにボックスがpropertyパネルに現れます。


f:id:kusakabob:20180717221019p:plain


ここにNode Treeから対応するNodeをドラッグ&ドロップすると、そのNodeへの参照を得ることができます。

this.spriteやthis.objといった具合です。


そしてそれらのNodeのComponentにアクセスする場合、this.sprite.getComponent()を使えば良いです。

Child Nodeを参照する


同じタイプのたくさんのオブジェクト*4をゲーム画面に登場させたい場合、
それらのオブジェクトをひとつの親Nodeの子供Nodeとすることで、親Nodeから全てのオブジェクトにアクセスすることができます。

cc.Class({
    extends: cc.Component,

    start: function () {
        var cannons = this.node.children;
        // ...
    }
});


名前で特定のNodeを指定することもできます。

this.node.getChildByName("Cannon 01");


また階層が深い場合はcc.findが使えます。

this.backNode = cc.find("Canvas/Menu/SFX",this.node);


cc.findの2つ目の引数this.nodeを消すことにより、root Node以下の全てのNodeから検索を行います。



上記の方法でNodeやComponentへの参照を獲得することにより、それらのPropertyにアクセスして値を変更することができます。

*1:Component

*2:Componentの種類

*3:ファイル名、大文字小文字の区別がある

*4:敵や特殊効果

作ったゲームをシェアするために考えたことーCocosCreator

f:id:kusakabob:20180718181347p:plain



ゲームをネットに公開するにあたり試行錯誤したことを書きます。


今回はカジュアルゲームのデモ公開が目的でした。
なので

  • シェアのしやすさ
  • お金がかからない
  • 時間がかからない


といったことを基準に、どのようにゲームを公開するのが一番いいんだろうと考えました。


結論、itch.ioに忍者がキャベツを切るゲームを公開しました。


下記リンクから遊べます!


MA-Ninja by GyoRisha


対象プラットフォームを考える


CocosCreatorでは

上記のプラットフォームをカバーしています。


ワンコード、マルチプラットフォームというのはもはやゲームエンジンに必須ですね。
プラットフォームごとに言語を変えるのは負担が大きいです。


どのプラットフォームにするのかということで悩みました。


一つずつ選択肢をみていきます。

Web Mobile & Web Desktop


どちらもWebで遊べるゲームとしてファイルを書き出します。
Web上での見え方が違うみたいです。


Webゲームは一番シェアしやすいです。
urlを送ればすぐ遊べます。


柔軟性も高いです。
様々な技術とつなぐことができますし、プラットフォームも様々なものがあります。
収益化も比較的容易に実現できます。


今回はシェアのしやすさを優先したのでWebアプリにすることにしました。

Facebook Instant Games


Messengerやニュースフィード上でカジュアルゲームができるというプラットフォームです。


Facebook、Messengerでプレイできる「Instant Games」を発表--「パックマン」など17ゲームを用意 - CNET Japan


まだサービスが始まってから2年ほどなのでアプリの数が少なくチャンスがあると個人的には思っています。
大手も参入してきますが、他と比べるとだいぶブルーオーシャンですね。


母体がSNSなので、ゲームをシェアするのにはうってつけです。
マーケティング効果も期待できそうです。


しかし誰がどのゲームをプレイしたのかを公開するのはやめて欲しいですね。

ギャンブル系や可愛い系のゲームしてるのを、知人に知られるのは嫌です笑

設定でそこらへんはいじれるのかも?


審査の厳しさがどの程度なのかといったことにも興味があるので、
一度公開してみようとは考えています。

Wechat Games


とてもざっくりした説明になりますが、

Wechatは中国版LINEです。

そして、Wechat GamesはLine Gameです。


Cocosエンジンのユーザーには中国人が多いのでWechat Camesが公式サポートされているのだと思います。


リファレンスが中国語だったので情報はあまり得られませんでした。


中国市場狙うなら必須って感じですが、今回の目的にはそぐわなかったのでパスしました。

QQ Play


これも中華系のプラットフォームです。

マルチプレイヤーオンラインゲームが遊べるようです。

QQ游戏_QQ游戏大全_游戏下载_QQ游戏官网


どんなゲームがあるのか覗いてみると結構楽しいです。


ここも中国市場狙うなら抑えておきたいですね。


中国語を勉強するモチベーションがとても上がりました。

iOS, Android


スマホでゲーム出すならこの2つですね。


ただ、カジュアルゲームをぱぱっと作ってシェアするのは難しいです。


iOSで2つ、Androidで3つ出したんですが、
基本的に審査を通過しないとアプリは出せません。


なので簡単に公開はできないです。


また、プレイするためにスマホにインストールしなければいけないという点もマイナスです。

  • 手間である
  • 容量を圧迫する
  • ウイルスなどのリスク

などです。


ゲームをプレイするためにはストアを経由する必要があるのでシェアもしにくいです。


とはいえ、市場の大きさは担保されているので、開発者にとって魅力的なプラットフォームであることに変わりはありません。

Mac


MacApp StoreなのでiOSプラットフォームとだいたい共通しているのですが、
今までの選択肢の中で一番魅力が低いように思えます。


自分がMacでゲームを遊んだことがないのでなんともいえないですね。。。

Webゲームをどこに公開するか


Web向けにビルド&コンパイルすることにしたんですが、
そのファイルをどこに置くのかという問題に直面しました。


サーバー借りてそこに置くというのが一般的なのかもしれません。


無料サーバーという選択肢もあるのでお金はかかりません。


が、サーバー借りるほどのゲームでもないので、サーバーという選択肢は消しました。


こういうときに便利なのがHerokuです。


Webアプリを手間をかけずにデプロイして公開できます。


ゲームをデプロイするのは初めてだったんで色々調べつつ、
Node.jsとExpressでサーバーを作ってみたんですが、
下のようなエラーが出てきました。

f:id:kusakabob:20180718195431p:plain


多分、package.jsの設定だと思うんですが、
時間がかかりそうだったのでこの問題を解決するのはやめました。


方針を転換して、ファイルをアップロードするだけでゲームを公開できるプラットフォームを探すことにしました。


そして、Kongregateとitch.ioを見つけました。


どちらもゲームをホスティングしてくれるWebゲームプラットフォームです。


Kongregate: Play free games online


Download the latest indie games - itch.io


こういうときに私はコミュニティがどれだけ盛り上がっているかに注目します。


見比べた結果、itch.ioのコミュニティサポートページの方が充実していました。


それとitch.ioの方がUX良いなという印象を受けました。


UIが綺麗だということもあるんですが、開発者ページが使いやすいといったことや、公開オプションの豊富さなど。


ということで、itch.ioにゲームアプリを公開しました。


これからミニゲームをたくさんあげていこうと思います。


Facebook Instant Gameにもあげるかも。
ハイリスクハイリターンって感じですね。

ゲーム画面の作り方ーCocosCreator

f:id:kusakabob:20180716154411p:plain


CocosCreatorでのゲーム画面の構成方法について説明します。

NodeとComponent


CocosCreatorはゲーム開発フローにcomponent-entity systemを採用しています。


簡単にいうと、ゲームを構成する要素をComponentの組み合わせで作るという方法です。


Componentはゲームロジックを定義、実行するコードです。


CocosCreatorでは基本的にJSでかかれます。*1


ゲームロジックとゲーム画面をつなぐ役割がNodeです。


ゲームロジック以外にも画像やテキストを紐づけることができます。


Nodeは画像やテキスト、Componentなどを保持する箱みたいなものです。


Nodeに色々とくっつけていくことで、一つのゲーム要素を作ります。


例えば、タッチされたときにキャベツを切る忍者などが作れます。

Nodeの作り方


エディターの左上にNode Treeパネルがあります。


f:id:kusakabob:20180717214934p:plain


これはNodeの階層構造です。
Nodeをフォルダのように管理できます。


➕ボタンを押すことで新たなNodeを追加することができます。


Nodeをクリックすると下のような画面が出てきます。


f:id:kusakabob:20180717215407p:plain


NodeのPropertiesを編集することで、画像やテキストの大きさや位置などを簡単に変更できます。


一番下のAdd ComponentをクリックするとComponentを追加することができます。


自分の作ったゲームロジック Componentをくっつけたい場合は、Add Custom Componentを選択します。


Componentは好きなだけ追加できます。


基本的にNode追加、Componentくっつける、の繰り返しでゲームを作るというワークフローです。


f:id:kusakabob:20180716154411p:plain


上の画像だと、Canvasが全てのNodeの親ノード*2です。


そして、

  • score:スコアラベル
  • bar:上下に動くバー
  • gameOver:ゲームオーバーラベル
  • effect:切ったときに現れるエフェクト
  • obj:上から落ちてくるキャベツ
  • ninja:忍者
  • gameCtrl:ゲームロジック


の構造です。


最後のgameCtrl以外はテキストや画像など目に見えるものなので*3わかりやすいです。


gameCtrlはComponentのみがくっついており、空Nodeです。


f:id:kusakabob:20180717221019p:plain


このPropertyはJSファイルの中で定義します。

properties: {
        obj: {
            default: null,
            type: cc.Node,
        },
        ninja: {
            default: null,
            type:cc.Node,
        },
        scoreDisplay: {
            default: null,
            type:cc.Label,
        },
        effect: {
            default: null,
            type:cc.Node,
        },
        gameOverDisplay: {
            default:null,
            type:cc.Node,
        },
       bar:{
           default:null,
           type:cc.Node,
       },
        
    },
...


propertiesに上記のように記載すると、エディターのpropetiesパネルにボックスが表示されます。


ここに他のNode*4ドラッグアンドドロップすることで、ComponentがそれらNodeへの参照をえることができます。


つまりgameCtrl NodeのComponentから全てのNodeの値やComponentにアクセスすることができるようになります。


Nodeを一括管理でき、ゲームをコントロールしやすくなるので、
このような空Nodeを作るのは便利ですし推奨されています。

所感


このワークフローを理解しているとCocosCreatorで高速開発できます。


私は最初ここを理解していなかったので大分苦労しました。。。


基本を抑えておくのが大事ですね。

*1:Coffee ScriptとTypeScriptも使える。

*2:ルートNodeにすることが推奨されている。

*3:effectは透明、切ったときに透明度を変えて表示。

*4:ninjaやeffect

マイクロアーケードのデモを作りましたーCocosCreator


micro arcade. this score is sent to blockchain. #indiegame #indiedev #pixelart #blockchain


CocosCreatorで早速マイクロアーケードを作って見ました。


f:id:kusakabob:20180716154411p:plain


マイクロアーケードとはブロックチェーン上のゲームセンターで遊べるミニマルなゲームのことです。


そして唯一の目的はスコアを稼ぐことです。
このスコアをメダルに変えて、そのメダルを使って他のゲームを遊ぶことができます。


マイクロアーケードというフォーマットとメダルトークンを使って、
巨大なゲームブロックチェーンネットワークを作るというビジョンです。


仮想通貨の所有権ではなく1プレイするための権利の所有権をブロックチェーンにより管理します。


マイクロアーケードの詳細についてはMAMのWhitePaperにまとめました。


MAM(Micro Arcade Medal)のWhitePaper - ブロックチェーンゲーム制作チェーン -game code archive-

ゲームの説明


冒頭の動画を見てもらえればなんとなくわかっていただけると思うのですが、簡単なアクションゲームです。


上からオブジェクトが落ちてきます。
上下するバーと重なったときにボタンを押すと忍者がオブジェクトを切ります。
そしてスコアが100増えます。
失敗したらGameOverになります。


GameOverしたタイミングでスコアをブロックチェーンに送っています。


ブロックチェーンに送っているというか、ローカルで走っているdAppsChain(ノードは私だけ)にスコアを書き込んでるだけなんですが。。


つまりプロトタイプです。


上記はLoom SDKを使って実現しています。


loomx.io


マイクロアーケードとしてのこだわり


このゲームを動かしているコードの量は、


コメントや改行ありで200行ちょいなので、ぎゅっとコンパクトにすると100行未満になるかと思います。


これはプロトタイプなのですが、作り込んでも300行は超えないはずです。


優秀なゲームエンジン(UnityやCocosCreator、他にもたくさん)のおかげで、
ちょっとしたゲームならこのくらいでできます。


そしてマイクロという特性を達成することができます。


マイクロであるということにより、

  • バグが起きにくい>テストを大幅削減
  • 誰でもコードの中身が理解できるようになる>透明性の確保
  • 誰でも作れる、誰でも遊べる>ゲームネットワークの多様性

などの効果を期待しています。


昨今の複雑化するゲームへのアンチテーゼ的な意味もありますので、マイクロであるということは重要です。


また、アーケードなので、スコアを稼ぐことが目的です。


作る側にとっても、遊ぶ側にとっても、とてもわかりやすい指標になります。


今回作ったゲームは上記の条件を満たすマイクロアーケードのデモです。


もう一つゲームを作って、
ゲーム間メダルをやりとりする機能を実装するのが次の目的です。


以上、活動報告でした!

ジャンプさせたり色を変えたりしたい:アクションの逆引きーCocosCreator

ジャンプや色を変化させる、大きさを変化させるなどのアクションの付け方を逆引きできるようにまとめました。


公式にリファレンスはあります。


cc


かし、何をしたいときにどれを呼べば良いというのが逆引き形式で乗っておらず、不便だと感じました。
なので逆引きでどのメソッド使えばいいのか簡易リファレンスとしてまとめました。


全てのアクション関係のメソッドはカバーしたと思うのですが、抜け漏れありましたら教えてください。。


それぞれ実際にどのようなアニメーションになるかはここを参照するとわかりやすいと思います。
Actions · Cocos Developer Guide

アクションのスピードを変えたい、スローモーションにしたい、早送りにしたい


speed(action, speed)

  • speedの値が大きいほど時間がかかる

他のノードを追いたい

follow(followedNode, rect)

  • 2つ目の引数はどこからどこまで追いかけるかという境界線を設定している

くねくね動かしたい

cardinalSplineTo(duration,points,tension)

cardinalSplineBy(duration,points,tension)

catmullRomTo(dt, points)

catmullRomBy(dt, points)

bezierBy ( t c )

bezierTo ( t c )

  • cardinalAplineToの場合、
    • どのくらいの時間で、
    • どの点を通り(配列で管理)
    • どのくらいくねるか
    • tension0は直線、大きくなればなるほど曲線が緩くなる
    • ToとByの違いは、Toは絶対座標に移動、Byは相対座標、つまりアクションを取るノードからみてどのくらい進むのか
  • cardinalSplineとcatmullRom、Bezierの違いは指示の仕方、同じ効果を達成できる
  • ex: cc.cardinalSplineTo(2,[cc.p(350, 350),cc.p(500, 500),cc.p(600,300)],1),

位置を変えたい

updatePosition(newPos)

徐々に加速させたいor徐々に減速させたい

easeIn(rate)

easeOut(rate)

  • Inは加速
  • outは減速
  • action.easing(cc.easeIn(rate)のように書く
  • ex:cc.moveTo(0.5,cc.p(100,100)).easing(cc.easeIn(0.4))
  • カーブの描き方によるバリエーションがひくほどある
  • 以下easeファミリー
    • easeInOut: slow > fast > slow
    • easeExponential~: 指数関数的に
    • easeSine~:サインカーブ
    • easeElastic~:ラジアンカーブ
    • easeBounce~:バウンシングエフェクト
    • easeBack~:逆方向にゆっくり動いた後、正しい方向に加速していく、逆もある
    • easeBezierAction:ベジェ曲線でモーションカーブかける
    • easeQuadraticAction~: 二次方程式カーブ
    • easeQuarticAction~:四次の代数方程式<=わからん
    • easeQuinticAction~:5次曲線
    • easeCircleAction~:円形
    • easeCubicAction~:キュービックライン

見えなくしたい

toggleVisibility()

消したい

removeSelf(isNeedCleanUp)

  • isNeedCleanUpはBooleanでメモリから消すかどうか

ひっくり返したい

flipX(flip)

flipY(flip)

アニメーションなしで即座に配置したい

place ( pos [y ] )

  • posは座標orx座標、数字の場合、2つ目の引数がy座標
  • 絶対座標にアニメーションなしで配置する

コールバックアクションを作りたい

callFunc ( selector [selectorTarget ] [data ] )

  • コールバックとは、他の関数に引数として渡される関数のこと
  • 渡された関数の実行は別の関数によって管理される
  • 好きな文脈でまとまった処理を実行できる
  • var finish = cc.callFunc(this.removeSprite, this);
    • finishと書くとremoveSpriteを実行して画像を消すというアクションを行う

異なるアクションを組み合わせたい

sequence ( tempArray )

  • アクションの配列を入れると順番に実行してくれる
  • ex: 水平に動いた後にジャンプして消える

アクションを繰り返したい

repeat ( action times )

repeatForever ( action )

アクションを同時に実行したい

spawn ( tempArray )

  • アクションの配列が入る

回転させたい

rotateTo ( duration deltaAngleX [deltaAngleY ] )

rotateBy ( duration deltaAngleX [deltaAngleY ] )

  • Toは0基準で指定された数値になるまでオブジェクトを回転する。
  • Byはオブジェクトから見て何度回転するかを指定する。

直線移動させたい

moveTo ( duration position y )

moveBy ( duration deltaPos deltaY )

  • Toは絶対座標、指定されたポイントまで動く
  • Byは相対座標、オブジェクトの位置から指定された値分動く

斜めに歪めたい

skewTo ( t sx sy )

skewBy ( t sx sy )

ジャンプさせたい

jumpBy ( duration position [y ] height jumps )

jumpTo ( duration position [y ] height jumps )

大きくしたり小さくしたい

scaleTo ( duration sx [sy ] )

scaleBy ( duration sx [sy ] )

点滅させたい

blink ( duration blinks )

透明度を変えたい、フェイドイン、フェイドアウト

fadeTo ( duration opacity )

fadeIn ( duration )

fadeOut ( d )

色を変えたい

tintTo ( duration red green blue )

tintBy ( duration deltaRed deltaGreen deltaBlue )

アクションの実行を遅らせたい

delayTime ( d )

アクションを巻き戻したい

reverseTime ( action )

アクションを起こすターゲットを動的に書き換えたい

targetedAction ( target action )

  • runActionで設定されるターゲットを上書きする。


以上です!


sequenceとspawnを使うことで、アクションを組み合わせることができます。


様々な動きが作れるようになります!

MAM(Micro Arcade Medal)のWhitePaper

Micro Arcade Medalとは


ブロックチェーンの新たなユースケースの一つとして自分のアイデアをこの記事でシェアします。
White Paperと書いてありますが、ICOが目的ではありません。


考えをシェアすることでコミュニティからフィードバックを受け、より良いアイデアにしていきたいと思っています。


マイクロアーケードメダル*1というDappsのアイデアなのですが、
一言で言うと、


decentralized(分散的)なゲームセンターです。


中央集権的なゲーム業界の構造を変え、
ユーザー、ゲーム開発者のどちらもハッピーなシステムを作りたいです。


純粋に楽しいゲームを作り、楽しいゲームを遊べるという環境。
そして、ゲーム開発者がゲームを開発し続けるだけのお金をゲーム開発から稼げる環境。


上記のような市場が作れればどちらもハッピーです。


現在のゲーム市場は様々な要因から歪められていると感じています。
結果、ゲームの楽しさを損なうと同時に開発者のインセンティブを下げていると思います。


ブロックチェーンネットワーク上に誰でも等しくゲームを公開でき、誰でも遊ぶことができる場所を作ることで、
多くのしがらみを取り除くことができ、ゲームとしての純粋な楽しさの追求を行えるではないかと考えました。


MAMは個人ゲーム開発を通して感じた問題についての一つのソリューション案です。


また、未だ金融以外の応用事例の少ないブロックチェーン技術の適応案でもあります。


目次

MAMが解決する問題


私は個人でゲームを開発しています。
極簡単なシューティングであったり、パズルゲームをApp StoreとPlay Storeにリリースしています。


と書くとゲーム業界の人なのかと思われるかもしれませんが、実は超新参者です。


元々SEだったんですが、業務内容がつまらなすぎてすぐ辞めました笑
そして、自分のやりたいことの一つであるゲーム開発を始めました。


個人ゲーム開発を通して、いくつかモバイルゲームアプリ市場*2に関して感じた問題があります。


それらの問題をまとめると以下のようになります。


現在の市場は歪んでおり、ゲーム本来の楽しさを提供する場所ではなくなっている。
またゲーム開発のハードルを上げている。


そして、以下のような点からそのような問題があると感じました。

  • ランキングの支配による多様性の制限
  • 課金要素によるUIの複雑化
  • 継続アップデートの必要性
  • 中間業者による中抜き

ランキングの支配による多様性の制限


ゲームアプリの数が多すぎます。
ゆえに何を遊べばいいのかわかりません。


基本的に製作者がストアから消さない限りアプリは残り続けます。


誰も遊ばなくなり、保守もされなくなったいわゆるゾンビアプリが大量に存在します。


そのような状況もあり、App StoreやPlay Storeからアクセスできるゲームアプリの量は年々増えていきます。


どのゲームが面白くて、どれを遊べばいいのかを選ぶのはとても困難です。


結果、皆ランキングを見てランキング上位のゲームを遊ぶことなります。
そしてそれらは大体ソシャゲです。


課金システムで儲けることができ、その金でマーケティングができ、ユーザーが増え、さらに儲かる…


といった循環で収益をあげやすいというのが、課金システムと相性が良いソシャゲがランキング上位を占めている理由ではないかと思います。


ランキングが支配する構造はゲームアプリの多様性を狭めています。


同じようなゲームが市場には溢れかえり、飽和状態になっている感じます。

課金要素によるUIの複雑化


モバイルゲームの画面はとても複雑化していると感じます。


複雑さが面白さを生み出すパターンもあると思うのですが、
本来シンプルであるべきゲームも複雑化しています。


私が昔よくプレイしていたゲームはシンプルなアーケードゲームでした。
起動すればすぐにゲームが始まり、終わったらスコアが表示されます。
ゲームの内容が単純に面白く、1プレイがすぐに終わるので何回も遊びました。


しかし、最近アップデートして遊んでみると、UIが一新されて、とても複雑なものになっていました。


それらは主にガチャや動画広告、バナーなど、、収益化のための部品です。
大量のコストをかけ無料でゲームを提供しているので、それは仕方ないのですが、、


ゲーム内容に集中できず、前ほどの楽しさを感じませんでした。


結果私はアプリをアンインストールしてしまいました。


ゲームはゲームの内容に集中できるようにデザインされるべきだと思います。

継続アップデートの必要性


前述の通り、ゲームは市場に溢れかえっており、次々と新しいものが現れます。


そのため、ゲームは何回も繰り返し遊ばれることが少なくなります。


もちろん、例外はありますが一般的な傾向として一つのゲームにかける時間は少なくなっていると感じます。


ユーザーのゲーム離れを食い止めるために、運営側はゲームの継続アップデートをしなくてはなりません。
仕事として行なっている場合には特に、、


継続アップデートはインディーゲームの開発者にとって大きな負担となります。
また、決して楽しい作業ではないと私個人としては思います。


これが出来ない場合、大概のゲームは消費されてユーザーのデバイスから消えることになります。


開発者にとってもゲームにとってもハッピーな状況ではないです。

中間業者による中抜き


これは一番問題だと感じました。


大体のモバイルゲームにアクセスする場合、AppleGoogleアカウントを作る必要があります。


基本的にゲーム開発はプラットフォームを提供する企業に大きく依存しています。


開発者が自分のアプリをマネタイズする場合、それらの企業に中間手数料を取られます。


これはモバイルゲームに限ったことではないです。


ゲーム開発者自らのゲームを配布する場合、プラットフォームの存在は欠かせません。


ゆえに、プラットフォーム提供側の立場はゲーム開発側よりも基本的に上になります。


当たり前と言えば当たり前なのですが。
当たり前のことを当たり前とすると何も変わりません。


自分の作ったゲームの中身が精査されたり、中間手数料を取られるのは、
正直あまり気持ちの良いことではありません。


上記の理由で、


現在の市場は歪んでおり、ゲーム本来の楽しさを提供する場所ではなくなっている。
またゲーム開発のハードルを上げている。


という問題があるのではないかと思いました。


このような問題をブロックチェーンを使うことで解決し、
新しい仕組みを作れるのではないかと考えました。


それがMicro Arcade Medalです。

MAMはどのように問題を解決するのか


MAMは分散化されたゲームセンターです。


ゲームと関係ない過剰な課金要素を取り除き、ゲームの面白さを追求するプラットフォームです。


また、ゲーム開発者が正当な報酬を受け取れるようにもします。


そして、誰もがゲームで遊ぶと同時にゲームを作れるような環境を目指します。


それを実現するために、Micro ArcadeとMedalというコンセプトを考えました。

Micro Arcade


これは私の造語ですが、MAMで遊べるゲームは全てMicro Arcadeであるべきだと現在考えています。


唯一の基準であり、これを満たしている限りブロックチェーン上のゲームセンターにアップロードでき遊べるものとします。

  • Micro: ゲームとして最小限の要素のみで構築されている
  • Arcade:ゲームの目的はハイスコアを稼ぐことである


Microという特性により、

  • ゲーム開発初心者でも作りやすい
  • 多少コードが読めれば中身がわかる(透明性の確保)
  • 余計なUIや機能を排除し、ゲームの面白さに焦点を当てる
  • 保守が必要最小限
  • バグが起きにくい


といったことが達成できます。


Arcadeという特性により、

  • ゲーム開発の指針が打ち立てやすい(初心者にとって作りやすい)
  • 1ゲームプレイを単位として扱いやすい(ゲームスタートからゲームオーバーするまで)
  • 異なるゲームをスコアという基準で統一できる

Medal


MAMネットワークではゲームを1回プレイするためにメダルトークンを使います。


メダルは買うこともできますし、プレイヤーと交換もできます。


現実のゲームセンターにないエキサイティングな点としては、


ゲームで得たスコアをメダルに変換できるということです。


つまり、ゲームをやり込めばやりこむほど、より多くのゲームを遊べるようになります。


メダルを入れたら遊ぶだけです。ユーザーを邪魔するものはありません。


メダルはメダルであり、仮想通貨への交換はできないものとします。*3


これはこのDappsを仮想通貨にしないためです。


あくまで、ゲームを遊ぶ権利の所有権を譲渡するというシステムです。


スコアを基準とすることで、ゲームの平均点*4でそのゲームの難しさが相対的にどのくらいなのかがわかります。


難しさにより、1プレイにかかるメダルの量や報酬を決定します。


以上が現在のMAMの基本的なコンセプトです。
MAMはアイデアの完成形ではなく過程です。
この記事は随時アップデートし、より具体的にわかりやすく、詳細化していきます。

追記 メダルについてのアイデア(7月18日)

メダルを交換するインセンティブ


メダルはゲームを遊ぶために必要ですが、同時にコレクション要素もあります。


メダルはユニークなものであり、同じメダルはありません。


ゲームでハイスコアを取るほど、レアなメダルを獲得できる可能性が上がります。


ゲームをプレイする以外にもメダルを集めるという楽しさをプラスすることにより、ユーザー間でのメダルのやりとりが活発になりコミュニティが活性化することを期待しています。

救済策


遊んでいてメダルがなくなってしまった場合、遊んだゲームのレビューやシェアをすることでメダルがもらえるようにします。

BOU(Bet On Yourseld)


1プレイを特別で価値あるものにするためのアイデアです。


プレイヤーはプレイをする前に、自分がどれだけのスコアを稼げるかメダルをかけることができます。


スマートコントラクトを自分への契約に適応するという考えです。


成功すればそれ相応の報酬がもらえますが、失敗するとそのメダルは帰ってきません。


よりゲームがエキサイティングになります。

*1:以下MAM

*2:スマホゲーム

*3:仮想通貨からの交換はできる

*4:もしくは別の方法