スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[WP]no.007 リプレイ記録(TonyuSystem)

powも無ぇ!logも無ぇ!continueも参照型もビット演算も無ぇ!
おらTonyuざ嫌だ~ hspへ出るだ~ 原曲よく知らない


TonyuSystemでリプレイファイルの記録、再生。
WeeklyPrograming扱いにしておこう… 製作時間は1時間ちょっと。

中学生くらいにSTGを作成した時にリプレイ載せようと思って載せれなかったことを突然思い出したので。
TonyuSystemにはビット演算が無いので、剰余でなんとか。


実行方法:Managerクラスのオブジェクトのみを画面に生成しておき、実行する。

遊び方
Readyと表示されている状態で、Spaceを押す。
すると直ぐにPlayerオブジェクトが表示されるので、方向キーで適当に動かしてみる。
この時、「rec0.dat」というファイル名で入力を書き出している。
300F経過後、Playerオブジェクトは死ぬ。
その後、再びPlayerオブジェクトが表示され、rec0.datを読み込み、操作を再現する。

バグはあるかも知れません。

小数点計算の精度があまりよろしくないので、全く同じような動作をするとは限らない、と説明しておきます。
一定タイミングでキーフレームの挿入等の対策が必要。余計ずれそうな気はしますが。

あぁ、バージョンは1.27(Html5でない方)です。Tonyu2はよく分からないです(ファイルの読み書き辺りなど)



KeyCtrlクラス
extends Object;

// mode 0=record 1=play
// status 0=ready 1=run

constructor KeyCtrl(m){
mode=m;
status=0;
data=0;
predata=0;
}

function fileopen(f){
if (mode==0){
file=new FileWriter(f);
}
if (mode==1){
file=new FileReader(f);
}
}

function fileclose(){
file.close();
}

// 得られる値は0か1なので注意
// 押されたフレーム数でない
function _getkey(id){
c=pow(2,id);
return (data/c)%2;
}

// フレーム終了後ではなく、フレーム開始前に1回だけ呼び出す。
// どちらも大して変わらないが。
function _update(){
j=1;
if (mode==0){ // 書き出しモード
// 現在のキー情報を作る
data=0;
for (i=0;i<7;i++){
if (id2codekey(i)!=0){
data+=j;
}
j=j*2;
}
if (status==1){ // 書き出し中
if (predata!=data){ // キーの状態に変化があった
if (count!=0) file.write(count*2); // フレーム数書き出し
file.write(data*2+1); // キー情報書き出し
count=0;
}else{
if (count==127){ // 1byte=0~255なので、127までしか書き出せない
file.write(count*2); // フレーム数書き出し
count=0;
}
count++;
}
predata=data;
}else{
count=0;
predata=-1;
}
}else if(mode==1){ // 読み出しモード
if (count<=0){ // フレームが0になった。
count=0;
d=file.read(); // 次のデータを読み出す
if (d%2==0){ // フレーム数データを取り出した
count=d/2;
}else{ // キー情報を取り出した
data=(d-1)/2;
}
}else{
count--;
}
}
}

function run(){
status=1;
count=0;
}
function stop(){
status=0;
}

function id2codekey(id){
if (id==0) return getkey(90);
if (id==1) return getkey(88);
if (id==2) return getkey(37);
if (id==3) return getkey(38);
if (id==4) return getkey(39);
if (id==5) return getkey(40);
return 0;
}

// aのb乗を計算。ただし、bは整数かつ0以上。
function pow(a,b){
var r;
for (r=1;b>0;b--)r=r*a;
return r;
}

Managerクラス

extends SecretChar;


while(1){
while (!getkey(32)){ // space押されるまで待機
drawText(10,10,"Ready",$clBlack,14);
update();
}

// player生成
a=new Player(100,100,3,0);
appear(a);
a.key=new KeyCtrl(0);
a.key.fileopen("rec0.dat");
a.key.run();

while (!a.died){ // 死ぬまで待つ
update();
}

// player生成
a=new Player(100,100,3,0);
appear(a);
a.key=new KeyCtrl(1);
a.key.fileopen("rec0.dat");
a.key.run();

while (!a.died){ // 死ぬまで待つ
update();
}
}

Playerクラス

extends SpriteChar;

vx=0.0;
vy=0.0;
while (key==null) update(); // keyが与えられるまで待機


for(t=0;t<300;t++){
key._update();
if (key._getkey(2)) vx-=0.2;
if (key._getkey(3)) vy-=0.2;
if (key._getkey(4)) vx+=0.2;
if (key._getkey(5)) vy+=0.2;
x+=vx;y+=vy;
vx=vx*0.95;
vy=vy*0.95;
update();
}

function onDie(){ // keyの後処理は自分で
key.stop();
key.fileclose();
}


初心者向きではないです。KeyCtrlはPlainCharでないことに注意。
pow(a,b)は、aのb乗を計算します。ただし、bは整数かつ0以上。

出力されるデータファイルは、1ビット目が0ならば、その文字はフレーム数、1ならばキー入力の変更

うまく改変して載せてみてください。



追記20150716
肝心な説明を忘れていた。

本来は
1.キー状態から数値(1byte)を作る
2.数値をファイルに書き込む
3.Update();で同期

で十分ですが、生成される数値は前回と同じであることが多いですね?
1フレーム単位でキーボード入力を押したり離したり忙しいゲームは滅多に無いと思います。格ゲー?
同じbyteデータが何度も続く…これは圧縮するしかない…!
なので、キー入力情報の後にフレーム数のデータを入れてます。「xxyyzzという入力はttフレーム続きますよー」情報。一応、1Fだけの時は省略できるようなデータ構造にはなっていますが、通常のプレイでは要らない気がします。そんな事に1bit割いてるなら、127->255フレームまで対応できるようにした方がファイルサイズ小さくなるかも。

次回のweeklyprogramは圧縮伸張でもいいですなぁ
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

tag : TonyuSystem

コメントの投稿

非公開コメント

ブログ移転のお知らせ
ブログをshonen.hateblo.jpに移転します. 新規の記事はこちらに投稿します.
プロフィール

舞葉(ぶよう)

Author:舞葉(ぶよう)
github.io
はてなブログ(競プロ)

古い記事のソースコードは色分けしていないので、高機能テキストエディタに貼り付けたほうが見やすいかも。

検索フォーム
このブログについて
自分がつまづいた話題、なんとなく書きたいと思ったこと、ググったけど殆ど資料なかったぞオイ な話等をアップする予定。通りすがりでも、参考になっていただければと。プログラムの例外入力、メモリリークは責任負いません。投稿された記事は修正・削除する場合があります。
カテゴリ
タグ

HSP3アルゴリズムとデータ構造c++RubyJavaUnity画像解析C機械学習C#LinuxcodeIQKinectMinecraftTonyuSystemraspberrypiPythonHTML5音声制御Simulinkruby俺ルール通信制御Javascriptシミュレーション

counter-shinobi
固定記事
最新記事
最新コメント
月別アーカイブ
ブロとも申請フォーム

この人とブロともになる

アクセスランキング
[ジャンルランキング]
コンピュータ
635位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
94位
アクセスランキングを見る>>
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。