Trong Pông, làm thế nào để bạn tính toán hướng của quả bóng khi nó nảy ra khỏi mái chèo?


28

Tôi đang cố gắng xoay quanh vấn đề Hello World-y rất phát triển này. Tôi đã tạo một trò chơi TicTacToe trong XNA vì vậy tôi đoán bước tiếp theo sẽ là bản sao Breakout .

Hãy nhớ rằng tôi không có kiến thức về lập trình trò chơi hoặc thậm chí tôi nên áp dụng toán học vào đâu. Đó là lý do tại sao tôi hỏi câu hỏi này.


Đối với câu hỏi: Làm thế nào tôi có thể xác định nơi bóng sẽ nảy khi chạm vào mái chèo ở dưới cùng của màn hình?

Tôi tưởng tượng nó sẽ giống như:

  1. Tốc độ chụp và góc từ bóng đến.
  2. Phát hiện nơi nó chạm vào thanh (ngoài cùng bên trái, ngoài cùng bên phải, ở giữa) và theo đó cho tốc độ cao hơn nếu chạm vào các khu vực bên ngoài.
  3. Đây là nơi tôi bị mắc kẹt. Hehe.

Bất kỳ hiểu biết? Tôi nhận ra đây không phải là một câu hỏi kiểu trả lời đơn giản, nhưng tôi chắc chắn rằng mọi người đều phải đối mặt ở một số điểm.

Tôi đang đọc cuốn sách Đại số tuyến tính được đề xuất trên trang web này, nhưng tôi vẫn không biết liệu tôi có nên áp dụng nó ở đây không.


Viết pong trước khi đột phá, sau đó bạn có thể xuất các lớp bóng, tường và mái chèo và mở rộng chúng sao cho chúng hoạt động với các loại gạch và sức mạnh khác nhau. Thêm vào đó, tôi sẽ xem xét pong đơn giản hơn đột phá.
Ẩn danh

Câu trả lời:


30

Đâ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;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ó.


Hiệu ứng đó là những gì tôi sẽ làm; tốc độ nhanh hơn khi nó chạm vào các cạnh của thanh. Cảm ơn một bó đã dành thời gian để viết ra. Tôi đang gặp một số khó khăn để hiểu một số điều mặc dù; ví dụ, trong snipper đầu tiên, 'giao nhau' là gì? Ngoài ra, 'paddle1Y' là chiều cao của thanh có đúng không?

giao nhau là vị trí của quả bóng nơi nó giao nhau với mái chèo. Tôi thực hiện một phép tính quá phức tạp mà tôi thực sự thậm chí không hiểu ngay bây giờ, nhưng về cơ bản, đó là giá trị Y của quả bóng tại thời điểm nó va chạm. paddle1Y là giá trị Y của mái chèo, từ đỉnh màn hình; PADDLEHEIGHT là chiều cao của mái chèo ("thanh").
Ricket

Bạn sẽ phải thêm gì để cho phép các quả bóng "cong"? Ví dụ, khi bóng sắp chạm vào mái chèo, bạn di chuyển mái chèo để tạo đường cong cho quả bóng. Một cái gì đó như thế này: vi.wikipedia.org/wiki/Curve_ball
Zolomon

Xem bản chỉnh sửa và cho tôi biết suy nghĩ của bạn (nếu bạn cần thêm thông tin về thứ gì đó, đừng lấy thứ gì đó, v.v.)
Ricket

Cảm ơn! Câu trả lời tuyệt vời, tôi đã luôn tự hỏi làm thế nào để đạt được hiệu quả đó!
Zolomon

8

Đã được một thời gian kể từ khi tôi làm điều này, nhưng tôi nghĩ rằng tôi đã làm đúng.

Cho một va chạm hoàn hảo, góc phản xạ bằng góc tới.

Bạn biết bình thường của mái chèo của bạn (giả sử một mặt phẳng): N Bạn biết vị trí ban đầu của quả bóng của bạn (ở đầu dấu thời gian của bạn): P Bạn biết vị trí mới của quả bóng (ở cuối dấu thời gian): P 'Bạn biết điểm va chạm của mình: C Giả sử rằng bạn đã tính rằng đoạn P -> P' đi qua mái chèo của bạn, tư thế phản xạ mới của bạn (P '') sẽ là:

