- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在为简历编写的迷宫生成程序中遇到了一个特殊问题。我正在使用 canvas 并且整个事情都完美无缺,只是它最终无法正确绘制正方形。
它通过使用这个对象模板来工作:
{row:nRow,
col:nCol,
visited:false,
left:true,
right:true,
top:true,
bottom:true};
我使用深度优先搜索来生成迷宫。为了打破墙壁,我检测到邻居相对于当前瓷砖的位置,然后关闭它们之间的墙壁。
例如,如果我要破坏北面的邻居,我会执行以下操作:
currentTile.top = false;
neighbor.bottom = false;
我用谷歌控制台进行了三重检查,这部分工作正常。但是,当我使用 Canvas 重绘它时,它没有正确移除墙壁,它看起来像这样:
代码来自 GitHub :
var canvas;
var ctx;
var tiles = [];
var visitedStk = [];
init();
function createPoint(nRow, nCol) {
/*Cell class*/
var obj = {
row: nRow,
col: nCol,
visited: false,
left: true,
right: true,
top: true,
bottom: true
};
return obj;
}
function init() {
/*Initialize needed variables. */
$("#newMazeBtn").click(reDrawMaze);
canvas = $("#mazeCanvas")[0];
ctx = canvas.getContext("2d");
drawBase();
}
function drawLine(sX, sY, eX, eY) {
/*Draw a line from the starting X and Y positions to the ending X and Y positions*/
ctx.moveTo(sX, sY);
ctx.lineTo(eX, eY);
}
function drawCell(x, y, side, tile) {
/* Draw cell based on wall properties */
var left = tile.left;
var right = tile.right;
var top = tile.top;
var bottom = tile.bottom;
var size = 25;
ctx.beginPath();
if (left) {
drawLine(x, y, x, y + size);
}
if (right) {
drawLine(x + size, y, x + size, y + size);
}
if (bottom) {
drawLine(x, y + size, x + size, y + size)
}
if (top) {
drawLine(x, y, x + size, y);
}
ctx.stroke();
}
function drawBase() {
/* Draw the tiles on the canvas*/
var side = 25;
for (var i = 0; i < 10; i++) {
tiles[i] = [];
for (var j = 0; j < 10; j++) {
tiles[i].push(createPoint(i, j));
drawCell(i * side, j * side, side, tiles[i][j]);
}
}
generateMaze(0, 0);
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function redrawTiles() {
var currentTile;
clearCanvas();
var side = 25;
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
currentTile = tiles[i][j];
drawCell(i * side, j * side, side, currentTile);
}
}
}
function reDrawMaze() {
/*Button Handle for 'New Maze' */
var startCol = Math.floor(Math.random() * 10) - 1;
var startRow = Math.floor(Math.random() * 10) - 1;
clearCanvas();
drawBase();
}
function generateMaze(row, col) {
/* Depth First Search*/
var currentTile = tiles[row][col];
var neighbor = findNeighbor(row, col);
/*Check if cell has been visited */
if (!currentTile.visited) {
currentTile.visited = true;
visitedStk.push(currentTile);
}
/* Break Case */
if (visitedStk.length == 0) {
redrawTiles();
return;
}
/*If a neighbor is found*/
else if (neighbor !== undefined) {
/*Break the wall in between*/
if (neighbor.row > currentTile.row) { /*Bottom*/
currentTile.bottom = false;
neighbor.top = false;
}
if (neighbor.row < currentTile.row) { /*Top*/
currentTile.top = false;
neighbor.bottom = false;
}
if (neighbor.col < currentTile.col) { /*Left*/
currentTile.left = false;
neighbor.right = false;
}
if (neighbor.col > currentTile.col) { /*Right*/
currentTile.right = false;
neighbor.left = false;
}
/*Update Current Tile*/
currentTile = neighbor;
}
/*If no neighbor was found, backtrack to a previous cell on the stacke*/
else {
var backtrack = visitedStk.pop();
generateMaze(backtrack.row, backtrack.col);
currentTile = backtrack;
}
generateMaze(currentTile.row, currentTile.col);
}
function findNeighbor(row, col) {
/*Find the neighbor of the given tile using the tiles array.*/
var top, bottom, left, right;
var stk = []
var neighbor = undefined;
var n;
/* Check for left neighbor */
if (row >= 0 && col > 0) {
left = tiles[row][col - 1];
(!left.visited) ? stk.push(left): undefined
}
/* Check for right neighbor */
if (row >= 0 && col < 9) {
right = tiles[row][col + 1];
(!right.visited) ? stk.push(right): undefined;
}
/* Check for top neighbor */
if (col >= 0 && row > 0) {
top = tiles[row - 1][col];
(!top.visited) ? stk.push(top): undefined
}
/* Check for bottom neighbor */
if (col >= 0 && row < 9) {
bottom = tiles[row + 1][col];
(!bottom.visited) ? stk.push(bottom): undefined
}
var len;
while (stk.length > 0) {
/* Choose a random neighbor */
len = stk.length;
n = Math.floor(Math.random() * stk.length);
neighbor = stk[n];
if (!neighbor.visited) {
break;
} else {
stk.splice(n, 1);
}
}
/*Return, will return undefined if no neighbor is found*/
return neighbor;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<div id="maze" style="width:500px; margin:0 auto;">
<canvas id="mazeCanvas" width="550" height="550"></canvas>
</div>
<div id="buttons">
<hr />
<button id="newMazeBtn">New Maze</button>
<button id="aboutBtn">About</button>
</div>
灰线不应该在那里,我不知道为什么会这样。
最佳答案
很高兴看到其他人解决迷宫生成问题!其乐无穷。 :)
看起来您在绘制迷宫时因交换行/列而被绊倒了。如果查看 redrawTiles
函数,您会发现您将 i
视为行,将 j
视为列(因为您正在访问当前图 block 作为 tiles[i][j]
,并且 drawBase
以行优先顺序设置数组)。
但是,drawCell
期望第一个参数是 x
(列),而不是 y
( 行),但您将i
(行)作为第一个参数传递。因此,当您调用 drawCell
时,行被解释为 x 坐标,列被解释为 y 坐标,而不是相反。
将前两个参数交换到 drawCell
可以解决这个问题。我强烈建议使用名为 row
和 column
的变量,而不是 i
和 j
,我也会建议标准化所有函数,这样如果它们声明行/列参数,则行在前,然后是列。这样你就不太可能被这个问题绊倒。
希望对您有所帮助!
关于javascript - 使用 Javascript 和 Canvas 生成迷宫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37625952/
我正在尝试使用以下 keytool 命令为我的应用程序生成 keystore : keytool -genkey -alias tomcat -keystore tomcat.keystore -ke
编辑:在西里尔正确解决问题后,我注意到只需将生成轴的函数放在用于生成标签的函数下面就可以解决问题。 我几乎读完了 O'Reilly 书中关于 D3.js 的教程,并在倒数第二页上制作了散点图,但是当添
虽然使用 GraphiQL 效果很好,但我的老板要求我实现一个用户界面,用户可以在其中通过 UI 元素(例如复选框、映射关系)检查呈现给他们的元素并获取数据,这样做将为该人生成 graphql 输入,
我尝试在 Netbean 6.8 中使用 ws-import 生成 Java 类。我想重新生成 jax-ws,因为在 ebay.api.paypalapi 包中发现了一个错误(我认为该错误是由于 Pa
我有一个 perl 脚本,它获取系统日期并将该日期写入文件名。 系统日期被分配给 TRH1 变量,然后它被设置为一个文件名。 $TRH1 =`date + %Y%m%d%H%M`; print "TR
我是 Haskell 的新手,需要帮助。我正在尝试构建一种必须具有某种唯一性的新数据类型,因此我决定使用 UUID 作为唯一标识符: data MyType = MyType { uuid ::
我制作了一个脚本,它可以根据 Mysql 数据库中的一些表生成 XML。 该脚本在 PHP 中运行。 public function getRawMaterials($apiKey, $format
所以这是我的项目中的一个问题。 In this task, we will use OpenSSL to generate digital signatures. Please prepare a f
我在 SAS LIFEREG 中有一个加速故障时间模型,我想绘制它。因为 SAS 在绘图方面非常糟糕,我想实际重新生成 R 中曲线的数据并将它们绘制在那里。 SAS 提出了一个尺度(在指数分布固定为
我正在为 Django 后端制作一个样板,并且我需要能够使它到达下一个下载它的人显然无法访问我的 secret key 的地方,或者拥有不同的 key 。我一直在研究一些选项,并在这个过程中进行了实验
我正在创建一个生成采购订单的应用程序。我可以根据用户输入的详细信息创建文本文件。我想生成一个看起来比普通文本文件好得多的 Excel。有没有可以在我的应用程序中使用的开源库? 最佳答案 目前还没有任何
我正在尝试使用 ScalaCheck 为 BST 创建一个 Gen,但是当我调用 .sample 方法时,它给了我 java.lang.NullPointerException。我哪里错了? seal
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我尝试编写一些代码,例如(在verilog中): parameter N = 128; if (encoder_in[0] == 1) begin 23 binary_out = 1;
我正忙于在 Grails 项目中进行从 MySQL 到 Postgres 的相当复杂的数据迁移。 我正在使用 GORM 在 PostGres 中生成模式,然后执行 MySQL -> mysqldump
如何使用纯 XSLT 生成 UUID?基本上是寻找一种使用 XSLT 创建独特序列的方法。该序列可以是任意长度。 我正在使用 XSLT 2.0。 最佳答案 这是一个good example 。基本上,
我尝试安装.app文件,但是当我安装并单击“同步”(在iTunes中)时,我开始在设备上开始安装,然后停止,这是一个问题,我不知道在哪里,但我看到了我无法解决的奇怪的事情: 最佳答案 似乎您没有在Xc
自从我生成 JavaDocs 以来已经有一段时间了,我确信这些选项在过去 10 年左右的时间里已经得到了改进。 我能否得到一些有关生成器的建议,该生成器将输出类似于 .Net 文档结构的 JavaDo
我想学习如何生成 PDF,我不想使用任何第三方工具,我想自己用代码创建它。到目前为止,我所看到的唯一示例是我通过在第 3 方 dll 上打开反射器查看的代码,以查看发生了什么。不幸的是,到目前为止我看
我正在从 Epplus 库生成 excel 条形图。 这是我成功生成的。 我的 table 是这样的 Mumbai Delhi Financial D
我是一名优秀的程序员,十分优秀!