基于X86编程语言实现的迷宫游戏

Tempted

发布日期: 2019-03-24 23:25:10 浏览量: 1177
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

1. 功能简介与实现效果

一个用X86实现的迷宫游戏,首先,在进入游戏首页之后,玩家可以根据自己的喜好选择自己想要玩的难度,本游戏总共有是三个难度,Easy,Normal,Hard,分别对应三个不同难度的迷宫;

在选择了迷宫难度之后,将会刷新出一个对应难度的迷宫,在这个游戏中,玩家扮演的是一个想要逃离迷宫的小人,这个人用一个笑脸表示,只有当玩家控制角色到达迷宫的出口,即迷宫中标有 A 的位置时候,才能获得游戏的胜利;玩家将通过键盘上的W,A,S,D 键对角色进行移动,分别对应向上,左,下,右移动;当碰到障碍物的时候,角色将不能往那个方向移动;

在成功走出迷宫之后,玩家可以选择进入下一关或者是离开游戏;如果玩家已经走出最难的迷宫,那么玩家也可以选择继续游戏,重新玩一遍游戏;

2. 程序流程图

3. 实现过程

3.1 第一步,我们需要在DATA SEGMENT 中存放一些我们之后要使用的数据

  • 首先,是将整个迷宫模型保存在MSG_EASYMAZE(简单难度),MSG_NORMALMAZE(普通难度),MSG_HARDMAZE中(困难难度),分别对应三个难度的迷宫模型(这里限于篇幅值显示了MSG_EASYMAZE,另外两个迷宫是一样的原理,具体内容可以下载最下面的源代码查看)
  1. MSG_EASYMAZE DB "---------------------------------------------|", 0AH, 0DH
  2. DB " | | | | | |", 0AH, 0DH
  3. DB "| |------------ |--- | | | | | | | |", 0AH, 0DH
  4. DB "| | | | | | | | | |", 0AH, 0DH
  5. DB "| |--| ---| |--|-----| |------ | |--| |", 0AH, 0DH
  6. DB "| | | | |--| | |", 0AH, 0DH
  7. DB "|--- | |-----| | ------| ------|", 0AH, 0DH
  8. DB "| | | | |--| | | |", 0AH, 0DH
  9. DB "| ------| ------| |--| | |--- |--- | |", 0AH, 0DH
  10. DB "| | | | A", 0AH, 0DH
  11. DB "|--------------------------------------------|$"
  • 然后,是一些字符串,这些字符串将在游戏引导界面告诉玩家该如何操作:
  1. NEW_LINE DB 13,10,"$"
  2. MSG_WON DB "You Have Won!!! $", 0AH, 0DH
  3. MSG_NEXTLEVEL DB 13,10,"Go To The Next Level: Enter Y to the Next Level,Input Others to Exit!$",0AH, 0DH
  4. MSG_CONTINUE DB 13,10,"If Continue: Enter Y to Continue,Input Others to Exit!$",0AH, 0DH
  5. MSG_INSTRUCTION DB "WELCOME !!! $", 0AH, 0DH
  6. MSG_SETLEVEL DB "Enter the level you want to play(0 for easy,1 for normal,2 for difficulty): ",0AH, 0DH
  7. DB "Any Invalid Input Will Be Treat As 0: $",0AH, 0DH
  8. MSG_CONTROL DB "You are about to play the game, remember,you can use the w,a,s,d in the keyboard to move",0AH, 0DH
  9. DB "w for up, a for west, s for down, d for east, enter any key to play the game, have a good time!!!$",0AH, 0DH
  • 然后是一些我们需要使用的变量:
变量名 功能
x 玩家当前的x坐标
y 玩家当前的y坐标
NextX 玩家下一步的x坐标
NextY 玩家下一步的y坐标
position 临时变量,用于取出某个位置的内容(用于判断是不是为空,如果为空,则可以移动到该位置)
dirInput 临时变量,用于保存输入的移动指令,w,s,a,d
difficulty 临时变量,用于保存输入的难度
player 表示玩家(打印该变量即打印玩家)
direction 输入的指令(如Y表示Yes,用于判断是否继续游戏等函数)
  1. x DB 0H ; the x-coordinate of the player
  2. y DB 0H ; the y-coordinate of the player
  3. NextX DB 0H ; the next x-coordinate of the player
  4. NextY DB 0H ; the next y-coordinate of the player
  5. position DB 0H ; a template variable that we use to contain the character in the position
  6. dirInput DB 0H ; the direction you input that your player will move
  7. difficulty DW 0H
  8. player DB 01H
  9. direction DB 0H

