日記

qt / opengl / なんか興味持ったものとか日記とか書くかもしれません

qt quickでjubeat自作した

qt quickで音げー

この記事はQt Advent Calendar 2014 - Qiitaの20日目のエントリーです。

 


高校生がソフトからハードまで音ゲー自作した - YouTube

10/4(土)及び10/5(日)東京工業大学附属科学技術高等学校にて開催された、文化祭にてマイコン制御部で、qt quickを使用して作った某オトゲーを本日は紹介します。

ハードウェアは@BLUE4z

ソフトウェアは@latte_zero

が担当しました。ゲームの概要は動画をご覧ください。

こちらでは主にqt-quickの細かい技術面、参考url、書籍などをカバーしていきます。

qt quick/qmlを選択した理由

部室にはクロスプラットフォーム信者が多く、単に私もqtが好きだったからです。もともとc++で作成したいたのですが一ヶ月前になり、どう考えても間に合わないのでqmlの勉強も含めて作成しました。

qmlで作成した結果全体の行数は2000行もないと思います。(多分)
オトゲーはアニメーションやエフェクトが非常に多いため、どっちにしろc++なら死んでました。おそらくその10倍は行ったと思います。

 

上画面について

実機は2つのディスプレイに分かれていると思います。しかし予算、時間の関係上一つのディスプレイに無理やり詰め込んでいます。

 

メニュー画面について

正直これが一番難関でした。qt quickには標準でリストをループさせるという機能がなかったからです(多分) *1

そこで以下のリンクを参考にし、前後の要素を削除しながら動的に次に来るべき要素を読み取りロードするという流れでうまくやりぬきました。

http://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
したがって、楽曲の位置は固定されてないし、楽曲の数が一つなら、すべて同じ楽曲でうめつくされると思います。

 

クリアエフェクトについて

文字が徐々に出現していく方法を一から記述するのはとてもめんどかったので、メニュー画面の方法と同じlistviewのtransitionを使いました。その部分のソースコードを抜粋します。

 

 



Timer{
    id:result_listview_adder
    onTriggered: result_textadd()
    interval: 100
}

function result_textadd(){
   result_listview.model.insert(clear_nowlength,{"txt":result_text.charAt(clear_nowlength), "num":clear_nowlength});
   if(clear_nowlength === result_text.length){
      result_listview_adder.running=false
   }
}

ListView{
   x:490
   y:20
   id:result_listview

   width: 200; height: 1000
   spacing:-100
   model: ListModel {}

delegate:Rectangle{
    rotation:90
   width:200
   height:260
   id:titlerec
   color:"transparent"
   property int spreadth:500
    property int sam_ani:100
    Glow {
      anchors.fill: parent
      source: text
      radius: 80
      samples:sam_ani
       color: "white"
       spread:spreadth/1000
}

Image{
   id: text
   visible:false
   source:Name.dhire + "movie_marker/img/CLEARED/" + num + ".png"
}

}
add: Transition {
    id: addTrans
    NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 ;easing.type: Easing.OutQuad}
   NumberAnimation { property: "scale"; from: 2.0; to: 1.0; duration: 400; easing.type: Easing.OutQuad}
   NumberAnimation{ property: "x"; to: addTrans.ViewTransition.item.x + 100;duration:400; easing.type: Easing.OutQuad}
   NumberAnimation{ property:"spreadth"; from: 1000; to: 0; duration: 400; easing.type: Easing.InOutQuad}
   NumberAnimation{ property:"sam_ani"; from: 60; to: 40; duration: 400; easing.type: Easing.InOutQuad}
   ScriptAction{script:{clear_nowlength++}}
   }
}

 こいつに  result_listview_adder.running=true

とやってやれば再生されるはずです。(多分)

プログラムは一つ一つ文字が画像になっていますが、おそらく普通のテキストでも可能だと思います。

座標の位置は微調整しました。動画ではありませんが

失敗時のfailedはまた別にもうひとつプログラムを用意しております。

 

ゲーム画面について

ここはほとんどのゲームと構成が同じです。canvasをtimerを使い描画しまくっています。corei7-2670 hdgraphics4000でもこれほどぬるぬる動作しました。
しいて工夫した点を挙げるならば、後ろの動画やコンボ数などは一切キャンバスを使用していません。canvasは透過させ後ろにおいてひたすらアニメーションさせているだけです。

 

公開にあたって

楽曲などは著作権の関係上配布することができません。著作権フリーの楽曲の譜面を作成し、使用していつか公開するかもしれません。

 

参考文献

以下の参考書は入門にあたって非常に参考になりました。

 

 

※1記事を公開してからtwitterにて@task_jp さんから listループのためにpathviewというものがあるとご教授いただきました。ありがとうございます。

ListView の最初と最後をつなげて表示する - Qt 5 の未来は明るいブログ