2009年6月28日日曜日

花火ゲーム(やわらかライセンス)2009

( ゜ワ゜)ノさん原案、eller改造のミニゲーム。

2008年版から若干改良され、コンボ機能が付きました。連続してHANABIを取るとスコアアップ!高機能を目指したスリリングな展開を楽しめます。

/* HANABIGA @ やわらかライセンス by eller 2009/06/28
 * ===============================================
 * HANABIGAからの改造個所:
 *     コンボの導入
 * SAKURAGAからの改造個所:
 *     "さくら" → "たまや"       // "かぎや"でも良い
 *     キャラクタの移動動作変更(ちょい簡単に)
 *     背景色など色合い変更
 *     ゲームオーバー中はキャラクタを生成しないように
 *     キャラクタ接触時にどかーん
 *     ゲームオーバー時にどかーん
 *     redraw 0 と redraw 1 を入れ替え
 *     randomize追加
 *     640 → ginfo_winx など
 */


//#runtime "hsplet3"
#include "hspmath.as"
#packopt name "hanabiga"

#define FRAME_WAIT          16

#define PLAYER_SPEED        3.0
#define PLAYER_SP_REDUCE    0.8

#define CHAR_MAX            256
#define HANABI_MAX          8

#define CHAR_TYPE_NONE      0
#define CHAR_TYPE_SA        1
#define CHAR_TYPE_KU        2
#define CHAR_TYPE_RA        3

#define CHAR_FACE_SA        "た"
#define CHAR_FACE_KU        "ま"
#define CHAR_FACE_RA        "や"
#define CHAR_FACE_HANABI    "・"

#define HANABI_PARTS_NUM    14

#define CHAR_ROT_SP         0.05
#define CHAR_ROT_MOVE       0.8

#define CHAR_SIZE           16.0

#define COMBO_TIME_MAX      60

// 準備
;   screen 0, 480, 320
    title "HANABIGA 2009"
    font "MS ゴシック" ,16,1
    randomize

    player_x = double(ginfo_winx / 2)
    player_y = double(ginfo_winy / 2)
    player_vx = 0.0
    player_vy = 0.0

    dim char_type,CHAR_MAX
    ddim char_x,CHAR_MAX
    ddim char_y,CHAR_MAX
    ddim char_vx,CHAR_MAX
    ddim char_vy,CHAR_MAX
    dim char_timer,CHAR_MAX

    ddim hanabi_x,HANABI_MAX
    ddim hanabi_y,HANABI_MAX
    dim hanabi_radius,HANABI_MAX
    dim hanabi_life,HANABI_MAX
    dim hanabi_life_max,HANABI_MAX
    dim hanabi_r,HANABI_MAX
    dim hanabi_g,HANABI_MAX
    dim hanabi_b,HANABI_MAX

    buffer 1,640,480
    repeat 40
        color cnt0cnt * 2
        boxf 0 , cnt * ginfo_winy / 40 , ginfo_winx , (cnt + 1) * ginfo_winy / 40
    loop

    gsel 0
    gmode 3,,,64

// メイン処理

repeat
    // INIT
    gosub *initpl
    // タイトル
    repeat
        redraw 0
        gosub *clearscreen
        gosub *movehanabi
        gosub *movechar
        gosub *collision
        if(player_life > 0){
            gosub *moveplayer

            a = 10 - (player_score / 5) \ 10
            if( a < 2 ) : a = 1
            if(player_timer \ a  == 0) : gosub *addchar
        }else{
            gosub *burstall
            color 255255255
            pos (ginfo_winx - 198)/ 2, (ginfo_winy - 16) / 2
            mes "H A N A B I  O W A T A"

            stick inp
            if(inp & 16) : break
        }

        gosub *showstatus

        redraw 1
        await FRAME_WAIT
    loop
loop




