2011-01-02 2 views
24

После внедрения Pacman и Snake я реализую следующую очень очень классическую игру: Pong.Понг: Как весло знает, куда попадет мяч?

Реализация на самом деле проста, но у меня осталась одна небольшая проблема. Когда один из весла (я не уверен, называется ли это веслом) управляется компьютером, у меня возникают проблемы с его позиционированием в правильном положении.

Мяч имеет текущее положение, скорость (которая сейчас постоянна) и угол направления. Поэтому я мог бы рассчитать положение, где он попадет в сторону управляемого компьютером весла. И поэтому я могу расположить весло прямо там. Но, однако, в реальной игре есть вероятность того, что компьютерная лопатка пропустит мяч. Как я могу реализовать эту вероятность?

Если я использую только вероятность сказать 0.5, что лопасть компьютера ударит по мячу, проблема решена, но я думаю, что это не так просто.

Из оригинальной игры, я думаю, что вероятность зависит от расстояния между текущей позицией весла и положением, которое мяч попадает в рамку.

Есть ли у кого-нибудь какие-либо намеки, как именно это рассчитывается?

ответ

20

Мы подготовили (псевдо-3D) настольный теннис для нашего школьного класса CS. Мы сделали это, мы заставили компьютер всегда перемещать весло к мячу, но с максимальной скоростью - таким образом, он мог бы пропустить мяч, если он слишком далеко, но он все еще умный. Помогает ли это?

+5

Это как оригинальный Pong работал, я думаю. – Lucas

+0

Ого! Я не знал этого. Круто! :) – Mehrdad

+2

Когда я учился в колледже, мы сделали это, установив центр весла равным центру шара (минус радиус). Компьютер не мог пропустить. –

5

Я бы подумал, что весло всегда должно перемещаться из своего текущего положения в определенную точку, где должен был бы быть шар, выравниваемый по вертикали с веслом. Тогда у вас может быть 50% -ный шанс, что весло переместится в эту точную точку и отклонит мяч, вероятность 25% будет превышать, возможно, на некоторые пиксели X и вероятность 25%, что он будет недосчитан. Еще лучший способ сделать это может заключаться в том, чтобы он переместился в эту позицию на кривую колокола, чтобы каждый раз промахиваться на разные суммы.

2

После нескольких итераций, если ваше весло (то есть ваше или AI в зависимости от вашей перспективы) слишком близко к верхней или нижней части экрана, просто невозможно покрыть требуемое расстояние. Весло может легко просто следовать за y-значением мяча. Если вы слишком далеко, вы пропустите.

В качестве альтернативы, вы можете иметь сброс AI по центру после каждого удара, или путешествие к центру, пока мяч движется в сторону (т.е. к противнику)

Или более кратко:
- двигаться в направлении центр, пока мяч отходит - имитировать y-координату шара во время приближения.

отсюда вы можете изменить сложность, сделав механизм имитации y-коорда медленнее шара (более последовательный и, возможно, то, чем была оригинальная реализация, поскольку трудности абстрагированы от простых коэффициентов скорости) или добавление случайной ошибки для каждого движения или иным образом.

4

Я не уверен, что «официальный» способ сделать это, но я всегда просто использовал (псевдокод)

if (ball is above paddle) { 
    move paddle up 
} 
if (ball is below paddle) { 
    move paddle down 
} 

Тогда я дал весло слегка изменяющуюся скорость, которая была достаточно медленно что он не всегда мог идти в ногу с мячом. Вид сырой, но он работает.

Эта нить также имеет некоторые интересные идеи, которые вы можете захотеть взглянуть на: http://www.gamedev.net/community/forums/topic.asp?topic_id=439576

4

Другие ответы обсудить, как выбрать правильное направление, чтобы двигаться в различных обстоятельствах. Вы также можете добавить время задержки, прежде чем компьютерный плеер «отреагирует», начав двигаться в этом направлении, что отражает типичный отклик игроков.

29

Цитируя очень приятной книге «Опережая Лучу» (Google Books: http://books.google.co.uk/books?id=DqePfdz_x6gC&lpg=PP1&dq=racing%20the%20beam&pg=PA40#v=onepage&q&f=false) оригинальный метод был:

Чтобы имитировать человеческую ошибку, присущую точного позиционирования лопастной, Весло AI пропускает его настройку каждые восемь кадров. Получающееся поведение явно незаметно, но это позволяет игроку играть достаточно далеко, чтобы он иногда пропускал мяч. Это также технически тривиально реализовать, требуя только одну маску и двоичную операцию И, для которой существует соответствующая инструкция 6502. Программист может протестировать, если результат равен нулю с другим одним кодом операции, при необходимости разветвясь, чтобы пропустить инструкции, которые перемещают весло.

Даже это поведение должно быть слегка изменено, чтобы игра работала вообще. Если игрок AI просто прекратил отслеживать мяч каждые восемь кадров, он был бы безнадежно не синхронизирован в течение нескольких секунд. Чтобы предотвратить это, ИИ следует за вторичной схемой отслеживания шара вблизи верхней и нижней части игрового поля. Если мяч сталкивается с одной из этих стен, в то время как лопатка также выровнена с ним, лопасть корректируется, восстанавливаясь от любого дрейфа, который накапливался с момента последнего удара шара по стене. Результатом является стохастическое несоосность и перестройка компьютерного весла и шара.

4

Как раз так случилось, что на днях я написал клон-понг просто для удовольствия.

Вы можете воспроизвести его here и посмотреть исходный код here.

ИИ принимает текущую скорость мяча и умножает расстояние от стены до стены. Затем он перемещается к этой расчетной позиции с ограниченной скоростью. Он не учитывает вертикальные отскоки, но это своего рода предназначение (чтобы сделать ИИ удачным).

Вот соответствующий фрагмент кода:

/* Update enemy based on simple AI */ 
enemy.update = function (delta) { 
    var impactDistance, impactTime, targetY, speed; 
    speed = .25; // a little slower than the human player 

    if (ball.vx < 0) { 
     // Ball is moving away, AI takes a nap .. 
     return; 
    } 

    // Figure out linear trajectory .. 
    impactDistance = width - ball.width - ball.x; 
    impactTime = impactDistance/(ball.vx * .25 * 1000); 
    targetY = ball.y + (ball.vy * .25 * 1000) * impactTime; 

    if (Math.abs(targetY - (this.y + this.height/2)) < 10) { 
     // AI doesn't need to move 
     return; 
    } 

    if (targetY < this.y + (this.height/2)) { 
     // Move up if ball is going above paddle 
     speed = -speed; 
    } 

    this.y += speed * delta; 
    this.keepInBounds(); 
}; 
+0

Спасибо. Кажется, я очень плохой игрок в понг. Я потерял 1:10;) Может быть, потому что было очень странно, что компьютер находится на правильной стороне игры, а не человек;) – RoflcoptrException

Смежные вопросы