P '+ 2 * (N * (P' chấm -N))

Biểu thức phụ N * (P 'dot -N) tính toán độ sâu dọc theo mức độ va chạm bình thường của quả bóng. Dấu trừ là để sửa cho thực tế chúng ta đang kiểm tra độ sâu đối diện với hướng bình thường.

P '+ 2 * phần của phần phụ sẽ di chuyển quả bóng trở lại phía trên mặt phẳng va chạm gấp 2 lần độ sâu của va chạm.

Nếu bạn muốn va chạm ít hơn hoàn hảo, hãy thay đổi hệ số 2 thành (1 + (1-k)) trong đó k là hệ số ma sát của bạn. Một va chạm hoàn hảo có giá trị ak bằng 0, làm cho góc phản xạ chính xác với góc tới. Giá trị k bằng 1 gây ra va chạm trong đó quả bóng sẽ ở trên bề mặt của mặt phẳng va chạm.

Vectơ vận tốc mới của bạn, V '', hướng sẽ là P '' - C. Bình thường hóa nó và nhân với vận tốc đến của bạn và cường độ vận tốc kết quả của bạn sẽ giống nhau, nhưng theo hướng mới. Bạn có thể khỉ với vận tốc đó bằng cách nhân nó với một hệ số, l, sẽ tăng (l> 1) hoặc giảm (l <1) vận tốc kết quả.

Để tóm tắt:

P '' = P '+ (1-k) * (N * (P chấm -N)) V' '= l * V * ((P' '- C) / | P' '- C |)

Trong đó k và l là hệ số bạn chọn.


5

Sự phản chiếu có thể được thực hiện "đúng" hoặc thực hiện "dễ dàng".

Cách "đúng" là tính toán các vectơ vuông góc với các bức tường. Trong 2D, điều đó khá dễ và bạn có thể chỉ cần viết mã cho chúng. Sau đó, bước phản xạ về cơ bản giữ nguyên thành phần "song song" của chuyển động và đảo ngược thành phần "vuông góc". Có lẽ có thông tin chi tiết trên web cho điều này, thậm chí có thể tại MathWorld.

Cách "dễ dàng" là chỉ phủ nhận chuyển động X hoặc Y khi bạn va vào tường. Nếu bạn đánh vào các bức tường bên, bạn sẽ phủ nhận X. Nếu bạn đánh vào đỉnh, bạn phủ nhận Y. Nếu bạn muốn tăng tốc độ bóng, chỉ cần tăng bất cứ điều gì bạn muốn; bạn có thể tăng tốc theo hướng hiện tại bằng cách nhân cả tốc độ X và Y hoặc bạn chỉ có thể tăng tốc trên một trục.


Không phải là cách "dễ dàng" và cách "đúng" được mô tả ở trên về cơ bản giống nhau sao ??
Tom

Chúng giống hệt nhau nếu các bức tường nằm dọc theo các trục chính. Nếu các bức tường không phải là tất cả dọc theo các trục X, Y và Z thì không, hai cái này hoàn toàn khác nhau.
dash-tom-bang

5

Bản thân tôi cũng đang thực hiện một trò chơi Arkanoid và tôi nghĩ giải pháp về cách quả bóng hoạt động khi đánh mái chèo khá đơn giản và nhanh hơn so với cách tiếp cận sin / cos ... nó hoạt động tốt cho mục đích của một trò chơi như thế này Đây là những gì tôi làm:

  • Tất nhiên, vì tốc độ bóng tăng theo thời gian tôi nội suy các bước trước / sau x, y để giữ phát hiện va chạm chính xác, lặp qua tất cả "stepX" và "stepY" được tính chia cho từng thành phần tốc độ theo mô đun của vectơ hình thành bởi các vị trí bóng hiện tại và tương lai.

  • Nếu xảy ra va chạm với mái chèo, tôi chia tốc độ Y cho 20. "20" này là giá trị thuận tiện nhất tôi tìm thấy để có được góc tối đa của mình khi bóng chạm vào hai bên của mái chèo, nhưng bạn có thể thay đổi nó thành bất cứ điều gì nhu cầu của bạn là, chỉ cần chơi với một số giá trị và chọn tốt hơn cho bạn. Bằng cách chia, giả sử tốc độ là 5, là tốc độ trò chơi ban đầu của tôi với con số này (20), tôi nhận được "hệ số hồi phục" là 0,25. Tính toán này giữ cho các góc của tôi khá tỷ lệ thuận khi tốc độ tăng theo thời gian lên tới giá trị tốc độ tối đa của tôi, ví dụ, có thể là 15 (trong trường hợp đó: 15/20 = 0,75). Xem xét rằng các mái chèo x, y của tôi được đặt ở giữa (x và y đại diện cho trung tâm của mái chèo), sau đó tôi nhân kết quả này bằng sự khác biệt giữa vị trí bóng và vị trí mái chèo. Sự khác biệt càng lớn, các góc kết quả. Bên cạnh đó, bằng cách sử dụng một miếng đệm ở giữa, bạn sẽ có được dấu chính xác cho mức tăng x tùy thuộc vào phía bóng chạm mà không phải lo lắng về việc tính toán trung tâm. Trong mã giả:

Cho n = 0 đến mô đun ...

nếu va chạm được xác định thì speedX = - (speedY / 20) * (paddleX - ballX); speedY = -speedY;
lối thoát hiểm; kết thúc nếu

...

x = x + stepX; y = y + stepY;

kết thúc cho

Remeber, luôn cố gắng giữ mọi thứ ĐƠN GIẢN. Tôi hy vọng nó sẽ giúp!


4

Mái chèo trong Breakout, khi nó đi theo phong cách bạn mô tả thường được mô hình hóa như một bề mặt cong. Góc của sự thay đổi dựa trên vị trí trên mái chèo mà nó chạm vào. Trên tâm chết, đường tiếp tuyến của đường cong hoàn toàn nằm ngang và bóng phản xạ như mong đợi. Khi bạn di chuyển ra khỏi trung tâm, tiếp tuyến của đường cong sẽ ngày càng trở nên góc cạnh và kết quả là bóng phản xạ khác nhau.

Điểm mấu chốt là góc phản xạ chứ không phải tốc độ bóng là những gì thay đổi. Tốc độ bóng nói chung chỉ tăng chậm theo thời gian.


1
Bạn nói như một bề mặt cong và điều đó nghe có vẻ hợp lý trong đầu tôi nhưng một khi tôi cố gắng nghĩ về điều đó thì mọi thứ trở nên mờ nhạt nhanh chóng. Làm thế nào tôi thậm chí có thể tuyên bố rằng trong mã là một biến hoặc một cái gì đó.

Một cái gì đó như angle = 1 - 2 * (ball.x - paddle.left) / paddle.widthsẽ cung cấp cho bạn một số từ 1 đến -1; điều này (lần một số giá trị được điều chỉnh cho cơ chế trò chơi của bạn) là độ dốc của đường tiếp tuyến tại điểm quả bóng va chạm. Phản ánh ra khỏi dòng đó chứ không phải là ngang một cách nghiêm ngặt.

4

Nolan Bushnell đã đưa ra một bài phát biểu tại SIEGE vào cuối tuần vừa qua và nói về một vấn đề tương tự với pong ban đầu. Bạn không cần phải làm nhiều phép tính phức tạp. Nếu bạn đánh vào phần bên trái của bảng hte, hãy gửi bóng sang trái. Làm tương tự cho bên phải.

Để bắt đầu với bạn có thể tạo góc cho bên trái và bên phải 45 độ. Khi bạn kết thúc trò chơi, bạn có thể quay lại và làm cho việc này trở nên phức tạp hơn nhưng hãy làm điều này đơn giản nhất có thể để bắt đầu.


1
Tôi cũng thấy bài phát biểu đó, quan điểm của ông là đây là một quyết định thiết kế không phải là quyết định toán học: "góc tới = góc phản chiếu" sẽ đúng nhưng làm cho lối chơi yếu. Ngoài ra, trong Pông và Bứt phá ban đầu, tốc độ là một chức năng của việc có bao nhiêu va chạm bóng / mái chèo (vì vậy nó tăng tốc theo thời gian). Họ cũng giảm kích thước mái chèo sau một số lần truy cập nhất định, quá. Tôi sẽ tránh cho phép quả bóng đi thẳng lên, sau đó bạn có thể rời mái chèo ở đó vô thời hạn.
Ian Schreiber

4

Breakout là một công việc kinh điển dành cho người mới bắt đầu để bắt đầu đi sâu vào thế giới lập trình trò chơi dựa trên vật lý. Về cơ bản quả bóng có một chuyển động nảy khi đập vào tường. Như ai đó ở trên đã đề xuất góc tới bằng với góc phản xạ. Nhưng khi bạn xem xét bóng đập mái chèo. Logic được chia thành 3 phần. 1.) Bóng đập vào phần giữa của mái chèo. 2.) Bóng đập vào phần bên trái của mái chèo. 3.) Bóng chạm vào vị trí bên phải của mái chèo.