*initpl
    player_x = double(ginfo_winx / 2)
    player_y = double(ginfo_winy / 2)
    player_vx = 0.0
    player_vy = 0.0
    player_life = 1
    player_chain_type = CHAR_TYPE_SA
    player_score = 0
    player_combo = 0

    combo_time = 0

    scroll_vx = 0.01
    scroll_vy = -2.0

    repeat CHAR_MAX
        char_type(cnt) = CHAR_TYPE_NONE
    loop
    return

*clearscreen
    pos 0,0
    gcopy 1,0,0,ginfo_winxginfo_winy
    return

*moveplayer
    stick inp,255

    if(inp & 1) : player_vx -= PLAYER_SPEED
    if(inp & 2) : player_vy -= PLAYER_SPEED
    if(inp & 4) : player_vx += PLAYER_SPEED
    if(inp & 8) : player_vy += PLAYER_SPEED
    player_timer++

    player_vx *= PLAYER_SP_REDUCE
    player_vy *= PLAYER_SP_REDUCE

    player_x = limitf(player_x + player_vx, 0.0ginfo_winx - CHAR_SIZE)
    player_y = limitf(player_y + player_vy, 0.0ginfo_winy - CHAR_SIZE)
    
    color 255
    pos player_x,player_y
    if( player_chain_type == CHAR_TYPE_SA ){
        mes CHAR_FACE_SA
    } else : if( player_chain_type == CHAR_TYPE_KU ){
        mes CHAR_FACE_KU
    } else : if( player_chain_type == CHAR_TYPE_RA ){
        mes CHAR_FACE_RA
    }

    if (combo_time > 0) : combo_time-- : else : player_combo = 0
    return

*collision
    repeat CHAR_MAX
        if( char_type(cnt) == CHAR_TYPE_NONE ) : continue

        dx = player_x - char_x(cnt)
        dy = player_y - char_y(cnt)
        ifabs(dx) < CHAR_SIZE & abs(dy) < CHAR_SIZE ) {
            if( char_type(cnt) == player_chain_type ){
                player_chain_type++
                if(player_chain_type > CHAR_TYPE_RA){
                    player_chain_type = CHAR_TYPE_SA
                }

                if (combo_time > 0) {
                    player_combo++
                }
                player_score += 10 + player_combo
                combo_time = COMBO_TIME_MAX
            }else{
                player_life--
            }
            char_type(cnt) == CHAR_TYPE_NONE
            x = char_x(cnt)
            y = char_y(cnt)
            gosub *addhanabi
        }
    loop
    return

