2013年2月15日金曜日

しずくデモ

しずくが上から落ちてきて、いっぱいになったらまた最初から繰り返すデモです。
終了するには「×」を押してください。

/******************************************************************/
/* しずくデモ
/******************************************************************/
/* 内蔵フォントを使うので、全角文字もOK

/* これらは変数であって定数ではないので、グローバル配列の大きさ指定やcase値には使えない
int WX ://=(80/2)
int WY ://=24
int MAX =75  :/* 棚の本数   
int LNG =5  :/* 滴の最大長さ

/* 内部キャラクター
int WALL='#' :/* 外壁
int BALL='o' :/* 滴  
int TANA='=' :/* 棚 
int SPC =' ' :/* 空間

int dx,dy :/* 移動方向
int clng :/* 動作中ポインター
int retY :/* X-BASICレベルでは2つのリターン値を戻せないのでグローバル変数を経由する

dim int drpx(5)   :/* 移動x座標バッファー
dim int drpy(5)   :/* 移動y座標バッファー
dim char tvram(96,96) :/* 仮想VRAM / virtual video RAM
      :/* 機種によってサイズが可変なので、最大値で確保しておく

int wtt  :/* ウエイト

/******************************************************************/
/* メインルーチン
/******************************************************************/

getWidth(WX,WY):// システムの設定したテキスト画面サイズを得る
setUpScroll(NO):// テキスト画面の上スクロールを止める (V2.0)
 WX=WX/2
MAX=(WX*WY/13)
int ts,t
/*int c
 srand2() /* 乱数初期化
 wtt=CalcWait()/100*8:/* ウエイト算出(8ms)
 repeat
  InitScreen() :/* 画面初期化
  if Cascades() then break:/* 滴移動
  beep()
  locate(8,7)
  if isLocalizeJapan() then {
   print "もう一度見ますか? ";
  } else {
   print "Watch again ?";
  }
 /* c='Y';
  ts =time()
  repeat:/* 15秒たったら自動的に再開する
   t=time()
  until t-ts>=15
 until NO :/*(c<>'Y' && c<>CR)
end

/******************************************************************/
/* 以下内部関数
/******************************************************************/

func InitScreen()
/* 初期画面作成
int i,j,x,y
 cls()
 print "  CASCADES"
 init_tvram()

 /* 外枠作成
 for y=1 to WY-2:/* 縦
  storexy(   0,y,WALL)
  storexy(WX-1,y,WALL)
 next
 for x=0 to WX-1:/* 横
  storexy(x,WY-1,WALL)
 next

 /* 棚作成
 for i=0 to MAX-1
  x=1+rand2(WX-2) :/* 両端を除く
  y=2+rand2(WY-3) :/* 一番上とその次と最下行を除く
  for j=0 to 3
   if (x+j>=WX-1) then break /* x-over
   if (scrn(x+j,y)=SPC) then storexy(x+j,y,TANA)
  next
 next
 // 全画面一気表示
 printScreenAll(1,WY-1)
endfunc

/******************************************************************/

func int Cascades()
/* 滴処理
int x,y
//int ts=time():/* 開始時間
//int t,dt=0
 while CheckDropPoint()=0
  /* 開いているとき
  /* 初期位置設定
  x=SetFirstPoint()
  y=1
  repeat
   //t=time()
   //if t-ts>dt then { :/* 秒が変った
   // dt=dt+1
   // locate(30,0):print dt;
   //}
   //if inkey()=ESC then return(1)

   /* 移動&表示
   Drop(x,y)
   if clng=0 then break
   clng=clng-1
   x=drpx(clng)
   y=drpy(clng)
  until x=0 and y=0
 endwhile
 /* 最上行が開いていなかったら終わり
 return(0)
endfunc

/******************************************************************/

func int CheckDropPoint()
/* 最上行が開いているかどうかを調べる
int x
 for x=1 to WX-2
  if scrn(x,1)=SPC then return(0) :/* 開いている
 next
 return(1) :/* 開いていない
endfunc

/******************************************************************/

func int SetFirstPoint()
/* スタートポイント設定(最上行)
int i,x
 x=1+rand2(WX-2):/* 始点決定
 while scrn(x,1)<>SPC
  x=x+1
  if (x=WX-1) then x=1
 endwhile
 clng=LNG-1
 for i=0 to clng-1
  drpx(i)=0
  drpy(i)=0:/* 0=未記録の印
 next
 drpx(clng)=x
 drpy(clng)=1
 dx=0
 dy=1: /* 下へ
 return(x)
endfunc

/******************************************************************/

