|
|
2012/3/31(Sat) 01:23:00|NO.45656
STGを作った次は2Dアクションにチャレンジしようと思ったのですが、
完全に行き詰りました。(参考スクリプトをみてやる気を失う。)
なので、ざっと2Dアクションの仕組みを知っておこうと考えたのです。
自機のあたり判定、マップの作り方、スクロールの方法・・・
STGとのあたり判定の違いに困っています。
あたり判定を複数作るには具体的にどうしていいか・・・
とにかく分かりやすく説明していただけると助かります。
解説お願いします。
|
|
2012/3/31(Sat) 10:04:16|NO.45665
>自機のあたり判定、マップの作り方、スクロールの方法・・・
>STGとのあたり判定の違いに困っています。
>あたり判定を複数作るには具体的にどうしていいか・・・
マップデータは色々作り方があるのですが、
0,0,0,0,0,0
0,0,0,0,1,1
1,1,1,1,1,1
と言うように全てのチップにIDをつけ、それを並べる方法ですね。
[0]が当たり判定の無いチップ、
[1]が当たり判定のある床や壁のチップと言う感じです。
フリーソフトで上記のようなデータが作れるマップエディタもありますし活用してみて下さい。
当たり判定を複数作る方法は、キャラデータを配列にするのが一般的です。
・全キャラ同士の当たり判定
・周囲マップチップの当たり判定
ループなどを使って1つずつ総当りしてチェックします。
|
|
2012/4/1(Sun) 15:34:29|NO.45676
Veさん解答ありがとうございます!
何となくイメージが湧いてきました。
ですが、
>当たり判定を複数作る方法は、キャラデータを配列にするのが一般的です。
というところがイマイチよくわかりません(汗)
マップのチップにIDをふる・・・マッピング経験ゼロ?でして
そのところの具体例を挙げていただいて説明してくださると助かります。
|
|
2012/4/1(Sun) 18:06:54|NO.45677
かたちだけ紹介しよう。
//文字列にしたほうがマップデータは書きやすいですよ。
//まあ、最終的には数字配列のほうが便利ですけど、
//今はこれでOK
screen 0, 320, 320
sdim MapData, 5000 ;マップデータを入れる配列
sdim MapLine, 500 ;マップの行取得のときの行取得
dim BlockX , 100 ;ブロックのX座標
dim BlockY , 100 ;ブロックのY座標
//マップデータ作成
MapData ="0000000000"+"\n"
MapData+="0000000000"+"\n"
MapData+="0000000000"+"\n"
MapData+="0000000000"+"\n"
MapData+="0000000000"+"\n"
MapData+="0000000000"+"\n"
MapData+="0011110000"+"\n"
MapData+="0000000000"+"\n"
MapData+="1111111111"+"\n"
MapData+="0000000000"
notesel MapData
noteget MapLine, 0
MapX = strlen(MapLine) ;マップのXサイズ
MapY = noteinfo(0) ;マップのYサイズ
MapSize = MapX*MapY ;マップのサイズ
buffer 2
repeat MapSize
/*ここで仮想ウィンドウにマップ描写*/
//一行ずつnotegetで取得し、peekを使おう
//peekの返り値をswitch文で判定して描写
//この際、1の数を調べておく。また、すべてのブロックの座標を、
//BlockXとBlockYに同時に入れる。
loop
gsel 0
//メインループ
repeat
redraw 0
//画面クリア
color 255, 255, 255 :boxf
//本来ならgosubで飛ばしまくるけど今回はシカト
/*ここに自分の描写と動きのプログラムを組む*/
/*ここにbuffer 2をコピーするプログラムを組む*/
/*ここで当たり判定を書く*/
//当たり判定はrepeat~loopで1の数だけ繰り返して行う
//当たり判定はBlockXやBlockYを駆使してがんばって作る
//(自分も去年の夏苦労しました。)
redraw 1
await 10
loop
もうすぐ、自分は自分のようなプログラミング初心者のためのHPを立てるので、
わからなくなったら来てください。(関係ないことすみません)

