「Moai SDK」タグアーカイブ

Moai SDK でタップゲーを作る (スワイプ用のコンポーネントが変…

自分で作ったスワイプを実現する仕組みが、ちゃんと動いてないのがわかった。
修正中…。

で、少し見なおしたら修正できたので、次はアイテムのアイコン(のつもりの画像)や、アイテム名を表示するあたりを実装しようと思う。
そこまで実装したら、アイテムがリスト表示された要素をスワイプ操作できるようになるはず。

Moai SDK で作るタップゲー (画面内の表示を切り替えるタブメニューの配置

アイテム閲覧の画面構成をノートに書きだしたので、実装を開始した。

  • どの種類のアイテムを閲覧するのかを選ぶタブメニュー
  • アイテムがリスト表示されたスワイプできる領域
  • アイテムをタップしたときの詳細表示

から構成される予定。
これらの動作は、状態遷移で表現せずにボタンが押された時のコールバックで処理してしまおうと思っている。

とりあえず、タブメニューまでが実装できた。
↓ソースコード
https://bitbucket.org/satofumi/dwarf_weapon_shop/src/e1c0225cad59e28bfa8f87fb6399bbf6a2e308db/src/items.lua?at=default

dwarf_items_2014_1008

タブメニューの個々の要素はボタンで構成されているので、下記コードをボタンが押された時のコールバックとして登録することで、メニューの排他まわりを実現している。

-- 押下時のコールバックを登録する
local function decided_callback(button_self)
   -- 押下を排他にする
   for _, button in pairs(button_) do
      if button_self ~= button then
         button:set_normal()
      end
   end

   -- スクロールエリアを切り替える
   -- !!!
end

実装に思っていたよりも時間がかかってしまうのは、ぶっちゃけ辛いけど頑張ろうと思う。

 

Moai SDK で作るタップゲー (ゲーム情報の配置

シーンを切り替えるボタンの配置が終わったので、ゲームの情報を表示させてみた。

dwarf_2014_1006_2

装飾が全然ないけど、とりあえずはこれで良いことにする。
次は、アイテムなんかの内部のデータ表現をどうするか、とかを決めてしまいたい。
そうしたら、アイテムを閲覧するシーンの実装ができるようになる。

Moai SDK で作るタップゲー (ボタンの作成と画面の切り替え

とりあえずシーンを遷移するためのボタン(白色の画素とも言う)を配置て、ボタンを押したらそのシーンへの遷移も行われるようにした。

dwarf_2014_1006

ソースコード
https://bitbucket.org/satofumi/dwarf_weapon_shop/src/47f005ad6caf3b477855629de1fc1ceade7dbbe4/src/workshop.lua?at=default

さて、ゲームっぽいあたりの実装は、これからだ!

Moai SDK で作るタップゲー (文字を明滅させるあたり

Moai SDK でアニメーションをどうにかする方法の説明は、下記フォーラムの記事にまとめてあった。

http://getmoai.com/wiki/index.php?title=Moai_SDK_Basics_Part_Two

私にとって直感的だったのは、コルーチン内でアニメーションの指示と待機を繰り返す、という方法だったので、そういうコードで文字を明滅させるようにした。

-- tap_message の明滅を指示する
local function blink_text()
   while true do
      tap_message:set_color(Colors.white, C.blink_second)
      Gui:wait(tap_message)

      tap_message:set_color(Colors.black, C.blink_second)
      Gui:wait(tap_message)
   end
end
blink_message_task_ = MOAICoroutine:new()
blink_message_task_:run(blink_text)

依存関係があるようなアニメーションだと混乱しそうだけど、とりあえずはこれで良いことにしたい。

 

Moai SDK で作るタップゲー (プロローグ画面の作成)

要は、タップしたら次のシーンに進むあたりを実装します。 実装したいことは

  • プロローグのメッセージと “Tap to Start” っていう文字列の表示。 “Tap to Start” の方は明滅させたい。
  • スクリーンがタップされたら次の状態に進ませる。

だけです。
そして、これを実装したコードが、以下のようになります。

--! \file
--! \brief プロローグの表示

require("name_input")


_G.prologue = {}

local layer_ = nil
local is_tapped_ = false


local function update_components()
   Gui.layers:remove(layer_)
   layer_ = Layer:new()

   -- !!! 背景画像

   local message = Gui.set_text_label(C.prologue.message)
   layer_:insert(message)

   local tap_message = Gui.set_text_label(C.prologue.tap_message)
   layer_:insert(tap_message)

   -- tap_message の明滅を指示する
   -- !!!

   Gui.layers:push_front(layer_)
  end


prologue["Enter"] = function(state)
   update_components()

   is_tapped_ = false

   -- フェード・イン
   Gui.screen:fade_in(C.fade_second)
end


prologue["Execute"] = function(state)
   if Input:force_redraw() then
      update_components()
   end

   -- tap されたら次のシーンに遷移させる
   local x, y, up = Input:pointer()
   if up then
      Gui.screen:fade_out(C.fade_second)
      is_tapped_ = true
   end

   -- フェードアウトが完了したら次のシーンに遷移させる
   if is_tapped_ and not Gui.screen:is_fading() then
      state:change_to(name_input)
   end
end


prologue["Exit"] = function(state)
   Gui.layers:remove(layer_)
   layer_ = nil
end

dwarf_prologue_2014_1003

どこに何を配置する、という画像リソースの場所などの状態は constants.lua に記述してあるので、このコードでは主にロジック的なあたりを表現しています。

「文字列を明滅させるあたりは、どう記述するのが Moai SDK っぽいのか?」は、現在模索中です。 (いずれ実装します。

Moai SDK で、タップゲーを作る

Moai SDK を利用して、タップゲーを作ろうと思います。
1ヶ月くらい前からメイドさんをテーマにした喫茶店のゲームを作成しているのですが、それの練習という立ち位置で作成していきます。 (この練習版で作ったコードは、そのままメイドさんの方に流用できるはず!

さて、タップゲーと言っても音ゲーとか色々ありますが、ここでは「Cookie Clicker」 風の何かを作りたいと思います。 で、ゲームは周回プレイを前提にしつつ、1周のゲーム時間は1時間くらいになるように調整しようと思います。

ソースコードの管理ページ: https://bitbucket.org/satofumi/dwarf_weapon_shopa
仕様などのドキュメント: http://hyakuren-soft.sakura.ne.jp/dwarf_weapon_shop

Android のアプリを作ってリリースしてみる

いろいろと思い立って、Android のアプリを作ることにしました。
今回の目標は「アプリを作って Google Play で配布すること」です。

まず何を作るかですが、タップした位置に「ガラスが割れたような画像」を配置するだけのアプリにします。

まず BitBucket にプロジェクトを作ります。 プロジェクト名は touch_wareru (タッチ割れる)にしました。 はい、大丈夫です。 センスがないのは自覚しています。

開発プロジェクトは下記アドレスで公開しています。
https://bitbucket.org/satofumi/touch_wareru

開発には Moai SDK を使うことにします。 (Moai SDK は Lua スクリプトでもって Android を含む各種環境で動作するゲームを記述できる SDK です)

で、なんやかんやで実装したのが、以下の Lua スクリプトです。

[lua]
--! \file
--! \brief タッチ割れる

require("strict")
require("input")


math.randomseed(os.time())

local Screen_width = MOAIEnvironment.horizontalResolution or 640
local Screen_height = MOAIEnvironment.verticalResolution or 480
MOAISim.openWindow("touch wareru", Screen_width, Screen_height)

local layer = MOAILayer2D.new()
MOAISim.pushRenderPass(layer)

local viewport = MOAIViewport.new()
viewport:setSize(Screen_width, Screen_height)
viewport:setScale(Screen_width, Screen_height)
layer:setViewport(viewport)

local crack_deck = MOAIGfxQuad2D.new()
crack_deck:setTexture("glass.png")
crack_deck:setRect(-64, -64, 64, 64)


local Max_props = 100
local props = {}
local props_size = 0

local function remove_front_prop(props)
   layer:removeProp(props[1])
   table.remove(props, 1)
   props_size = props_size - 1
end

local function push_back_prop(props, prop)
   layer:insertProp(prop)
   table.insert(props, prop)
   props_size = props_size + 1
end

local function new_prop(x, y, degree)
   local prop = MOAIProp2D.new()
   prop:setDeck(crack_deck)
   prop:setLoc(layer:wndToWorld(x, y))
   prop:setRot(degree, 0)

   return prop
end

local function update()
   while true do
      -- タップ位置を取得する
      local is_clicked, x, y = clicked_input()
      if is_clicked then
         if props_size >= Max_props then
            -- 最も古い画像を削除して、メモリ使用量が増え続けないようにする
            remove_front_prop(props)
         end

         -- タップされた位置に、画像を表示する
         local degree = math.random(0, 360)
         push_back_prop(props, new_prop(x, y, degree))
      end

      coroutine.yield()
   end
end

local thread = MOAIThread.new()
thread:run(update)
[/lua]

とりあえず、タッチした場所に割れたようなガラスの画像が表示されます。

touch_wareru_screenshot

さて、次は Google Play への登録です。
Google Play の開発者になるには 2,500 円ほど要求されます。 支払ってしまえば問題なしです。

で、Google Play Developer Console の Web ページにログインして、うきうきしながら touch_wareru.apk をアップロードしようとすると signed パッケージにしろっていうエラーが出ましたが、下記サイトを参考になんとかしました。

http://sp.vitalify.jp/archives/?p=587

あとは Google Play にパッケージ情報を書き込んで登録ボタンを押すと、「Google Play に反映されるまで数時間かかるかもよ?」 っていうメッセージが表示されます。 私の場合は 12 時間くらい経過してから反映された気がします。

ともあれ、Moai SDK を使ったアプリ作成から Google Play への登録までができました。
やればできるのが、わかった。

 

Moai SDK でゲームを作ろう (状態遷移の処理について)

前回の記事 にて Android の実機にウィンドウを表示させるあたりまで作成しました。今回はゲームの状態遷移まわりの実現方法について説明します。

ゲームの状態遷移

ここでの状態遷移とは「最初のメニュー画面」「ステージ選択画面」といった、大きく切り替わる単位だとします。今回作っているゲームは、選択したステージをクリアできるようにするタイプで、状態遷移の図は下記のようになります。

dot_inline_dotgraph_1

このような状態と遷移を実現するにあたり、Lua で State_machine クラスと state モジュールを作成します。State_machine クラスと state モジュール、状態の一つである first_menu_state.lua を順に示します。

state_machine.lua

-- 状態遷移の処理

_G.State_machine = {}

function State_machine:new ()
?? local members = {
????? states_ = {},
????? current_state_ = nil,
?? }

?? State_machine.__index = State_machine
?? setmetatable(members, State_machine)

?? return members
end

function State_machine:set_state (state)
?? self.current_state_ = nil
?? self:change_state(state)
end

function State_machine:change_state (state)
?? if self.current_state_ ~= nil then
????? self.current_state_["Exit"]()
?? end

?? self.current_state_ = state
?? self.current_state_["Enter"]()
end

function State_machine:execute ()
?? if self.current_state_ ~= nil then
????? self.current_state_["Execute"]()
?? end
end

state.lua

-- 状態遷移の初期化

module("state", package.seeall)

require("state_machine")
require("first_menu_state")
require("stage_select_state")
require("stage_play_state")
require("option_state")
require("credit_state")

local state_machine_ = nil

function initialize ()
?? state_machine_ = State_machine.new()
end

function set_state (state)
?? state_machine_:set_state(state)
end

function start ()
?? local thread = MOAIThread.new()

?? local function update_function ()
????? while true do
???????? state_machine_:execute()
???????? coroutine.yield()
????? end
?? end
?? thread:run(update_function)
end

function change_state (state)
?? state_machine_:change_state(state)
end

first_menu_state.lua

-- 最初のメニュー

_G.First_menu_state = {}

First_menu_state["Enter"] =
?? function ()
      -- 画面の作成などのセットアップの処理
      -- ...
?? end

First_menu_state["Execute"] =
?? function ()
????? -- !!! ボタンが押された時の処理とか
?? end

First_menu_state["Exit"] =
?? function ()
      -- システムのクリーンアップの処理
      -- ...
?? end

このような仕組みについては O’Reilly から出版されている「ゲーム開発者の AI 入門」や「ゲーム AI プログラミング」に詳しく説明してあります。お勧めです。

簡単に説明すると、状態毎に Enter, Execute, Exit という名前に関数を登録しておき、その状態に入ったときに Enter の関数を実行し、状態から出るときに Exit の関数を実行します。また Execute の関数は、その状態にいる間に毎回呼び出されます。この関数を登録しているのが例えば first_menu_state.lua で、実際に状態遷移の処理をしているのが state_machine.lua です。state.lua では、first_menu_state.lua などを読み込む処理をしています。

ここまででゲームの全体的な状態を管理するコードが作成できたので、次回の記事では Moai SDK に慣れるのを兼ねてゲーム起動直後の画面を作成したいと思います。