javascript - 在玩家周围但不在玩家身上产生随机物体
问题描述
目前我正在为一个学校项目用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>
解决方案
对于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
推荐阅读
- javascript - Display div with a hint only if one specific option is chosen/active. AngularJS
- python - lightgbm 的importance_type 'split' 和xgboost 中的importance_type 'weight` 一样吗?
- java - 创建 BitSet 的 toByteArray 方法(错误的字节顺序)
- javascript - 算法可以达到的最远建筑物 - JavaScript
- javascript - 你能用不同的数据处理选项重新“初始化”一个 Facebook 像素吗?
- api - API Get 请求在网络外被阻止
- sql - 给定时间内的 Postgres SUM
- regex - 如何在 Powershell 中解析这个字符串?
- android - FirebaseFirestore add() 方法在验证之前执行(get() 文档)
- php - 插入列表 ID 和项目