3.2 之后我们添加进入游戏之前的引导界面代码

  1. START:
  2. MOV AX, DATA
  3. MOV DS, AX
  4. MOV ES, AX
  5. INSTRUCTION:
  6. CALL CLEAN_SCREEN
  7. LEA DX, MSG_INSTRUCTION ; print the welcome
  8. CALL SHOW
  9. LEA DX, NEW_LINE
  10. CALL SHOW
  11. LEA DX, MSG_CONTROL ; print how to control the player
  12. CALL SHOW
  13. LEA DX, NEW_LINE
  14. CALL SHOW
  15. LEA DX, MSG_SETLEVEL ; choose the difficulty
  16. CALL SHOW
  17. CALL GET_INPUT
  18. MOV direction, AL
  19. CMP direction,'0'
  20. JE GAME_START ; easy game
  21. CMP direction,'1'
  22. JE GAME_START_NORMAL ; normal game
  23. CMP direction,'2'
  24. JE GAME_START_HART ; hard game
  25. CALL GAME_START ; default : easy game

3.3 第三步,选择对应难度之后绘制对应难度的地图,下面以easy game为例

  • 首先,是绘制迷宫
  1. ;start the game
  2. GAME_START:
  3. CALL EASYMAZE ;draw the maze
  4. CALL SET_STARTPOS ;set the start position of the character
  5. CALL PRINT_PLAYER
  6. JMP ChangePos
  7. ; Draw the easy maze
  8. EASYMAZE:
  9. CALL CLEAN_SCREEN
  10. LEA DX, MSG_EASYMAZE
  11. CALL SHOW
  12. RET
  • 打印出地图之后,我们需要在起始位置:即迷宫的入口打印玩家
  1. ;Set the begin position of the player
  2. SET_STARTPOS:
  3. MOV NextX, 0H
  4. MOV NextY, 1H
  5. MOV x, 0H
  6. MOV y, 1H
  7. MOV DL, x
  8. MOV DH, y
  9. MOV BH, 0H
  10. MOV AH, 2H
  11. INT 10H
  12. RET
  13. ; Print the player to the console
  14. PRINT_PLAYER:
  15. MOV DL, player
  16. CALL SHOW_CHARACTER
  17. RET

3.4 第四步,开始监听键盘输入指令,对输入的对应指令进行处理,移动玩家

  • 监听键盘输入:w, a, s, d
  1. ChangePos:
  2. CALL GET_INPUT ; get the input
  3. MOV dirInput, AL
  4. ; case : w/W(up),a/A(left),s/S(down),d/D(right)
  5. CMP dirInput, 'W'
  6. JE MOVE_NORTH
  7. CMP dirInput, 'A'
  8. JE MOVE_WEST
  9. CMP dirInput, 'S'
  10. JE MOVE_SOUTH
  11. CMP dirInput, 'D'
  12. JE MOVE_EAST
  13. CMP dirInput, 'w'
  14. JE MOVE_NORTH
  15. CMP dirInput, 'a'
  16. JE MOVE_WEST
  17. CMP dirInput, 's'
  18. JE MOVE_SOUTH
  19. CMP dirInput, 'd'
  20. JE MOVE_EAST
  21. JMP ChangePos
  • 根据对应的输入控制角色进行相应的移动,我们以输入了W为例,整个移动过程如下
    • 删除原位置的字符
    • 更新下一步的位置
    • 判断下一步的位置是否合法
    • 如果是,移动坐标到该位置,反之,不移动
    • 回到ChangePos继续监听键盘输入,进行下一步移动
  1. MOVE_NORTH:
  2. CALL REMOVE_OLDPOS ;remove the character in previous position
  3. DEC NextY
  4. CALL ISVALID_POS
  5. DEC y ;if the positon is empty, then update the position
  6. MOV DL, x
  7. MOV DH, y
  8. CALL SET_CURSOR
  9. CALL PRINT_PLAYER
  10. JMP ChangePos ; go back to the ChangePos function, to read the next input
  • 删除原位置的字符
  1. ;This function is used to remove the character in previous position
  2. REMOVE_OLDPOS:
  3. MOV DL, x
  4. MOV DH, y
  5. CALL SET_CURSOR
  6. MOV DL, ' '
  7. CALL SHOW_CHARACTER
  8. RET
  • 判断新的位置是否合法:
    • 获得新的位置里面的字符
    • 该字符为空格,表示可以移动
    • 不为空,进入POS_NOTEMPTY函数判断是否为 ‘ A ’,为 ’ A ‘,获胜;反之,表示撞到了墙,不移动
  1. ISVALID_POS:
  2. MOV DL, NextX ; get the new position of the player
  3. MOV DH, NextY
  4. CALL SET_CURSOR
  5. MOV BH, 0h
  6. CALL GET_CHARACTER ; get the character in the new position
  7. MOV position, AL ; if if was empty, then we can the player to that direction
  8. CMP position, ' '
  9. JNE POS_NOTEMPTY
  10. RET
  11. POS_NOTEMPTY:
  12. CMP position, 'A' ; if it's the EXIT, then you win!!!
  13. JE WIN
  14. MOV DL, x
  15. MOV DH, y
  16. CALL SET_CURSOR
  17. MOV NextX, DL
  18. MOV NextY, DH ; set the new position the same as the old, it means you hit the wall and can not move
  19. CALL PRINT_PLAYER
  20. JMP ChangePos ; go back to the ChangePos function, to read the next input
  • 整个游戏过程就是不停的监听键盘输入,获得输入之后进行移动;如果此时已经离开了迷宫,则游戏成功;反之,继续监听键盘输入。