*movechar
    color 255,128
    repeat CHAR_MAX
        if( char_type(cnt) == CHAR_TYPE_NONE ) : continue

        pos char_x(cnt) , char_y(cnt
        char_x(cnt) += char_vx(cnt)
        char_y(cnt) += char_vy(cnt)

        char_timer(cnt)++
        char_x(cnt) += CHAR_ROT_MOVE * sin(double(CHAR_ROT_SP * char_timer(cnt)))
        char_y(cnt) += CHAR_ROT_MOVE ;* cos(double(CHAR_ROT_SP * char_timer(cnt)))

        if( char_y(cnt) < -16.0 ) : char_type(cnt) = CHAR_TYPE_NONE

        if( char_type(cnt) == CHAR_TYPE_SA ){
            mes CHAR_FACE_SA
        } else : if( char_type(cnt) == CHAR_TYPE_KU ){
            mes CHAR_FACE_KU
        } else : if( char_type(cnt) == CHAR_TYPE_RA ){
            mes CHAR_FACE_RA
        }
    loop
    return

*addchar
    repeat CHAR_MAX
        if( char_type(cnt) != CHAR_TYPE_NONE ) : continue

        char_type(cnt) = 1 + rnd(3)
        char_x(cnt) = double(rnd(800) - 80)
        char_y(cnt) = 20.0 + ginfo_winy
        char_vx(cnt) = scroll_vx
        char_vy(cnt) = scroll_vy
        char_timer(cnt) = rnd(256)
        break
    loop
    return

*showstatus
    pos ginfo_winx - 160 , ginfo_winy - 40
    color 255255255
    mes strf("SCORE : %8d", player_score)
    mes strf("COMBO : %8d", player_combo)
    return


#const HANABI_CST 2.0 * M_PI / HANABI_PARTS_NUM
*movehanabi
    repeat HANABI_MAX
        if( hanabi_life(cnt) <= 0 ) : continue

        hanabi_life(cnt)--
        color hanabi_r(cnt), hanabi_g(cnt), hanabi_b(cnt)
        ; hanabi_y(up_cnt)++
        up_cnt = cnt
        r = cos(M_PI * hanabi_life(cnt) / hanabi_life_max(cnt) / 2.0) * hanabi_radius(cnt)
        repeat HANABI_PARTS_NUM
            pos hanabi_x(up_cnt) + cos(HANABI_CST * cnt) * r, hanabi_y(up_cnt) + sin(HANABI_CST * cnt) * r
            mes CHAR_FACE_HANABI
        loop
    loop
    return

*addhanabi
    result = 0
    repeat HANABI_MAX
        if( hanabi_life(cnt) > 0 ) : continue

        hanabi_x(cnt) = x
        hanabi_y(cnt) = y

        size = 10 + rnd(12)
        hanabi_life_max(cnt) = size
        hanabi_life(cnt)     = size
        hanabi_radius(cnt)   = size * 3

        hsvcolor rnd(192), 255255
        hanabi_r(cnt) = ginfo_r
        hanabi_g(cnt) = ginfo_g
        hanabi_b(cnt) = ginfo_b

        result = 1
        break
    loop
    return result

*burstall
    repeat CHAR_MAX
        if( char_type(cnt) = CHAR_TYPE_NONE ) : continue

        x = char_x(cnt)
        y = char_y(cnt)
        gosub *addhanabi
        if stat : char_type(cnt) = CHAR_TYPE_NONE
    loop
    return

2008年6月7日土曜日

Online HSP Document Libraryをワンキーヘルプとして使う

ちょいネタ。
このスクリプトをから作成できる実行ファイルを既存のhelpman.exeと置き換えることで、Online HSP Document Libraryをワンキーヘルプとして利用できます。
実行ファイルの作成はctrl+F9の「実行ファイル自動作成」を利用してください。

#packopt name "helpman"
#packopt hide 1
    exec "http://www.onionsoft.net/hsp/ref/ohdl.cgi?cmd=hdsrch&arg="+dir_cmdline16
    end

2008年5月17日土曜日

自力型変換(int⇔str)

整数値と文字列を相互に変換します。HSPでは特に気にせず利用できる機能ですが、自力でやると結構面白いものです。

数値の桁数を計算するためにHSPMathのlog10関数を使用。おまけとしてTrim関数がついてます。

2008.05.17 memcpyをなくすことで計量化
// 自力で型変換
//     2008.05.17 計量化
#module
#include "hspmath.as"
// 文字列の始めと終わりにある半角スペースを除去
#defcfunc Trim str s, local target, local target_length, local result
    target = s
    target_length = strlen( target )
    repeat target_length
        start_idx = cnt
        if peek( target, start_idx ) != ' ' : break
    loop
    repeat target_length, 1
        end_idx = target_length - cnt
        if peek( target, end_idx ) != ' ' : break
    loop
    result = strmid( target, start_idx, end_idx + 1 - start_idx )
    return result

#define ctype not_digit(%1) ((%1) < '0' | '9' < (%1))

// 文字列を整数値に変換
#defcfunc str2int str s, local target, local result, local target_length
    result = 0
    target = Trim( s )
    if peek( target ) = '-' : sign = -1 : else : sign = 1
    if peek( target ) = '-' | peek( target ) = '+' {
        target = strmid( target, 1strlen( target ) - 1 )
    }
    target_length = strlen( target )

    for i, iStart, target_length
        if not_digitpeek( target, i ) ) : _break
        result = result * 10 + peek( target, i ) - '0'
    next
    return result * sign

