HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0924
孝乃花スコアの保存7解決


孝乃花

リンク

2021/9/24(Fri) 06:28:33|NO.93955

 2点教えていただきたいです。
.魯ぅ好灰△良充
 ゲームプレイ中、過去のハイスコアを表示する方法を知りたいです。スクリプトの正解数(seikai)を得点としたいです。

▲好灰△諒歛検Ε薀鵐ング作成・名前の表示
 ゲーム終了後、gameover、finishボタン選択の後に、スコアの保存、ランキングの表示をできるようにしたいです。

以下スクリプトです。
*Start
mmload"sht_a01.mp3",0,1
mmload"startsound.mp3",1,2
mmload"sht_a06.mp3",2,1
screen 0,600,400
mmplay 0
title "修造ENGLISH"
redraw 0
color:boxf
celload "266-0.png",1
color 255,0,0:font "HG明朝E",50:pos (870-50*11)/2,100:mes "修造ENGLISH"
color $FF,$FF,$00:font "HG明朝E",30:pos (600-30* 6)/2,180:mes "〜LEVEL1〜"
color 255,255,255:font "HG明朝E",30:pos (400- 8*15)/2,250:mes "スタート(Enter)"
:pos (400- 8*15)/2,275:mes "課金(SPC)"
pos (400- 8*15)/2,300:mes "終了(ESC)"

redraw 1
repeat
pos 400,200
celput 1
stick key
if(key&32):mmplay 1:break
if(key&16):mmplay 1:goto*kakin
if(key&128):mmplay 1:end
await 20
loop

mmplay 2
notesel buf
ab=0
ac=1

time=500 : ; await 20を500回くり返すことで約10秒に変更。


noteload "type1.txt",50000 : ; 外に出す。
sdim kaitou,500 : ; 外に出す。初期化は代入で行う。



*main
cls ; このスクリプトならclsでいいと思う。
pos 270,100
celput 1
pos 0,0
font "MS ゴシック",48,1
mes "正解="+seikai+"":mes "不正解="+huseikai+""
noteget a,ab
mes a
noteget b,ac
kaitou="" : ; 初期化。
objmode 2 : ; clsを残したので、これらも残す。
font msgothic,48
objsize 250,50
input kaitou
objsel 0 : ; これが無いと2回目以降にinputボックス内に入力カーソルがデフォで出ない。
mes "PUSH ENTER"

; mainを2つに分ける。
*main_2
time=time-1
redraw 0 : ; 画面のチラツキを防ぐ。
color 255,255,255 : boxf 300,300,599,399 : ; 残り時間の表示を消去。
color 0,0,0 : ; 消去の際に色を変えたので、文字の色に黒を指定。
pos 300,300
mes "残り時間:"+str((time+49)/50) : ; timeが49以下になると0と表示されるのを防ぐために49を足す。
redraw 1
if time<1:goto *gameover : ; 残り時間を表示させてから*gameoverに飛ぶように順番変更。
; wait 100は使わない。
stick ky
if (ky&32)!=0 :goto *judge : ; ifは私の好みの書き方なだけの変更。gosubをgotoに変更。
await 20 : ; wait 1を変更。
goto *main_2 : ; 変更。

*judge
if kaitou=b{
mes "正解"
seikai=seikai+1
}else{
mes "不正解"
huseikai=huseikai+1
}
wait 100
ab=ab+2
ac=ac+2

if huseikai=3:goto*gameover
goto *main : ; gosubをgotoに変えたのでreturnも変更

*gameover
clrobj:await 16
cls
redraw 1
pos 80,170:color 255,0,0
font "MS gothic",96
mes"Game Over"
pos 100,300
font "MS gothic",20
objsize 100,50
button"one more",*main
pos 300,300
button"finish",*Start
stop; 別ラベルに飛ぶように変更。

*longmode
mmplay 2
notesel buf
ab=0
ac=1

time=1000 : ; await 20を500回くり返すことで約10秒に変更。

