|
|
|
2008/3/10(Mon) 22:55:38|NO.14050
昔々、パソコンといえばNECと富士通とSHARPだった時代。
あるマシンにはPCGという、手軽にキャラクタを作る機能があったとさ。
ファイル名を"pf-x.as"とでもして保存してほしい。
#ifndef PF-XAS_
#define PF-XAS_
#module "PF_X"
#defcfunc hex str OneByte
d="00"+OneByte:d=strmid(d,-1,2)
hh=peek(d,0)-'0':hh-=((hh>9)*7)+((hh>24)<<5):hh=hh*((hh>0)and(hh<16))
hl=peek(d,1)-'0':hl-=((hl>9)*7)+((hl>24)<<5):hl=hl*((hl>0)and(hl<16))
return (hh<<4)+hl
#defcfunc VramAddress int x , int y
return ((PCGScreenHeight-1-y)*(((PCGScreenWidth*3)+3)&0xfffffffc))+(x*3)
#deffunc writeCHRLine int sID,int plane,int sLine,int sData
x=sID<<3:y=sLine:s=sData:for o,0,8:dat=0xff:if(s&tbit(o))=0:dat=0
poke VRAM,VramAddress(x+7-o,y)+RGBPLANE(plane),dat:next:return
#deffunc RBYTE int sID , str sData
if sID<0|PCGMax<=sID{return}:PCGData=sData:for i,0,24
writeCHRline sID,i/8,i\8,hex(strmid(PCGData,i<<1,2)):next:return
#deffunc WBYTE2 int sx,int sy,int sID
if PCGMax<0|PCGMax<=sID{return}:PF_X_STATUS(sx,sy)=sID
pos sx<<4,sy<<4:gzoom 16,16,PCGID,sID<<3,0,8,8:return
#deffunc WBYTE int sx,int sy,int cno,str data
wx=sx:wy=sy:source=data:len=strlen(source):index=0:while(index<len)
id=peek(source,index):wy+=(id=0x64)-(id=0x75):wx+=(id=0x72)-(id=0x6c)
id=(id*(id>=0x20&id<=0x5f))-(id<0x20|id>0x5f):WBYTE2 wx,wy,id
wx+=(id>0):index++:wend:return
#defcfunc STATUS int sx,int sy
return PF_X_STATUS(sx,sy)
#deffunc STATUSCLS
for i,0,40:for o,0,30:PF_X_STATUS(i,o)=-1:next:next:return
#deffunc init_PF_X int mId,int wi,int hi,int sMax,int RGBFLG
PCGID=mID:PCGMax=sMax:PCGScreenWidth=sMAX<<3:PCGScreenHeight=8
baseID=ginfo(2):buffer PCGID,PCGScreenWidth,PCGScreenHeight,0
color:boxf:mref VRAM,66:gsel baseID
if RGBFLG=0{RGBPLANE(0)=0:RGBPLANE(1)=2:RGBPLANE(2)=1}
else {RGBPLANE(0)=2:RGBPLANE(1)=1:RGBPLANE(2)=0}
dim PF_X_STATUS,wi,hi:tbit=1,2,4,8,16,32,64,128:return
#global
init_PF_X 1,40,30,96,0
#endif
引越しをする事になり、古い本を整理していてPF-Xの原本を見つけた。
以前から記憶だけで作っていたが、せっかくなので仕様にあわせて修正した。
使い方
キャラクタ登録
RBYTE int asciiコード, str キャラクタ定義文字列
キャラクタ描画
WBYTE int x,int y , int c(未使用) , str 表示用文字列
画面削除
STATUSCLS
画面に書いたキャラ番号取得
int = STATUS( int x,int y )
| |
|
2008/3/10(Mon) 22:57:28|NO.14051
キャラクタ定義文字列を今時の子供につ売れと言っても酷そうなので
キャラ歌エディタ。
当時のC-EDITに似せてみた。
#packopt name "c-edit"
#include "pf-x.as"
#module
#deffunc flocate int sx , int sy
posx = sx<<4:posy = sy<<4:pos posx,posy:return
#deffunc fcolor int sc
cno = sc:colorg=(cno&4)*0xff:colorr=(cno&2)*0xff:colorb=(cno&1)*0xff
color colorr,colorg,colorb:return
#deffunc fprint str string
data=string:len=strlen( data ):color:boxf posx,posy,posx+(len<<3),posy+16
color colorr,colorg,colorb:pos posx,posy:mes data:posy +=16:return
#global
screen 0,640,480,0:boxf:color 255,255,255:fcolor 7:font "MS ゴシック",16
con ="0123456789ABCDEF"
ascii=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKJMNOPQRSTUVWXYZ[\]^_"
m=0:x=0:y=0:c=7:dim chrdata,16,16:sdim pfxs,49,128
sdim sdata,80*128:notesel sdata:title "C-EDIT for HSP"
for i,0,128:pfxs(i)="000000000000000000000000000000000000000000000000"
RBYTE i,pfxs(i):next:gosub *makescreen:gosub *printscreen
*mainloop:stick s,256:cx=mousex/16:cy=mousey/16
if s & 256 {
if (cx> 4&cx<21&cy>1&cy<18)=1:chrdata(cx-5,cy-2)=c
if (cx> 5&cx<14&cy= 0) =1:c=cx-6
if (cx>25&cy> 1&cy<18) =1:gosub *chrset
if (cx> 0&cx< 4&cy= 0) =1:m=m^1:wait 25
if (cx>27&cx<32&cy=21) =1:cy=0:gosub *load
if (cx>27&cx<32&cy=22) =1:cy=0:gosub *save
if (cx>27&cx<35&cy=23) =1:cy=0:gosub *saveprogram
}
if s & 512 {
if (cx>4&cx<21&cy>1&cy<18)=1:c=chrdata(cx-5,cy-2)
if (cx>25&cy> 1&cy<18) =1:gosub *chrget
}
if s & 128 :goto *makedata
if s & 32 :gosub *saveprogram
gosub *printscreen:await 16:goto *mainloop
*makescreen:fcolor 7
flocate 5, 1:fprint con:flocate 5,18:fprint con
flocate 27, 1:fprint "2 3 4 5"
for i,0,16:con2=strmid(con,i<<1,2):fcolor 7
flocate 4,2+i:fprint con2:flocate 21,2+i:fprint con2
flocate 25,2+i:fprint con2
flocate 26,2+i:fprint strmid(ascii,i ,1)
flocate 28,2+i:fprint strmid(ascii,(i+16),1)
flocate 30,2+i:fprint strmid(ascii,(i+32),1)
flocate 32,2+i:fprint strmid(ascii,(i+48),1):next
flocate 1,21:fprint " B0 1 2 3 4 5 6 7R0 1 2 3 4 5 6 7G0 1 2 3 4 5 6 7"
flocate 5, 0:fprint "[ ]選択色[ ]"
flocate 28,21:fprint "LOAD":fprint "SAVE":fprint "PROGRAM"
for i,0,8:fcolor i:flocate 6+i,0:fprint "■":next :return
*printscreen:redraw 0:for i,0,16:for o,0,16:
pc=chrdata(i,o):px=i+5:py=o+2:gosub *putcell:next:next
fcolor c:flocate 19, 0:fprint "■"
fcolor 7:flocate 0, 0:fprint "M=" + ( 8 * ( m + 1 ) -1 ) +" "
bx=0:by=0:gosub *makedata:flocate 1,22:fprint "["+pfxd+"]":RBYTE 0,pfxd
bx=8:by=0:gosub *makedata:flocate 1,23:fprint "["+pfxd+"]":RBYTE 1,pfxd
bx=0:by=8:gosub *makedata:flocate 1,24:fprint "["+pfxd+"]":RBYTE 2,pfxd
bx=8:by=8:gosub *makedata:flocate 1,25:fprint "["+pfxd+"]":RBYTE 3,pfxd
WBYTE2 1,3,0:WBYTE2 2,3,1:WBYTE2 1,4,2:WBYTE2 2,4,3
for i,0,16:WBYTE2 27,2+i,0x20+i:WBYTE2 29,2+i,0x30+i
WBYTE2 31,2+i,0x40+i:WBYTE2 33,2+i,0x50+i:next:redraw 1:return
*putcell:fcolor pc:flocate px , py:fprint "■":return
*makedata:bd="":rd="":gd="":for iy,0,8:b=0:r=0:g=0:for ix,0,8
cd=chrdata( bx+ix , by+iy )
b=(b<<1)+((cd&1)!=0):r=(r<<1)+((cd&2)!=0):g=(g<<1)+((cd&4)!=0)
next:bd=bd+strf("%02x",b):rd=rd+strf("%02x",r):gd=gd+strf("%02x",g):next
pfxd=bd+rd+gd:return
*chrset:cno=((cx=27)*0x20)+((cx=29)*0x30)+((cx=31)*0x40)+((cx=33)*0x50)+(cy-2)
if(cno<0x20 &cno>0x5f)=1:return
bx=0:by=0:gosub *makedata:RBYTE cno,pfxd:pfxs(cno)=pfxd
if m!=0 {bx=8:by=0:gosub *makedata:RBYTE cno+1,pfxd:pfxs(cno+1)=pfxd
bx=0:by=8:gosub *makedata:RBYTE cno+2,pfxd:pfxs(cno+2)=pfxd
bx=8:by=8:gosub *makedata:RBYTE cno+3,pfxd:pfxs(cno+3)=pfxd }:return
*chrget:cno=((cx=27)*0x20)+((cx=29)*0x30)+((cx=31)*0x40)+((cx=33)*0x50)+(cy-2)
if( cno<0x20 &cno>0x5f)=1:return
WBYTE2 1,3,cno
if m!=0 {WBYTE2 2,3,cno+1:WBYTE2 1,4,cno+2:WBYTE2 2,4,cno+3}
for i,0,16:for o,0,16:pget 16+(i<<1),48+(o<<1)
chrdata(i,o)=(ginfo_b!=0)+((ginfo_r!=0)<<1)+((ginfo_g!=0)<<2)
next:next:return
*saveprogram:sdata="":noteadd "#include \"pf-x.as\""
noteadd " screen 0,640,480,0 : font \"MS ゴシック\",16"
for i,0x20,0x60
if pfxs(i)!="000000000000000000000000000000000000000000000000"{
data =" RBYTE 0x" + strf("%02x",i) + ",\"" + pfxs( i ) + "\" // "
data += strmid(ascii,i-0x20,1):noteadd data }
next:dialog "hsp",17:if stat!=1 :return
filename = refstr:if strmid(filename,-1,4)!=".hsp" :filename +=".hsp"
notesave filename:wait 100:return
*save:sdata="":for i,0x20,0x60:noteadd pfxs( i ):next
dialog "txt",17:if stat!=1 :return
filename = refstr:if strmid(filename,-1,4)!=".txt" :filename +=".txt"
notesave filename:wait 100:return
*load:dialog "txt",16:if stat!=1 :return
filename = refstr:noteload filename
for i,0,0x20:pfxs(i)="000000000000000000000000000000000000000000000000"
RBYTE i,pfxs(i):next:for i,0x20,0x60:noteget data:notedel 0:pfxs(i)=data
RBYTE i,pfxs(i):next:wait 100:return
| |
|
2008/3/10(Mon) 23:02:16|NO.14052
先日、どこかに捨てものだが、これもソースが出てきたので元の物に
なるべく似せてみた。
使用サンプル
//----------------------------------------------------------------------------
// PONPON.
//----------------------------------------------------------------------------
#packopt name "ponpon"
#include "pf-x.as"
#define locate(%1,%2) pos (%1)<<4,(%2)<<4
//----------------------------------------------------------------------------
screen 0,32*16,24*16:color:boxf:color 255,255,255:font "MS ゴシック",16
RBYTE 0x41,"00000000000000003c7e7edbdbdb7e663c7e7edbdbdb7e66" // A:ponpon
RBYTE 0x42,"0000000000000000dfdfdf00fdfdfd000000000000000000" // B:壁
RBYTE 0x43,"00000000000000004428107c107c10004428107c107c1000" // C:お金
RBYTE 0x44,"925438fe38549200925438fe38549200925438fe38549200" // D:イガイガ
RBYTE 0x45,"ffffffffffffffff0000000000000000ffffffffffffffff" // E:ENERGY
//----------------------------------------------------------------------------
randomize:STATUSCLS:hs=0:h=5:en="EEEEEEE "
*start:redraw 0:s=0:g=0:px=2:py=2:pv=1:for i,0,32:for o,0,22:t=" "
if(o<2|o=21|i=0|i=31|((o+3)\4=0&(i!=2&i!=29))):t="B"
WBYTE i,o,7,t:next:next
*set:for i,4,21,4:for o,1,5:WBYTE rnd(20)+5,i,7,"DCD":next:next:
//----------------------------------------------------------------------------
*mainloop:redraw 0:WBYTE px,py,7," ":stick c,5
px+=-((c&0x01)!=0&STATUS(px-1,py)=0x20)+((c&0x04)!=0&STATUS(px+1,py)=0x20)
py+=pv:t=STATUS(px,py):py-=pv*(t=0x42):pv*=(t!=0x42)-(t=0x42):
h-=(t=0x44):if t=0x43{s++:if s\10=0{h+=(h<7):goto *set}}:if s>hs :hs=s
WBYTE 3,0,7," ":locate 3,0:print "HI−SCORE:"+hs
WBYTE 20,0,7," ":locate 20,0:print "SCORE:"+s
locate 6,22:print "ENERGY:"+h:WBYTE 13,22,7,strmid(en,7-h,7)
if h=0{gosub *go}:WBYTE px,py,7,"A":redraw 1:await 50:goto *mainloop
//----------------------------------------------------------------------------
*go:redraw 1:locate 11,10:print "GAMEOVER":h=5:WBYTE px,py,7,"A"
*lp:stick st,15,0:if (st and 16)!=0{goto *start}:await 50:goto *lp
まさに自分が小学生の頃にお世話になってた物であるが。
ぱっと使うには今でも十分通用すると思う。
あ、そうそう。
PF-X<-by でぶ大先生
C-EDIT<-by たぶんでぶ大先生
PONPON<-by TEIJIRO
| |
|
2008/3/10(Mon) 23:09:06|NO.14054
表示用文字列は
WBYTE 0,0,7,"ABdllCD"
等と書く事ができる。
キャラクタをアスキーコードでAの番号に登録すると、ここの文字列で"A"と書いた所に
登録した絵が出る仕組みだ。
"AAAAAA"などとかくと、書いた文だけ絵がでる。
dll等の小文字はマクロ。表示位置を変更することが出来る。
矢印にすると分かりやすいが、
"ABdllCD"は"AB↓←←CD"と言う意味で、実際の表示時には
AB
CD
という表示の仕方をされる。
|
|
2008/3/10(Mon) 23:13:10|NO.14055
本来の仕様では、登録できる番号の範囲は32(0x20)から137(0x5f)まで。
ただ、これのばあい0から登録することはできる。
表示時に文字列を直に書けないだけである。
マクロはudlrの全方向有る。
マクロが小文字の関係で、アルファベット小文字は登録可能範囲外。
|
|
2008/3/11(Tue) 01:58:22|NO.14071
PCG は Programmable Character Generator の頭文字で X1 か MZ での機能。
ちょっと懐かしい。
|
|
2008/3/11(Tue) 02:21:49|NO.14075
RBYTE '0',"FFFFFFFFFFFFFFFF"
RBYTE '1',"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
WBYTE ,0,7,"0000000000000000000000000000000"
WBYTE ,1,7,"0001000100011111000111111100000"
WBYTE ,2,7,"0001000100010000000100000100000"
WBYTE ,3,7,"0001000100010000000100000100000"
WBYTE ,4,7,"0001111100011111000111111100000"
WBYTE ,5,7,"0001000100000001000100000000000"
WBYTE ,6,7,"0001000100000001000100000000000"
WBYTE ,7,7,"0001000100011111000100000000000"
WBYTE ,8,7,"0000000000000000000000000000000"
WBYTE ,9,7,"0000000000000000000000000000000"
|
|
2008/3/11(Tue) 08:41:42|NO.14079
C-EDIT使い方
ドット絵を描く容量は見たら分かると思う。
色は8色限定。というか、PF-Xが8色限定。
左上の「M=7」の所をクリックすると、「M=15」と交互に切り替わる。
これは編集しているキャラクタのサイズ切り替え。7のとき8*8、15のとき16*16.
なんでそんな数字なのかは知らん。
画面上で編集すると、下の文字列が変化していると思う。
4行あるが、上から順番に、左上8*8、右上8*8、左下8*8、右下8*8の順の、
1キャラクタ分のキャラクタ定義文字列。
編集した絵は、右の方のなんか数字や記号の書いてある所に登録できる。
たとえば、Aの右となりを左クリックすると、そこにキャラクタが登録される。
左クリックすると、キャラクタを画面に呼び出す。
M=15のモードになっていると、指定したところから順に4キャラクタ分の登録、呼び出し
ができる。
LOAD、SAVEは見ての通り。
PROGRAMは保存の一種。
pf-xをインクルードしてキャラクタを定義した所までのスクリプトを自動で作ってくれる。
出力例
#include "pf-x.as"
screen 0,640,480,0 : font "MS ゴシック",16
RBYTE 0x41,"0307070703003d010307070703003d010307070703003d01" // A
RBYTE 0x42,"80c0c0c08000780080c0c0c08000780080c0c0c080007800" // B
RBYTE 0x43,"010101000204081001010100020408100101010002040810" // C
RBYTE 0x44,"000000008040201000000000804020100000000080402010" // D
表示例
WBYTE 10,10,7,"ABdllCD"
|
|
2008/3/11(Tue) 08:55:51|NO.14080
キャラクタ定義文字列
1キャラクタは8*8ドットサイズ
色の出る部分を16進数で指定する。
以下、サンプル(■が色の付く部分とする)
□□□□ = 0 : □■□□ = 4 : ■□□□ = 8 : ■■□□ = c
□□□■ = 1 : □■□■ = 5 : ■□□■ = 9 : ■■□■ = d
□□■□ = 2 : □■■□ = 6 : ■□■□ = a : ■■■□ = e
□□■■ = 3 : □■■■ = 7 : ■□■■ = b : ■■■■ = f
たとえば、
□□■□□■□□
の横8ドットの場合、「2」と「4」で「24」と指定する。
コレを縦に8回分指定して、1プレーンの定義ができる。
青プレーン、赤プレーン、緑プレーンの三原色を順番に書いて、1キャラクタが完成する
例 PANPUU CAT
□□□□□□□□ = 00 : □□■□□■□□ = 24 : □□■□□■□□ = 24
□□□□□□□□ = 00 : □■■■■■■□ = 7e : □■■■■■■□ = 7e
□□□□□□□□ = 00 : ■■■■■■■■ = ff : ■■■■■■■■ = ff
□□□□□□□□ = 00 : ■■□■■□■■ = db : ■■□■■□■■ = db
□□□□□□□□ = 00 : □■■■■■■□ = 7e : □■■■■■■□ = 7e
□□□■■□□□ = 18 : ■□■■■■□■ = bd : ■□■■■■□■ = bd
□□□■■□□□ = 18 : □□■■■■□□ = 3c : □□■■■■□□ = 3c
□□□□□□□□ = 00 : ■■■□□■■■ = e7 : ■■■□□■■■ = e7
青プレーン 赤プレーン 緑プレーン
0000000000181800 247effdb7ebd3ce7 247effdb7ebd3ce7
定義例
RBYTE 0x41 , "0000000000181800247effdb7ebd3ce7247effdb7ebd3ce7"
|
|
2008/3/11(Tue) 09:07:41|NO.14081
PCGは確かX1でしたかね。
PF-Xは恐らく「PC-88とFM-7でX1のPCG機能もどきをやるぞ」という意味の名前だと思われ。
>RBYTE '0',"FFFFFFFFFFFFFFFF"
>RBYTE '1',"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
変な模様が入りますな。
定義文字列は48文字きっちり指定で、指定されていない所は動作不詳と言う事で。
>RBYTE '0',"ffffffffffffffff00000000000000000000000000000000"
>RBYTE '1',"ffffffffffffffffffffffffffffffff0000000000000000"
|
|
2008/3/11(Tue) 22:59:14|NO.14098
>登録できる番号の範囲は32(0x20)から137(0x5f)まで。
と書いたが、0x5fは95でやんの。間違えた。95まで。
WBYTE2 int x , int y , int 番号
キャラクタ登録時には0番から登録できると書いたが、普通のWBYTEでは書けないキャラクタコードに
割り当てた場合、この命令で直接番号を指定する事で表示できる。
|
|
2008/3/12(Wed) 06:37:26|NO.14119
初心者に必要なものは
「とにかく簡単にキャラクタを動かす手段」
だと思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
// 背景作成
bg1 =" "
bg2 ="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
for i,0,24: WBYTE 0,i,7,bg1:next:WBYTE 0,24,7,bg2
// キャラクタ移動
x=20
*mainloop
stick s , 5
WBYTE x,23,7," "
mx = 0
if (s & 1)!=0 & x> 0 : mx = -1
if (s & 4)!=0 & x<39 : mx = 1
x = x + mx
WBYTE x,23,7,"B"
await 100
goto *mainloop
|
|
2008/3/12(Wed) 06:58:09|NO.14121
そして次に必要なものは画面に書いてある物の判定方法だと思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
// 背景作成
bg1 =" "
bg2 ="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
for i,0,24: WBYTE 0,i,7,bg1:next:WBYTE 0,24,7,bg2
for i,0,10: WBYTE rnd(40),rnd(23),7,"A":next
// キャラクタ移動
x =20
y =23
jf= 0 // ジャンプ中を判断するフラグ
*mainloop
stick s , 21
WBYTE x,y,7," "
mx = 0
my = 0
if (s & 1)!=0 & x> 0 : mx = -1 // 左移動
if (s & 4)!=0 & x<39 : mx = 1 // 右移動
if STATUS( x , y + 1 ) = ' ' : my = 1 // 足の下に何も無ければ下移動
if (s & 16)!=0 & y> 0 : my = -1 // 下移動より上移動が優先(ジャンプもどき)
x = x + mx
y = y + my
WBYTE x,y,7,"B"
await 100
goto *mainloop
|
|
2008/3/12(Wed) 12:52:41|NO.14124
そして、何でもいいから、とりあえず完成させてみると言う姿勢が
大事だと思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
// マップデータ
sdim map,21,20
map( 0)="AAAAAAAAAAAAAAAAAAAA"
map( 1)="A AAA AA AAAA A"
map( 2)="A A AAAA A"
map( 3)="A AAA A AAAA A"
map( 4)="AAAAAAA A AAAAA AA A"
map( 5)="AA A A A AA A"
map( 6)="AA AAAAAA AAA A AAAA"
map( 7)="AA AA A A A"
map( 8)="AA AA AA AA A AA A"
map( 9)="AAAAAA A AAAA A"
map(10)="AAAAAAAAAAAA A A"
map(11)="AA AA AA A"
map(12)="AA AAAAAAAAAAAA A A"
map(13)="AA A A AA A AA"
map(14)="AA AAA A A A A"
map(15)="AA AAA A AAAAAA AA A"
map(16)="AA A A A"
map(17)="AAAAAAAAAAAAAAAAA AA"
map(18)="A A A"
map(19)="AAAAAAAAAAAAAAAAAAAA"
// 初期設定
x=1:y=1
// ゲーム主処理
*mainloop
// キャラクタ移動
stick s , 15
mx = 0 : my = 0
if (s & 1)!=0 : mx = -1 // 左移動量セット
if (s & 4)!=0 : mx = 1 // 右移動量セット
if (s & 2)!=0 : my = -1 // 上移動量セット
if (s & 8)!=0 : my = 1 // 下移動量セット
// 移動先が通路で無いなら移動量をクリア
if strmid( map( y+my ) , x+mx , 1 )!= " " { mx=0:my=0 }
// キャラクタ移動
x = x + mx : y = y + my
// 画面の表示
WBYTE 0,0,7, strmid( map( y - 1 ) , x -1 , 3 )
WBYTE 0,1,7, strmid( map( y ) , x -1 , 3 )
WBYTE 0,2,7, strmid( map( y + 1 ) , x -1 , 3 )
WBYTE 1,1,7,"B"
// 座標の表示
color 255,255,255:boxf 0,48,47,64
pos 0,48:color 00,0,0:mes "" + x + "," + y
// ゴール判定
if x=18 & y=18 { mes "ゴール!" : stop }
await 100
goto *mainloop
| |
|
2008/3/12(Wed) 20:38:29|NO.14132
一つ作れたなら、それを改造していくのもいいと思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
RBYTE 0x43,"fff9f3f3f3f3e3e708140808180818000814080818081800" // C
RBYTE 0x44,"ab418815a81580552a418815a8158055548211a815a801aa" // D
// マップデータ
sdim map,21,20
map( 0)="AAAAAAAAAAAAAAAAAAAA"
map( 1)="A AAACAA D AAAACA"
map( 2)="A A AAAA A"
map( 3)="A AAA A AAAA A"
map( 4)="AAAAAAADADAAAAA AA A"
map( 5)="AA A A A AACA"
map( 6)="AA AAAAAA AAA A AAAA"
map( 7)="AA AA A A A"
map( 8)="AA AADAA AA ACAA A"
map( 9)="AAAAAA A AAAA A"
map(10)="AAAAAAAAAAAA A A"
map(11)="AA D AA AA A"
map(12)="AA AAAAAAAAAAAA A A"
map(13)="AA A A AA A AA"
map(14)="AA D AAA A D A A A"
map(15)="AA AAA A AAAAAA AA A"
map(16)="AA D A A A"
map(17)="AAAAAA AAAAAAAAAADAA"
map(18)="AC CA A"
map(19)="AAAAAAAAAAAAAAAAAAAA"
// 初期設定
x=1:y=1:k=0
// ゲーム主処理
*mainloop
// キー入力受付
stick s , 15
// 移動予定量確認
mx = 0 : my = 0
if (s & 1)!=0 : mx = -1 // 左移動量セット
if (s & 4)!=0 : mx = 1 // 右移動量セット
if (s & 2)!=0 : my = -1 // 上移動量セット
if (s & 8)!=0 : my = 1 // 下移動量セット
// 移動先確認
c =strmid( map( y+my ) , x+mx , 1 )
// 壁なら移動量クリア
if c = "A" { mx=0:my=0 }
// カギならカギもち数を増やしてマップからカギを消す
if c = "C" { k+=1 : poke map( y+my ) , x+mx , ' ' }
// 扉なら
if c = "D" {
// カギにあまりがあるなら、カギを減らして扉を消す
if k>0 { k-=1 : poke map( y+my ) , x+mx , ' ' }
else { mx=0:my=0 }
// カギが余ってないなら移動量クリア
}
// キャラクタ移動
x = x + mx : y = y + my
// 画面の表示
WBYTE 0,0,7, strmid( map( y - 1 ) , x -1 , 3 )
WBYTE 0,1,7, strmid( map( y ) , x -1 , 3 )
WBYTE 0,2,7, strmid( map( y + 1 ) , x -1 , 3 )
WBYTE 1,1,7,"B"
// 座標の表示
color 255,255,255:boxf 0,48,64,80
pos 0,48:color 0,0,0
mes "" + x + "," + y:mes "key :" + k
// ゴール判定
if x=18 & y=18 { mes "ゴール!" : stop }
await 100
goto *mainloop
| |
|
2008/3/13(Thu) 08:42:58|NO.14155
色々やっていれば、過去に放置した物に立ち返ってみると、
案外、出来るようになってたりすると思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
// 背景作成
bg1 =" "
stg ="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
stg +="AAAA A AAAAA AAAAAAAAA A AAAAAAAAAAA"
stg +="A A AAA AA AAAAA AA AAA AAAAAA AAAAA"
stg +="AAAAAAAAAAAAAA AA A"
stg +="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
for i,0,24: WBYTE 0,i,7,bg1:next
// 初期設定
x =20:y =23:l = 0
jf= 0 // ジャンプ中を判断するフラグ
jc= 0 // ジャンプ高さカウンタ
*mainloop
stick s , 21
WBYTE x,y,7," "
// キー受付
mx = 0
my = 0
if (s & 1)!=0 & x> 0 : mx = -1 // 左移動
if (s & 4)!=0 & x<39 : mx = 1 // 右移動
// ジャンプ判定
// 10マス上に上がった、もしくは画面外にでたらジャンプ上り終了
if jc > 10 or y <= 0 : jf = 2
// 足元が空中でなければジャンプの処理を終了、状態をクリア
// そうでなければ、下へ落ちてゆく処理
if STATUS( x+mx , y+1 )!= ' ' { jf = 0 : jc = 0 }
else { my = 1 }
// ジャンプしようとした時、ジャンプ終了して降下中で無ければジャンプ
if (s & 16)!=0 & jf!=2 { my = -1 : jf=1 : jc+=1 }
// ジャンプ中にボタンを離したらジャンプは終了
if (s & 16) =0 : jf = 2
// 地面移動
// 画面真ん中より右に行こうとしたら、自分の右移動を止めて地面の方を動かす
if x >=20 & mx = 1 { mx = 0 : l += 1 }
x = x + mx:y = y + my
WBYTE 0,24,7,strmid( stg , l , 40 )
WBYTE x, y,7,"B"
if y = 24 {
color 255,255,255:pos 100,100:mes "ゲームオーバー"
stop
}
if l >=160 {
color 255,255,255:pos 100,100:mes "ゴール!"
stop
}
await 100:goto *mainloop
| |
|
2008/3/14(Fri) 08:42:12|NO.14196
見た目とかどうでもいい機能とかに拘って止まっているよりは、
見た目が不恰好でもまずは幾つか仕上げてみれば、コーディングの
大体の間隔がつかめるようになると思うんだ。
#include "pf-x.as"
screen 0,640,400,0 : font "MS ゴシック",16
// キャラクタ定義
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x41,"0000000000000000fdfdfd00bfbfbf000000000000000000" // A
RBYTE 0x42,"ffffffffffffffff383838107c102844383838107c102844" // B
RBYTE 0x43,"fff9f3f3f3f3e3e708140808180818000814080818081800" // C
RBYTE 0x44,"ab418815a81580552a418815a8158055548211a815a801aa" // D
RBYTE 0x45,"00040200000000003c7effffffff7e3c3c7effffffff7e3c" // E
// 背景作成
sdim map,41,20
map( 0)="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
map( 1)="A A"
map( 2)="A A"
map( 3)="A A"
map( 4)="A AAAAA A"
map( 5)="A E A"
map( 6)="A A"
map( 7)="A AAAA AAAAA A"
map( 8)="A E A"
map( 9)="A A"
map(10)="A AAAAAA AAAAAA A"
map(11)="A A"
map(12)="A A"
map(13)="A ADA AAA A"
map(14)="A AAA E A"
map(15)="A A"
map(16)="A A"
map(17)="A A"
map(18)="A A"
map(19)="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
for i,0,20: WBYTE 0,i,7,map(i):next
// 初期設定
x=1:y=1:kx=35:ky=1
*mainloop
stick s , 15
WBYTE x,y,7," ":WBYTE kx,ky,7," "
// キー受付
mx = 0
my = 0
if (s & 1)!=0 : mx = -1 // 左移動
if (s & 4)!=0 : mx = 1 // 右移動
if (s & 2)!=0 { my = -1 : mx = 0 } // 左移動
if (s & 8)!=0 { my = 1 : mx = 0 } // 右移動
// 移動先の物判定
c = STATUS( x+mx,y+my )
// 障害物
if c = 'A' or c = 'D' { mx = 0: my = 0 }
// 台
if c = 'E' {
if STATUS(x+mx+mx,y+my+my)=' ' { WBYTE x+mx+mx,y+my+my,7,"E" }
else { mx = 0: my = 0 }
}
// かぎ
if kx=x+mx and ky=y+my {
if STATUS(x+mx+mx,y+my+my)=' ' { kx+=mx: ky+=my }
else { mx = 0: my = 0 }
}
if STATUS(kx,ky+1)=' ' : ky+=1
// キャラクタ移動&表示
x = x + mx:y = y + my
WBYTE x, y,7,"B":WBYTE kx, ky,7,"C"
if STATUS(kx,ky+1)='D' {
color 255,255,255:pos 100,100:mes "クリア!"
stop
}
await 100:goto *mainloop
| |
|
2008/3/16(Sun) 20:59:44|NO.14330
上級者になる近道は、先輩のひとりごとにも
しっかり耳を傾けることだと思うんだ。
#include "pf-x.as"
// この3つで難易度を調節(簡単にするとスコアが減少)
#const InvGunMax 2 // インベーダが撃てる数
#const InvKakuritsu 8 // インベーダが攻撃する確率(1/x)
#const DefLife 5 // 初期ライフ
#define ctype Lim(%1,%2,%3) (%1==limit(%1,%2,%3))// %1 が %2〜%3 の範囲内かを求めるマクロ
#define TwoSet(%1,%2,%3,%4) %1(%2,0)=%3:%1(%2,1)=%4// %1 の (%2, 0)と(%2, 1) に %3, %4 を代入するマクロ
#define elsif else:if
#define InvNumMax (EnemyHeads(0) + EnemyHeads(1) + EnemyHeads(2))
#const x 0
#const y 1
randomize:screen 0,496,280,0:font "MS ゴシック",16
title "SpaceInvader : Life "+ DefLife:boxf
RBYTE ' ', "000000000000000000000000000000000000000000000000"
RBYTE 'A', "0000000000000000fbfbfb03ff00dfdf0000000000000000" // 外壁
RBYTE 'B', "181818181818181818181818181818181818181818181818" // Bullet (弾丸)
RBYTE 'X', "0000000000000000247effdb7ea524e7247effdb7ea524e7" // インベーダ1 (fさん、いただきます)
RBYTE 'Y', "183c7edbff245aa50000000000000000183c7edbff245aa5" // インベーダ2
RBYTE 'Z', "0000044c0000000000004c4c00000000307cb2b2fe4c824c" // インベーダ3
RBYTE 'I', "1028286cc6c6fe0000000000828282aa0000000082828200" // 自機 (スペースシャトルにしか見えない)
RBYTE '-', "0000000000000000fbfbfb03ff00dfdf0000000000000000" // 壁
RBYTE '*', "181818181818181818181818181818180000000000000000" // 敵の攻撃
#const MapLine 15
sdim map, 41, MapLine
map( 0) = " AAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
map( 1) = " A A "
map( 2) = " A A "
map( 3) = " A A "
map( 4) = " A A "
map( 5) = " A A "
map( 6) = " A A "
map( 7) = " A A "
map( 8) = " A A "
map( 9) = " A-- ---- --- ---- --A "
map(10) = " A A "
map(11) = " A A "
map(12) = " A A "
map(13) = " A A "
map(14) = " AAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
I=14:HP=DefLife:dim iGun,2:iGun=-1,-1
dim EnemyHeads,3:EnemyHeads=21,21,11:InvNum =InvNumMax
dim ePx, 22, 2:dim ePy, 22, 2:dim ePz, 11, 2
ePx(0, 0) = 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25
ePx(0, 1) = 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
memcpy ePy, ePx, 22 * 4, 0, 0:ePy(0, 1) = 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
memcpy ePz, ePx, 11 * 4, 0, 10 * 4 : ePz(0, 1) = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
dim Pi,2:dim InvGun,InvGunMax,2:foreach InvGun:TwoSet InvGun,cnt,-1,-1:loop
dim SCORE,7
#enum total = 0 // トータル・スコア
#enum time // タイム・スコア
#enum life // ライフ・スコア
#enum buttle // バトル・スコア
#enum missHit // ミス・スコア (減点)
#enum moved // ムーブ・スコア(減点)
#enum bonus // ボーナス・スコア
SCORE.missHit = 100
SCORE.moved = 1000 // 許容範囲
goto *mainlp//--------------------------------
#deffunc HitToInv int p1, int p2, int p3
goto *_HitToInv_Core
#deffunc AttackByInv int p1, int p2
goto *_AttackByInv_core
*mainlp:redraw 2:stick key,23 // メインループ開始
if (key&&1){move=-1}elsif (key&&4){move=1}
if Lim(I+move,3,27){I+=move:move=0:SCORE.moved--}
if (iGun != -1) {GunLine=STATUS(iGun.x, iGun.y -1)
if(GunLine!' '){if Lim(GunLine, 'X', 'Z'):HitToInv iGun.x,iGun.y-1,GunLine:SCORE.buttle+=(GunLine-'X')*100
iGun = -1, -1}else{iGun.y --:if(peek(map(iGun.y-1),iGun.x)=='-'|peek(map(iGun.y-1),iGun.x)=='A'){iGun = -1, -1:SCORE.missHit --}}
}if(key&2|(key&16)){gosub *attack}
if(rnd(15)==0){if(Pi.y!=2){if(Pi.y&&1){Pi.x++}else{Pi.x--}:if(abs(Pi.x)==3){Pi.y++}
}else{if(PiMove){Pi.x++}else{Pi.x--}:if(abs(Pi.x)==3){PiMove^=1}}
}repeat InvGunMax:if(InvGun(cnt)==-1){continue}
InvGun(cnt, 1) ++:GunLine = STATUS(InvGun(cnt), InvGun(cnt, 1))
if (GunLine!' '){TwoSet InvGun,cnt,-1,-1:InvAtNum --:if (GunLine=='I'){HP --:title "SpaceInvader : Life "+HP}elsif(GunLine=='B'){iGun = -1, -1:SCORE.missHit ++}
}loop
for lpcnt,Pi.x+3,Pi.x+24,1:if(STATUS(lpcnt,10)=='-'){_continue}
repeat 9:if Lim(STATUS(lpcnt,9-cnt),'X','Z'){if (rnd(InvKakuritsu)==0):AttackByInv lpcnt,(9-cnt)+1:if(stat==-1){lpcnt=Pi.x+24}break}:loop
next:STATUSCLS:gosub*Draw:redraw 1// 再描画
if ( HP <= 0 ){fin=0:goto*finish}elsif(InvNum <= 0){fin=1:goto*finish}
wait 6:SCORE.time ++
goto *mainlp//--------------------------------------------------------------
*finish:font "MS ゴシック", 60, 1:pos 120, 100
if (fin){color 255, 255, 255:mes "YOU WIN !"
SCORE.bonus += 200 // クリアボーナス
SCORE.life = (HP * 100) - ( (DefLife - 5) * 50 ) + (HP == DefLife) * 800 // ライフ・スコア
SCORE.buttle += 500 // バトル・スコア(パーフェクト)
} else {color 255, 0, 0:mes "YOU LOSE..."
SCORE.life -= (DefLife - 5) * 50 // LS (減点)
SCORE.moved -= 500 // 失敗により減点
}SCORE.bonus += (InvGunMax - 3) * 30 // 敵の弾丸の最大数
SCORE.bonus += (8 - InvKakutitsu) * 10 // 敵の射撃確率
if (Pi.y != 2) : SCORE.bonus += 1000 // 最終行まで来なかったらボーナス
foreach SCORE : SCORE.total += SCORE.cnt : loop// 得点を集計
title "SpaceInvader - Total "+ strf("%10d", SCORE.total) +" !":redraw 1// スコア表示
stop//######## サブルーチン ##########################
*Draw:repeat MapLine:WBYTE 0,1+cnt,0,map(cnt):loop // マップ再描画
WBYTE I,13,0,"I":if(iGun!-1):WBYTE iGun.x,iGun.y,0,"B"
repeat 22:if(ePx.cnt):WBYTE ePx(cnt)+Pi.x,ePx(cnt,1)+Pi.y,0,"X"
if(ePy.cnt):WBYTE ePy(cnt)+Pi.x,ePy(cnt,1)+Pi.y,0,"Y"
if(cnt<11){if(ePz.cnt){WBYTE ePz(cnt)+Pi.x,ePz(cnt,1)+Pi.y,0,"Z"}}
loop:foreach InvGun:if (InvGun.cnt != -1) { WBYTE InvGun(cnt), InvGun(cnt, 1), 0, "*"}loop
return
*attack:if(iGun.x!-1){return}iGun=I,12
return
#deffunc _AttackByInv_core_ int p1,int p2
*_AttackByInv_core:if ( InvAtNum == InvGunMax ){return-1}
repeat InvGunMax:if(InvGun(cnt)==-1){TwoSet InvGun, cnt, p1, p2}break:loop:InvAtNum ++
return 1
#define SearchInvader(%1,%2,%3,%4=22) repeat %4:if((%3(cnt)+Pi.x)==%1&&(%3(cnt,1)+Pi.y)==%2){TwoSet %3,cnt,0,0:InvNum--:break}loop
#deffunc HitToInv_core int p1,int p2,int p3
*_HitToInv_Core
if (p3 == 'X') { SearchInvader p1, p2, ePx}
elsif (p3 == 'Y') { SearchInvader p1, p2, ePy}
elsif (p3 == 'Z') { SearchInvader p1, p2, ePz, 13 }
return
冒頭でなんか偉そうなこと言ってますけど、
本来のスペース・インベーダーとは全然違います。
インベーダーたちがこっちに来ても問題ありません。
後、スコア基準は適当です。
| |
|
2008/3/16(Sun) 21:03:47|NO.14332
ウわ、よくできている(笑
|
|
2008/3/17(Mon) 15:16:38|NO.14352
元々pf-xは横40*縦25の画面の大きさにしか対応していない。
このモジュールは640*480の画面に対し16*16のキャラクタを表示する事を考えて
縦40*横30にしか対応していなかった。
そこで、それ以上の画面でも大丈夫な様に修正した。
#ifndef PF-XAS_
#define PF-XAS_
#module "PF_X"
#deffunc init_PF_X int mId,int wi,int hi,int sMax,int RGBFLG
PCGID=mID:PCGMax=sMax:PCGScreenWidth=sMAX<<3:PCGScreenHeight=8
baseID=ginfo(2):buffer PCGID,PCGScreenWidth,PCGScreenHeight,0
color:boxf:mref VRAM,66:gsel baseID:pfxw=wi:pfxh=hi
if RGBFLG=0{RGBPLANE(0)=0:RGBPLANE(1)=2:RGBPLANE(2)=1}
else {RGBPLANE(0)=2:RGBPLANE(1)=1:RGBPLANE(2)=0}
dim PF_X_STATUS,pfxw,pfxh:tbit=1,2,4,8,16,32,64,128:return
#defcfunc hex str OneByte
d="00"+OneByte:d=strmid(d,-1,2)
hh=peek(d,0)-'0':hh-=((hh>9)*7)+((hh>24)<<5):hh=hh*((hh>0)and(hh<16))
hl=peek(d,1)-'0':hl-=((hl>9)*7)+((hl>24)<<5):hl=hl*((hl>0)and(hl<16))
return (hh<<4)+hl
#defcfunc VramAddress int x , int y
return ((PCGScreenHeight-1-y)*(((PCGScreenWidth*3)+3)&0xfffffffc))+(x*3)
#deffunc writeCHRLine int sID,int plane,int sLine,int sData
x=sID<<3:y=sLine:s=sData:for o,0,8:dat=0xff:if(s&tbit(o))=0:dat=0
poke VRAM,VramAddress(x+7-o,y)+RGBPLANE(plane),dat:next:return
#deffunc RBYTE int sID , str sData
if sID<0|PCGMax<=sID{return}:PCGData=sData:for i,0,24
writeCHRline sID,i/8,i\8,hex(strmid(PCGData,i<<1,2)):next:return
#deffunc WBYTE2 int sx,int sy,int sID
if (sx<0|sy<0|sx>=pfxw|sy>=pfxh)=1:return
if PCGMax<0|PCGMax<=sID{return}:PF_X_STATUS(sx,sy)=sID
pos sx<<4,sy<<4:gzoom 16,16,PCGID,sID<<3,0,8,8:return
#deffunc WBYTE int sx,int sy,int cno,str data
wx=sx:wy=sy:source=data:len=strlen(source):index=0:while(index<len)
id=peek(source,index):wy+=(id=0x64)-(id=0x75):wx+=(id=0x72)-(id=0x6c)
id=(id*(id>=0x20&id<=0x5f))-(id<0x20|id>0x5f):WBYTE2 wx,wy,id
wx+=(id>0):index++:wend:return
#defcfunc STATUS int sx,int sy
if (sx<0|sy<0|sx>=pfxw|sy>=pfxh)=1:return 0
return PF_X_STATUS(sx,sy)
#deffunc STATUSCLS
for i,0,pfxw:for o,0,pfxh:PF_X_STATUS(i,o)=-1:next:next:return
#global
init_PF_X 1,40,30,96,0
#endif
初期化命令
init_PF_X int pfx画像保持ID,int 横幅, int 縦幅, int 最大登録数, int 色順番
pf-x画像保持ID
キャラクタ定義文字列を画像に展開して保持させる画面ID
デフォルトは1
横幅
縦幅
文字通り。デフォルトは40*30
最大登録数
キャラクタ定義できる最大数。
デフォルトは0x00から0x5fまで登録と言う事で96。
色順番
PF-Xのキャラクタ定義の色順番は大昔のPCの画像色プレーンの順番と同じになっている。
すなわち、青、赤、緑の順番。これを1にするとRGBの順に変更できる。
デフォルトは0。
テスト殆どして無いけどなー。
前と同じでpf-x.asのファイル名で保存して欲しい。
| |
|
2008/3/18(Tue) 14:41:46|NO.14408
バグ取りついでに修正したので、古いのを削除して再書き込み
この直ぐ上の新しいpf-xでないと、エラーが出ると思うので宜しく。
#include "pf-x.as"
screen 0,480,320,0 : font "MS ゴシック",16
init_PF_X 1,20,20,96,0
RBYTE 0x20,"ffffffffffffffff00000000000000000000000000000000" //
RBYTE 0x21,"010101ff101013fffe66be00efc74800fefefe00efefef00" // !
RBYTE 0x22,"010101ff101010fffef68a00efef2800fefefe00efefef00" // "
RBYTE 0x23,"010101ff101010fffe8e0200e763a000fefefe00efefef00" // #
RBYTE 0x24,"010101ff101010ffbef68200ef4e0800fefefe00efefef00" // $
RBYTE 0x25,"f8e3cfdfbfbfbffb071c302040404004071c302040404004" // %
RBYTE 0x26,"1fc7f3fbfdfdfd5de0380c04020202a2e0380c04020202a2" // &
RBYTE 0x27,"bfbab5ffa9c49fd440454a00563b602b40454a00563b602b" // '
RBYTE 0x28,"ffad55ff1543f9930052aa00eabc066c0052aa00eabc066c" // (
RBYTE 0x30,"fffcf8f1f2f2f38100000001020203010000000102020301" // 0
RBYTE 0x31,"ff1f0be5d5d5f5e5000000e4d4d4f4e4000000e4d4d4f4e4" // 1
RBYTE 0x32,"7c45544544b9c3fc7c455445443903007c45544544390300" // 2
RBYTE 0x33,"05e5eee50db1bb4304e4eee40cb0b80004e4eee40cb0b800" // 3
RBYTE 0x34,"fffcf8f1f2f2f3c100000001020203010000000102020301" // 4
RBYTE 0x35,"ff1b05e5d5d5f5e5000004e4d4d4f4e4000004e4d4d4f4e4" // 5
RBYTE 0x36,"bea2aaa2a2dde0ff3e222a22221d00003e222a22221d0000" // 6
RBYTE 0x37,"05eee5ed036f778f04eee4ec0060700004eee4ec00607000" // 7
RBYTE 0x38,"fff8d0a7ababafa7000000272b2b2f27000000272b2b2f27" // 8
RBYTE 0x39,"ff3f1f8f4f4fcf81000000804040c080000000804040c080" // 9
RBYTE 0x3a,"a0a777a7b08dddc220277727300d1d0020277727300d1d00" // :
RBYTE 0x3b,"3ea22aa2229dc33f3ea22aa2229cc0003ea22aa2229cc000" // ;
RBYTE 0x3c,"ffd8a0a7ababafa7000020272b2b2f27000020272b2b2f27" // <
RBYTE 0x3d,"ff3f1f8f4f4fcf83000000804040c080000000804040c080" // =
RBYTE 0x3e,"a077a7b7c0f6eef12077273700060e002077273700060e00" // >
RBYTE 0x3f,"7d45554545bb07ff7c44544444b800007c44544444b80000" // ?
RBYTE 0x40,"0000000000000000ffffffffffffffff0000000000000000" // @
RBYTE 0x41,"fffffffffff0efdf000000000000040c0000000000000f1f" // A
RBYTE 0x42,"ffffffffffff3fdf000000000000000000000000000000c0" // B
RBYTE 0x43,"dfbfbf7f7f7eb9c718100000000000001f3f3f7f7f562800" // C
RBYTE 0x44,"eff3fdfefe7ebdc30000000000000000e0f0f8f4fa542800" // D
RBYTE 0x45,"fffffffffffffcfb00000000000000030000000000000003" // E
RBYTE 0x46,"ffffffffff0ff7fb0000000000008080000000000000f0f8" // F
RBYTE 0x47,"f7cfbf7f7f7ebdc30300000000000000070f3f7f7f3a1400" // G
RBYTE 0x48,"fbfdfdfefe7e9de30000000000000000f8f8f4fad42a1400" // H
RBYTE 0x49,"fffffffffff0efdf0000000000000f1f000000000000040c" // I
RBYTE 0x4a,"ffffffffffff3fdf00000000000000c00000000000000000" // J
RBYTE 0x4b,"dfbfbf7f7f56a9c71f3f3f7f7f7e38001810000000000000" // K
RBYTE 0x4c,"eff3f9f4fa52a9c3e0f0fcfefe7e3c000000000000000000" // J
RBYTE 0x4d,"fffffffffffffcfb00000000000000030000000000000003" // M
RBYTE 0x4e,"ffffffffff0ff7fb000000000000f0f80000000000008080" // N
RBYTE 0x4f,"f7cfbf7f7f3a95c3070f3f7f7f7e3c000300000000000000" // O
RBYTE 0x50,"fbf9f5fad42a95e3f8fcfcfefe7e1c000000000000000000" // P
mapsizex=10:mapsizey=30:sdim mps,11,30
mps( 0)="ffffffffff":mps( 1)="8ff0000001":mps( 2)="8ff00239fd":mps( 3)="8ffff201cd"
mps( 4)="8000023801":mps( 5)="80000605fd":mps( 6)="fff882007d":mps( 7)="80001b8049"
mps( 8)="8000307e09":mps( 9)="b1fe3e00c9":mps(10)="800020e0c1":mps(11)="fffffffff1"
mps(12)="8000000381":mps(13)="b00079fb9f":mps(14)="83ffc58001":mps(15)="8200548021"
mps(16)="9e0016803f":mps(17)="b000f4bfff":mps(18)="900886a003":mps(19)="979c9cae63"
mps(20)="d03e41a001":mps(21)="907f3e2fe1":mps(22)="90ff80efef":mps(23)="bdffff840f"
mps(24)="83ffe01e81":mps(25)="86003084bf":mps(26)="8c7f998487":mps(27)="98ffdbe6ff"
mps(28)="81ffc38201":mps(29)="ffffffffff"
gosub *mapset:randomize:sdim mc,8,4:sdim ec,8,2,2:emax=30
mc( 0)="01dll23":mc( 1)="45dll67":mc( 2)="89dll:;":mc( 3)="<=dll>?"
ec(0,0)="ABdllCD":ec(0,1)="EFdllGH":ec(1,0)="IJdllKL":ec(1,1)="MNdllOP"
dr="%&dll'(":dx=mapsizex-4:dy=mapsizey-4
x=2:y=2:v=0:vp=0:level=1:expl=0:hp=20:mhp=20:hpc=0
jf=0:jc=0:je=0:mpx=0:mpy=0:cwx=9:cwy=9
dim ef,emax:dim ex,emax:dim ey,emax:dim et,10:dim eh,emax
*lp:stick s,31:mx=(((s&4)!=0)&(x<(mapsizex-2)))-(((s&1)!=0)&(x>0))
mx*=(strmid(mapd(y),x+mx+(mx=1),1)=" "&strmid(mapd(y+1),x+mx+(mx=1),1)=" ")
jf=(((s&2)!=0)|jf)&((s&2)!=0&je=0):jc=(jc+(jf=1))*jf
je=((jc>5)|je)&(strmid(mapd(y+2),x+mx,2)=" "):if strmid(mapd(y+2),x+mx,2)=" "&(s&2)=0:je=1
my=((strmid(mapd(y+2),x+mx,2)=" ")*(jf=0))-(jf=1&strmid(mapd(y-1),x+mx,2)=" ")
gosub *attackcheck:if expl>=level*5 {level+=1:expl=0 }
hpc+=level:if hpc>30{hpc=0:hp+=1:if hp>mhp{hp=mhp}}
x+=mx:y+=my:v=(((mx=-1)|v)&(mx!=1)):vp=(vp^1)*(mx!=0)
mpx=limit(x-cwx,0,(mapsizex-20)):mpy=limit(y-cwy,0,(mapsizey-20))
redraw 0:for o,0,20:WBYTE 0,o,7,strmid(mapd(o+mpy),mpx,20):next
color:boxf 320,0,480,320:color 255,255,255:pos 336,16
mes "LEVEL "+strf("%3d",level)+"\n"
mes "MAXHP "+strf("%3d",mhp ) +"/HP "+strf("%3d",hp)+"\n"
mes "EXP "+strf("%3d",expl):WBYTE dx-mpx,dy-mpy,7,dr
gosub *enemy:WBYTE x-mpx,y-mpy,7,mc((v<<1)+vp):redraw 1
if hp<=0{pos 128,136:mes "GameOver":stop}
if x=dx&y=dy{pos 136,136:mes "Clear!":stop}
await 50:goto *lp
*attackcheck:at=-1:for eno,0,emax
af=(ef(eno)=1&ex(eno)-1<=x+mx&ex(eno)+1>=x+mx&ey(eno)-1<=y+my&ey(eno)+1>=y+my)
if af=1 { hp-=et(eno)+1:mx=0:my=0:eh(eno)-=level:at=eno}
if ef(eno)!=0&eh(eno)<=0{ ef(eno)=0:expl+=et(eno)+1 }
next:return
*enemy:for eno,0,emax:if ef(eno)=0 {gosub *enemyset:_continue}
em=((rnd(50)=0)-(rnd(50)=0))*(et(eno)>0)
em*=(strmid(mapd(ey(eno)),ex(eno)+em+(em=1),1)=" "&strmid(mapd(ey(eno)+1),ex(eno)+em+(em=1),1)=" ")
ey(eno)+=(strmid(mapd(ey(eno)+2),ex(eno)+em,2)=" ")
ecnt+=1:ecnt=ecnt*(ecnt<32):ex(eno)+=em
echr=ec(et(eno),(ecnt>>4)):if (ecnt>>4)=1 & eno=at :echr="@@dll@@"
WBYTE ex(eno)-mpx,ey(eno)-mpy,7,echr:next:return
*enemyset:ex(eno)=rnd(mapsizex-2)&0xfffe:ey(eno)=rnd(mapsizey-2)
et(eno)=rnd((ex(eno)>(mapsizex>>1)&ey(eno)>(mapsizey>>1))+1):eh(eno)=(et(eno)+1)*10
if strmid(mapd(ey(eno)),ex(eno),2)=" "&strmid(mapd(ey(eno)+1),ex(eno),2)=" ":ef(eno)=1
return
*mapset:sdim mapd,(mapsizex*8)+1,mapsizey*2
for o,0,mapsizey:for i,0,mapsizex:d=int("$"+strmid(mps(o),i,1)):sy=o<<1
sx=(i<<3) :t=((d&8)!=0):gosub *tipset:sx=(i<<3)+2:t=((d&4)!=0):gosub *tipset
sx=(i<<3)+4:t=((d&2)!=0):gosub *tipset:sx=(i<<3)+6:t=((d&1)!=0):gosub *tipset
next:next:mapsizex*=8:mapsizey*=2:return
*tipset
if t=0 {poke mapd(sy ),sx,' ':poke mapd(sy ),sx+1,' '
poke mapd(sy+1),sx,' ':poke mapd(sy+1),sx+1,' '}
else { poke mapd(sy ),sx,'!':poke mapd(sy ),sx+1,'\"'
poke mapd(sy+1),sx,'#':poke mapd(sy+1),sx+1,'$'}
return
| |
|