4. 逃离迷宫之后的界面

逃离迷宫后,你将会进入WIN函数,在这个函数里,你将选择是进入下一关(如果还有更高的难度的迷宫)还者是继续游戏(你已经通关所有难度的游戏了,可以重新再玩一次)

  1. WIN:
  2. CALL CLEAN_SCREEN
  3. LEA DX, MSG_WON
  4. CALL SHOW
  5. CMP difficulty,02H ; difficulty = 02H, you have pass all the games
  6. JNE SHOW_MSG_NEXTLEVEL ; if difficulty != 02H, go to choose if go to the next level
  7. JMP EXIT_GAME ; if difficulty == 02H, go to choose if continue
  8. EXIT_GAME:
  9. LEA DX, MSG_CONTINUE ; print the instruction
  10. CALL SHOW
  11. CALL READ_INPUT
  12. CMP AL, "Y"
  13. JNE EXIT
  14. JMP GAME_START
  15. EXIT:
  16. CALL CLEAN_SCREEN
  17. MOV AX, 4C00H
  18. INT 21H

5. 一些功能函数

最后我们需要的提供一些功能函数:清屏,获得某个位置的内容,显示字符串,显示字符,设置光标的位置等

  1. ; CALL this function to print in the console
  2. SHOW:
  3. MOV AH, 09H
  4. INT 21H
  5. RET
  6. ; CALL this function to print a character in the console
  7. SHOW_CHARACTER:
  8. MOV AH, 02H
  9. INT 21H
  10. RET
  11. ;CALL this function to clean the console
  12. CLEAN_SCREEN:
  13. MOV AL, 3H
  14. MOV AH, 0H
  15. INT 10H
  16. RET
  17. ; Print the player to the console
  18. PRINT_PLAYER:
  19. MOV DL, player
  20. CALL SHOW_CHARACTER
  21. RET
  22. ; Get the input from the keyboard
  23. GET_INPUT:
  24. MOV AH, 7H
  25. INT 21H
  26. RET
  27. ; Set the position of the cursor
  28. SET_CURSOR:
  29. MOV AH, 2H
  30. INT 10H
  31. RET
  32. ; Get the character in a position
  33. GET_CHARACTER:
  34. MOV AL, 0h
  35. MOV AH, 08h
  36. INT 10H
  37. RET
  38. ; Get the input
  39. READ_INPUT:
  40. MOV AH, 01
  41. INT 21H
  42. RET

6. 总结

整个程序的运行过程就是这样,一开始比较难处理的是如何获取某个位置的字符内容,之后通过使用上面的SET_CURSOR函数和GET_CHARACTER函数就解决了;目前让我比较在意的一点就是迷宫不能做的太大,如果做的太大的话就会导致打印的时候输出很奇怪,不过目前的程序运行起来是没有问题的๑乛◡乛๑

上传的附件 cloud_download 基于X86实现的迷宫游戏.zip ( 833.58kb, 9次下载 )
error_outline 下载需要12点积分

发送私信

永远别说永远,凡事都有可能

8
文章数
14
评论数
最近文章
eject