| |
|
2012/4/1(Sun) 20:05:22|NO.45678
spiderさん、サンプルスクリプト(?)ありがとうございます。
全く見たことが無い形なのでとても参考になると思います。
僕も質問するばっかじゃいけないので解読を頑張らないと・・・
(sdim関数を用いている2行あたりからいきなりつまづいた!)
|
|
2012/4/1(Sun) 20:43:36|NO.45680
catsさん、
>数字だけを並べる方法だと1つの画像ファイルから10個(0~9)のマップチップしか
>表示できないと思うので
がよくわかりません(汗)
さっそく混乱気味です・・・
spiderさんにも質問返していいですか?
「+"\n"」という部分は改行ということでしょうか、
mesを用いてためしに表示してみたところ\nの文字列が消え、
代わりに改行さえれています。
なんだかよくわからなくなってきました。
|
|
2012/4/1(Sun) 21:26:23|NO.45681
例えばブロックの絵が15個あったとします。
その15個を0~14の数字に代入しようとします。
しかし
01234567891011121314
という数字の書き方だとプログラムは
「10」を「1のブロックの絵と0のブロックの絵」に分けて読み込んでしまいます。
同じく「11」も「1の絵と1の絵」、「12」も「1の絵と2の絵」となってしまいます。
そこで
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
という書き方で「,」で区切って読み込ませると10以降の数字もきちんと読み込みます。
説明が下手ですみません;
まあ「,」が入るとプログラムが分からないのならば
「ア」や「イ」などのカナを使ってもかまいません。
|
|
2012/4/1(Sun) 21:51:34|NO.45684
catsさん、なるほど、そういうことですか!
そう考えると
000102...2021222324という風に
二文字ずつ取得すると、文字も読みやすくていいかもしれません!
(今の僕の技術量だと実現不可だが・・・)
spiderさんのサンプルに使われている、
\nの使い方がいまいちよく分かりませんが誰か説明お願いします。
|
|
2012/4/1(Sun) 22:17:00|NO.45688
「\n」は改行に使います。
MapData ="0000000000"+"\n"
MapData+="0000000000"+"\n"
つまり"0000000000"が一行目で"\n"で改行して"0000000000"を二行目にする、
というプログラムです。
(例)
mes "改行します\n改行しました"
|
|
2012/4/1(Sun) 22:39:55|NO.45690
おっ進んでますね。
遅れたようですんまへん。
で、本題へ。
自分は最初から文字列主義なんですが、
やりやすいやりにくいは個人差なので陸百-Kさんにお任せします。
あと、0~15までなら扱えますよ。(16進数を使って)
めんどくさいからどうしても15まで使いたいときしかやんないけど・・・
Buf ="ABCDE"+"\n"
Buf+="FFFFF"
String = strmid(Buf, 0, 1)
mes int(strf("$%s", String))
この場合、peekは使えません。strmidを使おう。(無駄かも)
|
|
2012/4/1(Sun) 22:44:29|NO.45691
続けてすみません。
上のは、雛形です。
(実際にアクションゲーに取り入れるには改造が必要)
それと文字列二列になっててすいません。(いみねぇ)
いろいろあほですみません。
|
|
2012/4/1(Sun) 22:55:25|NO.45692
catsさん、\nの使い方が分かりました!ありがとうございます!
spiderさんのスクリプトへ再度質問します。
buffer 2への描写(マップ部品)ですが、具体的にどう位置指定していいかわかりません(汗)
質問してばかりでもうしわけないのですが、やはり見本を見て覚えたいものです。
僕の勝手な構想では以下のようになっているのですが・・・
;一行目の描写
if mapsize>=0 & mapsize<=10 {
pos 0+30*mapsize,0 ;+30はマップチップXサイズの分
gcopy ~
}
みたいになってしまいます。(なぜか)
もっと効率の良さそうな一般的なスクリプトの組み方というか、
マップの描写部分をもう少し詳しく教えていただけませんか?
|
|
2012/4/1(Sun) 23:03:25|NO.45693
spiderさん、どうもタイプ速度が遅すぎて返信に間に合いません(汗)
なんだか16進数とか扱ったことがないものがでてきてしまいました;
とりあえず、僕は文字列型の数値だけをあ使うことにします。
それと、
>catsさん、なるほど、そういうことですか!
>そう考えると
>000102...2021222324という風に
>二文字ずつ取得すると、文字も読みやすくていいかもしれません!
>(今の僕の技術量だと実現不可だが・・・)
は可能でしょうか、00→0に置換されてそうなのですが・・・
|
|
2012/4/2(Mon) 01:21:07|NO.45700
HSP3フォルダ\sample\game\にマップチップ描画のサンプルがある
map1.hsp
map2.hsp
>は可能でしょうか、00→0に置換されてそうなのですが・・・
文字列型(sdim,str)と整数型(dim,int)の違いを理解した方が良いと思う
|
|
2012/4/2(Mon) 06:00:57|NO.45704
暇人さん、僕はとてつもない馬鹿野郎でした((
文字列型と整数型の違いはわかっていたみたいなのですが、
どこかショートしていたようです(((((
たぶん、a=00→a=0みたいなことを想像したからだと(馬鹿
a="00"は何かしない限り文字列型のままなんですよね・・・
サンプルありましたか、後で見ておきます。
|
|
2012/4/2(Mon) 06:19:48|NO.45705
>HSP3フォルダ\sample\game\にマップチップ描画のサンプルがある
>map1.hsp
>map2.hsp
のmap2.hspの28行目までは、それでも何となくわかるかな~程度の
ものだったんですけど、29行目以降が難しいです。
|
|
2012/4/2(Mon) 11:31:02|NO.45707
>29行目以降が難しいです。
29行目からはマップの描画をしています。
24~27行目の数字で描画するチップを決めています。
何も指定しなければ0(草原)になります。
gmode 0
repeat [縦のマップチップ数(Y)]
y=cnt ;Yを1カウント
pos 0,y*cy ;
repeat [横のマップチップ数(Y)]
x=cnt;Xを1カウント
celput map_id,map(x,y) ;"mapbg.bmp"を描画する
/*↑では24~27行目できめた場所に決めたマップチップを描画*/
/*例えば25行目にmap(2,2)=1を追加すると(2,2)に森が描画される*/
loop
loop
あとcelputはgcopyと同じような命令です。
|
|
2012/4/2(Mon) 12:20:48|NO.45708
repeat~loopをいっぺんに二回使うのが解かりづらければ、
次のようにすれば一度ですみます。
screen 0, 192, 192
sdim Buf, 5000 ;確保
sdim BufLine, 500 ;確保
//マップデータ作成
Buf ="000000"+"\n"
Buf+="001100"+"\n"
Buf+="000000"+"\n"
Buf+="001100"+"\n"
Buf+="000000"+"\n"
Buf+="111111"
//文字列の情報を取得
notesel Buf
noteget BufLine, 0 ;一行取得して
MapX = strlen(BufLine) ;横の長さを取得
MapY = noteinfo(0) ;行数取得
MapSize = MapX*MapY ;マップの文字数取得
repeat MapSize ;文字数だけ繰り返し
x = cnt\MapX ;\は余算なので一文字ずつ調べていったときの横のインデックスになる
y = cnt/MapX ;/は除算なので一文字ずつ調べていったときの縦のインデックスになる
noteget BufLine, y ;行取得
Code = peek(BufLine, x);1byte取得
//比較して描画
switch Code
case '1' ;コードで返されるのでクォーテーションをつける
boxf x*32, y*32, x*32+31, y*32+31 ;32はマップチップのサイズです
swbreak
swend
loop
|
|
2012/4/2(Mon) 19:21:34|NO.45714
もう細かいところは理解できないんですけれども、
spiderさんのサンプルでは
マップのすべてを指定しているのに対し、
00001000 □□□■□□□
00000000 □□□□□□□
11111111 ■■■■■■■
map2.hspのスクリプトは、座標を細かく指定して、
描写しているということですね!
(4,1) □□□■□□□
(0,2) □□□□□□□
(1~7,3) ■■■■■■■
ここまで分かってやはり描写部分が理解できない・・・
|
|
2012/4/2(Mon) 19:50:36|NO.45715
返信遅れてわけわからなくならないようにするために時刻書いておきます。
19:31
spiderさんのスクリプトの・・・
> repeat MapSize ;文字数だけ繰り返し
のあたりまでは理解できて...いるんですけれど
19:37
>x = cnt\MapX ;\は余算なので一文字ずつ調べていったときの横のインデックスになる
>y = cnt/MapX ;/は除算なので一文字ずつ調べていったときの縦のインデックスになる
\を式に用いたことがないので、試してみたんですが、0\10=0 , 1\10=1 , 2\10=2...
\は割り算記号と同じ役目を持つんですか?
ということは、xとyは同じ数値になるんじゃ・・・あれ?
|
|
2012/4/2(Mon) 19:58:09|NO.45716
|
|
2012/4/2(Mon) 20:12:26|NO.45718
どの順で描画されているのかはwaitを入れると分かりやすいですね。
repeat MapSize ;文字数だけ繰り返し
x = cnt\MapX ;\は余算なので一文字ずつ調べていったときの横のインデックスになる
y = cnt/MapX ;/は除算なので一文字ずつ調べていったときの縦のインデックスになる
noteget BufLine, y ;行取得
Code = peek(BufLine, x);1byte取得
//比較して描画
switch Code
case '1' ;コードで返されるのでクォーテーションをつける
color 0,0,0 ;黒
swbreak
default
color 200,200,200 ;灰
swend
boxf x*32, y*32, x*32+31, y*32+31 ;32はマップチップのサイズです
await 200
color 255,0,0 :pos x*32, y*32 :mes ""+Code ;文字コードを赤で表示
loop
|
|
2012/4/2(Mon) 20:13:16|NO.45719
spiderさんの\を使ったスクリプト、カッコいいです!
よく意味が分からなかったので、
repeat 100
mes ""+(cnt/10)+" "+(cnt\10)
loop
とやったら、
感動しました!
初心者にもわかりやすい(?)
for~nextを載せときます
screen 0,800,450
map(0)="000000000000000000000000"
map(1)="000010000000000000000000"
map(2)="000000000000000000111111"
map(3)="001000000000000000000000"
map(4)="000000000000100000000000"
map(5)="000000000000000010000000"
map(6)="001000000000000111000000"
map(7)="001000000100001111100000"
map(8)="111111111100111111110011"
repeat 400
redraw 0
color 255,255,255:boxf
color
;描画部分▼
for y,0,10
for x,0,24
if strmid(map(y),x,1)="1":boxf x*50+ずれ,y*50,x*50+49+ずれ,y*50+49
next
next
;描画部分▲
ずれ--
redraw 1
await 20
loop
dialog "クリアー(笑)":end
|
|
2012/4/2(Mon) 20:21:05|NO.45720
ようやくこの意味が分かったような気がする!
x = cnt\MapX ;\は余算なので一文字ずつ調べていったときの横のインデックスになる
y = cnt/MapX ;/は除算なので一文字ずつ調べていったときの縦のインデックスになる
|
|
2012/4/2(Mon) 20:26:49|NO.45721
あ、TMKLさんの解答をいただいて
>\は割った余りですよ
>mes 5\2
わかりました!
逆に、次の
>screen 0,800,450
>map(0)="000000000000000000000000"
>map(1)="000010000000000000000000"
>map(2)="000000000000000000111111"
>map(3)="001000000000000000000000"
>map(4)="000000000000100000000000"
>map(5)="000000000000000010000000"
>map(6)="001000000000000111000000"
>map(7)="001000000100001111100000"
>map(8)="111111111100111111110011"
>
>repeat 400
>redraw 0
>color 255,255,255:boxf
>color
>
>;描画部分▼
>for y,0,10
>for x,0,24
>if strmid(map(y),x,1)="1":boxf x*50+ずれ,y*50,x*50+49+ずれ,y*50+49
>next
>next
>;描画部分▲
>
>ずれ--
>redraw 1
>await 20
>loop
>
>dialog "クリアー(笑)":end
が分からなくなった(汗)
|
|
2012/4/2(Mon) 20:30:30|NO.45722
私のは無視してください!
spiderさんのスタイリッシュなスクリプトを参考にしてください!!!
|
|
2012/4/2(Mon) 20:33:55|NO.45723
あ、ミスってる
for y,0,10 ×
for y,0,9 ○
|
|
2012/4/2(Mon) 20:39:26|NO.45724
もうわからない!
とにかくspiderさんのスクリプトを再度
見直してみます・・・
たしか、割り算の余算を利用したx,yのインデックスのあたりまで
理解したはず・・・だから、次は
|
|
2012/4/2(Mon) 20:47:38|NO.45725
それにしても、マップスクリプトを描写も含めて
28行で収めるなんて、スゴイ・・・
一通り理解できて(なんとなくだけれど)
おもわず拍手してしまった((
|
|
2012/4/2(Mon) 21:16:01|NO.45728
|
|
2012/4/2(Mon) 22:12:44|NO.45734
また出遅れました。(HP完成させてた)
で、言いたい事は
①慣れればみんなより速く、短いスクリプトをかけますよ。
②横スクロールアクションにするなら、
非常にシンプルなものからはじめましょう。
そして、当たり判定という壁とスクロール処理という壁に
ぶち当たるでしょう。がんばってください!!!
③トホホッティーさんのようなアクションゲーからつくるのも
アリかもしれません。それなら、重力加速度、スクロール、
綿密な当たり判定などの難題からは解放されますし。
|
|
2012/4/2(Mon) 23:09:35|NO.45736
みなさんありがとうございました。
このスレもだいぶ長くなってしまいましたので、とりあえず・・・
解決しましたということで(マッピングの仕組みは大体分かった)
また分からなくなったら質問させていただきます。
みなさん本当にありがとうございました!
|
|