手元に実機も実行環境もありませんのでサポート不可です。
文章は執筆当時のものをそのまま掲載していますので、時代・時節と合わない表現が含まれています。
また、一部に半角カナ文字が使用されています。
今回の講義はここまでの総まとめという事で、「簡単なゲームを作る」という事になっっていますが、まぁ、そんなに難しいのは作りません。極々簡単なもので、「どこかにランダムにキャラが表示され、それを追いかける」というものです。
使う技術は、前回講義で使用した「カーソル移動」をそのまま流用しながら、更に(疑似)乱数というものを導入することにします。
という事で、まずは乱数の実現をしなければなりません。
ところでここでいう乱数というものは、疑似乱数というものであって、JISで定義されているような乱数は実現していません。ですから、値の出現確率にやや偏重があったりする可能性もありますが、極力そのような事のないようにしようと思います。
さて、まず簡単に「一般に言う乱数」というものを考えて見ましょう。
我々が実際にでくわす乱数というのは、ある程度の散乱があり、統一性が見い出しにくければそれだけで「ランダムだ」判断してしまいます。という事は、この事を利用すると、ちょっとした簡単な方法で疑似乱数が実現できます。
まずは、最も簡単なアルゴリズムで実現できるものを示しましょう。
Proc QuasiRandomRoutine1 Near
push ax bx
mov ax,[Word cs:RandomValue]
mov bx,ax
shl ax,3 ;ax := Random Value * 8
inc ax
mov [Word cs:RandomValue],ax
pop bx ax
ret
EndP
RandomValue:
dw ?
この方法では「以前の乱数値 × 8 + 1」という演算を行っていますが、値自体は一方的に大きくなっていく方向にありますが、例えば下位1 Byteだけをとってみると、これが実に以外になかなかの乱数値を弾いています。
また、×8としていますが、この値を変更したり、+1を0以外の値にしたりするだけで、更に違った結果が得られます。
ただ欠点としては、この方法ではある程度の回数演算を繰り返すと、次からの値が想像しやすなるという欠点をもっています(線形な演算を元しているので、当然の事ですが)。
ではこの欠点を解消するにはどうすればいいのでしょうか。
ここで電算機の機能を思い返して欲しいのですが、大抵の電算機には「時計」というものが内臓されています。時計の値は連続に見ると単に連続した数列でしかないのですが、最初は3秒後、次は7秒後、6秒後、2秒後・・・と時計を参照する時間自体がまちまちであったとすると、その時の時計の値、特に秒単位の部位などというのは、実によくできた乱数みたいなものとなります。
つまり、この時計の値を利用するという事です。ただし、間違ってもこの時計の値をそのまま利用するのではなく(そのまま利用してもいいのですが、それではあまりにも芸がないものですので)、先程の疑似乱数Routineに利用してやりたいとおもいます。
Proc QuasiRandomRoutine2 Near
push ax bx
call NowTimeGet
mov ax,[Word cs:RandomValue]
mul [Word cs:NowTime]
call NowTimeGet
add ax,[Word cs:NowTime]
mov [Word cs:RandomValue],ax
pop bx ax
ret
EndP
Proc NowTimeGet Near
push ax bx cx dx
mov ax,00200h ;PC-88VA Only
int 08ch ;PC-88VA Only
mov ax,02c00h ;MS-DOS Function
int 021h ;MS-DOS Function
and dx,00000111100000000b
xchg dh,dl
inc dx
mov [Word cs:NowTime],dx
pop dx cx bx ax
ret
EndP
RandomValue:
dw ?
NowTime:
dw ?
やってる事は実に単純ですね。まず時間を読み取り、その時間の秒の1の位を掛算し、さらにもう一回時間を読んで、同じく秒の1の位を足算しています(尚、非零値を必ず得られるようにする為に、秒は+1されています)。こうすれば、かなり乱数に近い値が得られるようになっている事と思います。
(注:NowTimeGet Procedureに於いて、PC-88VA Seriesをお使いの場合は、MS-DOS FunctionとCommentを打っている行を削除してください。また、VA以外の機種ではPC-88VA OnlyとCommentを打っている行を削除してください(尚、MS-DOS(或いは互換環境)上で動作させている事が前提です。そうでない場合は各機種の持つ時間の読み込み方法を利用してください))
さてこれで、殆ど乱数が実現できたに等しいのですが、まだまだ飽きたらないという場合には更に次の方法を示す事にしましょう。
Proc QuasiRandomRoutine3 Near
push ax bx
mov ax,[Word cs:RandomValue]
mov bx,ax
shl bx,8 ;BX := AX * 259
add bx,ax
shl ax,1
add bx,ax
mov [Word cs:RandomValue],bx
pop bx ax
ret
EndP
RadomValue:
dw ?
この方法では「以前の値 × 259」という演算を繰り返すだけです。実に簡単なもので、以前私が作ったゲームでも実際に採用した方法でもあります。
このように疑似でいいとあれば、乱数は実に簡単に実現する事ができます。
(注:これら疑似乱数は、以前本講義中でも紹介しました
「8086マシン語秘伝の書」 日高 徹/青山 学 共著 啓学出版
という書籍の86頁から99頁までの内容を参考に作成されています)
さて、乱数の実現ができましたので、次にこれを利用したいと思います。
今回目標では「キャラをランダムに表示する」という事に意義がありますので、これを実現しなければなりません。
という事でこの疑似乱数関数を実際に使用したものを示してみましょう。
Proc ObjectCharacterSet Near
push ax bx cx dx
ObjectCharacterXLocation: ;X軸の設定
mov al,79
xor bx,bx
call QuasiRandomRoutine
mov bl,[Byte cs:RandomValue]
ObjectCharacterXLocationLoop:
cmp bl,al ;X軸がはみ出していないか
jbe ObjectCharacterYLocation
sub bl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterXLocationLoop
ObjectCharacterYLocation: ;Y軸の設定
mov al,23
xor cx,cx
call QuasiRandomRoutine
mov cl,[Byte cs:RandomValue]
ObjectCharacterYLocationLoop:
cmp cl,al ;Y軸がはみ出していないか
jbe ObjectCharacterPrint
sub cl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterYLocationLoop
ObjectCharacterPrint:
mov [Word cs:ObjectCharacterPoint + 0],bx
mov [Word cs:ObjectCharacterPoint + 2],cx
mov dl,'O'
call CharacterPrint
pop dx cx bx ax
ret
EndP
;Call
; [Word cs:RandomValue] : Random Seed
;
;Return
; [Word cs:RandomValue] : 求めたRandom値
Proc QuasiRandomRoutine Near
push ax bx
mov ax,[Word cs:RandomValue]
mov bx,ax
shl bx,8 ;BX := AX * 259
add bx,ax
shl ax,1
add bx,ax
mov [Word cs:RandomValue],bx
pop bx ax
ret
EndP
;Call
; BX : X軸
; CX : Y軸
; DL : 表示する文字
Proc CharacterPrint Near
push bx cx di es
shl bx,1 ;BX := BX * 2
mov di,bx
shl cx,5 ;CX := CX * (80 * 2)
add di,cx
shl cx,2
add di,cx
mov bx,0a000h
mov es,bx
mov [Byte es:di],dl
pop es di cx bx
ret
EndP
ObjectCharacterPoint:
dw ? ;X
dw ? ;Y
RadomValue:
dw ?
この例では3つ目に示した疑似乱数を使用しています。
さてここでやっている事は実に簡単なものです。単に乱数を読み出して、その値が範囲に納まるように加工(引算)し、表示するというだけです。
このようにすれば、実に簡単に「ランダムな位置に表示する」という事で実現できたわけですね。
では、最後に衝突判定を付け足し、ゲームとして実現させましょう。
まず衝突判定というものですが、これ単に「座標の重なり」を見ればいいだけです。
つまり、自キャラの位置と目的の位置とが一致すれば「衝突」と判断し、不一致ならば「非衝突」というわけになるのですが、こういった判断方法は実によく多用されているものだと思います。
ちなみに、この方法ではCharacter数が多くなると時間がかかるようになってしまうという欠点がありますが、次回講義で取り上げる予定の仮想画面を利用して衝突を判断するという技法もありますが、ここでは取り上げません(内容は次回ということで)。
さて、では例を示しましょう。
;For PC-88VA Sample Program
;--------For Assembler Option
Ideal
P186
Model Small
Stack 00200h
;--------Code Segment Start
CodeSeg
;--------Main Process
;........Main Process - Initialize
Initialize:
call TextVRAMInitialize
call RandomizeRoutine
call ObjectCharacterSet
call KeyboardInitialize
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
mov dl,'A'
call CharacterPrint
;........Main Process - MainRoutine
MainRoutine:
call VSYNCWait
call MyCharacterMove
test al,000010000b
jnz ReturnSystem
call CollisionCheck
or ax,ax
jz MainRoutine
call ObjectCharacterSet
jmp Short MainRoutine
;........Main Process - ReturnSystem
ReturnSystem:
mov ax,04c00h
int 021h
;--------Other Procedures
;........Other Procedures - VSYNCWait
;
; Call
; None
;
; Return
; None
;
Proc VSYNCWait Near
push ax
VSYNCWait1:
in al,040h
test al,000100000b
jz VSYNCWait1
VSYNCWait2:
in al,040h
test al,000100000b
jnz VSYNCWait2
pop ax
ret
EndP
;........Other Procedures - CollisionCheck
;
; Call
; [DWord cs:CharacterPoint] : 自キャラ現在位置
; [DWord cs:ObjectCharacterPoint] : 目的現在位置
;
; Return
; AX : 衝突していればFFFFh、していなければ0000h
;
Proc CollisionCheck Near
push bx cx
xor ax,ax
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
cmp bx,[Word cs:ObjectCharacterPoint + 0]
jnz CollisionCheckEnd
cmp cx,[Word cs:ObjectCharacterPoint + 2]
jnz CollisionCheckEnd
not ax
CollisionCheckEnd:
pop cx bx
ret
EndP
;--------Character Set
;........Character Set - MyCharacterMove
;
; Call
; [Word cs:CharatcerPoint + 0] : 自キャラX軸
; [Word cs:CharatcerPoint + 2] : 自キャラY軸
;
; Return
; AL : 押されたKeyの内容
; [Word cs:CharatcerPoint + 0] : 自キャラX軸
; [Word cs:CharatcerPoint + 2] : 自キャラY軸
;
Proc MyCharacterMove Near
push bx cx dx
call KeyInputCheck
or al,al
jz MyCharacterMoveEnd
test al,000010000b
jnz MyCharacterMoveEnd
MyCharacterMoveCheckStart:
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
mov dl,' '
call CharacterPrint
MyCharacterMoveUpCheck:
test al,000001000b
jz MyCharacterMoveDownCheck
or cx,cx
jz MyCharacterMoveDownCheck
dec cx
MyCharacterMoveDownCheck:
test al,000000100b
jz MyCharacterMoveLeftCheck
cmp cx,23
jae MyCharacterMoveLeftCheck
inc cx
MyCharacterMoveLeftCheck:
test al,000000010b
jz MyCharacterMoveRightCheck
or bx,bx
jz MyCharacterMoveRightCheck
dec bx
MyCharacterMoveRightCheck:
test al,000000001b
jz MyCharacterMoveEndFront
cmp bx,79
jae MyCharacterMoveEndFront
inc bx
MyCharacterMoveEndFront:
mov dl,'A'
call CharacterPrint
mov [Word cs:CharacterPoint + 0],bx
mov [Word cs:CharacterPoint + 2],cx
MyCharacterMoveEnd:
pop dx cx bx
ret
EndP
;........Character Set - ObjectCharacterSet
;
; Call
; None
;
; Return
; [Word cs:ObjectCharacterPoint + 0] : 目的のX軸
; [Word cs:ObjectCharacterPoint + 2] : 目的のY軸
;
Proc ObjectCharacterSet Near
push ax bx cx dx
ObjectCharacterXLocation: ;X軸の設定
mov al,79
xor bx,bx
call QuasiRandomRoutine
mov bl,[Byte cs:RandomValue]
ObjectCharacterXLocationLoop:
cmp bl,al ;X軸がはみ出していないか
jbe ObjectCharacterYLocation
sub bl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterXLocationLoop
ObjectCharacterYLocation: ;Y軸の設定
mov al,23
xor cx,cx
call QuasiRandomRoutine
mov cl,[Byte cs:RandomValue]
ObjectCharacterYLocationLoop:
cmp cl,al ;Y軸がはみ出していないか
jbe ObjectCharacterPrint
sub cl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterYLocationLoop
ObjectCharacterPrint:
mov [Word cs:ObjectCharacterPoint + 0],bx
mov [Word cs:ObjectCharacterPoint + 2],cx
mov dl,'O'
call CharacterPrint
pop dx cx bx ax
ret
EndP
;--------Random Routines
;........Random Routines - RandomizeRoutine
;
; Call
; None
;
; Return
; [Word cs:RandomValue] : Random Seed
;
Proc RandomizeRoutine Near
push ax
call NowTimeGet
mov ax,[Word cs:NowTime]
mov [Word cs:RandomValue],ax
pop ax
ret
EndP
;........Random Routines - QuasiRandomRoutine
;
; Call
; [Word cs:RandomValue] : Random Seed
;
; Return
; [Word cs:RandomValue] : 求めたRandom値
;
Proc QuasiRandomRoutine Near
push ax bx
mov ax,[Word cs:RandomValue]
mov bx,ax
shl bx,8 ;BX := AX * 259
add bx,ax
shl ax,1
add bx,ax
mov [Word cs:RandomValue],bx
pop bx ax
ret
EndP
;........Random Routines - NowTimeGet
;
; Call
; None
;
; Return
; [Word cs:NowTime] : 現在時刻(秒の1の位)
;
Proc NowTimeGetNear Near
push ax bx cx dx
mov ax,00200h
int 08ch
and dx,00000111100000000b
xchg dh,dl
inc dx
mov [Word cs:NowTime],dx
pop dx cx bx ax
ret
EndP
;--------Keyboard Routines
;........Keyboard Routines - KeyboardInitialize
;
; Call
; None
;
; Return
; None
;
Proc KeyboardInitialize Near
push ax
mov ax,00500h
int 082h
pop ax
ret
EndP
;........Keyboard Routines - KeyInputCheck
;
; Call
; None
;
; Return
; AL : Key Push Flag
; None - None - None - Stop = Up - Down - Left - Right
;
Proc KeyInputCheck Near
pushf
push bx cx ds
cld
mov ax,cs
mov ds,ax
mov si,Offset InputKeyTable
xor bx,bx
mov cx,5
KeyInputCheckLoop:
push cx
lodsb
mov ah,00dh
int 082h
lodsb
mov cl,al
shr ah,cl
rcl bl,1
pop cx
loop KeyInputCheckLoop
mov ax,bx
pop ds cx bx
popf
ret
EndP
;........Keyboard Routines - KeyBufferClear
;
; Call
; None
;
; Return
; None
;
Proc KeyBufferClear Near
push ax
mov ax,00400h
int 082h
pop ax
ret
EndP
;--------Text Routines
;........Text Routines - TextVRAMinitialize
;
; Call
; None
;
; Return
; None
;
Proc TextVRAMInitialize Near
push ax dx
mov ax,01702h
int 083h
mov dx,00154h ;VRAM Bank Change (T-VRAM)
mov al,041h
out dx,al
pop dx ax
ret
EndP
;........Text Routines - Character Print
;
; Call
; BX : X軸
; CX : Y軸
; DL : 表示する文字
;
; Return
; None
;
Proc CharacterPrint Near
push bx cx di es
shl bx,1 ;BX := BX * 2
mov di,bx
shl cx,5 ;CX := CX * (80 * 2)
add di,cx
shl cx,2
add di,cx
mov bx,0a000h
mov es,bx
mov [Byte es:di],dl
pop es di cx bx
ret
EndP
;--------Datas
;........Datas - CharacterPoint
CharacterPoint:
dw 40 ;X
dw 12 ;Y
;........Datas - ObjectCharacterPoint
ObjectCharacterPoint:
dw ? ;X
dw ? ;Y
;........Datas - RandomValue
RandomValue:
dw ?
;........Datas - NowTime
NowTime:
dw ?
;........Datas - InputKeyTable
InputKeyTable:
db 009h,1 ;Stop
db 008h,2 ;Up
db 00ah,2 ;Down
db 00ah,3 ;Left
db 008h,3 ;Right
;--------End of Source
End
;For PC-9800 Sample Program
;--------For Assembler Option
Ideal
P186
Model Small
Stack 00200h
;--------Code Segment Start
CodeSeg
;--------Main Process
;........Main Process - Initialize
Initialize:
call TextVRAMInitialize
call RandomizeRoutine
call ObjectCharacterSet
call KeyboardInitialize
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
mov dl,'A'
call CharacterPrint
;........Main Process - MainRoutine
MainRoutine:
call VSYNCWait
call MyCharacterMove
test al,000010000b
jnz ReturnSystem
call CollisionCheck
or ax,ax
jz MainRoutine
call ObjectCharacterSet
jmp Short MainRoutine
;........Main Process - ReturnSystem
ReturnSystem:
call KeyBufferClear
mov ax,04c00h
int 021h
;--------Other Procedures
;........Other Procedures - VSYNCWait
;
; Call
; None
;
; Return
; None
;
Proc VSYNCWait Near
push ax
VSYNCWait1:
in al,0a0h
test al,000100000b
jz VSYNCWait1
VSYNCWait2:
in al,0a0h
test al,000100000b
jnz VSYNCWait2
pop ax
ret
EndP
;........Other Procedures - CollisionCheck
;
; Call
; [DWord cs:CharacterPoint] : 自キャラ現在位置
; [DWord cs:ObjectCharacterPoint] : 目的現在位置
;
; Return
; AX : 衝突していればFFFFh、していなければ0000h
;
Proc CollisionCheck Near
push bx cx
xor ax,ax
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
cmp bx,[Word cs:ObjectCharacterPoint + 0]
jnz CollisionCheckEnd
cmp cx,[Word cs:ObjectCharacterPoint + 2]
jnz CollisionCheckEnd
not ax
CollisionCheckEnd:
pop cx bx
ret
EndP
;--------Character Set
;........Character Set - MyCharacterMove
;
; Call
; [Word cs:CharatcerPoint + 0] : 自キャラX軸
; [Word cs:CharatcerPoint + 2] : 自キャラY軸
;
; Return
; AL : 押されたKeyの内容
; [Word cs:CharatcerPoint + 0] : 自キャラX軸
; [Word cs:CharatcerPoint + 2] : 自キャラY軸
;
Proc MyCharacterMove Near
push bx cx dx
call KeyInputCheck
or al,al
jz MyCharacterMoveEnd
test al,000010000b
jnz MyCharacterMoveEnd
MyCharacterMoveCheckStart:
mov bx,[Word cs:CharacterPoint + 0]
mov cx,[Word cs:CharacterPoint + 2]
mov dl,' '
call CharacterPrint
MyCharacterMoveUpCheck:
test al,000001000b
jz MyCharacterMoveDownCheck
or cx,cx
jz MyCharacterMoveDownCheck
dec cx
MyCharacterMoveDownCheck:
test al,000000100b
jz MyCharacterMoveLeftCheck
cmp cx,23
jae MyCharacterMoveLeftCheck
inc cx
MyCharacterMoveLeftCheck:
test al,000000010b
jz MyCharacterMoveRightCheck
or bx,bx
jz MyCharacterMoveRightCheck
dec bx
MyCharacterMoveRightCheck:
test al,000000001b
jz MyCharacterMoveEndFront
cmp bx,79
jae MyCharacterMoveEndFront
inc bx
MyCharacterMoveEndFront:
mov dl,'A'
call CharacterPrint
mov [Word cs:CharacterPoint + 0],bx
mov [Word cs:CharacterPoint + 2],cx
MyCharacterMoveEnd:
pop dx cx bx
ret
EndP
;........Character Set - ObjectCharacterSet
;
; Call
; None
;
; Return
; [Word cs:ObjectCharacterPoint + 0] : 目的のX軸
; [Word cs:ObjectCharacterPoint + 2] : 目的のY軸
;
Proc ObjectCharacterSet Near
push ax bx cx dx
ObjectCharacterXLocation: ;X軸の設定
mov al,79
xor bx,bx
call QuasiRandomRoutine
mov bl,[Byte cs:RandomValue]
ObjectCharacterXLocationLoop:
cmp bl,al ;X軸がはみ出していないか
jbe ObjectCharacterYLocation
sub bl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterXLocationLoop
ObjectCharacterYLocation: ;Y軸の設定
mov al,23
xor cx,cx
call QuasiRandomRoutine
mov cl,[Byte cs:RandomValue]
ObjectCharacterYLocationLoop:
cmp cl,al ;Y軸がはみ出していないか
jbe ObjectCharacterPrint
sub cl,al ;はみ出さなくなるまで引算
jmp Short ObjectCharacterYLocationLoop
ObjectCharacterPrint:
mov [Word cs:ObjectCharacterPoint + 0],bx
mov [Word cs:ObjectCharacterPoint + 2],cx
mov dl,'O'
call CharacterPrint
pop dx cx bx ax
ret
EndP
;--------Random Routines
;........Random Routines - RandomizeRoutine
;
; Call
; None
;
; Return
; [Word cs:RandomValue] : Random Seed
;
Proc RandomizeRoutine Near
push ax
call NowTimeGet
mov ax,[Word cs:NowTime]
mov [Word cs:RandomValue],ax
pop ax
ret
EndP
;........Random Routines - QuasiRandomRoutine
;
; Call
; [Word cs:RandomValue] : Random Seed
;
; Return
; [Word cs:RandomValue] : 求めたRandom値
;
Proc QuasiRandomRoutine Near
push ax bx
mov ax,[Word cs:RandomValue]
mov bx,ax
shl bx,8 ;BX := AX * 259
add bx,ax
shl ax,1
add bx,ax
mov [Word cs:RandomValue],bx
pop bx ax
ret
EndP
;........Random Routines - NowTimeGet
;
; Call
; None
;
; Return
; [Word cs:NowTime] : 現在時刻(秒の1の位)
;
Proc NowTimeGet Near
push ax bx cx dx
mov ax,02c00h
int 021h
and dx,00000111100000000b
xchg dh,dl
inc dx
mov [Word cs:NowTime],dx
pop dx cx bx ax
ret
EndP
;--------Keyboard Routines
;........Keyboard Routines - KeyboardInitialize
;
; Call
; None
;
; Return
; None
;
Proc KeyboardInitialize Near
push ax
mov ax,00300h
int 018h
pop ax
ret
EndP
;……..Keyboard Routines - KeyInputCheck
;
; Call
; None
;
; Return
; AL : Key Push Flag
; None - None - None - Stop = Up - Down - Left - Right
;
Proc KeyInputCheck Near
pushf
push bx cx ds
cld
mov ax,cs
mov ds,ax
mov si,Offset InputKeyTable
xor bx,bx
mov cx,5
KeyInputCheckLoop:
push cx
lodsb
mov ah,004h
int 018h
lodsb
mov cl,al
shr ah,cl
rcl bl,1
pop cx
loop KeyInputCheckLoop
mov ax,bx
pop ds cx bx
popf
ret
EndP
;........Keyboard Routines - KeyBufferClear
;
; Call
; None
;
; Return
; None
;
Proc KeyBufferClear Near
push ax bx
KeyBufferClearLoop:
mov ax,00100h
int 018h
or bh,bh
jz KeyBufferClearEnd
xor ax,ax
int 018h
jmp Short KeyBufferClearLoop
KeyBufferClearEnd:
pop bx ax
ret
EndP
;--------Text Routines
;........Text Routines - TextVRAMinitialize
;
; Call
; None
;
; Return
; None
;
Proc TextVRAMInitialize Near
pushf
push ax cx di es
cld
mov ax,0a000h
mov es,ax
xor di,di
mov ax,00020h
mov cx,80 * 24
rep stosw
pop es di cx ax
popf
ret
EndP
;........Text Routines - Character Print
;
; Call
; BX : X軸
; CX : Y軸
; DL : 表示する文字
;
; Return
; None
;
Proc CharacterPrint Near
push bx cx di es
shl bx,1 ;BX := BX * 2
mov di,bx
shl cx,5 ;CX := CX * (80 * 2)
add di,cx
shl cx,2
add di,cx
mov bx,0a000h
mov es,bx
mov [Byte es:di],dl
pop es di cx bx
ret
EndP
;--------Datas
;........Datas - CharacterPoint
CharacterPoint:
dw 40 ;X
dw 12 ;Y
;........Datas - ObjectCharacterPoint
ObjectCharacterPoint:
dw ? ;X
dw ? ;Y
;........Datas - RandomValue
RandomValue:
dw ?
;........Datas - NowTime
NowTime:
dw ?
;........Datas - InputKeyTable
InputKeyTable:
db 00ch,1 ;Stop
db 007h,3 ;Up
db 007h,6 ;Down
db 007h,4 ;Left
db 007h,5 ;Right
;--------End of Source
End
このゲームでは自キャラは「A」、目標は「O」で表示されています。
Cursor Keyで移動し、Stop Keyで終了になります。
やってる事は今までやった事全てを用いているだけで、追加した内容はありませんね。実に単純な設計だと思います。
というわけで、ここまでで目標としいた「単純なゲームを作る」という事は実現できました。
しかし、今回の内容ではあまりに単純すぎましたので、先程もいいましたように次は「仮想画面の実現」を取り上げ、更に実際に実用できる直前の段階までつきとめようと思います。
というわけで次回講義は「簡単なゲームを作ろう—中編— 仮想画面の実現」です。
ちなみに、「中編」なのはあともう1つ最後に付け足しとして「—後編— 味付け」ということで、効果音をつけてみたり、点数をつけてみたり、時間制限を考えみたり等々、更にゲームらしくする事が目的です(尚、Graphicは使用せずTextのみで行います)。
では次回をお楽しみに。
手元に実機も実行環境もありませんのでサポート不可です。
文章は執筆当時のものをそのまま掲載していますので、時代・時節と合わない表現が含まれています。
また、一部に半角カナ文字が使用されています。