// 整数値を文字列に変換
#defcfunc int2str int p, local target, local result, local result_length
    if p = 0 : return "0"

    target = abs( p )
    result_length = 1 + log10( target ) + ( p < 0 )
    sdim result, result_length + 1
    repeat 1 + log10( target ), 1
        poke result, result_length - cnt, ( target \ 10 ) + '0'
        target /= 10
    loop
    if p < 0 {
        poke result, 0'-'
    }
    return result
#global

2008年4月19日土曜日

花火ゲーム(やわらかライセンス)

( ゜ワ゜)ノさん原案、eller改造のミニゲーム。

このスクリプトはやわらかライセンスのもとで、自由に改造・配布が可能です。


/* HANABIGA @ やわらかライセンス by eller 2008/04/19
 * ===============================================
 * SAKURAGAからの改造個所:
 *     "さくら" → "たまや"       // "かぎや"でも良い
 *     キャラクタの移動動作変更(ちょい簡単に)
 *     背景色など色合い変更
 *     ゲームオーバー中はキャラクタを生成しないように
 *     キャラクタ接触時にどかーん
 *     ゲームオーバー時にどかーん
 *     redraw 0 と redraw 1 を入れ替え
 *     randomize追加
 *     640 → ginfo_winx など
 */


//#runtime "hsplet3"
#include "hspmath.as"
#packopt name "hanabiga"

#define FRAME_WAIT          16

#define PLAYER_SPEED        3.0
#define PLAYER_SP_REDUCE    0.8

#define CHAR_MAX            256
#define HANABI_MAX          8

#define CHAR_TYPE_NONE      0
#define CHAR_TYPE_SA        1
#define CHAR_TYPE_KU        2
#define CHAR_TYPE_RA        3

#define CHAR_FACE_SA        "た"
#define CHAR_FACE_KU        "ま"
#define CHAR_FACE_RA        "や"
#define CHAR_FACE_HANABI    "・"

#define HANABI_PARTS_NUM    14

#define CHAR_ROT_SP         0.05
#define CHAR_ROT_MOVE       0.8

#define CHAR_SIZE           16.0

// 準備
;   screen 0, 480, 320
    title "SAKURAGA 2008"
    font "MS ゴシック" ,16,1
    randomize

    player_x = double(ginfo_winx / 2)
    player_y = double(ginfo_winy / 2)
    player_vx = 0.0
    player_vy = 0.0

    dim char_type,CHAR_MAX
    ddim char_x,CHAR_MAX
    ddim char_y,CHAR_MAX
    ddim char_vx,CHAR_MAX
    ddim char_vy,CHAR_MAX
    dim char_timer,CHAR_MAX

    ddim hanabi_x,HANABI_MAX
    ddim hanabi_y,HANABI_MAX
    dim hanabi_radius,HANABI_MAX
    dim hanabi_life,HANABI_MAX
    dim hanabi_life_max,HANABI_MAX
    dim hanabi_r,HANABI_MAX
    dim hanabi_g,HANABI_MAX
    dim hanabi_b,HANABI_MAX

    buffer 1,640,480
    repeat 40
        color cnt0cnt * 2
        boxf 0 , cnt * ginfo_winy / 40 , ginfo_winx , (cnt + 1) * ginfo_winy / 40
    loop

    gsel 0
    gmode 3,,,64

// メイン処理

repeat
    // INIT
    gosub *initpl
    // タイトル
    repeat
        redraw 0
        gosub *clearscreen
        gosub *movehanabi
        gosub *movechar
        gosub *collision
        if(player_life > 0){
            gosub *moveplayer

            a = 10 - (player_score / 5) \ 10
            if( a < 2 ) : a = 1
            if(player_timer \ a  == 0) : gosub *addchar
        }else{
            gosub *burstall
            color 255255255
            pos (ginfo_winx - 198)/ 2, (ginfo_winy - 16) / 2
            mes "H A N A B I  O W A T A"

            stick inp
            if(inp & 16) : break
        }

        gosub *showstatus

        redraw 1
        await FRAME_WAIT
    loop
