首页 > 解决方案 > 在玩家周围但不在玩家身上产生随机物体

问题描述

目前我正在为一个学校项目用javascript制作一个简单的射击游戏。我对 Javascript 很陌生,所以我不时遇到一些问题。我想出了如何每 x 秒生成随机对象,但我不知道如何让它们生成让我们说离我/玩家至少 50 像素。

我尝试更改对象的 x 和 y 值,但没有成功。谁能帮我这个?

先感谢您!

  var 
	canvas,
  ctx,
  width = 960,
  height = 540,
  rightKey = false,
  leftKey = false,
  upKey = false,
  downKey = false,
  player_x = 480,
	player_y = 270, 
	player_w = 30, 
	player_h = 30,
  bulletTotal = 3,
  bullet = [],
	canvas = document.getElementById("canvas"),
	ctx = canvas.getContext("2d"),
	spawnRate = 1500,
	spawnRateOfDescent = 0.50,
	lastSpawn = -1,
	objects = [];


function spawnRandomObject() {
   
    var c = "red";
	
    var object = {	 
        x: Math.random() * (canvas.width - 70) + 15,     
        y: Math.random() * (canvas.height - 70) + 15
    }
    objects.push(object);
}

function animate() {
  
    var time = Date.now();
  //I tried adding this disctance var but it gives an error
	var distance = (player_x - object.x)^2 + (player_y - object.y)^2;
   
    if (time > (lastSpawn + spawnRate)) {
        lastSpawn = time;
        spawnRandomObject();
    }
// here I tried to spawn a new object if it was in 50px of the player.	
	if (distance < 2500){
		spawnRandomObject();
	}
	
	
    requestAnimationFrame(animate);
 
    for (var i = 0; i < objects.length; i++) {
        var object = objects[i];
        ctx.beginPath();
		ctx.lineWidth = "3";
		ctx.strokeStyle = "black"
        ctx.rect(object.x, object.y, 40,40);
        ctx.closePath();
		ctx.lineWidth = "3";
		ctx.strokeStyle = "black"
        ctx.fillStyle = "red";
        ctx.fill();
		ctx.stroke();
    }
}
animate();


function clearCanvas() {
 ctx.clearRect(0,0,width,height);
 }



function drawplayer() {
 if (rightKey) player_x += 5;
 else if (leftKey) player_x -= 5;
 if (upKey) player_y -= 5;
 else if (downKey) player_y += 5;
 if (player_x <= 30) player_x = 30;
 if ((player_x + player_w) >= width) player_x = width - player_w;
  if (player_y <= 30) player_y = 30;
 if ((player_y + player_h) >= height) player_y = height - player_h;
 
	ctx.beginPath();
	ctx.lineWidth = "3";
	ctx.strokeStyle = "black";
	ctx.arc(player_x, player_y, 30, 0, 2 * Math.PI);
	ctx.fillStyle = "blue";
	ctx.fill();
	ctx.stroke();
	ctx.closePath();
 
}


function drawbullet() {
  if (bullet.length)
    for (var i = 0; i < bullet.length; i++) {
     ctx.fillStyle = 'blue';
     ctx.fillRect(bullet[i].x -18,bullet[i].y - 20, bullet[i].width ,bullet[i].height)
   }
}
function movebullet() {
 for (var i = 0; i < bullet.length; i++) {
 	 bullet[i].x += bullet[i].speedX;
   bullet[i].y += bullet[i].speedY;
   if(bullet[i].x < 0 || bullet[i].x > width ||
   		bullet[i].y < 0 || bullet[i].y > height) bullet.splice(i, 1);
 }
}

function init() {
 //canvas = document.getElementById('canvas');
 //ctx = canvas.getContext('2d');
 setInterval(gameLoop, 25);
 document.addEventListener('keydown', keyDown, false);
 document.addEventListener('keyup', keyUp, false);
}
function gameLoop() {
 clearCanvas();
 movebullet();
 drawplayer();
 drawbullet();
}

