'What does it take for pacman to function correctly?
I'm experiencing 2 problems:
- the "you win" screen does not show up
- the pacman has a trail.
IDEAL
p286
MODEL small
STACK 100h
DATASEG
pacman db " _ __ __ _ ___ _ __ ___ __ _ _ __ ", 13, 10
db "| '_ \ / _` |/ __| '_ ` _ \ / _` | '_ \ ", 13, 10
db "| |_) | (_| | (__| | | | | | (_| | | | | ", 13, 10
db "| .__/ \__,_|\___|_| |_| |_|\__,_|_| |_| ", 13, 10
db "|_| ", 13, 10,'$'
how_to_play db "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #",13,10
db "# how to play: #",13,10
db "# The pacman is to eat the Apple #",13,10
db "# Use arrows to you'r move the pacman #",13,10
db "# #",13,10
db "# the game over when the pacman ate Apple #",13,10
db "# #",13,10
db "# good luck! #",13,10
db "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #",13,10
db " press any key to start...$"
you_win db" _ ", 13, 10
db" _ _ __ _ _ __ _(_)_ __ ", 13, 10
db"| | | |/ _ \| | | | \ \ /\ / / | '_ \ ", 13, 10
db"| |_| | (_) | |_| | \ V V /| | | | | ", 13, 10
db" \__, |\___/ \__,_| \_/\_/ |_|_| |_| ", 13, 10
db" |___/ ", 13, 10, '$'
AppleX dw 150
AppleY dw 20
img db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,14,14,14,14,14,00,00,00,00,00
db 00,00,00,00,12,14,14,14,14,14,14,14,14,00,00,00
db 00,00,00,12,14,12,14,14,14,14,14,14,14,14,00,00
db 00,00,12,14,14,14,14,14,14,14,14,15,15,00,14,00
db 00,00,14,12,14,14,14,14,14,14,14,15,15,00,14,00
db 00,12,12,14,14,14,14,14,14,14,14,14,14,14,14,00
db 00,12,14,12,14,14,14,14,14,14,14,14,14,14,14,00
db 00,12,12,14,12,14,14,14,14,14,14,14,14,14,00,00
db 00,12,14,12,14,14,14,14,14,14,14,14,00,00,00,00
db 00,12,12,14,12,14,14,14,14,14,00,00,00,00,00,00
db 00,00,12,12,14,12,14,14,14,14,14,14,00,00,00,00
db 00,00,12,14,12,14,12,14,14,14,14,14,14,14,00,00
db 00,00,00,12,14,12,14,12,14,12,14,12,14,12,00,00
db 00,00,00,00,12,12,12,14,12,14,12,14,12,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
img2 db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,14,14,14,14,14,00,00,00,00,00
db 00,00,00,00,12,14,14,14,14,14,14,14,14,00,00,00
db 00,00,00,12,14,12,14,14,14,14,14,14,14,14,00,00
db 00,00,12,14,14,14,14,14,14,14,14,15,15,00,14,00
db 00,00,14,12,14,14,14,14,14,14,14,15,15,00,14,00
db 00,12,12,14,14,14,14,14,14,14,14,14,14,14,14,14
db 00,12,14,12,14,14,14,14,14,14,14,14,14,14,14,14
db 00,12,12,14,12,14,14,14,14,14,14,14,14,14,14,14
db 00,12,14,12,14,14,14,14,14,14,14,14,14,14,14,14
db 00,12,12,14,12,14,14,14,14,14,14,14,14,14,14,14
db 00,00,12,12,14,12,14,14,14,14,14,14,14,14,14,00
db 00,00,12,14,12,14,12,14,14,14,14,14,14,14,14,00
db 00,00,00,12,14,12,14,12,14,12,14,12,14,12,00,00
db 00,00,00,00,12,12,12,14,12,14,12,14,12,00,00,00
db 00,00,00,00,00,00,12,12,12,12,12,00,00,00,00,00
black db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
apple db 7,2,2,2,6,6,6,2,7,7
db 7,2,2,7,6,6,7,2,2,7
db 2,2,2,7,6,6,7,2,2,7
db 7,7,7,4,4,4,4,7,7,7
db 7,4,4,4,4,4,4,4,4,7
db 4,4,4,4,4,4,4,4,4,4
db 4,4,4,4,4,4,4,4,4,4
db 4,4,4,4,4,4,4,4,4,4
db 4,4,4,4,4,4,4,4,4,4
db 4,4,4,4,4,4,4,4,4,4
db 4,4,4,4,4,4,4,4,4,4
db 7,4,4,4,4,4,4,4,4,7
db 7,7,7,4,4,4,4,7,7,7
imgA dw ?
x dw 16
y dw 0
color db 2
; --------------------------
CODESEG
proc PutPixel
pusha
mov bh,0h
mov cx,[x]
mov dx,[y]
mov al,[color]
mov ah,0ch
int 10h
popa
ret
endp PutPixel
proc Waiting
pusha
L3:
push cx
mov cx, 400
L4:
nop
loop L4
pop cx
loop L3
popa
ret
endp Waiting
proc Instruction
pusha
mov ah, 09
mov dx, offset how_to_play
int 21h
; Wait for key press
mov ah,0bh
int 21h
popa
ret
endp Instruction
proc PrintPacman
pusha
mov ah, 09
mov dx, offset pacman
int 21h
popa
ret
endp PrintPacman
proc YouWin
pusha
; Return to text mode
mov ah, 0
mov al, 2
int 10h
mov ah, 09
mov dx, offset you_win
int 21h
popa
ret
endp YouWin
proc PrintPacmanImg
pusha
mov cx, 16
mov si,[imgA]
lop:
push cx
mov cx, 16
sub [x],cx
lop2:
mov dl, [si]
mov [color], dl
call PutPixel
inc [x]
inc si
loop lop2
inc [y]
pop cx
loop lop
sub [y],16
popa
ret
endp PrintPacmanImg
proc DelPacmanImg
pusha
mov si,offset black
mov cx, 16
lopb:
push cx
mov cx, 16
sub [x],cx
lop2b:
mov dl, [si]
mov [color], dl
call PutPixel
inc [x]
inc si
loop lop2b
inc [y]
pop cx
loop lopb
sub [y],16
popa
ret
endp DelPacmanImg
proc lopDelete
pusha
lopdel:
call DelPacmanImg
mov si, offset img2
mov [imgA], si
call PrintPacmanImg
call waiting
call DelPacmanImg
mov si, offset img
mov [imgA], si
call PrintPacmanImg
call waiting
call DelPacmanImg
add [x],10
cmp [x],336
ja down
jmp lopdel
down:
add [y],15
cmp [y], 60
ja stop
mov [x],16
jmp lopdel
stop: popa
ret
endp lopDelete
proc PrintApple
pusha
push [x]
push [y]
mov bx,[AppleX]
mov [x], bx
mov bx,[Appley]
mov [y], bx
lea si, [apple]
mov cx, 13
l:
push cx
mov cx, 10
sub [x],cx
l2:
mov dl, [si]
mov [color], dl
call PutPixel
inc [x]
inc si
loop l2
inc [y]
pop cx
loop l
sub [y],16
pop [y]
pop[x]
popa
ret
endp PrintApple
proc Game
mov ax, 013h ; Init Graph
int 010h
call PrintApple
;the place pacman start moving
mov [x], 20
mov [y],100
ReadKey:
cmp [x],150
jb continu
cmp [x],160
jnbe continu
checky:
cmp [y],15
jb continu
cmp [y], 25
jbe gameover
continu:
call DelPacmanImg
mov si, offset img2
mov [imgA], si
call PrintPacmanImg
call waiting
call DelPacmanImg
mov si, offset img
mov [imgA], si
call PrintPacmanImg
call waiting
mov ah, 0
int 016h
cmp ah, 75 ; Left
jne Skip1
sub [x], 10
Skip1:
cmp ah, 77 ; Right
jne Skip2
add [x], 10
Skip2:
cmp ah, 72 ; Up
jne Skip3
sub [y], 10
Skip3:
cmp ah, 80 ; Down
jne Skip4
add [y], 10
Skip4:
jmp ReadKey
gameover:
mov ax, 02h ;RestoreTextMode
int 010h
ret
endp Game
proc second_apple_pos
mov [AppleX], 220
mov [AppleY], 300
ret
endp second_apple_pos
start:
mov ax, @data
mov ds, ax
; --------------------------
mov ax, 013h ; Init Graph
int 010h
call DelPacmanImg
mov si, offset img2
mov [imgA], si
call PrintPacmanImg
call waiting
call DelPacmanImg
mov si, offset img
mov [imgA], si
call PrintPacmanImg
call waiting
call game
call second_apple_pos
call game
;Return to text mode
mov ah, 0
mov al, 2
int 10h
call YouWin
; --------------------------
exit:
mov ax, 4c00h
int 21h
END start
Solution 1:[1]
Why the pacman exhibits a trail
For an object to move on the screen, you must delete it prior to changing one (or both) of its coordinates. Your code currently is drawing the object, changing the coordinates according to the inputted arrow key, and then redrawing the object in its new location. The old version was not removed from the screen.
continu:
call DelPacmanImg <<< This is redundant
mov si, offset img2
mov [imgA], si
call PrintPacmanImg
call waiting <<< This needs an argument in CX
call DelPacmanImg <<< This is redundant
mov si, offset img
mov [imgA], si
call PrintPacmanImg
call waiting <<< This needs an argument in CX
mov ah, 00h ; BIOS.WaitKeyboardKey
int 16h ; -> AX
call DelPacmanImg <<< Here you must delete the object
cmp ah, 4Bh ; Left
jne Skip1
sub [x], 10
Skip1:
...
Why the 'you win' screen doesn't show up
You have chosen to play two games before showing the "you win" screen. For the second game you initialize the position of the apple offscreen! The screen that you use (13h) has a resolution of 320 pixels horizontally and 200 pixels vertically, so mov [AppleY], 300
is outside of the screen's rectangle. Under these circumstances it can become very hard to find the area on the screen where your program can detect a win...
Also, if you position the apple alternatively, you should change the testing area correspondingly instead of keeping that rectangle hard coded.
Some free review
The outer loop (L2) in the Waiting procedure depends on CX for which your program does not provide a value. Either specify one as an argument to the proc or assign a value within the proc itself.
Your program uses the rather bizarre method of referring to an object via a coordinate that lies outside and to the right of the enclosing rectangle. It's very strange (to me at least), but hey, it can work.
The (first) apple at (150,20) and the area that you test:
130 140 150 160
v v v v
ttttttttttt <- 15
t t
t t
t t
t t
aaaaaaaaaa* t <- 20
a at t
a at t
a at t
a at t
a attttttttttt <- 25
a a
a a
a a
a a
a a
a a
aaaaaaaaaa
When pacman eats the apple at (150,20):
130 140 150 160
v v v v
ttttttttttt <- 15
t t
t t
t t
t t
pppppppppppppppp* t <- 20
p a pt t
p a pt t
p a pt t
p a pt t
p a pttttttttttt <- 25
p a p
p a p
p a p
p a p
p a p
p a p
p aaaaaaaaap
p p
p p
pppppppppppppppp
; Wait for key press mov ah,0bh int 21h
This DOS function does not wait for a key press! It merely reports if a key is available. It does not wait for one to become available.
; Return to text mode mov ah, 0 mov al, 2 int 10h
It's more usual to select the 80x25 text mode via its number 3.
mov ah, 09 mov dx, offset you_win int 21h
I would suggest you wait for a key press here, instead of having the program terminate directly after.
cmp [x],336 ja down
In the lopDelete procedure (what does that do?), this instruction refers to a non-existing X coordinate! Valid X range from 0 to 319.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sep Roland |