UJMLサンプル012:はじく感じで移動する(2006/02/02)
簡単な移動、例えば上を押すと上に3pixel移動、はサンプルを紹介したが(こちら)、はじく感じで移動するサンプルも作成した。
はじくといっても、減速しながら移動するというだけなのだが、こういうエフェクトは使い手に心地よさを与えることが多い。使いすぎは禁物だが、何かのときに、「ひゅーっと出てきて、ひゅーっと去る」ような、料理のスパイスのように効かせると良い。
できれば動いている感じをそのままお見せしたいが、静止画像ではそうはいかなかった。
このサンプルはSDK付属のwalk.ujmlを参考にしている。walk.ujmlの方が読みやすい部分もあるので、是非そちらも参照すると良いと思う。
このサンプルでは
・移動中はキー入力を受け付けない
・移動時の初速と、減速度合いはENTITYで指定できる
といった具合になっている。
---コード
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ujml PUBLIC "-//UIEVOLUTION//DTD UJML 1.2//EN" "ujml.dtd" [
<!ENTITY LABEL_WIDTH_STRING "X:000 Y:000" >
<!ENTITY SPACING "4">
<!ENTITY MOVE_SUB "1"><!-- 減速の度合 -->
<!ENTITY MSEC_FRAME "50"><!-- フレームの処理間隔 -->
<!ENTITY INITIAL_DIST "10"><!-- 最初の移動速度 -->
]>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
XYの位置の練習 カーソルキーで動かすとXYの値が変わる
移動ははじく感じでだんだ遅くなる。減速の度合いはMOVE_SUBで設定する。
はじいた瞬間の移動距離はINITIAL_DISTで設定する。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<ujml>
<application>
<state-variables>
<state-var name="sBox" type="boolean"/>
<state-var name="sTick" type="boolean"/>
<state-var name="sInput" type="boolean"/>
</state-variables>
<variables>
<var name="mScrWidth" type="int"/>
<var name="mScrHeight" type="int"/>
<var name="mWidth" type="int"/>
<var name="mHeight" type="int"/>
<var name="mPosX" type="int"/>
<var name="mPosY" type="int"/>
<var name="mDX" type="int"/>
<var name="mDY" type="int"/>
<var name="mMovingStep" type="int"/>
<var name="mTotalMoving" type="int"/>
</variables>
<functions>
<function name="processTick" type="void">
<script>
<!-- 移動後のXY座標を算出する。 -->
sBox = false;
sBox = true;
if (mMovingStep * &MOVE_SUB; &_LTE; (&INITIAL_DIST;)) {
<!-- 移動後のXY座標を算出する。 -->
mPosX = mPosX + mDX * (&INITIAL_DIST; - mMovingStep * &MOVE_SUB;);
mPosY = mPosY + mDY * (&INITIAL_DIST; - mMovingStep * &MOVE_SUB;);
mMovingStep++;<!-- だんだん移動距離を短くするために、移動ステップ数を増やす。 -->
<!-- 同じ処理を再度実行 -->
sTick = false;
sTick = true;
} else {
<!-- 移動距離が0になったので移動処理をやめて、入力待ち状態にする。 -->
sInput = true;
}
</script>
</function>
<function name="moveBox" type="void">
<parameters>
<var name="dx" type="int"/>
<var name="dy" type="int"/>
<var name="fMove" type="boolean"/>
</parameters>
<script>
if (fMove) {
<!-- 移動ステップ数を初期化 -->
mMovingStep = 0;
<!-- どの方向に移動させるか -->
mDX = dx;
mDY = dy;
<!-- 箱の移動処理をさせる。 -->
sTick = false;
sTick = true;
<!-- 移動中は入力を拒否するためにsInputをfalseにする。-->
sInput = false;
}
</script>
</function>
</functions>
<script>
<!-- スクリーンの幅と高さ -->
mScrWidth = _getIntProperty(&_PROPERTY_INT_SCREEN_WIDTH;);
mScrHeight = _getIntProperty(&_PROPERTY_INT_SCREEN_HEIGHT;);
<!-- 全文字数分の幅 -->
mWidth = (&SPACING; * 2) +_text_width("&LABEL_WIDTH_STRING;", &_FONT_SIZE_MEDIUM;,
&_FONT_STYLE_ITALIC;, &_FONT_FACE_SYSTEM;);
<!-- 高さ -->
mHeight = (&SPACING; * 2) + _text_height(&_FONT_SIZE_MEDIUM;, &_FONT_STYLE_ITALIC;,
&_FONT_FACE_SYSTEM;);
mPosX = &MOVE_SUB;;
mPosY = &MOVE_SUB;;
sInput = true;
sBox = true;
</script>
<states>
<state var="sTick">
<transition value="true">
<delay>&MSEC_FRAME;</delay>
<script>processTick();</script>
</transition>
</state>
<state var="sInput">
<transition value="true">
<display>
<!-- カーソルを押すイベントをキャッチするためのBOX -->
<!-- もちろん空なので表示はされませんよ -->
<box>
<event name="onselect">
<accelerators>
<key>LEFT</key><!-- 左 -->
</accelerators>
<script>
moveBox(-1, 0, _gt(mPosX, -1));
</script>
</event>
</box>
<box>
<event name="onselect">
<accelerators>
<key>RIGHT</key><!-- 右 -->
</accelerators>
<script>
moveBox(1, 0, _lt(mPosX+mWidth, mScrWidth));
</script>
</event>
</box>
<box>
<event name="onselect">
<accelerators>
<key>UP</key><!-- 上 -->
</accelerators>
<script>
moveBox(0, -1, _gt(mPosY-mHeight, -1));
</script>
</event>
</box>
<box>
<event name="onselect">
<accelerators>
<key>DOWN</key><!-- 下 -->
</accelerators>
<script>
moveBox(0, 1, _lt(mPosY+mHeight, mScrHeight));
</script>
</event>
</box>
</display>
</transition>
</state>
<state var="sBox">
<transition value="true">
<display>
<!-- XYの座標を表示する箱 -->
<box>
<x><eval>mPosX</eval></x>
<y><eval>mPosY</eval></y>
<width><eval>mWidth</eval></width>
<height><eval>mHeight</eval></height>
<fg>&_COLOR_BLACK;</fg>
<bg>&_COLOR_BLACK;</bg>
<label>
<text><eval>_strcat("X:",mPosX," Y:",mPosY)</eval></text>
<x>&SPACING;</x>
<y>&SPACING;</y>
<fg>&_COLOR_WHITE;</fg>
<bg>&_COLOR_BLACK;</bg>
</label>
</box>
<!-- 左上の黄色い目印 -->
<box>
<x><eval>mPosX</eval></x>
<y><eval>mPosY</eval></y>
<width>3</width>
<height>3</height>
<fg>&_COLOR_YELLOW;</fg>
<bg>&_COLOR_YELLOW;</bg>
</box>
</display>
</transition>
</state>
</states>
</application>
</ujml>
コメント