loop




*initpl
    player_x = double(ginfo_winx / 2)
    player_y = double(ginfo_winy / 2)
    player_vx = 0.0
    player_vy = 0.0
    player_life = 1
    player_chain_type = CHAR_TYPE_SA
    player_score = 0

    scroll_vx = 0.01
    scroll_vy = -2.0

    repeat CHAR_MAX
        char_type(cnt) = CHAR_TYPE_NONE
    loop
    return

*clearscreen
    pos 0,0
    gcopy 1,0,0,ginfo_winxginfo_winy
    return

*moveplayer
    stick inp,255

    if(inp & 1) : player_vx -= PLAYER_SPEED
    if(inp & 2) : player_vy -= PLAYER_SPEED
    if(inp & 4) : player_vx += PLAYER_SPEED
    if(inp & 8) : player_vy += PLAYER_SPEED
    player_timer++

    player_vx *= PLAYER_SP_REDUCE
    player_vy *= PLAYER_SP_REDUCE

    player_x = limitf(player_x + player_vx, 0.0ginfo_winx - CHAR_SIZE)
    player_y = limitf(player_y + player_vy, 0.0ginfo_winy - CHAR_SIZE)
    
    color 255
    pos player_x,player_y
    if( player_chain_type == CHAR_TYPE_SA ){
        mes CHAR_FACE_SA
    } else : if( player_chain_type == CHAR_TYPE_KU ){
        mes CHAR_FACE_KU
    } else : if( player_chain_type == CHAR_TYPE_RA ){
        mes CHAR_FACE_RA
    }
    return

*collision
    repeat CHAR_MAX
        if( char_type(cnt) == CHAR_TYPE_NONE ) : continue

        dx = player_x - char_x(cnt)
        dy = player_y - char_y(cnt)
        ifabs(dx) < CHAR_SIZE & abs(dy) < CHAR_SIZE ) {
            if( char_type(cnt) == player_chain_type ){
                player_chain_type++
                if(player_chain_type > CHAR_TYPE_RA){
                    player_chain_type = CHAR_TYPE_SA
                }

                player_score++
            }else{
                player_life--
            }
            char_type(cnt) == CHAR_TYPE_NONE
            x = char_x(cnt)
            y = char_y(cnt)
            gosub *addhanabi
        }
    loop
    return

