ゲームを作りたい人のための ソースコード集

私がその日作った短めのソースを簡単な解説とともに載せていきます
ゲーム制作初心者にとって参考になるかもしれないソースが多いです





タブ区切りを揃える

横並びの単語を一定数のtabで区切ると、右側の単語が揃わずバラバラになることがあります

このプログラムはそれを解消するプログラムです

左側に変換元の文字列を入れてボタンを押すと、右側に変換された文字列が表示されます

 


bfstr={"
Programming     Language
HSP                Script
Hello    World
"}
;変換前
pos 0,0:mesbox bfstr,320,400
afstr=""
;変換後
pos 320,0:mesbox afstr,320,400:stat_afstr=stat:hwnd_afstr = objinfo(stat_afstr, 2)
pos 320,400:objsize 320,50:button gosub "Arrangement",*arrangement
sdim lstdt,,10,10000:lstlid=0
sdim bfstrline,,10000
sdim bfstrcell,,10
tablen=8    ;タブの幅
bfstrsize=strlen(bfstr)
stop
*arrangement
    chksize=0
    split bfstr,"¥n",bfstrline
    ;一行ごとにタブで区切られた文節を取得
    repeat length(bfstrline):lcnt=cnt
        repeat length(bfstrcell)
            bfstrcell(cnt)=""
        loop
        chksize+(strlen(bfstrline(cnt))+2)
        split bfstrline(cnt),"¥t",bfstrcell
        id=0
        repeat length(bfstrcell)
            if bfstrcell(cnt)!=""{
                lstdt(id,lcnt)=bfstrcell(cnt)
                id++
            }
        loop
        if chksize>bfstrsize:break
        lstlid++
    loop
    ;文節の最大長を取得
    max=0
    repeat lstlid
        if max<strlen(lstdt(0,cnt)){
            max=strlen(lstdt(0,cnt))
        }
    loop
    ;一行ごとに右側が揃うタブ数を計算して追加
    rightid=(max/tablen+1)*tablen
    repeat lstlid:lcnt=cnt
        trid=0
        repeat length(lstdt)-1
            if lstdt(cnt,lcnt)!=""{
                afstr+=lstdt(cnt,lcnt)
                if lstdt(cnt+1,lcnt)!=""{
                    lpnum=(rightid-strlen(lstdt(cnt,lcnt)))/tablen+1
                    repeat lpnum
                        afstr+="¥t"
                    loop
                }
            }
        loop
        afstr+"¥n"
    loop
    objprm stat_afstr,afstr
    sendmsg hwnd_afstr, $B1, , -1    ;EM_SETSEL (文字列の全選択)
    sendmsg hwnd_afstr, $0301        ;WM_COPY (クリップボードに転送)
    return

0
    posted by higashijugem 22:36comments(0)|-|





    バッチファイル

    コマンドプロンプト上で実行させるバッチファイルを作成し、動かすプログラムです

     

     

    dircur=dir_cur
    resfile=dircur+"¥¥result.txt"    ;出力先ファイル
    batfile=dircur+"¥¥command.bat"    ;実行バッチファイル
    hs=""
    notesel hs
    hs="cd "+dircur+"¥n"
    ;標準出力と標準エラー出力を両方ともファイルへ出力する
    ;コマンド > ファイル名 2>&1
    hs+="ipconfig /all > "+resfile+" 2>&1"
    notesave batfile
    ;バッチファイルが作成されたかチェック
    mes"作成中・・・"
    repeat
        exist batfile
        if strsize>=0{
            break
        }
        wait 1
    loop
    exec "cmd /c "+batfile    ;Windowsのファイルを実行
    mes"バッチファイル¥n "+batfile
    mes"保存先¥n "+resfile

    0
      posted by higashijugem 23:06comments(0)|-|





      コントロール自動サイズ調整

      コントロール(サンプルではリッチエディットコントロール)のサイズをウィンドウの大きさに合わせるプログラムです

      ウィンドウのサイズが変わる度にWM_COMMANDメッセージを通知し、MoveWindow関数を利用してサイズを変更しています

       


      #uselib "kernel32"
      #cfunc LoadLibrary "LoadLibraryA" str
      #func FreeLibrary "FreeLibrary" int
      #uselib "user32"
      #func GetWindowLong "GetWindowLongA" int,int
      #func SetWindowLong "SetWindowLongA" int, int, int
      #func MoveWindow "MoveWindow" int, int, int, int, int, int
      ;ウィンドウ
      screen 0, ginfo(20), ginfo(21), 0, , , 640, 480
      ;最大化、サイズ変更に対応
      GetWindowLong hwnd, -16
      SetWindowLong hwnd, -16, stat | $10000 | $40000
      ;リッチエディットコントロール
      hModRichEd32 = LoadLibrary("Riched20.dll") ;DLL読み込み&初期化
      pos 0,0:winobj "RichEdit20A", "", 0, 0x50b000c4 , 0, 0, 1, 10000
      stat_re=stat:hwnd_re = objinfo_hwnd(stat_re)
      ;WM_COMMANDメッセージ
      oncmd gosub *command, $111
      ;終了処理
      onexit gosub *exit
      stop
      *command
          MoveWindow hwnd_re, 0,0,ginfo(12),ginfo(13), 1
          return
      *exit
          FreeLibrary hModRichEd32 ;DLLの開放
          end

      0
        posted by higashijugem 20:03comments(0)|-|





        aのn乗を任意の数で割った余り(繰り返し自乗法)

        繰り返し自乗法を用いて余りを求めるプログラムです

        再帰関数を用いて実装されています

         

         

        #module
        #defcfunc repeatsquaring double n, double p, double m
            if p=0:return 1
            if p¥2=0{
                t=repeatsquaring(n, p/2, m)
                return t*t¥m
            }
            return n*repeatsquaring(n, p-1, m)
        #global
        n=13    ;乗数
        p=300    ;指数
        m=33    ;除数
        mes""+n+" の "+p+" 乗≡ "+strf("%d",repeatsquaring(n,p,m))+" (mod "+m+" )"
        ;確認用
        ans=1
        repeat p
            ans*n
            ans¥m
        loop
        mes""+n+" の "+p+" 乗≡ "+ans+" (mod "+m+" )"

        0
          posted by higashijugem 22:11comments(0)|-|





          aのn乗を素数で割った余り(周期性)

          aのn乗を素数で割った余りを求めるプログラムです

          以下の記事の「周期性を使う方法」を参考にさせていただきました

          「3の100乗を19で割ったあまりは?」を4通りの方法で計算する

           


          a=3        ;乗数
          n=100    ;指数
          p=19    ;除数
          t=1        ;剰余
          dim mlst,p
          repeat p-1    ;周期性リスト
              if cnt>=n:break
              t*a
              if t>p{
                  t¥p
              }
              mlst(cnt)=t
              mes""+a+" の "+(cnt+1)+" 乗≡ "+t+" (mod "+p+" )"
          loop
          mes"・¥n・¥n・¥n"
          pos 300,0
          if p>n{
              tt=n-1
          }else{
              tt=n¥(p-1)-1
          }
          mes""+a+" の "+n+" 乗≡ "+mlst(tt)+" (mod "+p+" )"

          0
            posted by higashijugem 11:21comments(0)|-|





            弾幕

            SLG(シューティングゲーム)のような弾幕を再現したプログラムです

            クリックすることで弾幕のパターンが切り替わります

             

             

            #include "hgimg3.as"
            hgsetreq SYSREQ_MAXOBJ,10000    ;オブジェクト最大数変更
            hgini

            #const patnum 1
            #const csz 16

            oncmd gosub *wm_lbuttondown, $0201
            oncmd gosub *wm_lbuttonup, $0202

            buffer 2,csz,csz*patnum
            ;アニメーション画像作成
            boxf
            x=0:y=0:deg=0
            color 255,255,255:circle 0,0,csz-1,csz-1
            setuv 0,0,csz-1,csz-1    ;登録テクスチャUV座標を指定
            addspr sp0,1    ;2Dスプライトモデルを作成
            settex csz,csz,0,-1    ;テクスチャを登録
            ;イベント作成
            newevent evid    ;イベントリストを作成
            event_prmon evid,PRMSET_MODE,OBJ_MOVE|OBJ_XFRONT    ;パラメータービット設定イベントを追加
            event_wait evid,1    ;ウェイト
            event_jump  evid,0    ;イベントの最初に戻る
            ;処理開始
            screen 0
            dim objiddt,1000:objfcsid=0
            repeat length(objiddt)
                regobj objiddt(cnt),sp0    ;オブジェクトの登録
                setpos objiddt(cnt),-400,0
            loop
            spd=4
            *main
                hgdraw:hgsync 17
                title"パターン:"+(flg+1)
                if wparam>0{
                    gosub *mouseclick
                }
                goto *main
            *wm_lbuttondown    ;マウスボタンを押す
                time=0
                return
            *wm_lbuttonup    ;マウスボタンを離す
                flg++
                if flg>2:flg=0
                return
            *mouseclick
                if flg=0{
                    if time{
                        time--
                    }else{
                        repeat 18
                            rad=deg2rad(cnt*20)
                            setevent objiddt(objfcsid),evid,0
                            setpos objiddt(objfcsid),0,0
                            setdir objiddt(objfcsid),cos(rad)*spd,sin(rad)*spd,0
                            objfcsid++
                            if objfcsid>=length(objiddt):objfcsid=0
                        loop
                        time=20
                    }
                }else:if flg=1{
                    if time{
                        time--
                    }else{

                        rad=deg2rad(c1*10)
                        setevent objiddt(objfcsid),evid,0
                        setpos objiddt(objfcsid),0,0
                        setdir objiddt(objfcsid),cos(rad)*spd,sin(rad)*spd,0
                        objfcsid++
                        if objfcsid>=length(objiddt):objfcsid=0
                        rad=deg2rad(c1*10+180)
                        setevent objiddt(objfcsid),evid,0
                        setpos objiddt(objfcsid),0,0
                        setdir objiddt(objfcsid),cos(rad)*spd,sin(rad)*spd,0
                        objfcsid++
                        if objfcsid>=length(objiddt):objfcsid=0
                        c1++
                    }
                }else:if flg=2{
                    if time{
                        time--
                    }else{
                        repeat 18
                            rad=deg2rad(cnt*20+c1)
                            setevent objiddt(objfcsid),evid,0
                            setpos objiddt(objfcsid),0,0
                            setdir objiddt(objfcsid),cos(rad)*spd,sin(rad)*spd,0
                            objfcsid++
                            if objfcsid>=length(objiddt):objfcsid=0
                        loop
                        time=6:c1+10
                    }
                }
                return

            0
              posted by higashijugem 13:47comments(0)|-|





              リッチエディットコントロール

              リッチエディットコントロール(リッチエディタ、リッチテキストエディタなど)を作成、表示するプログラムです

               


              #include "kernel32.as"
              #const style    0x50b000c4 
              /*
              ES_MULTILINE    0x00000004
              ES_AUTOVSCROLL    0x00000040
              ES_AUTOHSCROLL    0x00000080
              WS_HSCROLL        0x00100000
              WS_VSCROLL        0x00200000
              WS_BORDER        0x00800000
              WS_VISIBLE        0x10000000
              WS_CHILD        0x40000000
              */
              onexit *exit
              Loadlibrary "RICHED20.DLL"    ;DLLを読み込む
              plib=stat
              pos 0,0
              winobj "RichEdit20A","",0,style,ginfo_winx,ginfo_winy
              stop
              *exit
                  FreeLibrary plib    ;読み込んだDLLを介抱
                  end

              0
                posted by higashijugem 22:26comments(0)|-|





                VRAM操作

                VRAMの値を書き換えて矩形を描写するプログラムです

                領域の幅が4の倍数でない場合や範囲外を指定した場合でも、正常に表示されます

                 


                #module
                #deffunc areacheck var p,var l,var te,int ge
                    if l<0{
                        p=p+l
                        l=l*(-1)
                    }
                    te=l+p
                    if te<0{
                        te=0
                    }else:if te>ge{
                        te=ge
                    }
                    if p<0{
                        p=0
                    }
                    return
                #global
                #module
                #deffunc vramset array vram,int tx,int ty,int tw,int th,int tc,int tgw,int tgh
                    x=tx:y=ty:w=tw:h=th:c=tc:gw=tgw:gh=tgh
                    r=c&0xff
                    g=(c>>8)&0xff
                    b=(c>>16)&0xff
                    areacheck x,w,tew,gw
                    areacheck y,h,teh,gh
                    if (gw*3)¥4!=0{
                        fx=1
                        ix=1-((gw*3)¥4)
                    }else{
                        fx=0:ix=0
                    }
                    j=y
                    repeat
                        if j>=teh:break
                        tj=(gh-j-1)
                        sfx=fx*tj
                        six=ix*tj
                        i=x+sfx
                        repeat
                            if i>=tew+sfx:break
                            index=(tj*gw+i)*3+six
                            poke vram,index,r
                            poke vram,index+1,g
                            poke vram,index+2,b
                            i++
                        loop
                        j++
                    loop
                    return
                #global
                boxf
                mref vram,66
                vramset vram,50,50,100,100,$ffffff,ginfo(12),ginfo(13)
                redraw

                0
                  posted by higashijugem 07:36comments(0)|-|





                  判別分析法

                  大津の手法」と呼ばれる二値化の画像フィルタ処理です

                  以下のサイトに詳しい情報が載っています

                  http://imagingsolution.blog.fc2.com/blog-entry-113.html

                   

                  HSPにはOpenCVを利用した拡張プラグインがデフォルトで入っているので

                  それを用いて処理を行っています

                   


                  #const gmw 640
                  #const gmh 480
                  #include "hspcv.as"
                  randomize
                  screen 2:title"入力画像"
                  repeat 10
                      repeat 4:col(cnt)=0:loop
                      repeat 2:col(rnd(4))=0xffffff:loop
                      repeat 4
                          x(cnt)=rnd(gmw),rnd(gmw),rnd(gmw),rnd(gmw)
                          y(cnt)=rnd(gmh),rnd(gmh),rnd(gmh),rnd(gmh)
                      loop
                      gsquare -257,x,y,col
                  loop
                  gsel 0:title"出力画像"
                  wait 100
                  ;2値化処理
                  cvbuffer 0,gmw,gmh
                  gsel 2
                  cvputimg 0
                  cvthreshold CV_THRESH_OTSU,,255,0    ;判別分析法
                  gsel 0,1
                  cvgetimg 0

                  0
                    posted by higashijugem 22:16comments(0)|-|





                    キャラクターアニメーション(DirectX)

                    HSPの拡張プラグイン「hgimg3」を用いて作成した、ただ歩き回るだけのオブジェクトです

                    マウスの左ボタンを押すことでオブジェクトの数を増やすことができます

                     

                     

                    #include "hgimg3.as"
                    hgini

                    #const patnum 16
                    #const csz 32

                    oncmd gosub *wm_lbuttondown, $201    ;マウスの左クリックされた時

                    buffer 2,csz,csz*patnum
                    ;アニメーション画像作成
                    boxf
                    x=0:y=0:deg=0
                    repeat patnum
                        color 255,,255:circle x+1,y+9,x+csz-1,y+csz-9
                        color ,,255:circle x+7,y+7,x+csz-7,y+csz-7
                        rad=deg2rad(deg)
                        color 255
                        circle 0,y+csz/2-sin(rad)*16,4,y+csz/2+sin(rad)*4
                        circle csz-5,y+csz/2+sin(rad)*16,csz,y+csz/2-sin(rad)*4
                        y+csz:deg+(360/16)
                    loop
                    setuv 0,0,csz-1,csz-1    ;登録テクスチャUV座標を指定
                    addspr sp0,1    ;2Dスプライトモデルを作成
                    settex csz,csz,0,-1    ;テクスチャを登録
                    ;イベント作成
                    newevent evid    ;イベントリストを作成
                    repeat patnum
                        event_uv evid,0,cnt*csz    ;UV設定イベントを追加
                        event_prmon evid,PRMSET_MODE,OBJ_MOVE|OBJ_XFRONT    ;パラメータービット設定イベントを追加
                        event_wait evid,1    ;ウェイト
                    loop
                    event_jump  evid,0    ;イベントの最初に戻る
                    ;処理開始
                    screen 0
                    dim objiddt,1000:objfcsid=0
                    gosub *wm_lbuttondown
                    *main
                        hgdraw:hgsync 17
                        repeat objfcsid
                            getposi objiddt(cnt),x,y,z
                            if x<=-128&y<=-128{
                                setpos objiddt(cnt),-128,-128        ;再配置
                                setdir objiddt(cnt),(0.01*rnd(20)+0.9),0,0    ;移動量設定
                                setang objiddt(cnt),0,0,deg2rad(90)    ;画像回転
                            }else:if x>=128&y<=-128{
                                setpos objiddt(cnt),128,-128
                                setdir objiddt(cnt),0,(0.01*rnd(20)+0.9),0
                                setang objiddt(cnt),0,0,deg2rad(180)
                            }else:if x>=128&y>=128{
                                setpos objiddt(cnt),128,128
                                setdir objiddt(cnt),-(0.01*rnd(20)+0.9),0,0
                                setang objiddt(cnt),0,0,deg2rad(270)
                            }else:if x<=-128&y>=128{
                                setpos objiddt(cnt),-128,128
                                setdir objiddt(cnt),0,-(0.01*rnd(20)+0.9),0
                                setang objiddt(cnt),0,0,deg2rad(0)
                            }
                        loop
                        goto *main
                    *wm_lbuttondown    ;マウスを左クリックでオブジェクト生成
                        if objfcsid<length(objiddt){
                            regobj objiddt(objfcsid),sp0    ;オブジェクトの登録
                            setevent objiddt(objfcsid),evid ;イベントセット
                            setpos objiddt(objfcsid),-csz*4,csz*4
                            setdir objiddt(objfcsid),0,-(0.01*rnd(20)+0.9),0
                            objfcsid++
                        }
                        return

                    0
                      posted by higashijugem 23:18comments(0)|-|