Khi bạn xem xét phần trung tâm: Bạn không cần khác biệt hiệu ứng nảy của phần được áp dụng khi đánh bóng. Bóng chỉ bị lệch một cách bình thường. Nhưng, khi một trong hai hướng được đánh, trường hợp là khác nhau.

Khi bóng được đánh ở phía bên trái, tức là xem xét bóng đến từ phía bên trái của màn hình và bạn đang đến với mái chèo từ phía bên phải. Sau đó, khi bạn đánh bóng với phần bên trái, quả bóng sẽ phản xạ theo hướng nó đến từ .ie.leftwards với cùng một góc mà nó xuất phát. Tương tự là trường hợp ngược lại. Trong phần bên phải cũng áp dụng điều tương tự.

Chuyển động này của quả bóng theo hướng trái hoặc phải khi nó bị đánh làm cho nó đáng tin hơn.

Hy vọng bạn có ý tưởng, ít nhất là khôn ngoan logic. Cảm ơn bạn


1

Hãy tưởng tượng bạn tính khoảng cách giữa tâm của mái chèo và điểm mà quả bóng Y chạm và gọi nó d. Giả sử dcó một giá trị dương khi bóng chạm phía trên tâm của mái chèo. Bây giờ bạn có thể thêm d * -0.1vào vận tốc Y của quả bóng của bạn và nó sẽ bắt đầu thay đổi hướng. Dưới đây là một ví dụ trong javascript có thể dễ dàng dịch sang c #!

