Javascript 在画布中随机生成不重复或重叠的对象
我如何在地图上生成对象,而不让它们在HTML5画布上占据相同的空间或重叠 X坐标在一定程度上是随机生成的。我想检查数组内部,看看它是否已经存在,以及之后的20个值(考虑宽度),但没有运气Javascript 在画布中随机生成不重复或重叠的对象,javascript,arrays,html,canvas,Javascript,Arrays,Html,Canvas,我如何在地图上生成对象,而不让它们在HTML5画布上占据相同的空间或重叠 X坐标在一定程度上是随机生成的。我想检查数组内部,看看它是否已经存在,以及之后的20个值(考虑宽度),但没有运气 var nrOfPlatforms = 14, platforms = [], platformWidth = 20, platformHeight = 20; var generatePlatforms = function(){ var positiony = 0, type; for (var i
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var positiony = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var positionx = (Math.random() * 4000) + 500 - (points/100);
var duplicatetest = 21;
for (var d = 0; d < duplicatetest; d++) {
var duplicate = $(jQuery.inArray((positionx + d), platforms));
if (duplicate > 0) {
var duplicateconfirmed = true;
}
}
if (duplicateconfirmed) {
var positionx = positionx + 20;
}
var duplicateconfirmed = false;
platforms[i] = new Platform(positionx,positiony,type);
}
}();
不是这个
......[]...[[]]...[[]]....[]....
我希望这是有道理的
供参考,这里是数组检查前的代码和难度,只是便宜的距离黑客
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var position = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
platforms[i] = new Platform((Math.random() * 4000) + 500,position,type);
}
}();
您可以实现一个while循环,该循环尝试插入一个对象,但如果对象发生碰撞,则会自动失败。然后添加一个计数器,并在放置所需数量的成功对象后退出while循环。如果对象靠得很近,此循环可能会运行更长时间,因此您可能还希望为其提供最大的使用寿命。或者您可以实现一个“甚至可以在x和y的地图上放置z对象”来防止它永远运行 下面是这个()的一个例子:
//在随机位置用20x20点填充数组,无重叠
var平台=[],
平台尺寸=20,
平台宽度=200,
平台高度=200;
函数生成平台(k){
var=0,
最大尝试次数=k*10;
while(放置0){
var x=Math.floor(Math.random()*平台宽度),
y=Math.floor(Math.random()*平台高度),
可用=真实;
for(平台中的var点){
if(数学abs(点x-x)
以下是实现网格快照哈希的方法:
var can=document.getElementById(“can”),
ctx=can.getContext('2d'),
wid=罐宽,
hei=罐的高度,
numPlatforms=14,
普拉特维德=20,
普拉特黑=20,
平台=[],
散列={};
对于(var i=0;i
注意,我将x和y值连接起来,并将其用作散列键。这是为了简化检查,并且是唯一可行的解决方案,因为我们将x/y坐标捕捉到特定的增量。如果我们不抓拍,碰撞检查会更复杂
对于大型集合(根据您的标准,似乎不太可能),最好使用排除方法:生成一个包含所有可能位置的数组,然后针对每个“平台”,从数组中随机选取一个项目,然后将其从数组中移除。这类似于你洗牌的方式
编辑-需要注意的一点是,
numPlatforms我使用这段代码搜索数组中的对象,找到了另一个问题()的答案
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
函数搜索(数组、值){
var j,k;
对于(j=0;j
最后,我还重写了一堆代码,以便在其他地方加快速度,更好地回收平台
这是可行的,但缺点是我的平台少了,因为它真的开始变慢了。最后,这是我想要的,但这样做不再可行
var platforms = new Array();
var nrOfPlatforms = 7;
platformWidth = 20,
platformHeight = 20;
var positionx = 0;
var positiony = 0;
var arrayneedle = 0;
var duplicatetest = 21;
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
function generatePlatforms(ind){
roughx = Math.round((Math.random() * 2000) + 500);
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var duplicate = false;
for (var d = 0; d < duplicatetest; d++) {
arrayneedle = roughx + d;
var result = search(platforms, arrayneedle);
if (result >= 0) {
duplicate = true;
}
}
if (duplicate = true) {
positionx = roughx + 20;
}
if (duplicate = false) {
positionx = roughx;
}
platforms[ind] = new Platform(positionx,positiony,type);
}
var generatedplatforms = function(){
for (var i = 0; i < nrOfPlatforms; i++) {
generatePlatforms(i);
};
}();
var platforms=new Array();
var nRof平台=7;
平台宽度=20,
平台高度=20;
变量x=0;
变量y=0;
var arrayneedle=0;
var检验=21;
函数搜索(数组、值){
var j,k;
对于(j=0;j=0){
重复=正确;
}
}
如果(重复=真){
位置X=粗糙度X+20;
}
如果(重复=错误){
位置x=粗糙度x;
}
平台[ind]=新平台(位置X、位置Y、类型);
}
var generatedplatforms=函数(){
对于(var i=0;i
您可以使用大数据,生成所有可能性,将每种可能性存储在一个数组中,对数组进行洗牌,
修剪前X项,这是您的非启发式算法 对象是否具有可变宽度?@JasonPerske否固定宽度为20px您可以将它们映射到网格(以20像素的增量捕捉对象),然后跟踪2d散列对象中填充的内容。@shmiddy我该怎么做?仍然存在检查它们是否碰撞或重叠的函数失败的问题,并将其放置在anyway@RudigerKidd我添加了一些JavaScript,应该可以做到这一点。我现在必须尝试一下,我最终找到了答案,但解决方案让它变得非常缓慢。让我们来试一试。感谢you@RudigerKidd哈希几乎总是比在数组中搜索值更快。例外是某些浏览器上的小数据集。
//Fill an array with 20x20 points at random locations without overlap
var platforms = [],
platformSize = 20,
platformWidth = 200,
platformHeight = 200;
function generatePlatforms(k) {
var placed = 0,
maxAttempts = k*10;
while(placed < k && maxAttempts > 0) {
var x = Math.floor(Math.random()*platformWidth),
y = Math.floor(Math.random()*platformHeight),
available = true;
for(var point in platforms) {
if(Math.abs(point.x-x) < platformSize && Math.abs(point.y-y) < platformSize) {
available = false;
break;
}
}
if(available) {
platforms.push({
x: x,
y: y
});
placed += 1;
}
maxAttempts -= 1;
}
}
generatePlatforms(14);
console.log(platforms);
var can = document.getElementById("can"),
ctx = can.getContext('2d'),
wid = can.width,
hei = can.height,
numPlatforms = 14,
platWid = 20,
platHei = 20,
platforms = [],
hash = {};
for(var i = 0; i < numPlatforms; i++){
// get x/y values snapped to platform width/height increments
var posX = Math.floor(Math.random()*(wid-platWid)/platWid)*platWid,
posY = Math.floor(Math.random()*(hei-platHei)/platHei)*platHei;
while (hash[posX + 'x' + posY]){
posX = Math.floor(Math.random()*wid/platWid)*platWid;
posY = Math.floor(Math.random()*hei/platHei)*platHei;
}
hash[posX + 'x' + posY] = 1;
platforms.push(new Platform(/* your arguments */));
}
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
var platforms = new Array();
var nrOfPlatforms = 7;
platformWidth = 20,
platformHeight = 20;
var positionx = 0;
var positiony = 0;
var arrayneedle = 0;
var duplicatetest = 21;
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
function generatePlatforms(ind){
roughx = Math.round((Math.random() * 2000) + 500);
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var duplicate = false;
for (var d = 0; d < duplicatetest; d++) {
arrayneedle = roughx + d;
var result = search(platforms, arrayneedle);
if (result >= 0) {
duplicate = true;
}
}
if (duplicate = true) {
positionx = roughx + 20;
}
if (duplicate = false) {
positionx = roughx;
}
platforms[ind] = new Platform(positionx,positiony,type);
}
var generatedplatforms = function(){
for (var i = 0; i < nrOfPlatforms; i++) {
generatePlatforms(i);
};
}();