Half-Life Position, Velocity, and Angles
Hướng dẫn này dành cho người mới với mong muốn tìm hiểu về vị trí, vận tốc và góc độ. Mục đích là để bạn có thể thoải mái thao tác các biến này trong Pawn trong amxx trong Half-Life.
Dimensions - kích thước
dimension - một tính chất của không gian; mở rộng trong một hướng nhất định
- 0th kích thước
Có thực sự là không kích thước ở đây - đó là kích thước 0, sau khi tất cả. Bạn có thể nghĩ về nó như là một điểm vô cùng nhỏ. Nó không mở rộng theo hướng nào.
Chúng tôi không thể chỉ định một vị trí trong không gian này.
- kích thước 1
Bây giờ chúng ta có một dòng trong một hướng. Bạn chỉ có thể thay đổi độ dài của dòng. Nhiều vấn đề trong vật lý được lý tưởng hóa vấn đề một chiều cho đơn giản. Ví dụ, cơ quan giảm thường lý tưởng hóa để rơi thẳng xuống không có độ lệch.
Chúng ta có thể chỉ định một vị trí trong không gian này với một số.
Ví dụ, một đường thẳng bắt đầu từ sàn nhà của bạn đi lên trần nhà của bạn. Hãy nói rằng sàn nhà là 0, trần nhà có thể là 2,5 (tính bằng mét, chúng ta hãy nói). Bất kỳ điểm nào ở giữa sẽ là giữa 0 và 2,5.
Trong mã, bạn có thể giữ vị trí với một biến như thế này:
Code:
new Float:fHeight
Tôi chỉ nói về kích thước đầu tiên, vì vậy, nói đúng, không có hướng rõ ràng. Bạn chỉ có thể đi lại.
Tuy nhiên, bạn có thể nói biến từ ví dụ của tôi tồn tại trong Y-hướng bởi vì thế giới của chúng tôi là trong ba chiều và nói "Y-hướng" có nghĩa là chúng ta đang nói về việc đi lên và xuống, nói chung.
Tùy thuộc vào ngữ cảnh, bạn có thể nói rằng một biến một chiều là trong X-hướng hoặc Z-hướng. Thông thường, bạn chỉ nói rằng đó là trong X hoặc Y hướng.
- kích thước thứ 2
Cuối cùng! Bây giờ chúng ta có thể di chuyển lên, xuống, trái, và bên phải (và bất kỳ sự kết hợp của các hướng dẫn). Các vấn đề vật lý phức tạp được lý tưởng hóa trong hai chiều. Ví dụ, chuyển động của đạn được lý tưởng hóa trong hai chiều.
Chúng ta có thể chỉ định một vị trí trong không gian hai chiều với một cặp số. Chúng ta gọi là cặp số tọa độ. Bằng văn bản, bạn thường thấy tọa độ viết như thế này (X, Y). X-hướng có nghĩa là trái và phải. Y-hướng có nghĩa là lên và xuống.
Trong mã, bạn có thể giữ vị trí với một biến như thế này:
Code:
new Float:fPosition[2]
Biến được gọi là một mảng và nó giữ hai giá trị. Giá trị đầu tiên, fPosition [0], nên giữ vị trí trong X-hướng. Giá trị thứ hai, fPosition [1], nên giữ vị trí trong Y-hướng. (Bạn cũng có thể sử dụng [1] cho X-hướng và [0] cho Y-hướng, nhưng nó rất hay để làm những việc trong một cách tiêu chuẩn để những người khác có thể hiểu được mã của bạn một cách nhanh chóng.)
Code:
public MakeHudMessage( id ) {
// X giá trị từ 0 đến 1, 0 là cạnh trái của màn hình, 1 là cạnh phải của màn hình
// Giá trị Y từ 0 đến 1, 0 là cạnh trên của màn hình, 1 là cạnh dưới của màn hình new Float:fPosition[2] fPosition[0] = 0.2 // tọa độ x
fPosition[1] = 0.5 // tọa độ y
set_hudmessage( 200, 100, 0, fPosition[0], fPosition[1], 0, 6.0, 12.0, 0.1, 0.2, 4 ) // red = 200, green = 100, blue = 0 // tọa độ x = 0.2,tọa độ y = 0.5
// effects = 0 // fxtime = 6.0 // holdtime = 12.0 // fadeintime = 0.1, fadeouttime = 0.2 // channel = 4 show_hudmessage( id, "Hi this is a hudmessage!" ) }
set_hudmessage chuẩn bị một tin nhắn HUD với vị trí, màu sắc, hiệu ứng, và thời gian
show_hudmessage hiển thị văn bản trong cách quy định của set_hudmessage
- Chiều thứ 3
OH BOY! Bây giờ chúng ta có thể di chuyển lên, xuống, trái, phải, về phía trước, phía sau và bất kỳ sự kết hợp của những hướng dẫn.
Chúng ta có thể chỉ định một vị trí trong không gian ba chiều với một nhóm ba con số. Bằng văn bản, bạn thường thấy tọa độ viết như thế này (X, Y, Z). Z-có nghĩa là hướng về phía trước và phía sau.
Nhưng chờ đợi! Z-có nghĩa là hướng về phía trước và ngược trong hình ở trên, nhưng nó thực sự có nghĩa là lên và xuống trong Half-Life. Tại sao? Các lập trình viên của Half-Life đã quyết định làm cho Z-hướng lên / xuống. Vì vậy, phía trước / sau / trái / phải được xử lý với các hướng X và Y.
Trong mã, bạn có thể giữ vị trí trong không gian ba chiều với một biến như thế này:
Code:
new Float:fPosition[3]
fPosition [0] nắm giữ các vị trí trong X-hướng, fPosition [1] nắm giữ các vị trí trong Y-hướng, và fPosition [2] giữ vị trí trong Z-hướng.
Code:
public PlayWithOrigins( id ) { new iOrigin[3] get_user_origin( id, iOrigin ) // move the player 20 units in the Z-direction (upwards) iOrigin[2] += 20 set_user_origin( id, iOrigin ) }
Vectors
Cho đến nay, tôi đã bao phủ 0, 1, 2, 3 và kích thước. Các ví dụ mã đã bị xử lý với tọa độ đại diện cho các vị trí, nhưng tôi đã ám chỉ một sử dụng khác nhau cho các mảng ba chiều với các ví dụ vật lý của tôi.
Bạn cần phải học hai từ mới: vector và vô hướng
vector - một số lượng sở hữu cả hai độ lớn và hướng, đại diện bởi một mũi tên hướng trong đó cho biết hướng về số lượng và chiều dài của nó là tỷ lệ thuận với độ lớn
vô hướng - biểu diễn bởi vị trí trên thang điểm hay dòng; chỉ có độ lớn
Khi chúng ta đang làm việc các vị trí, như vị trí của một người chơi trong một bản đồ hoặc vị trí của văn bản trên màn hình, chúng ta đang làm việc số lượng vô hướng. Giá trị vô hướng không có hướng, chỉ có độ lớn (kích thước). Khi bạn nói một người chơi có vị trí (X, Y, Z), bạn biết gì về việc có hay không anh đang chuyển động. Nếu anh ta đang chuyển động, bạn không biết ở đâu.
Vận tốc là một đại lượng véc tơ. Chúng ta hãy nhảy vào một ví dụ:
Code:
new Float:fVelocity[3] pev( id, pev_velocity, fVelocity )
pev là một hàm FakeMeta sử dụng để lấy các giá trị từ các thực thể
pev_velocity cho PEV () mà giá trị chúng tôi đang lấy
fVelocity giữ giá trị chúng tôi đang lấy, nó phải là một mảng 3 chiều
Sau khi thực hiện mã này, chúng ta hãy nói rằng vận tốc của chúng tôi bây giờ là (100, 200, 0). Điều này có nghĩa chúng ta có một vận tốc trong X-hướng 100 đơn vị mỗi giây, một Y-vận tốc 200 đơn vị mỗi giây, và Z-vận tốc từ 0 đơn vị mỗi giây. Những con số trực tiếp chỉ ra tầm quan trọng của tốc độ. Làm thế nào chúng ta có thể tìm thấy hướng? (Giá trị Vector có cả hai độ lớn và hướng.)
Đây là tình hình, ở dạng hình ảnh:
Chú ý rằng các vectơ cả hai bắt đầu từ nguồn gốc (0, 0, 0) và mở rộng ra khỏi nó.
Để có được sự chỉ đạo, bạn phải kết hợp cả ba thành phần vectơ (X, Y, Z) thành một. (Thành phần là các phần.)
Vì vậy, bây giờ chúng ta có thể thấy rằng fVelocity giữ một giá trị vector. Điều đó có nghĩa bạn có thể khám phá ra độ lớn và hướng của vận tốc bằng cách giải thích các giá trị nó nắm giữ.
- Speed versus Velocity - Tốc độ so với vận tốc
Họ không giống nhau. Tốc độ là một số lượng vô hướng và vận tốc là một đại lượng véc tơ. Bạn có thể lưu trữ tốc độ trong một biến như thế này:
Code:
new Float:fSpeed
Để lưu trữ tốc độ, bạn phải có một biến như thế này:
Code:
new Float:fVelocity[3]
Tốc độ có nghĩa là khoảng cách / thời gian, như dặm một giờ (mph) hoặc mét mỗi giây (m / s). Nó không cho bạn biết nơi bạn đang đi.
Vận tốc, khi bạn không giao dịch với mã, được viết bằng hai phần. Trước tiên, bạn nói tốc độ như 40 mph (có, tốc độ là một phần của vận tốc). Tiếp theo, bạn phải nói hướng. Ví dụ, Bắc. Khi chúng tôi đang làm việc với mã, bạn không có hai phần. Thay vào đó, bạn phải giải thích 3 giá trị để tìm ra tốc độ và hướng.
- Extracting Speed from Velocity - Lấy Tốc Độ Từ Vận Tốc
Nhớ Pythagoras? Ông có định lý này tiện lợi:
Code:
c * c = a * a + b * b
Nếu bạn nhìn vào hình ảnh trên với các mũi tên màu đỏ, xanh lá cây, và màu hồng, bạn có thể xem cách làm việc này. C là chiều dài của mũi tên màu hồng, a là chiều dài của mũi tên màu xanh lá cây, và b là chiều dài của mũi tên màu đỏ.
Trong ba chiều, nó như thế này:
Code:
hypotenuse * hypotenuse = x * x + y * y + z * z
Đây là những gì chúng tôi đang tìm kiếm:
Code:
speed * speed = x vel * x vel + y vel * y vel + z vel * z vel
Code:
new Float:fVelocity[3] // lưu trữ một số vận tốc vào fVelocity // chậm, cách không hiệu quả (nhưng bạn có thể xem những gì nó trông giống như) New Float:fSpeed = floatsqroot( fVelocity[0] * fVelocity[0] + fVelocity[1] * fVelocity[1] + fVelocity[2] * fVelocity[2] ) // nhanh chóng, cách hiệu quả New Float:fSpeed = vector_length( fVelocity )
- Extracting Direction from Velocity - Lấy Hướng Từ Vận Tốc
Chúng tôi không có Bắc, Nam, Đông và Tây trong Half-Life. Chúng tôi chỉ có góc, vì vậy đó là cách chúng tôi sẽ đại diện cho hướng vận tốc của chúng tôi.
Toán học phức tạp hơn, vì vậy hãy để nó ở đây:
Code:
new Float:fVelocity[3] new Float:fAngle[3] // lưu trữ một số vận tốc vector_to_angle( fVelocity, fAngle )
- Example - Ví Dụ
Vì vậy, chúng ta hãy làm một cái gì đó hữu ích vô dụng những kiến thức mới. Chúng tôi sẽ lưu vị trí của người chơi, khởi động anh ta theo một hướng ngẫu nhiên, và cuối cùng di chuyển anh ta trở lại vị trí ban đầu của mình.
Code:
public UselessFunction( id ) { new Float:fOrigin[3] new Float:fVelocity[3] // lưu tọa độ gốc của anh ta pev( id, pev_origin, fOrigin ) // tạo ra một vận tốc ngẫu nhiên fVelocity[0] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 ) fVelocity[1] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 ) fVelocity[2] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 ) // thiết lập tốc độ của anh ta, Woosh set_pev( id, pev_velocity, fVelocity ) // đưa anh trở lại vị trí ban đầu của mình trong 2,0 giây set_task( 2.0, "PutMeBackPLZ", id, _:fOrigin, 3 ) } public PutMeBackPLZ( iOrigin[3], id ) { // thiết lập tọa độ gốc của anh ta set_pev( id, pev_origin, iOrigin ) }
set_pev là một hàm FakeMeta sử dụng để thiết lập các giá trị khác nhau cho các thực thể
random_float tạo ra một số ngẫu nhiên giữa hai con số
random_num làm điều tương tự, nhưng trả về một int chứ không phải là một float
set_task được sử dụng để gọi một hàm sau vài giây
Angles - Góc
Có một sử dụng cho mảng ba chiều (biến như fVelocity [3]). Chúng được sử dụng để lưu trữ các góc của một thực thể.
- Pitch, Yaw, and Roll
Tôi sẽ sử dụng trí tưởng tượng của bạn để thực hiện điều này dễ hiểu. Hãy tưởng tượng một hotdog và đặt nó trên bàn trước mặt bạn với một đầu chỉ vào màn hình.
pitch -nâng một đầu của hotdog trong khi đầu kia nằm trên bàn làm việc
đặt nó trở lại xuống!
yaw - bây giờ, quay hotdog trên bàn làm việc
điểm nó vào màn hình một lần nữa!
roll - bây giờ, cuộn hotdog cùng bàn
Bây giờ làm hành động tương tự như bạn đã làm cho hotdog, nhưng di chuyển đầu của bạn thay vì hotdog. (Nghiêng đầu của bạn lên / xuống, xoay trái / phải, và sau đó cuộn nó.) Bạn nên bắt đầu cảm thấy một loại hài lòng bây giờ mà bạn hiểu ý nghĩa của pitch, yaw, and roll. Nếu không, hét vào mặt tôi.
Dưới đây là một hình ảnh tốt đẹp mà giải thích pitch, yaw, and roll. Nhờ arkshine! (Và nhờ vào sự sáng tạo, ai đó là.)
Trong Half-Life, các góc được lưu trữ thusly:
Code:
new Float:fAngle[3] fAngle[0] // pitch fAngle[1] // yaw fAngle[2] // roll
Bạn có thể sử dụng PEV () để lấy các góc độ, giống như chúng ta đã làm với vận tốc hay vị trí, nhưng có những góc cạnh khác nhau trong Half-Life. Bạn sẽ phải thử nghiệm với chúng để có được một ý tưởng tốt về mục đích chúng phục vụ.
pev_angles - định hướng của thực thể
pev_v_angle - định hướng của máy ảnh, (Góc nhìn của người chơi), v_angle = góc nhìn
pev_punchangle - độ lệch từ góc nhìn (POW! tôi đấm bạn trong hôn và bây giờ khuôn mặt của bạn xoay ở đó nhưng bạn sẽ từ từ trở về v_angle của bạn)
Bạn có thể nhận / thiết lập các chỉ như những người khác, với FakeMeta hoặc engine:
Code:
// FakeMeta new Float:fAngles[3] pev( id, pev_angles, fAngles ) set_pev( id, pev_angles, fAngles ) // Engine entity_get_vector( id, EV_VEC_angles, fAngles ) entity_set_vector( id, EV_VEC_angles, fAngles )
- Normal
Những gì là bình thường? Đó có phải là ngược lại với kỳ lạ? Wow, tôi mệt mỏi.
Nhiều từ vựng cho bạn
plane - một bề mặt phẳng hoặc cấp
normal -định nghĩa từ điển là khó hiểu, vì vậy ở đây là của tôi: một đường vuông góc với mặt phẳng
Tại sao điều này hữu ích? Vâng, nó nhận được phức tạp.
- Example - Ví Dụ
plugin Wall Text của tôi sử dụng các vị trí, vectơ, góc, và normal.
Mục tiêu của các plugin là để nhắm vào một bức tường và sơn văn bản trên đó.
Đây là quá trình từng bước:
1. Nhận được vị trí trên tường, nơi người dùng đang hướng tới.
2. Có được bình thường của bức tường. (Các bức tường là một chiếc máy bay và các điểm bình thường ra khỏi tường vào thế giới nơi mà người chơi tồn tại.)
3. Làm cho một vector trỏ sang trái (từ góc độ của bức tường bình thường).
4. SƠN!
5. Di chuyển qua bên trái, bằng cách sử dụng vector chúng tôi tính toán.
6. Lặp lại các bước 4-5 cho đến khi kết thúc.
Nếu bạn quan sát, bạn sẽ nhận thấy rằng tôi đã bỏ rơi để làm tính toán này cho các bề mặt dốc như dốc. Các plugin sẽ làm việc cho bức tường hoàn toàn đứng ở góc độ nào, nhưng nó sẽ thất bại nếu bạn muốn làm một tin nhắn đa dòng trên một bức tường dốc giống như một đoạn đường nối, bởi vì tôi đã quá lười biếng để viết code thêm.
Đây là các mã:
Code:
CreateNewMessage( id, szMessage[MESSAGE_LEN] ) { new Float:fAimOrigin[3] new Float:fPlayerOrigin[3] new Float:fAimVector[3] new Float:fNormalVector[3] new Float:fTextVector[3] // Góc nhìn của người sử dụng pev( id, pev_v_angle, fAimVector ) // vector trỏ theo hướng đó angle_vector( fAimVector, ANGLEVECTOR_FORWARD, fAimVector ) // Góc của người sử dụng pev( id, pev_origin, fPlayerOrigin ) // Kéo dài vector và di chuyển nó đến góc của người sử dụng fAimVector[0] = fAimVector[0] * 9999.0 + fPlayerOrigin[0] fAimVector[1] = fAimVector[1] * 9999.0 + fPlayerOrigin[1] fAimVector[2] = fAimVector[2] * 9999.0 + fPlayerOrigin[2] // thực hiện traceline, Lấy vector bình thường và vị trí cuối new iTr = create_tr2() engfunc( EngFunc_TraceLine, fPlayerOrigin, fAimVector, IGNORE_MONSTERS, id, iTr ) get_tr2( iTr, TR_vecEndPos, fAimOrigin ) get_tr2( iTr, TR_vecPlaneNormal, fNormalVector ) free_tr2( iTr ) // chuyển vector bình thường sang góc vector_to_angle( fNormalVector, fTextVector ) // Lấy vector con trỏ bên phải, từ góc của các vector bình thường angle_vector( fTextVector, ANGLEVECTOR_RIGHT, fTextVector ) // kéo dài chiều rộng của một nhân vật và chỉ về phía bên trái (từ góc độ của vector bình thường fTextVector[0] *= -1.0 * CHAR_WIDTH fTextVector[1] *= -1.0 * CHAR_WIDTH fTextVector[2] *= -1.0 * CHAR_WIDTH // ... }
0 nhận xét:
Post a Comment