noteload "type1.txt",50000 : ; 外に出す。
sdim kaitou,500 : ; 外に出す。初期化は代入で行う。
goto*main

*kakin
cls
font "MS gothic",96
pos 80,170:color 255,0,0
mes "2480円"
pos 100,300
font "MS gothic",20
objsize 100,50
button "購入",*oto
stop

*oto
mmplay 1
goto*longmode
よろしくお願いします。



この記事に返信する


SSSS

リンク

2021/9/24(Fri) 16:58:18|NO.93956

bsave命令やnotesave命令を使えば保存できます。
bsave命令の場合バイナリデータとして保存するので(比較的)解読されにくいです。
一応サンプルスクリプトです。

//保存するサンプル a = "椎名心美です。あなたは?" bsave "C:\\Users\\Public\\Document\\test.aaa",a


//読み込むサンプル b = "" bload "C:\\Users\\Public\\Document\\test.aaa",b mes b
修造ENGLISHとても面白そうなので完成したら是非見せてください。

font "",80 color 255,0,0 mes "修造式英単語道場、\n 始まるZO!"



沢渡

リンク

2021/9/24(Fri) 20:05:12|NO.93957

実際の実装についてはお任せするしかないので、やり方についてだけ。
あくまでもこれは「私ならこうする」というやり方です。

たとえば上位n人分のハイスコアを記録したいとして、
それらのスコアを記録するファイルが「scr.dat」、
スコアネームを記録するファイルが「scr_name.dat」だとします。
scr.datはn×4バイトのバイナリファイル(整数変数は一つ4バイト)、
scr_name.datはn行分のテキストファイルとします。
(スコアとスコアネームを一つにまとめる方法もあるが、
話が面倒になるので今回は二つファイルを作る)

まず、初めの方に置くべきデータ読み込み部分。

#const hiscr_num 10 //この人数分のデータを記録する dim hiscr,hiscr_num //人数分のハイスコア exist "scr.dat" : if strsize!=-1 : bload "scr.dat",hiscr,hiscr_num*4 //整数変数は一つあたり4バイト hiscr_name="" //スコアネーム notesel hiscr_name exist "scr_name.dat" : if strsize!=-1 : noteload "scr_name.dat" x=notemax if x<hiscr_num { //人数分の行数がないのなら行を追加 repeat hiscr_num-x noteadd "" loop } //以降、たとえば1位のスコアを取得したいのなら、スコアはhiscr(0)に入っていて、 //スコアネームはnoteget (任意の変数),0で取得できる。 //ただし、今回のスクリプトではbufもメモリノートパッド命令の対象にしているので、 //noteselで適宜切り替えること。

次にスコア登録部分。

//以下、今回のスコアはseikaiに入っているものとする。 rank=-1 //今回の順位。-1の場合はランク外。 repeat hiscr_num if seikai>hiscr(cnt) : rank=cnt : break loop if rank!=-1 { //スコア登録 //以下、スコアネームはmy_nameという変数内に入っているものとする。 repeat hiscr_num-1-rank //自分より下位のスコアを1位ずつズラす hiscr(hiscr_num-1-cnt)=hiscr(hiscr_num-2-cnt) loop hiscr(rank)=seikai bsave "scr.dat",hiscr,hiscr_num*4 //スコアネーム登録 notesel hiscr_name //ここでnoteselを使ったので、あとでもう一度noteselを使いbufに切り替える必要がある noteadd my_name,rank //順位の位置にスコアネームを挿入 if notemax>hiscr_num : notedel hiscr_num //ランク外になったスコアネームを削除 notesave "scr_name.dat" }



孝乃花

リンク

2021/9/24(Fri) 22:47:53|NO.93960

ご回答ありがとうございます。
SSSSさん、沢渡さんの方法で挑戦しましたが、できませんでした。
引き続き、スクリプト案、解説お願いいたします。



UT-X

リンク

2021/9/25(Sat) 00:50:53|NO.93961