func Drop(x;int,y;int)
/* 移動&表示
int r,l
 while (YES)
  /* 表示
  printxy(x,y,BALL)
  TWait(wtt):/* ウエイト
  
  /* 下が開いている?
  if scrn(x,y+1)=SPC then {
   /* 無条件に下に落ちる
   dx=0
   dy=1
   x=Move(x,y)
   y=retY
   continue
  }
  
  /* 移動先チェック
  if scrn(x+dx,y+dy)=SPC then {
   /* 移動可能
   x=Move(x,y)
   y=retY
   continue
  }
  
  /* 移動先に移動できない時
  if (dy=1) then { :/* 下に落ちるはずだった時
   /* 左右チェック
   r=(scrn(x+1,y)=SPC):/* 右
   l=(scrn(x-1,y)=SPC):/* 左
   
   /* 動けるなら左右移動に変更
   dx=0
   if (r) then { :/* 右が開いている
    dx=1
   }
   if (l) then { :/* 左が開いている
    dx=-1
    if (r) then { :/* 右も開いている
     /* 左右どちらかを選ぶ
     if rand2(2)=1 then dx=1
    }
   }
   if dx<>0 then {:/* 動ける時
    dy=0
    x=Move(x,y)
    y=retY
    continue
   }
  }
  /* 動けないときはループ終了
  break
 endwhile
endfunc

/******************************************************************/

func int Move(x;int,y;int)
/* 移動&消し
int i
 if (drpy(0)<>0) then printxy(drpx(0),drpy(0),SPC):/* 前の場所を消す
 x=x+dx
 y=y+dy
 if (clng>=1) then {
  for i=1 to clng
   drpx(i-1)=drpx(i)
   drpy(i-1)=drpy(i)
  next
 }
 drpx(clng)=x
 drpy(clng)=y
 retY=y:/* 2つ目のリターン値はグローバル変数経由で返す
 return(x)
endfunc

/******************************************************************/
/* 仮想VRAMシステム
/******************************************************************/

func str printChar$(c;char)
/* 表示文字取得
str c$
 switch (c)
  case ' ': c$= " ":break :/* 消す  
  case 'o': c$= "●":break :/* しずく
  case '#': c$= "■":break :/* 外壁
  case '=': c$= "□":break :/* 棚
 endswitch
 return (c$)
endfunc

func printxy(x;int,y;int,c;char)
/* 文字表示
 /* 仮想VRAMに出力
 tvram(x,y)=c

 /* 座標変換
 locate(x*2,y)
 
 /* キャラクター変換して表示
 print printChar$(c);
endfunc

func storexy(x;int,y;int,c;char)
/* 仮想VRAMに出力
 tvram(x,y)=c
endfunc

func char scrn(x;int,y;int)
/* 仮想テキストVRAMを読み出す
 return(tvram(x,y))
endfunc

func printScreenAll(stY;int,edY;int)
/* 全画面一気表示
/* X-BASIC for iOSはテキスト画面表示が遅いので対策(V1.0時代の名残)
int x,y
str linestr
 for y=stY to edY
  linestr=""
  for x=0 to WX-1
   linestr=linestr+printChar$(tvram(x,y))
  next
  locate(0,y):print linestr;
 next
endfunc

func init_tvram()
/* 仮想テキストVRAM初期化
int x,y
 for y=0 to WY-1
  for x=0 to WX-1
   tvram(x,y)=SPC
  next
 next
endfunc

/******************************************************************/
/* 汎用関数
/******************************************************************/

func srand2()
/* rand()乱数を初期化する
int tm
 t=time()
 tm=tm and &h0fff
 tm=tm*16
 srand(tm)
endfunc

func int rand2(seed;int)
/* 0~seed-1の乱数発生
 return (rand() mod seed)
endfunc

/******************************************************************/

func int CalcWait()
/* ウエイト量算出
int tim,tm
int count
 /* 0クロックチェック
 tm=time()
 repeat
  tim=time()
 until tim-tm<>0
 count=0
 repeat
  tm=time()
  count=count+1
 until tm-tim<>0
 return(count):/* 1秒に必要なカウント数
endfunc

/******************************************************************/

func TWait(wt;int)
int i,tm
 for i=0 to wt-1
  tm=time()
 next
endfunc

/******************************************************************/

Zipファイル :XBetc.zip

0 件のコメント:

コメントを投稿