Đây là logic có liên quan tôi đã sử dụng trên pong trên trang chủ của mình : (vui lòng chơi nó trước khi đọc, để bạn biết hiệu quả tôi đạt được với đoạn mã sau)
Về cơ bản, khi bóng va chạm với mái chèo, hướng của nó hoàn toàn không được chú ý; nó được đưa ra một hướng mới tùy theo khoảng cách từ tâm của mái chèo mà nó va chạm. Nếu quả bóng chạm vào mái chèo ngay chính giữa, nó được gửi đi chính xác theo chiều ngang; nếu nó chạm phải vào rìa, nó sẽ bay ra ở một góc cực độ (75 độ). Và nó luôn di chuyển với tốc độ không đổi.
var relativeIntersectY = (paddle1Y+(PADDLEHEIGHT/2)) - intersectY;
Lấy giá trị Y ở giữa của mái chèo và trừ đi giao điểm Y của quả bóng. Nếu mái chèo cao 10 pixel, con số này sẽ nằm trong khoảng -5 đến 5. Tôi gọi đây là "giao điểm tương đối" vì hiện tại nó đang ở trong "không gian mái chèo", giao điểm của quả bóng so với giữa mái chèo.
var normalizedRelativeIntersectionY = (relativeIntersectY/(PADDLEHEIGHT/2));
var bounceAngle = normalizedRelativeIntersectionY * MAXBOUNCEANGLE;
Lấy giao điểm tương đối và chia cho một nửa chiều cao mái chèo. Bây giờ số -5 đến 5 của chúng tôi là số thập phân từ -1 đến 1; nó bình thường . Sau đó nhân nó với góc tối đa mà bạn muốn bóng nảy. Tôi đặt nó thành 5 * Pi / 12 radian (75 độ).
ballVx = BALLSPEED*Math.cos(bounceAngle);
ballVy = BALLSPEED*-Math.sin(bounceAngle);
Cuối cùng, tính toán vận tốc bóng mới, sử dụng lượng giác đơn giản.
Đây có thể không hoàn toàn là hiệu ứng bạn sẽ làm hoặc bạn cũng có thể muốn xác định tốc độ bằng cách nhân giao điểm tương đối chuẩn hóa với tốc độ tối đa; điều này sẽ làm cho quả bóng đi nhanh hơn nếu nó chạm gần mép của một mái chèo, hoặc chậm hơn nếu nó đánh gần trung tâm.
Tôi có thể thích một số mã về một vectơ trông như thế nào hoặc làm thế nào tôi có thể lưu biến của vectơ mà các quả bóng có (tốc độ và hướng).
Một vectơ chứa cả tốc độ và hướng, ngầm. Tôi lưu trữ vector của tôi dưới dạng "vx" và "vy"; đó là tốc độ theo hướng x và tốc độ theo hướng y. Nếu bạn chưa tham gia một khóa học giới thiệu về vật lý thì điều này có vẻ hơi xa lạ với bạn.
Lý do tôi làm điều này là vì nó làm giảm các tính toán trên mỗi khung hình cần thiết; mỗi khung hình, bạn chỉ cần làm x += vx * time;
và y += vy * time;
thời gian là thời gian kể từ khung hình cuối cùng, tính bằng mili giây (do đó vận tốc được tính bằng pixel trên mili giây).
Về việc thực hiện khả năng cong bóng:
Trước hết, bạn cần biết vận tốc của mái chèo tại thời điểm bóng chạm; điều đó có nghĩa là bạn cần theo dõi lịch sử của mái chèo, để bạn có thể biết một hoặc nhiều vị trí trong quá khứ của mái chèo để bạn có thể so sánh chúng với vị trí hiện tại của nó để xem nó có di chuyển không. (thay đổi vị trí / thay đổi thời gian = vận tốc; vì vậy bạn cần 2 vị trí trở lên và thời gian của các vị trí đó)
Bây giờ bạn cũng cần theo dõi vận tốc góc của quả bóng, thực tế đại diện cho đường cong mà nó đang di chuyển, nhưng tương đương với độ xoáy của quả bóng trong thế giới thực. Tương tự như cách bạn nội suy góc nảy từ vị trí tương đối của quả bóng khi va chạm với mái chèo, bạn cũng cần phải nội suy vận tốc góc này (hoặc quay) từ vận tốc của mái chèo khi va chạm. Thay vì chỉ đơn giản là thiết lập độ xoáy như bạn làm với góc nảy, bạn có thể muốn thêm hoặc bớt vào độ xoáy hiện tại của quả bóng, bởi vì nó có xu hướng hoạt động tốt trong các trò chơi (người chơi có thể nhận thấy quả bóng đang quay và khiến nó quay tròn thậm chí điên cuồng hơn, hoặc chống lại sự quay tròn trong một nỗ lực để làm cho nó đi thẳng).
Tuy nhiên, lưu ý rằng mặc dù đây là cách thông thường nhất và có lẽ là cách dễ nhất để thực hiện nó, nhưng vật lý thực tế của một lần nảy không chỉ dựa vào vận tốc của vật thể mà nó chạm vào; một vật thể không có vận tốc góc (không quay) chạm vào một bề mặt ở một góc, sẽ có một vòng quay truyền vào nó. Điều này có thể dẫn đến một cơ chế trò chơi tốt hơn, vì vậy bạn có thể muốn xem xét điều này, nhưng tôi không chắc chắn về vật lý đằng sau nó vì vậy tôi sẽ không cố gắng giải thích nó.