HSP3Utilの機能に便利なものがあったので、それを使ったものを掲載します。
arraysave,arrayloadというもので、文字列型の配列変数を用いて
テキストファイルの読み書きができます。
ここでは、ハイスコアランキングを匿名かつ5位までのものとし、
「score.txt」に保存するものとします。
初期状態でのscore.txtの内容は、以下のようにしてください。

0 0 0 0 0

まず、スクリプトの一番最初(*Startの前)にこのコードを入れてください。
#include "hsp3util.as" ;配列変数による文書読み書きに使用する
sdim ranks,5 ;ここの数字がランキングの順位数となる dim hiscore,length(ranks)+1 ;順位数+1個分確保 arrayload "score.txt",ranks ;ランキングを読み込む noteunsel foreach ranks hiscore(cnt)=int(ranks(cnt)) ;文字列から数値に変換 loop

次に、スクリプトの一番最後にこのコードを入れてください。
*ranking
cls color 0,0,255 pos 10,10 font "MS gothic",36 if hiscore(0)<seikai{ ;1位だった場合、それを祝う mes "RANKING - HIGH SCORE!!" }else{ mes "RANKING" } font "MS gothic",48 sortval hiscore,1 ;そのうえで数字の大きな順に配列を並べなおす foreach ranks ranks(cnt)=str(hiscore(cnt)) ;数値を文字列に変換 loop arraysave "score.txt",ranks ;ランキングを表示する前に保存 noteunsel hitmp=0 foreach hiscore sortget hitmp,cnt if hitmp=5:color 255,0,0:else:color 0,0,0 if cnt<5{ ;順位によって1st、2nd、…となるようにする if cnt=0:ranktxt="1st" if cnt=1:ranktxt="2nd" if cnt=2:ranktxt="3rd" if cnt>2:ranktxt=""+(cnt+1)+"th" mes ""+ranktxt+" "+hiscore(cnt) }else{ if hitmp=5{ ;ランク外だった場合、5位のちょっと下に表示される(マリオ64DSリスペクト) mes "\n "+hiscore(cnt) } } loop color 0,0,0 pos 210,350 font "MS gothic",24 mes "ENTER でメインメニューに戻ります" mes "ESC で終了します" repeat stick key if(key&32):break if(key&128):end await 20 loop goto *Start

そして、*gameoverを以下のように書き換えます。
*gameover
clrobj:await 16 cls hiscore(5)=seikai ;hiscoreに1つ空きを持たせたので、そこに今回のスコアを代入 seikai=0:huseikai=0:ab=0:ac=1 ;リセット redraw 1 pos 80,170:color 255,0,0 font "MS gothic",96 mes"Game Over" noteunsel pos 100,300 font "MS gothic",20 objsize 100,50 button"one more",*main pos 300,300 button"finish",*ranking stop; 別ラベルに飛ぶように変更。

これでうまくいくはずです。



孝乃花

リンク

2021/9/25(Sat) 23:06:49|NO.93971

UT-Xさん、スクリプト案ありがとうございます。
理想としていたものに近づき、感激しています。
もう3つだけ、お聞かせください。
.廛譽っ罎妨什澆離魯ぅ好灰△鯢充┐気擦詈法はあるでしょうか?
▲薀鵐ングの中に、スコアと共に名前を入れる方法はあるでしょうか?
ランキングを10位まで増やすにはどうしたらよいでしょうか?
どうぞ、よろしくお願いいたします。



UT-X

リンク

2021/9/26(Sun) 11:28:33|NO.93977

1.*mainの以下の部分を書き換えてください。
mes "正解="+seikai+"":mes "不正解="+huseikai+""
↓ mes "ハイスコア="+hiscore(0)+"":mes "正解="+seikai+"":mes "不正解="+huseikai+""
これで、プレイ中にもハイスコアが表示されるようになります。