var canvas = document.querySelector('canvas');
var resize = function () {
  canvas.width = innerWidth;
  canvas.height = innerHeight;
};
resize();
var ctx = canvas.getContext('2d');
var ball = {
  size: 3,
  x: 1,
  y: canvas.height/2,
  vx: 2,
  vy: 0
};
var paddle = {
  height: 40,
  width: 3,
  x: canvas.width/2,
  y: canvas.height/2
};
addEventListener('mousemove', function (e) {
  paddle.y = e.clientY - (paddle.height/2);
});
var loop = function () {
  resize();
  ball.x += ball.vx;
  ball.y += ball.vy;
  if (ball.x > canvas.width || ball.x < 0) ball.vx *= -1; // horiz wall hit
  if (ball.y > canvas.height || ball.y < 0) ball.vy *= -1; // vert wall hit
  if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.width && ball.y >= paddle.y && ball.y <= paddle.y + paddle.height) {
    // paddle hit
    var paddleCenter = paddle.y + (paddle.height/2);
    var d = paddleCenter - ball.y;
    ball.vy += d * -0.1; // here's the trick
    ball.vx *= -1;
  }
  ctx.fillRect(ball.x,ball.y,ball.size,ball.size);
  ctx.fillRect(paddle.x,paddle.y,paddle.width,paddle.height);
  requestAnimationFrame(loop);
};
loop();
body {overflow: hidden; margin: 0}
canvas {width: 100vw; height: 100vh}
<canvas></canvas>



