我需要创建一个任务,使 MARS 中的位图显示变成迷宫。它必须看起来像这样:wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwupppwppppppppwppppwwwwwwwww wwwwwwwwwpwwpwpwwwwwwpwpwwpwwwwwwwww wwwwwwwwwpwppppppppppppppwpwwwwwwwww wwwwwwwwwpwpwwpwwppwwpwwpwpwwwwwwwww wwwwwwwwwppppppwppppwppppppwwwwwwwww wwwwwwwwwpwpwwpwwwwwwpwwpwpwwwwwwwww wwwwwwwwwpwppppppppppppppwpwwwwwwwww wwwwwwwwwpwwpwpwwwwwwpwpwwpwwwwwwwww wwwwwwwwwppppwpppsppppwppppwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww w=墙壁=蓝色,p=通道=黑色,s=玩家=黄色,u=退出=绿色,换行=结束。所以根据字母的含义我的迷宫应该是这样的。这是我的代码:
.data
mazeFilename: .asciiz "input_1.txt"
buffer: .space 4096
victoryMessage: .asciiz "You have won the game!"
amountOfRows: .word 16 # The number of rows of pixels
amountOfColumns: .word 32 # The number of columns of pixels
wallColor: .word 0x004286F4 # Color used for walls (blue)
passageColor: .word 0x00000000 # Color used for passages (black)
playerColor: .word 0x00FFFF00 # Color used for player (yellow)
exitColor: .word 0x0000FF00 # Color used for exit (green)
.text
# Function to read the maze from a file
read_maze:
# Open the file
li $v0, 13
la $a0, mazeFilename
li $a1, 0
li $a2, 0
syscall
move $s6, $v0
# Read the content of the file
li $v0, 14
move $a0, $s6
la $a1, buffer
li $a2, 4096
syscall
# Store the content in the bitmap memory
la $t0, buffer
move $t1, $gp
li $t2, 0
read_loop:
lb $t3, 0($t0)
beq $t3, 'w', set_wall_color
beq $t3, 'p', set_passage_color
beq $t3, 's', set_player_color
beq $t3, 'u', set_exit_color
addiu $t0, $t0, 1
addiu $t1, $t1, 4
addiu $t2, $t2, 1
blt $t2, 4096, read_loop
jr $ra
set_wall_color:
lw $t4, wallColor
sw $t4, 0($t1)
j read_loop
set_passage_color:
lw $t4, passageColor
sw $t4, 0($t1)
j read_loop
set_player_color:
lw $t4, playerColor
sw $t4, 0($t1)
j read_loop
set_exit_color:
lw $t4, exitColor
sw $t4, 0($t1)
j read_loop
# Function to move the player
move_player:
# Check the new position (simplified version assuming the position is valid)
# Add your own validation here
# Adjust pixel colors
lw $t0, playerColor
lw $t1, wallColor
lw $t2, passageColor
lw $t3, exitColor
sw $t0, 0($s0)
sw $t1, 0($s1)
sw $t2, 0($s2)
sw $t3, 0($s3)
# Return the new position
move $v0, $s0
move $v1, $s1
jr $ra
# Function to check if the new position is valid
check_new_position:
# Check if the new position is within the playfield
lw $t0, amountOfRows
lw $t1, amountOfColumns
blt $s0, $t0, valid_row
blt $s1, $t1, valid_column
j invalid_position
valid_row:
blt $s1, $t1, valid_column
j invalid_position
valid_column:
# Check if there are no walls at the new position
lw $t2, wallColor
lw $t3, 0($s0)
beq $t2, $t3, invalid_position
j valid_position
invalid_position:
# Return the current position
move $v0, $s0
move $v1, $s1
jr $ra
valid_position:
# Return the new position
move $v0, $s0
move $v1, $s1
jr $ra
# Functions to move the player in different directions
move_up:
subiu $s0, $s0, 1
jal check_new_position
lw $t0, playerColor
lw $t1, wallColor
lw $t2, passageColor
lw $t3, exitColor
sw $t0, 0($s0)
sw $t1, 0($s1)
sw $t2, 0($s2)
sw $t3, 0($s3)
move $v0, $s0
move $v1, $s1
jr $ra
move_down:
addiu $s0, $s0, 1
jal check_new_position
lw $t0, playerColor
lw $t1, wallColor
lw $t2, passageColor
lw $t3, exitColor
sw $t0, 0($s0)
sw $t1, 0($s1)
sw $t2, 0($s2)
sw $t3, 0($s3)
move $v0, $s0
move $v1, $s1
jr $ra
move_left:
subiu $s1, $s1, 1
jal check_new_position
lw $t0, playerColor
lw $t1, wallColor
lw $t2, passageColor
lw $t3, exitColor
sw $t0, 0($s0)
sw $t1, 0($s1)
sw $t2, 0($s2)
sw $t3, 0($s3)
move $v0, $s0
move $v1, $s1
jr $ra
move_right:
addiu $s1, $s1, 1
jal check_new_position
lw $t0, playerColor
lw $t1, wallColor
lw $t2, passageColor
lw $t3, exitColor
sw $t0, 0($s0)
sw $t1, 0($s1)
sw $t2, 0($s2)
sw $t3, 0($s3)
move $v0, $s0
move $v1, $s1
jr $ra
# Exit the program
exit:
li $v0, 10
syscall
main:
# Ask the user for input
li $v0, 12
syscall
move $s0, $v0
# Check if there is input
beq $s0, 0, sleep
# Perform the appropriate action
beq $s0, 'z', move_up
beq $s0, 's', move_down
beq $s0, 'q', move_left
beq $s0, 'd', move_right
beq $s0, 'x', exit
# Wait for 60ms
sleep:
li $v0, 32
li $a0, 60
syscall
# Repeat the loop
j main
问题是,如果我将此代码与位图显示链接并运行它,我只会看到一个蓝色方块。有人可以帮我吗?
对于想要检查完整代码的人来说,这是完整的任务: 向代码中添加足够的注释,并使用堆栈帧将代码组织到函数中。 2.2.1 读取迷宫 编写一个从文件中读取迷宫的函数: - 文本文件 input_1.txt 包含一个迷宫。确保您的程序可以动态读取该文件。对迷宫进行硬编码并不是目的。 - 文件中的每个字母代表迷宫中的一个盒子。适用以下编码:Character=Significance=Colour: w=wall=blue, p=transit=black, s=player=yellow, u=output=green, newline=end of row of box -内存中唯一存放迷宫应该保留的是位图内存。因此,迷宫的每个框仅作为彩色像素进行跟踪。 - 玩家不能穿过墙壁(蓝色),只能穿过走廊(黑色)。 - 玩家的位置也保存在两个寄存器中:一个用于行号,另一个用于列号。 - 要将这些行号和列号转换为像素的存储位置,您可以使用第 1 部分中的函数。 - 迷宫的顶行的行号为 0。迷宫的最左边的列的列号为 0。 4 x 5 正方形的迷宫,看起来像这样: (0.0) (0.1) (0.2) (0.3) (1.0) (1.1) (1.2) (1.3) (2.0) (2.1) (2.2) (2.3) (3.0 ) (3.1) (3.2) (3.3) (4.0) (4.1) (4.2) (4.3) - 因此,正如上一个任务中已经提到的,对应于行 0 和列 0 的像素将存储在内存地址注册 $gp.调整玩家的位置:编写一个函数来调整玩家在迷宫中的位置: - 该函数有 4 个参数:玩家的当前位置(行号和列号)和玩家的新位置(行号和列号)。对于此处的寄存器,请使用 $a0-$a3。 - 要将行号和列号转换为像素内存地址,您可以使用第 1 部分中的函数。 - 它首先检查新位置是否有效:检查是否存在墙壁以及新位置是否位于比赛场地内。 - 调整像素的颜色。 - 玩家的新位置将通过 $v0 中的新行号和 $v1 中的新列号返回 do order 函数。主游戏循环:编写一个包含使游戏继续进行的循环的主函数: - 主循环是执行以下步骤的无限循环: 1. 请求用户输入。为此,请使用以下编码:角色动作:z=向上移动,s=向下移动,q=向左移动,d=向右移动,x=结束游戏。 2:检查是否有输入: (a) 如果有输入:转到步骤3 (b) 如果没有输入:转到步骤4。 3:执行适当的动作(调整玩家位置或结束游戏)。 4. 使用“sleep”系统调用等待 60 毫秒。这使得游戏能够以适当的速度进行。 - 当玩家到达迷宫出口时,会打印一条消息(通过系统调用)并且游戏结束。 - 使用“readcharacter”系统调用读取输入。 - 确保使用相对路径读取迷宫文件。
您有一个 if 语句嵌套在 for 样式循环内,但您的控制流不正确。
只有在 if-then-else 全部失败的情况下,你才会推进指针和计数器。如果识别出某种颜色,则应用该颜色但跳过所有进度,因此它会继续设置相同的位图位置(第一个位于 $gp 处)。
您还将
jr $ra
用于未作为函数调用的内容。
您应该能够通过在调试器中单步执行来看到这些问题。如果您不知道如何调试,那么现在是学习的好时机。调试汇编与调试任何其他语言非常相似 - 通过检查指令之间的程序状态,单步查看每条指令是否正确执行操作。
建议以后写几行代码,然后在调试器中单步运行,看看新行是否有效。如果他们不这样做,那么你就知道问题出在哪里:新线路。如果您遵循这种做法,您将学到的东西将改变您编写其余代码的方式。因此,不要等到程序完成才第一次运行您的代码。