2.まず、*Startの前の部分を次のように書き換えてください。
#include "hsp3util.as" ;配列変数による文書読み書きに使用する
RANKMAX=5 ;ここの数字がランキングの順位数となる sdim ranks,64,RANKMAX ; ファイルの読み書きに用いる sdim scores,64,RANKMAX ; 文字列と数値の変換に用いる dim hiscore,RANKMAX+1 ; スコア用 順位数+1個分確保 sdim rankname,64,RANKMAX+1 ;名前用 順位数+1個分確保 arrayload "score.txt",ranks ;ランキングを読み込む repeat RANKMAX getstr scores(cnt),ranks(cnt),0,' ' getstr rankname(cnt),ranks(cnt),strsize,0 hiscore(cnt)=int(scores(cnt)) ;文字列から数値に変換 loop
次に、*gameoverの以下の部分を書き換えてください。
hiscore(5)=seikai ;hiscoreに1つ空きを持たせたので、そこに今回のスコアを代入
↓ hiscore(RANKMAX)=seikai ;hiscoreに1つ空きを持たせたので、そこに今回のスコアを代入
最後に、*ranking以下を次のように書き換えます。

*ranking cls color 0,0,255 pos 10,10 font "MS gothic",36 if hiscore(0)<seikai{ ;1位だった場合、それを祝う mes "RANKING - HIGH SCORE!!" }else{ mes "RANKING" } font "MS gothic",48 sortval hiscore,1 ;数字の大きな順に配列を並べなおす hitmp=0 sdim ranknames,64,RANKMAX+1 ;名前を並び替えるのに使う foreach hiscore sortget hitmp,cnt ranknames(cnt)=rankname(hitmp) if hitmp=RANKMAX:color 255,0,0:else:color 0,0,0 pos 10 if cnt<RANKMAX{ ;順位によって1st、2nd、…となるようにする poy=ginfo_cy if cnt=0:ranktxt="1st" if cnt=1:ranktxt="2nd" if cnt=2:ranktxt="3rd" if cnt>2:ranktxt=""+(cnt+1)+"th" mes ""+ranktxt+" "+hiscore(cnt) pos 180,poy if hitmp=RANKMAX{ input ranknames(cnt),410,ginfo_mesy,24 }else{ mes ranknames(cnt) } }else{ if hitmp=RANKMAX{ ;ランク外だった場合、最下位のちょっと下に表示される(マリオ64DSリスペクト) rankin=0 mes "\nYou "+hiscore(cnt) }else{ ;ランキングに入っている場合、名前登録を促す rankin=1 font "MS gothic",28 mes "\n名前を上の欄に\n入力してください" } } loop font "MS gothic",24 pos 290,290 objsize 300,50 if rankin=1{ button "セーブしてメニューへ",*ranksave tomenu=stat button "セーブして終了",*ranksave }else{ button "メニューへ",*ranksave tomenu=stat button "終了",*ranksave } stop *ranksave if stat=tomenu:menuflg=1:else:menuflg=0 ;どちらのボタンを押したか判別 if rankin=1{ ;ランク外の時は保存処理を飛ばす foreach hiscore rankname(cnt)=ranknames(cnt) if cnt=RANKMAX:break scores(cnt)=str(hiscore(cnt)) ;数値を文字列に変換 ranks(cnt)=scores(cnt)+" "+rankname(cnt) loop arraysave "score.txt",ranks ;ランキングを保存 } if menuflg=1:goto *Start end
これで名前も保存されるようになります。
score.txtには得点と名前が半角スペースで区切られて保存されます。

3.(2.の処理を行ったものとします)スクリプトの最初にある
RANKMAXの値がそのままランキングの順位数となるので、それを10にすれば10位まで表示できます。
ただし、それに合わせて文字のサイズや配置を調整する必要があります。



孝乃花

リンク

2021/9/26(Sun) 13:12:56|NO.93988

UTーXさん、ありがとうございます!!
できました!感激です!
本を読んでも、サイトを調べてもよくわからなかったので助かりました。
ただ、何でこれでできるのか、仕組みがまだよくわからないので、学習に努めます。
今後とも、ご指導よろしくお願いいたします。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.93955への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2021(c) All rights reserved.