function keyDown(e) {
 if (e.keyCode == 68) rightKey = true;
 else if (e.keyCode == 65) leftKey = true;
 if (e.keyCode == 87) upKey = true;
 else if (e.keyCode == 83) downKey = true;
 if (e.keyCode == 32 && bullet.length <= bulletTotal) {
   let b = {
     x: player_x + player_w/2, y: player_y + player_h/2, speedX: 0, speedY: 0, width: 20, height: 20
   };
   if(rightKey) {
     b.x += player_w;
     b.speedX += 20;
     b.height = 5;
   }
   if(upKey) {
     b.y -= player_h;
     b.speedY -= 20;
     b.width = 5;
   }
   if(downKey && b.speedY === 0) {
     b.y += player_h;
     b.speedY += 20;
     b.width = 5;
   }
   if(b.speedX === 0 && (leftKey || b.speedY === 0)) {
     b.x -= player_w;
     b.speedX -= 20;
     b.height = 5;
   }
   bullet.push(b);
 }
}

function keyUp(e) {
 if (e.keyCode == 68) rightKey = false;
 else if (e.keyCode == 65) leftKey = false;
 if (e.keyCode == 87) upKey = false;
 else if (e.keyCode == 83) downKey = false;
}

//window.onload = init;
init();
<!DOCTYPE html>
<html>
<head>
<style>
body{
	background-color:  #000066; 
}

canvas {
    border:1px solid black;
    background-color: #b3b3cc;
	  position: absolute;
	  left: 25%;
	  top: 25%;
}
</style>
</head>
<body>

 <canvas id="canvas" width="960" height="540"></canvas>

</body>
</html>

标签: javascripthtml

解决方案


对于2D 平台游戏,您可以使用以下代码:

这是生成具有排除范围的随机数的简单方法。

var randomEx = function (start, end, excludeArray) {
  var regions = excludeArray.length + 1;
  var region = parseInt(Math.random() * regions);
  var regionStart = start;
  if (region > 0) regionStart = excludeArray[region - 1][1];
  var regionEnd = end;
  if (region < excludeArray.length) regionEnd = excludeArray[region][0];
  var range = regionEnd - regionStart;
  return (regionStart + (Math.random() * range));
};

var click = function () {
  var start = Number(document.querySelector('#start').value);
  var end = Number(document.querySelector('#end').value);
  var excludeArray = JSON.parse(document.querySelector('#ex').value);
  var random = randomEx(start, end, excludeArray);
  document.querySelector('p').textContent = random;
};

document.querySelector('button').addEventListener('click', click);

click();
Start: <input id="start" value="2"/><br>
End: <input id="end" value="10"/><br>
Exclude: <input id="ex" value="[[3,5],[7,8]]"/><br>
<p></p>
<button>Random</button><br>

这是它的工作原理,让我们想象以下示例:

start = 2; end = 10; exclude from 3 to 5 and from 7 to 8

想象一条线,我们的排除范围标记为x

    0  1  2  3  4  5  6  7  8  9  10
    ---------xxxxxx------xxx--------
     region1      region2   region3

如您所见,这为我们创建了 3 个区域来放置我们的随机数。因此,让我们首先随机选择其中一个区域。让我们假设最困难的情况:我们选择的区域是region2.

所以我们的 regionStart 将是第一个排除范围的结束(数字 5),我们的 regionEnd 将是最后一个排除范围的开始(数字 7)。

现在我们只需要计算range我们所在区域的 : regionEnd - regionStart,我们的随机数就是regionStart + (Math.random() * range)。换句话说,我们的随机数将从我们的 regionStart 开始加上从 0 到计算范围的任何值。

请注意,由于代码不考虑分布,因此该算法将使较小的区域更多地填充单元。如果您需要线性分布,请改用此代码:https ://codepen.io/rafaelcastrocouto/pen/yRzvEM

对于单位同时具有 x 和 y 位置的游戏,此代码是一个选项:https ://codepen.io/rafaelcastrocouto/pen/KGXrBR?editors=0010


推荐阅读