0

Xin chào Tôi gần đây đã cố gắng thực hiện một trò chơi bóng và tìm ra giải pháp cho việc này. Vì vậy, những gì tôi đã làm: Mái chèo đang di chuyển trong khi chúng tôi đang chơi trò chơi. Hệ tọa độ của tôi là trái, điểm trên cùng bên trái của khung vẽ là 0,0. Các mái chèo đang di chuyển trong hệ thống tọa độ này. Trục x chỉ từ 0 đến chiều rộng khung vẽ và trục y đang trỏ từ 0 đến Chiều cao vải. Tôi đã tạo ra một mái chèo với kích thước cố định 100 chiều rộng và 20 chiều cao. Và sau đó tôi vẽ một vòng tròn tưởng tượng xung quanh nó. Khi bóng chạm vào mái chèo, tôi tính toán Centerpoint của mái chèo

double paddleCenter=Squash.paddle.getXpos()+Squash.paddle.getPaddleWidth()/2;

Sau đó, tôi trừ trung tâm khỏi vị trí hiện tại của quả bóng theo cách này hệ thống tọa độ sẽ ở trung tâm của mái chèo, ballCenter là điểm mà quả bóng chạm vào mái chèo (- (paddleference + r) .. 0 .. (paddleference + r )) đây không là gì ngoài việc thay đổi kích thước điểm nhấn trên mái chèo

double x0 = ballCenterX-paddleCenter;

tính điểm giao nhau của vòng tròn với sự trợ giúp của điểm đánh bóng (x0) đây là phép tính lại, chúng tôi yêu cầu tọa độ y trên đường tròn với tọa độ x0 đã biết và cần có một cú lật cho trục y

double y0 = -Math.sqrt(paddleRadius*paddleRadius-x0*x0);

tính đạo hàm của phương trình bình thường của đường tròn được xác định xung quanh mái chèo với radis paddleRadius f (x, y) = x ^ 2 + y ^ 2-r ^ 2

double normalX=2*x0;
double normalY=2*y0;

chuẩn hóa vectơ N, để có được một vectơ đơn vị cho bề mặt bình thường

double normalizer=Math.sqrt(normalX*normalX + normalY*normalY);
normalX=normalX/normalizer;
normalY=normalY/normalizer;

bây giờ chúng ta có các tiêu chuẩn bề mặt (đơn vị) được chuẩn hóa cho mái chèo. Tính toán hướng mới với các quy tắc bề mặt này, điều này sẽ được tính toán với sự trợ giúp của công thức vectơ phản xạ: new_direction = old_direction-2 * dot (N, old_direction) * N, nhưng thay vào đó, bề mặt bình thường luôn hướng lên trên, ý chí bình thường được thay đổi từ điểm này sang điểm khác khi bóng chạm vào mái chèo

double eta=2; //this is the constant which gives now perfect reflection but with different normal vectors, for now this set to 2, to give perfect reflection
double dotprod=vX*normalX+vY*normalY;
vX=vX-eta*dotprod*normalX;//compute the reflection and get the new direction on the x direction
vY=-vY;//y direction is remain the same (but inverted), as we just want to have a change in the x direction

Tôi đã công bố giải pháp của mình cho vấn đề này. Để biết thêm chi tiết và cho trò chơi hoàn chỉnh, bạn có thể xem kho github của tôi:

https://github.com/zoli333/BricksGame

được viết bằng java với nhật thực. Có một giải pháp khác cho nhận xét này trong Ball.java, trong đó việc thay đổi tỷ lệ không xảy ra Tôi không di chuyển hệ tọa độ tọa độ đến điểm trung tâm của mái chèo, thay vào đó tôi tính tất cả các yếu tố trên từ hệ tọa độ 0,0 của nó so với điểm trung tâm của mái chèo. Điều này cũng hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.