HSP3.5 HGIMG4 で剛体をキネティック(強制指定)モードにする

HSP3.5 HGIMG4 で剛体をキネマティック(強制指定)モードにする

HGIMG4 では三次元の物理演算剛体が使えますが、gppbind で3Dオブジェクトを3D物理演算剛体として指定すると基本的には setpos などでは移動できなくなり、3D物理演算に従った移動回転が発生します。
しかし gppset で GPPSET_KINEMATIC で x成分 に 1.0 を指定することでその物理演算剛体を強制指定モードに変更することができます。
注意する必要があるのはこの方法で移動させる場合は質量を 0.0 にしてはならないということです。

このキネマティックモードを利用してコインプッシャーもどきを作ってみました。
以下サンプルコードです。

#include "hgimg4.as"

    randomize
    gpreset
    setcls CLSMODE_SOLID, 0x000000

    whole_size = 32
    whole_half = whole_size / 2

    height_size = 2
    height_half = height_size / 2

    div_num = 4

    box_size = whole_size / div_num
    box_half = box_size / 2

    setborder whole_size * 2.0, whole_size * 2.0, whole_size * 2.0
// 前後移動イベント
    dim evs, 2
    foreach evs
        frs = 157, 163
        vel = double(box_size) / double(frs.cnt)

        newevent ev
        event_addpos ev, 0,0, - vel
        event_wait ev, frs.cnt
        event_addpos ev, 0,0, vel
        event_wait ev, frs.cnt
        event_jump ev, 0
        evs.cnt = ev
    loop

// プッシャー
    repeat 2
        i = cnt
        cols = 0x00ccff, 0x006699
        col = cols.i

        repeat div_num
            j = cnt
                repeat 3
                    k = cnt

                    gpbox id, box_size, col
                    x = (j * 2 - div_num / 2 - 1) * box_size / 2
                    y = box_half * (1 - i)
                    z = box_half * (-1 + i*2 - k*2)
                    setpos id, x, y, z
                    gppbind id, 1,2
                    gppset id, GPPSET_KINEMATIC, 1
                    setevent id, evs.i
                loop
        loop
    loop
// 黄色い箱
    repeat 200
        gpbox id, 2, 0xcccc00
        setpos id, rnd(7) - 3, whole_size / 2, rnd(7) - 3
        setobjmode id, OBJ_BORDER, 0
        gppbind id, 1, 2
        gppset id, GPPSET_DAMPING, 0,0
    loop
// 床壁
    gpfloor id, whole_size, whole_size, 0x006699
    gppbind id, 0
    repeat 3
        xs = -whole_half, 0, whole_half
        y = whole_half / 2
        zs = 0, -whole_half, 0
        ws = whole_size/2, whole_size, whole_size/2
        hs = whole_size, whole_size/2, whole_size
        rx = 0
        ry = 0
        rz = 0
        if cnt == 0 {
            rz = -64
        }
        if cnt == 1 {
            rx = 64
        }
        if cnt == 2 {
            rz = 64
        }
        gpfloor id, ws.cnt, hs.cnt, 0x339966
        setpos id, xs.cnt, y, zs.cnt
        setangr id, rx,ry,rz
        gppbind id, 0
    loop
// ライトとカメラ
    setangr GPOBJ_LIGHT, -16, -32,0
    setpos GPOBJ_CAMERA, 10, 20, 50
    gplookat GPOBJ_CAMERA, 0, 5, 0

    repeat
        getreq fps, SYSREQ_FPS

        stick key
        if key & 256 {
            gpbox id, 2, 0xcccc00
            setpos id, rnd(25)-12, whole_half, -whole_half
            setobjmode id, OBJ_BORDER, 0
            gppbind id, 1, 2
            gppset id, GPPSET_DAMPING, 0,0      
        }

        redraw 0        
        gpdraw
        pos 16,16
        color 224,224,224
        font "",48
        mes strf("%2d [fps]", fps)
        redraw 1
        await 1000/60
    loop
実行結果1
z04c1.png
黄色い箱がコインがわりのコインプッシャーです
実行結果2
z04c2.png
左クリックで黄色い箱を補充できます

プッシャーをキネマティックモードにしてイベントで前後移動させ、コイン代わりの箱は通常の3D物理演算で動作が決まるようになっています。

現状では gpbox ですべての辺の長さが等しい立方体しか生成できないため、立方体を複数並べてそれぞれの段の滝を実現しています。直方体とその形状の剛体も作れるようになると、もっと便利かなぁと思います。次期バージョンアップ時の追加に期待したいと思います。

参考

HSP3.5 hgimg4 を基礎から理解したい方は以下の記事がとてもおすすめです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.