Ось відповідна логіка, яку я використав на понг на своїй домашній сторінці : (будь-ласка, перейдіть його, перш ніж читати, щоб ви знали ефект, якого я досягаю за допомогою наступного коду)
По суті, коли м'яч стикається з веслом, його напрямок повністю не враховується; йому надається новий напрямок відповідно до того, наскільки далеко від центру весла воно зіткнулося. Якщо куля потрапила в лопатку прямо в центрі, вона відсилається рівно горизонтально; якщо вдарити прямо по краю, він відлітає під крайнім кутом (75 градусів). І завжди їде з постійною швидкістю.
var relativeIntersectY = (paddle1Y+(PADDLEHEIGHT/2)) - intersectY;
Візьміть середнє значення Y для весла та відніміть Y перетин кулі. Якщо весло висоти 10 пікселів, це число буде від -5 до 5. Я називаю це "відносним перетином", тому що зараз він знаходиться в "просторі весла", перетині м'яча відносно середини весла.
var normalizedRelativeIntersectionY = (relativeIntersectY/(PADDLEHEIGHT/2));
var bounceAngle = normalizedRelativeIntersectionY * MAXBOUNCEANGLE;
Візьміть відносний перетин і розділіть його на половину висоти весла. Тепер наше число від 5 до 5 - це десятковий від -1 до 1; це нормалізується . Потім помножте його на максимальний кут, на який потрібно відбити м'яч. Я встановив його на 5 * Pi / 12 радіанів (75 градусів).
ballVx = BALLSPEED*Math.cos(bounceAngle);
ballVy = BALLSPEED*-Math.sin(bounceAngle);
Нарешті, обчисліть нові швидкості кулі, використовуючи просту тригонометрію.
Це може бути не зовсім ефектом, на який ви збираєтесь, або ви можете також визначити швидкість шляхом множення нормованого відносного перетину на максимальну швидкість; це зробило би м'яч швидше, якщо він вдариться біля краю весла, або повільніше, якщо б'є біля центру.
Я, можливо, хотів би отримати якийсь код того, як виглядатиме вектор або як я міг би зберегти змінну вектора, яку мають кулі (швидкість і напрямок).
Вектор містить і швидкість, і напрямок, неявно. Я зберігаю свій вектор як "vx" і "vy"; тобто швидкість у напрямку x та швидкість у напрямку y. Якщо ви не пройшли вступний курс з фізики, це може здатися вам дещо чужим.
Причиною цього я є те, що це зменшує необхідні розрахунки за кадром; кожен кадр, який ви просто робите, x += vx * time;
і y += vy * time;
де час - час з моменту останнього кадру, в мілісекундах (отже, швидкості - у пікселях на мілісекунд).
Щодо реалізації можливості кривої кулі:
Перш за все, вам потрібно знати швидкість весла в момент удару м'яча; що означає, що вам потрібно буде відслідковувати історію весла, щоб ви могли знати одну чи кілька минулих позицій весла, щоб ви могли порівняти їх із поточним положенням, щоб побачити, чи він перемістився. (зміна положення / зміна часу = швидкість; тому вам потрібні 2 або більше позицій і час цих позицій)
Тепер вам також потрібно відстежити кутову швидкість кулі, яка практично представляє криву, по якій вона рухається, але еквівалентна реальному віджиманню кулі. Подібно до того, як ви би інтерполювали кут відскоку від відносного положення кулі при зіткненні з веслом, вам також знадобиться інтерполювати цю кутову швидкість (або віджимання) від швидкості весла при зіткненні. Замість того, щоб просто встановити віджимання, як ви робите з кутом відскоку, ви можете додати або відняти до існуючого віджимання м'яча, тому що це, як правило, добре працює в іграх (гравець може помітити, що м'яч крутиться, і змусить його крутитися ще дикіше чи протидіяти віджимання в спробі змусити його рухатися прямо).
Однак зауважте, що хоча це найпоширеніший сенс і, мабуть, найпростіший спосіб його втілення, фактична фізика відмов не покладається лише на швидкість об'єкта, в який він потрапляє; об’єкт без кутової швидкості (без віджиму), який потрапляє на поверхню під кутом, матиме на собі віджимання. Це може призвести до кращого ігрового механіка, тож, можливо, ви захочете розібратися в цьому, але я не впевнений у фізиці, що стоїть за ним, тому я не збираюся намагатися пояснити це.