Я сделал код с намерением, чтобы квадрат появлялся в месте нажатия мыши, оставался в этом месте, несмотря на движение мыши, и не исчезал при отпускании мыши.
ЭТО P5.JS! https://p5js.org/reference/
Вместо этого квадрат следует за мышью, пока она не будет отпущена, а затем исчезнет!
Я считаю, что мой код объявляет новую константу и удаляет старую каждый раз при запуске функции Shoot ().
var clocker = 0;// NOT YET USED
var player = {
x:400,
y:400,
};
function shoot(x1, y1, x2, y2, speed, range, power, playerDirection){
var bulletAlive = true;
var bulletDamage = power;
const startX = x1;
const startY = y1;
const destX = x2;
const destY = y2;
var bulletX = startX;
var bulletY = startY;
if (bulletAlive){
fill(0,100,200);
rect(destX-12.5,destY-12.5,25,25);
};
};
function setup() {
createCanvas(1000,650);
}
function draw() {
background(204,204,204);
if (mouseIsPressed){
shoot(player.x,player.y,mouseX,mouseY,2,100,0,"right");
}
}
Возможно, я неправильно использую const. Если да, то как мне его использовать? Как сделать так, чтобы destX и destY не менялись? (Не следуйте за мышью и не исчезайте)
PS: извините за разную информацию, это должно основываться на простой физике пули.
Объявление const
существует только в рамках shoot
. Таким образом, как только функция shoot
завершает выполнение, startX startY destX destY
, будучи const
, удаляется.
Возможное исправление:
var didShootAlready = false;
var startX, startY, destX, destY;
function shoot(/*params*/){
if (!didShootAlready){
didShootAlready = true;
startX = x1;
startY = y1;
destX = x2;
destY = y2;
}
//do the rest
}
Позволит ли это мне стрелять несколько раз?
Ага. Я просто привел пример, чтобы эти переменные оставались постоянными. Вы бы сделали свой другой код стрельбы вне «если».
до сих пор не понимаю ... как это будет работать? как это позволит мне вызывать эту функцию столько раз, сколько нужно id? стрелял бы уже был бы правдой.
Извините за то, что не ответил до сих пор. didShootAlready - это просто проверка того, следует ли вам изменять эти "const" координаты или нет. Выполните оставшуюся часть кода съемки, где комментарий («// сделаем все остальное») всегда выполняется, независимо от того, истинно ли didShootAlready.
Похоже, что есть некоторая путаница в области видимости, и, вероятно, есть лучший способ подумать об этой проблеме.
Сначала давайте посмотрим, что происходит не так, и обсудим несколько деталей, чтобы объяснить, почему.
let
, var
), константы всегда объявляются в определенной области.startX
внутри shoot
). (Обратите внимание, что если вы объявляете константу внутри оператора if
или другого блока, областью действия является блок. Однако здесь это не так.)Вот почему ваши константы не остаются постоянными. Вы вызываете shoot()
несколько раз, когда мышь опущена, и поэтому константы постоянно воссоздаются и им присваиваются новые значения.
Надеюсь, с этой информацией вы сможете увидеть проблемы с текущим подходом. Что касается решения, давайте подумаем, что именно происходит. shoot()
- это действие, которое должно запускаться, когда пользователь выдает команду «стрелять», например щелчок мышью. Функция draw()
- это непрерывное событие, запускаемое, чтобы сказать «эй, обновите экран». Помещение действия выстрела в событие розыгрыша - это своего рода несоответствие намерений и корень подобных проблем.
Вместо этого давайте представим идею объекта bullet
. Пуля имеет значения x
и y
. Пуля создается, когда пользователь стреляет, и в момент создания ей присваиваются определенные значения x и y. Ничего из этого не происходит внутри draw
, это происходит в другом приемнике событий, таком как "click"
.
Задача draw
- проверить, есть ли активная пуля, и, если она есть, нарисовать ее в указанных координатах x и y. Если нет пули, ничего не делайте. (Конечно, вам может понадобиться нарисовать и другие вещи, но это не связано с рисованием пули).
Разделение создания объектов и рисования объектов упрощает получение нужного вам контроля.
Обновлено: добавление некоторых примеров кода
Вот как будет выглядеть код, чтобы сделать именно то, что вы просили, используя идею объекта маркера, описанную выше. Встроенные комментарии должны объяснять каждый шаг.
// This is where we'll store an active bullet object.
// The `shoot()` function is responsible for setting this.
// `draw()` is responsible for rendering the bullet.
// Initially we'll set the value to `null` to explicitly
// indicate that there is no bullet.
let activeBullet = null;
// The purpose of `shoot()` is to create a bullet
// and make it available to be rendered.
function shoot(x, y) {
// Create the bullet object.
const newBullet = {
x: x,
y: y,
size: 25
};
// Set the active bullet to the new bullet. This will
// cause any previously active bullet to disappear.
activeBullet = newBullet;
}
// P5 functions
// ------------
function setup() {
createCanvas(1000, 650);
}
// Shoot when the player clicks.
function mousePressed() {
shoot(mouseX, mouseY);
}
function draw() {
// Always start with a blank canvas.
clear();
// If there is an active bullet, draw it!
// (`null` is "falsy", objects are "truthy", so the
// `if` statement will only run after the `activeBullet`
// variable is assigned a bullet object.)
if (activeBullet) {
fill(0, 100, 200);
rect(
activeBullet.x - activeBullet.size / 2,
activeBullet.y - activeBullet.size / 2,
activeBullet.size,
activeBullet.size
);
}
}
Вы также упомянули, что хотите перейти на простую физику пули. Чтобы показать, как хорошо работает идея объекта-пули, вот демонстрация, где вы можете щелкнуть, чтобы выстрелить несколькими пулями, все они перемещаются независимо и сталкиваются со стеной, в которой они удаляются. много больше участвует в создании игр, но, надеюсь, это вдохновляющая отправная точка :)
// Store canvas dimensions globally so we have easy access.
const canvasWidth = 1000;
const canvasHeight = 650;
// We'll add a "wall" object so we have something the bullets can
// collide with. This value is the X position of the wall.
const wallX = canvasWidth - 200;
// Instead of a single bullet, using an array can accommodate
// multiple bullets. It's empty to start, which means no bullets.
// We can also use `const` for this, because we won't ever assign
// a new value, we'll only modify the contents of the array.
const activeBullets = [];
function shoot(x, y) {
// Create the bullet object.
const newBullet = {
x: x,
y: y,
size: 25,
speed: 4
};
// Instead of overwriting a single bullet variable, we'll push
// the new bullet onto an array of bullets so multiple can exist.
activeBullets.push(newBullet);
}
// P5 functions
// ------------
function setup() {
createCanvas(canvasWidth, canvasHeight);
}
// Shoot when the player clicks.
function mousePressed() {
shoot(mouseX, mouseY);
}
function draw() {
// Always start with a blank canvas.
clear();
// Draw our "wall".
fill(50);
rect(wallX, 0, 60, canvasHeight);
// Set the fill color once, to use for all bullets. This doesn't
// need to be set for each bullet.
fill(0, 100, 200);
// Loop through the array of bullets and draw each one, while also
// checking for collisions with the wall so we can remove them. By
// looping backwards, we can safely remove bullets from the array
// without changing the index of the next bullet in line.
for (let i=activeBullets.length-1; i>=0; i--) {
// Grab the current bullet we're operating on.
const bullet = activeBullets[i];
// Move the bullet horizontally.
bullet.x += bullet.speed;
// Check if the bullet has visually gone past the wall. This
// means a collision.
if (bullet.x + bullet.size / 2 > wallX) {
// If the bullet has collided, remove it and don't draw it.
activeBullets.splice(i, 1);
} else {
// If the bullet hasn't collided, draw it.
rect(
bullet.x - bullet.size / 2,
bullet.y - bullet.size / 2,
bullet.size,
bullet.size
);
}
}
}
Хорошо, теперь я знаю, что происходит с моей логикой. Как я мог это сделать? Пока я не получу ответ, я изучу прототипы
Я добавил несколько примеров кода, чтобы лучше проиллюстрировать, как реализовать идею. К вашему сведению, большинству простых объектов не нужно ничего настраивать в их прототипах, работа с прототипами - это расширенная функция JS. Как видите, я использовал литералы простых объектов для маркеров.
Звучит хорошо. Потребуется много доработок, чтобы соответствовать моей концепции игры, но она удовлетворила все детали заданного мной вопроса. РЕШЕНО!
Удачи и приятного времяпровождения!