*movechar
    color 255,128
    repeat CHAR_MAX
        if( char_type(cnt) == CHAR_TYPE_NONE ) : continue

        pos char_x(cnt) , char_y(cnt
        char_x(cnt) += char_vx(cnt)
        char_y(cnt) += char_vy(cnt)

        char_timer(cnt)++
        char_x(cnt) += CHAR_ROT_MOVE * sin(double(CHAR_ROT_SP * char_timer(cnt)))
        char_y(cnt) += CHAR_ROT_MOVE ;* cos(double(CHAR_ROT_SP * char_timer(cnt)))

        if( char_y(cnt) < -16.0 ) : char_type(cnt) = CHAR_TYPE_NONE

        if( char_type(cnt) == CHAR_TYPE_SA ){
            mes CHAR_FACE_SA
        } else : if( char_type(cnt) == CHAR_TYPE_KU ){
            mes CHAR_FACE_KU
        } else : if( char_type(cnt) == CHAR_TYPE_RA ){
            mes CHAR_FACE_RA
        }
    loop
    return

*addchar
    repeat CHAR_MAX
        if( char_type(cnt) != CHAR_TYPE_NONE ) : continue

        char_type(cnt) = 1 + rnd(3)
        char_x(cnt) = double(rnd(800) - 80)
        char_y(cnt) = 20.0 + ginfo_winy
        char_vx(cnt) = scroll_vx
        char_vy(cnt) = scroll_vy
        char_timer(cnt) = rnd(256)
        break
    loop
    return

*showstatus
    pos ginfo_winx - 120 , ginfo_winy - 20
    color 255255255
    mes "SCORE : " + player_score
    
    return


#const HANABI_CST 2.0 * M_PI / HANABI_PARTS_NUM
*movehanabi
    repeat HANABI_MAX
        if( hanabi_life(cnt) <= 0 ) : continue

        hanabi_life(cnt)--
        color hanabi_r(cnt), hanabi_g(cnt), hanabi_b(cnt)
        ; hanabi_y(up_cnt)++
        up_cnt = cnt
        r = cos(M_PI * hanabi_life(cnt) / hanabi_life_max(cnt) / 2.0) * hanabi_radius(cnt)
        repeat HANABI_PARTS_NUM
            pos hanabi_x(up_cnt) + cos(HANABI_CST * cnt) * r, hanabi_y(up_cnt) + sin(HANABI_CST * cnt) * r
            mes CHAR_FACE_HANABI
        loop
    loop
    return

*addhanabi
    result = 0
    repeat HANABI_MAX
        if( hanabi_life(cnt) > 0 ) : continue

        hanabi_x(cnt) = x
        hanabi_y(cnt) = y

        size = 10 + rnd(12)
        hanabi_life_max(cnt) = size
        hanabi_life(cnt)     = size
        hanabi_radius(cnt)   = size * 3

        hsvcolor rnd(192), 255255
        hanabi_r(cnt) = ginfo_r
        hanabi_g(cnt) = ginfo_g
        hanabi_b(cnt) = ginfo_b

        result = 1
        break
    loop
    return result

*burstall
    repeat CHAR_MAX
        if( char_type(cnt) = CHAR_TYPE_NONE ) : continue

        x = char_x(cnt)
        y = char_y(cnt)
        gosub *addhanabi
        if stat : char_type(cnt) = CHAR_TYPE_NONE
    loop
    return

2008年3月29日土曜日

文字列のセンタリング

どう書く?orgより。
文字列の長さに応じて、ifで分岐しています。もっとスマートに記述できないものでしょうか?

/*
    どう書く?org より
        文字列のセンタリング
        http://ja.doukaku.org/87/
*/


#runtime "hsp3cl"
#module
#defcfunc spaces int len
    if len <= 0 : return ""

    sdim s, len + 1
    repeat len
        poke s, cnt' '
    loop
    return s

#defcfunc centered_text str target, int len
    if len <= 0 : return ""

    target_length = strlen(target)
    result = target
    if target_length < len {
        result = spaces((len - target_length)/2) + target + spaces((len - target_length + 1)/2)
    } else : if target_length > len {
        result = strmid(result, (target_length - len)/2, len)
    }
    return result
#global

    s = "*"
    repeat 10
        mes centered_text(s, 15)
        s += " *"
    loop
    stop


追記。
ifによる条件分岐をlimit関数に置き換えました。

/*
    どう書く?org より
        文字列のセンタリング
        http://ja.doukaku.org/87/
*/

#runtime "hsp3cl"

#module
#defcfunc centered_text str _source, int len
    if len <= 0 : return ""
    source = _source

    source_strlen = strlen(source)
    sdim result, len + 1
    memset result, ' ', len
    poke result, limit((len - source_strlen)/20, len/2), strmid(source, limit((source_strlen - len)/20, source_strlen), len)
    return result
#global

    s = "*"
    repeat 10
        mes centered_text(s, 15)
        s += " *"
    loop
    stop

2008年3月18日火曜日

HSP入門者向け講座リンク集 更新

クロノス・クラウンにてHSP入門者向け講座リンク集が更新されました。HSP関連サイトを横断的に検索できるサービスも追加されています。

なお、当ブログは難易度中~高と評価されています。

関連

2008年3月6日木曜日

はてなスターを設置しました

動作確認用のテスト投稿です。