Admin đã trở lại và lợi hại gấp đôi :D
Sun May 18, 2014 1:05 pm by admin_huyetsat
Sorry mọi người vì mình vắng mặt quá lâu, mình là HuyetSat, admin đây.
Hiện tại mình đã chuyển nền tảng phát triển game sang mobile (dùng libgdx framework) và cũng đang dev game và up lên play store, ai dùng đt android thì tải về ủng hộ ad nha:
play.google.com/store/apps/developer?id=Top+Game+Free
[img]…
[ Full reading ]
Hiện tại mình đã chuyển nền tảng phát triển game sang mobile (dùng libgdx framework) và cũng đang dev game và up lên play store, ai dùng đt android thì tải về ủng hộ ad nha:
play.google.com/store/apps/developer?id=Top+Game+Free
[img]…
[ Full reading ]
Comments: 1
Game4V và Event "Viết bài hay, nhận ngay quà tặng"
Mon Feb 20, 2012 11:18 pm by noheart91
Game4V là một trong những cộng đồng game thủ đầu tiên của Việt Nam với lịch sử hơn 5 năm hình thành và phát triển. Sau nhiều biến động, có thể nói hiện nay G4V là một cộng đồng game hoạt động hoàn toàn độc lập, không bị ảnh hưởng bởi tổ chức chuyên nghiệp nào với nền tảng máy chủ được trang bị từ …
[ Full reading ]
[ Full reading ]
Comments: 0
Mình sẽ tạm dừng hoạt động một thời gian
Fri Sep 02, 2011 7:19 am by HuyetSat
Vì lý do cá nhân nên tạm thời mình sẽ ko support xna trên các diễn đàn nữa.
Bạn nào gặp vấn đề về xna cứ mail trực tiếp cho mình.
thanh_vinh648@yahoo.com
Thân
Bạn nào gặp vấn đề về xna cứ mail trực tiếp cho mình.
thanh_vinh648@yahoo.com
Thân
Comments: 0
xin cho minh tham gia voi
Fri Apr 15, 2011 12:35 am by luongthanhbinh3824
Mình giỏi 3ds max có thể cho mình làm designer được không anh HuyetSat
Email: thanh_binh3824@yahoo.com
Phone: 0633703673
Email: thanh_binh3824@yahoo.com
Phone: 0633703673
Comments: 1
Latest topics
» Xin TUT game bắn trứng khủng longby anhkhoa2110 Mon Mar 16, 2015 4:29 pm
» xna getRGB texture image?
by bachdienquan Thu Feb 05, 2015 8:34 am
» Cần giúp đỡ về hiệu ứng hình ảnh khi va chạm
by phiemltv Fri Nov 28, 2014 12:20 pm
» Cho mình hỏi về boundbox
by septimus2810 Mon Jul 21, 2014 10:08 am
» Hỏi về cách di chuyển 1 điểm ở tọa độ này sang tọa độ khác cho trước.
by septimus2810 Mon Jul 21, 2014 10:02 am
» Admin đã trở lại và lợi hại gấp đôi :D
by konamij Fri Jun 27, 2014 2:50 pm
» lỗi An unhandled exception of type 'System.NullReferenceException'
by _VH_HV_ Mon Jun 16, 2014 1:59 pm
» networking cho game xna 2d
by admin_huyetsat Tue May 20, 2014 1:04 pm
» hướng dẫn traning C# chuẩn bị cho xna
by lqchinh Tue Apr 15, 2014 11:31 pm
» HelpGameBom2D
by thaimavn Mon Mar 24, 2014 10:35 am
» Hỏi về cách di chuyển 1 điểm ở tọa độ này sang tọa độ khác cho trước.
by bocapzz Mon Feb 24, 2014 10:45 pm
» Hỏi về cài đặt XNA game studio 4.0
by bocapzz Sat Dec 14, 2013 12:33 am
» Cuộc thi lập trình game thế giới 2013 với cơ hội thăm quan Phần Lan
by viope Tue Oct 29, 2013 4:51 pm
» chơi game làm bởi xna như thế nào?
by thinnhph01957 Sat Sep 14, 2013 3:23 pm
» Với 1 Game cái gì là quan trọng ?
by qhhqnavy Tue Aug 13, 2013 8:09 am
» Load fiel .fbx vào Xna bị mất màu
by qhhqnavy Wed Aug 07, 2013 7:42 pm
» Help me hàm Update và Draw với
by sieuthi Mon Dec 24, 2012 11:56 pm
» Hỏi về load hình chồng nhau trong XNA
by sieuthi Mon Dec 24, 2012 11:49 pm
» nơi ghi danh tham gia Game Development Team
by echdonghop Fri Dec 21, 2012 1:56 pm
» tài liệu cơ bản 5 chương cho xna
by Nelson Quang Thu Nov 22, 2012 12:26 pm
Camera và Tương tác với camera
2 posters
Trang 1 trong tổng số 1 trang
Camera và Tương tác với camera
1.Xây dựng một camera
Bạn có thể khởi đầu với 1 camera tĩnh (FixedCamera), nó sẽ giúp bạn quan sát một model đứng yên và tất nhiên, cái camera của bạn cũng như thế!
Bạn xây dựng lớp FixedCamera như sau:
-Khai báo thể hiện của camera
-Tạo ra và thiết lập cho model
-Thiết lập cho camera
-Dùng cho Draw Method:
Model sẽ sử dụng 2 Matrix là chúng ta đã tạo trong lớp trên
Tốt nhất bạn hãy hoàn thành quy trình trên nếu không muốn phải ngồi Debug
2.Xoay và di chuyển camera trong không gian 3D
Xoay điểm target
Để xoay một điểm nói chung quanh một trục, VD như trục X, ta có thể sử dụng:
Đầu tiên tạo ra góc xoay: Matrix.CreateRorationX((float)góc xoay)
Sau đó tạo ra điểm đang xoay:
Thay đổi tọa độ của camera:
Để thay đổi tọa độ, chúng ta thực hiện phép toán sau:
Position = Position + Movespeed*VectorForward;
tọa độ sẽ tiên đến theo phuơng của vectorForward với tôc độ là 1 hằng số.
Ví dụ như bạn muốn camẻra tiến về truớc, chúng ta có vectorForward là (0,0,-1), Speed thì tùy bạn thôi, kiểu của nó là float
Khi bạn muốn nó đi chéo qua một góc, bạn transform với góc đó (quanh 1 trục tọa độ) và dùng lại công thức trên
RotatedVectorForward = Vector3.Transform(RotatedVectorForward,CameraRotation);
Vector VectorForward sẽ bị xiên qua một góc mà CameraRotation quy định cho nó.
Position = Position + Movespeed*RotatedVectorForward;
3.Tạo camera góc nhìn thứ nhất (FPS)
Chúng ta dùng chuột để thay đổi góc nhìn cho camera. Khi bạn di chuyển chuột lên xuống. Chúng ta xoay điểm target theo trục X. Khi bạn di chuột trái hay phải. Chúng ta xoay điểm target theo trục Y. chúng ta khai báo các biến để lấy đc các giá trị trên:
originalMouseState là giá trị Vector2 nằm ở trung tâm màn hình.
Nếu chúng ta di chuọt (thay đổi tọa độ của nó) thì code như duới đây:
Khi bạn biết đc điều này, bạn sẽ biết object nào cần draw để làm nhẹ cho Ram và card màn hình.
Để biết thể tích vùng nhìn thấy, XNA cung cấp 1 lớp sẵn có cho chúng ta. Nó dc tính như sau:
Là tích của view và projection Matrix.
Khi bạn dùng cái này để kiểm tra va chạm với điểm hay bounding khác, nó sẽ trả về 1 trong 3 giá trị sau ở biến kiểu ContainmentType, tất nhiên chúng ta khai báo nó.
Contain: object hoàn toàn trong
Intersects: nằm trong 1 phần.
Disjoint: hoàn toàn nằm ngoài
1.Kiểm tra 1 điểm có nằm trong sight ko
2.Kiểm tra 1 đối tuợng có nằm trong sight
Với Object, chúng ta có thể tạo ra 1 bounding bao quanh object đó (Sphere hay Box), các bạn sử dụng method sau, nó nằm trong 1 class hỗ trợ lập trình khác mà chúng ta thảo luận chuơng sau:
myModel = XNAUtils.LoadModelWithBoundingSphere(ref modelTransforms, "Ship", Content);
Đại loại nó sẽ load model với một bounding nằm trong thuộc tính Tag của nó:
Lưu ý: Tag là thuộc tính có thể đc khai báo bằng struc của model, nó có thể lưu giữ thông tin bất kỳ như Sphere, texture... do người dùng định nghĩa
Khi bạn sử dụng model, sẽ có worldMatrix của nó, chúng ta tạo bounding kiểu Sphere theo vị trí ghi ở translate matrix, sau đó kiểm tra nó với frustum bounding của camera.
Trong code trên, model chỉ đc Draw nếu nó nằm trong sight của camera!
Qua chuơng sau bạn sẽ biết cách render model, h cứ hiểu thế đã.
Các bạn có thể dùng vòng for để tạo nhiều model, khi kiểm tra cũng dùng for đê KT từng thằng, tuy nhiên đây là cách ko thông minh, chúng ta có thể xây dựng lớp riêng cho Model theo kiểu DrawableGameComponent để chuơng trình chạy nhanh hơn.
6.Kiểm tra va chạm camera với model hay terrain
Nếu ko có phần này, camera mà chúng ta xây dựng ra sẽ tạo cho chúng ta cảm giác đi xuyên đc model hay ko có cảm giác trọng lực khi đi trên terrain.
Với Model
Để KT va chạm, model cần có bounding , để có nó các bạn load model như phần truớc.
Chúng ta cần tạo ra 1 bound bao quanh camera, sử dụng lớp có sẵn của XNA:
Đó là 1 hình cầu tâm là tọa độ camera và bán kính 1, nó đc dùng KT va chạm với boundng của model.
Sử dụng Model Bounding:
Tạo ra 1 biến lưu giữ tọa độ lần Update vị trí của camera, nếu có va chạm với bounding của Model, camera trở về vị trí truớc đó. KT va chạm ở Draw method, nó đc KT sau khi đã Update xong
2.Kiểm tra va chạm với terrain.
Việc tạo ra terrain ntn, các bạn sẽ biết trong chương sau. bây giờ chỉ là KT va chạm của camera với các thành phần của terrain đó thôi.
Chúng ta sử dụng lớp Terrain và một Method tính độ cao (tọa độ Y) tại một điểm bất kỳ trên terrain. Từ đó chúng ta suy ra tọa độ cao tối thiểu của camera tại điểm đó tức là camera của chúng ta sẽ ko thể đi xuyên xuống đất đc
Code sau đặt trong Update Method:
Dấu trừ "-" ở code trên là do khi xây dựng lớp Terrain, họ đã đưa các tham số theo số duơng trong method GetClippedHeightAt, mà khi tiến về phía truớc, theo Hệ tọa độ của XNA, là trái chiều trục Z => tọa độ Z luôn âm, chúng ta cần dấu trừ để nó duơng.
7.Thay đổi nền cho cảnh game (tạo Sky Box)
Chúng ta sẽ tạo một back ground = 1 texture. Đó phải là một cảnh gây cho chúng ta cảm giác rằng nó đang ở rất xa! Bởi lẽ nó chỉ là ảnh nền ko có tưong tác với các object khác. Do nó ở rất xa nên khi chúng ta tiến lại gần nó cũng ko có cảm giác to ra J nói cách khác là nó hoàn toàn tĩnh Đúng nghĩa của một BG.
Không gian của chúng ta gói lại trong một cube, player khi nhìn vào sẽ thấy mình đang đứng trong 1 vùng núi có những đám mây lững lờ.
Cái texture trên chứa 6 mặt của một hình cube, tất nhiên đó là 1 model. Nếu ko dùng model chúng ta có thể tạo ra cube bằng vertex.
Đầu tiên các bạn add c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll vào Reference nếu project của bạn chưa có
Tuơng tự đầu tiên chúng ta load model:
Trong Method Draw:
device.RenderState.DepthBufferWriteEnable = false;
Code sẽ Draw model mà không có thuộc tính độ sâu (trục Z), nghĩa là nó không chịu ảnh huởng của hình chiếu phối cảnh. Mặt khác, độ sâu của model ko có tức là nó luôn bị các object khác che đi.
effect.World = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(fpsCam.Position);
Vẽ worldMatrix theo từng mesh và nó luôn chuyển động theo camera, khoảng cách giữa nó và camera luôn ko đổi.
8.Chỉ vẽ những vùng nhìn thấy
Chia tách sight của camera thành những vùng nhỏ, những vùng này sẽ đc KT với sight của camera xem có collides ko, nếu có mới draw những object bên trong vùng đó. Một demo hay 1 game nhỏ thì không cần đến cái này nhưng nếu bạn muốn tạo ra 1 thế giới rộng lớn thì kỹ thuật duới đây rất có ích.
Để sử dụng, lớp OcTreeNode.cs sẽ đc add vào project của bạn. bạn đọc thêm về vertex và biết về đệ quy để hiểu đc lớp này.
Sử dụng trong Game1.cs :
OcTreeNode ocTreeRoot;
Thiết lập cho nó:
ocTreeRoot = new OcTreeNode(new Vector3(0, 0, 0), 21);
nó nghĩa là vùng trên scene của chúng ta nhận điểm gốc tọa độ làm tâm của vùng phân chia, nó có bán kính...
đó là vùng gốc nên chỉ cần 1 (hay nhiều hơn tùy bạn) từ vùng gốc đó chúng ta sẽ chia làm 8 vùng nhỏ để KT với camera. Đặt nó trong loadContent để còn load model vào trong nó để test:
Tưong tự phần trên, chúng ta sẽ chia cắt terrain để draw những vùng nhìn thấy, các bạn lưu ý phần truớc là Vùng chứa model còn ở đây là vùng chứa terrain dựng bằng file heightmap
Terrain đc dựng từ các node, là các điểm nhấn đc tạo ra từ QTnode, chúng ta sử dụng nó như sau:
//Khai báo biến
}
10.Sử dụng hiệu ứng cho camera
Camera chính là con mắt của các bạn khi chơi game, hiệu ứng cho camera cũng giông như là khi bạn đeo thêm 1 cái guơng lên mắt vậy, bạn có thể làm mọi vật nhèo đi hay thay đổi màu sắc của chúng thông qua cái kính đó!
Để sử dụng hiệu ứng chúng ta xây dựng lớp PostProcessor.cs lớp này có nhiệm vụ nhận các tham số của effect cung tên, xử lý nó và truyền cho effect
Để sử dụng lớp này trong Game1.cs của chúng ta, lần luợt làm như sau:
Chúng ta sẽ dùng hiệu ứng đảo màu theo thời gian cho camera làm ví dụ
//khai báo the hiện class postProcessor
//trong phần khai báo biến
//loadContent method
//load effect và load nó vào postProcessor
Effect ppEffect = Content.Load<Effect>("postprocessing");
postProcessor = new PostProcessor(device, ppEffect);
//Draw Method
//Tham số cho Effect
xTime là biến của effect, chúng ta cần biến đổi nó theo thời gian (lưu ý ở Draw Method cũng có tác dụng Update game!
Bạn có thể khởi đầu với 1 camera tĩnh (FixedCamera), nó sẽ giúp bạn quan sát một model đứng yên và tất nhiên, cái camera của bạn cũng như thế!
Bạn xây dựng lớp FixedCamera như sau:
- Code:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Camera
{
class FixedCamera
{
Đây là góc nhìn, chúng ta cần nó để có thuộc tính AspectRatio dựa vào hình chiếu phối cảnh
Viewport viewport;
Đây là 2 ma trận, chúng ta coi giá trị của nó là KQ để Draw bất cứ 1 model nào trong game, nhớ lại xem basic Effect cần 2 thuộc tính này đúng không nào?
//Để public cho đơn giản
public Matrix viewMatrix;
public Matrix projectionMatrix;
public FixedCamera(Viewport viewport, ModelSprite sprite)
{
this.viewport = viewport;
Hình chiếu phối cảnh không cần thay đổi
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, viewport.AspectRatio, 0.5f, 100f);
ViewMatrix phụ thuộc điểm mà camera huớng tới, do đó điểm target sẽ là tọa độ model chúng ta muốn quan sát còn vị trí đặt camera tất nhiên sẽ khác target rùi
viewMatrix = Matrix.CreateLookAt(sprite.Position + new Vector3(0, 20, 20), sprite.Position, Vector3.Up);
}
}
}
-Khai báo thể hiện của camera
-Tạo ra và thiết lập cho model
-Thiết lập cho camera
-Dùng cho Draw Method:
Model sẽ sử dụng 2 Matrix là chúng ta đã tạo trong lớp trên
Tốt nhất bạn hãy hoàn thành quy trình trên nếu không muốn phải ngồi Debug
2.Xoay và di chuyển camera trong không gian 3D
Xoay điểm target
Để xoay một điểm nói chung quanh một trục, VD như trục X, ta có thể sử dụng:
Đầu tiên tạo ra góc xoay: Matrix.CreateRorationX((float)góc xoay)
Sau đó tạo ra điểm đang xoay:
- Code:
//cameraRotation la 1 ma tran xoay quanh truc toa do
Vector3.Transform(cameraOriginalTarget, cameraRotation);
- Code:
cameraFinalTarget = cameraPosition + cameraRotatedTarget;
Khi muốn di chuyển position , ta thiết lập
//tốc độ di chuyển (const)
float moveSpeed = 0.05f;
// Hưóng di chuyển tiếp theo của camera (tiến tới truớc
Vector3 cameraOriginalForward = new Vector3(0, 0, -1);
//Khi tiến tới thì camera sẽ xoay, làm camera ko đi thẳng tơi phía truớc mà đi xiên theo góc xoay, đó là thứ ta muốn
Vector3 cameraRotatedForward = Vector3.Transform(cameraOriginalForward, cameraRotation);
//tọa độ đặt camera sẽ thay đổi , nó tăng (tiến) theo VectorForward và Vector này bị "xiên"
cameraPosition += moveSpeed * cameraRotatedForward;
//Update lại viewMatrix
UpdateViewMatrix();
private void UpdateViewMatrix()
{
//Vector Up và điểm target khi chưa xoay
Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
//sau khi xoay 2 cái trên
Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
//điểm target cần phải tiến theo vị trí của pos
Vector3 cameraFinalTarget = cameraPosition + cameraRotatedTarget;
//Xoay vector Up
Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);
//viewMatrix dc tao ra 1 cach hoan chinh
viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraFinalTarget, cameraRotatedUpVector);
}
Thay đổi tọa độ của camera:
Để thay đổi tọa độ, chúng ta thực hiện phép toán sau:
Position = Position + Movespeed*VectorForward;
tọa độ sẽ tiên đến theo phuơng của vectorForward với tôc độ là 1 hằng số.
Ví dụ như bạn muốn camẻra tiến về truớc, chúng ta có vectorForward là (0,0,-1), Speed thì tùy bạn thôi, kiểu của nó là float
Khi bạn muốn nó đi chéo qua một góc, bạn transform với góc đó (quanh 1 trục tọa độ) và dùng lại công thức trên
RotatedVectorForward = Vector3.Transform(RotatedVectorForward,CameraRotation);
Vector VectorForward sẽ bị xiên qua một góc mà CameraRotation quy định cho nó.
Position = Position + Movespeed*RotatedVectorForward;
3.Tạo camera góc nhìn thứ nhất (FPS)
Chúng ta dùng chuột để thay đổi góc nhìn cho camera. Khi bạn di chuyển chuột lên xuống. Chúng ta xoay điểm target theo trục X. Khi bạn di chuột trái hay phải. Chúng ta xoay điểm target theo trục Y. chúng ta khai báo các biến để lấy đc các giá trị trên:
originalMouseState là giá trị Vector2 nằm ở trung tâm màn hình.
Nếu chúng ta di chuọt (thay đổi tọa độ của nó) thì code như duới đây:
- Code:
float xDifference = currentMouseState.X - originalMouseState.X;
float yDifference = currentMouseState.Y - originalMouseState.Y;
leftrightRot -= rotationSpeed * xDifference;
updownRot -= rotationSpeed * yDifference;
Mouse.SetPosition(viewPort.Width / 2, viewPort.Height / 2);
UpdateViewMatrix();
//Cập nhật lại viewMatrix theo điều khiển con chuột
private void UpdateViewMatrix()
{
Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);
Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
//Xoay điểm target
Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
//Cập nhật theo tọa độ của camera
Vector3 cameraFinalTarget = cameraPosition + cameraRotatedTarget;
//Xoay và cập nhật lại cho VectorUp
Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);
Vector3 cameraFinalUpVector = cameraPosition + cameraRotatedUpVector;
//ViewMatrix đã hoàn thành
viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraFinalTarget, cameraRotatedUpVector);
}
Khi bạn dùng phím múi tên để di chuyển con chuột, tức là bạn đang muốn có 1 vectorForward như ở phần truớc. đầu tiên code để chúng ta có cái vector đó. Ở đây có thêm phím Q va Z để thay đổi tọa độ Y của camerra
if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W)) //Forward
AddToCameraPosition(new Vector3(0, 0, -1));
if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S)) //Backward
AddToCameraPosition(new Vector3(0, 0, 1));
if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D)) //Right
AddToCameraPosition(new Vector3(1, 0, 0));
if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A)) //Left
AddToCameraPosition(new Vector3(-1, 0, 0));
if (keyState.IsKeyDown(Keys.Q)) //Up
AddToCameraPosition(new Vector3(0, 1, 0));
if (keyState.IsKeyDown(Keys.Z)) //Down
AddToCameraPosition(new Vector3(0, -1, 0));
Tiếp theo là một method AddToCameraPosition() để thay đổi tọa độ camera:
private void AddToCameraPosition(Vector3 vectorToAdd)
{
float moveSpeed = 0.5f;
Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);
Vector3 rotatedVector = Vector3.Transform(vectorToAdd, cameraRotation);
cameraPosition += moveSpeed * rotatedVector;
UpdateViewMatrix();
}
Khi bạn biết đc điều này, bạn sẽ biết object nào cần draw để làm nhẹ cho Ram và card màn hình.
Để biết thể tích vùng nhìn thấy, XNA cung cấp 1 lớp sẵn có cho chúng ta. Nó dc tính như sau:
Là tích của view và projection Matrix.
Khi bạn dùng cái này để kiểm tra va chạm với điểm hay bounding khác, nó sẽ trả về 1 trong 3 giá trị sau ở biến kiểu ContainmentType, tất nhiên chúng ta khai báo nó.
Contain: object hoàn toàn trong
Intersects: nằm trong 1 phần.
Disjoint: hoàn toàn nằm ngoài
1.Kiểm tra 1 điểm có nằm trong sight ko
2.Kiểm tra 1 đối tuợng có nằm trong sight
Với Object, chúng ta có thể tạo ra 1 bounding bao quanh object đó (Sphere hay Box), các bạn sử dụng method sau, nó nằm trong 1 class hỗ trợ lập trình khác mà chúng ta thảo luận chuơng sau:
myModel = XNAUtils.LoadModelWithBoundingSphere(ref modelTransforms, "Ship", Content);
Đại loại nó sẽ load model với một bounding nằm trong thuộc tính Tag của nó:
Lưu ý: Tag là thuộc tính có thể đc khai báo bằng struc của model, nó có thể lưu giữ thông tin bất kỳ như Sphere, texture... do người dùng định nghĩa
Khi bạn sử dụng model, sẽ có worldMatrix của nó, chúng ta tạo bounding kiểu Sphere theo vị trí ghi ở translate matrix, sau đó kiểm tra nó với frustum bounding của camera.
Trong code trên, model chỉ đc Draw nếu nó nằm trong sight của camera!
Qua chuơng sau bạn sẽ biết cách render model, h cứ hiểu thế đã.
Các bạn có thể dùng vòng for để tạo nhiều model, khi kiểm tra cũng dùng for đê KT từng thằng, tuy nhiên đây là cách ko thông minh, chúng ta có thể xây dựng lớp riêng cho Model theo kiểu DrawableGameComponent để chuơng trình chạy nhanh hơn.
6.Kiểm tra va chạm camera với model hay terrain
Nếu ko có phần này, camera mà chúng ta xây dựng ra sẽ tạo cho chúng ta cảm giác đi xuyên đc model hay ko có cảm giác trọng lực khi đi trên terrain.
Với Model
Để KT va chạm, model cần có bounding , để có nó các bạn load model như phần truớc.
Chúng ta cần tạo ra 1 bound bao quanh camera, sử dụng lớp có sẵn của XNA:
Đó là 1 hình cầu tâm là tọa độ camera và bán kính 1, nó đc dùng KT va chạm với boundng của model.
Sử dụng Model Bounding:
Tạo ra 1 biến lưu giữ tọa độ lần Update vị trí của camera, nếu có va chạm với bounding của Model, camera trở về vị trí truớc đó. KT va chạm ở Draw method, nó đc KT sau khi đã Update xong
2.Kiểm tra va chạm với terrain.
Việc tạo ra terrain ntn, các bạn sẽ biết trong chương sau. bây giờ chỉ là KT va chạm của camera với các thành phần của terrain đó thôi.
Chúng ta sử dụng lớp Terrain và một Method tính độ cao (tọa độ Y) tại một điểm bất kỳ trên terrain. Từ đó chúng ta suy ra tọa độ cao tối thiểu của camera tại điểm đó tức là camera của chúng ta sẽ ko thể đi xuyên xuống đất đc
Code sau đặt trong Update Method:
Dấu trừ "-" ở code trên là do khi xây dựng lớp Terrain, họ đã đưa các tham số theo số duơng trong method GetClippedHeightAt, mà khi tiến về phía truớc, theo Hệ tọa độ của XNA, là trái chiều trục Z => tọa độ Z luôn âm, chúng ta cần dấu trừ để nó duơng.
7.Thay đổi nền cho cảnh game (tạo Sky Box)
Chúng ta sẽ tạo một back ground = 1 texture. Đó phải là một cảnh gây cho chúng ta cảm giác rằng nó đang ở rất xa! Bởi lẽ nó chỉ là ảnh nền ko có tưong tác với các object khác. Do nó ở rất xa nên khi chúng ta tiến lại gần nó cũng ko có cảm giác to ra J nói cách khác là nó hoàn toàn tĩnh Đúng nghĩa của một BG.
Không gian của chúng ta gói lại trong một cube, player khi nhìn vào sẽ thấy mình đang đứng trong 1 vùng núi có những đám mây lững lờ.
Cái texture trên chứa 6 mặt của một hình cube, tất nhiên đó là 1 model. Nếu ko dùng model chúng ta có thể tạo ra cube bằng vertex.
Đầu tiên các bạn add c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll vào Reference nếu project của bạn chưa có
Tuơng tự đầu tiên chúng ta load model:
Trong Method Draw:
- Code:
graphics.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1, 0);
device.SamplerStates[0].AddressU = TextureAddressMode.Clamp;
device.SamplerStates[0].AddressV = TextureAddressMode.Clamp;
device.RenderState.DepthBufferWriteEnable = false;
Code sẽ Draw model mà không có thuộc tính độ sâu (trục Z), nghĩa là nó không chịu ảnh huởng của hình chiếu phối cảnh. Mặt khác, độ sâu của model ko có tức là nó luôn bị các object khác che đi.
effect.World = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(fpsCam.Position);
Vẽ worldMatrix theo từng mesh và nó luôn chuyển động theo camera, khoảng cách giữa nó và camera luôn ko đổi.
8.Chỉ vẽ những vùng nhìn thấy
Chia tách sight của camera thành những vùng nhỏ, những vùng này sẽ đc KT với sight của camera xem có collides ko, nếu có mới draw những object bên trong vùng đó. Một demo hay 1 game nhỏ thì không cần đến cái này nhưng nếu bạn muốn tạo ra 1 thế giới rộng lớn thì kỹ thuật duới đây rất có ích.
Để sử dụng, lớp OcTreeNode.cs sẽ đc add vào project của bạn. bạn đọc thêm về vertex và biết về đệ quy để hiểu đc lớp này.
Sử dụng trong Game1.cs :
OcTreeNode ocTreeRoot;
Thiết lập cho nó:
ocTreeRoot = new OcTreeNode(new Vector3(0, 0, 0), 21);
nó nghĩa là vùng trên scene của chúng ta nhận điểm gốc tọa độ làm tâm của vùng phân chia, nó có bán kính...
đó là vùng gốc nên chỉ cần 1 (hay nhiều hơn tùy bạn) từ vùng gốc đó chúng ta sẽ chia làm 8 vùng nhỏ để KT với camera. Đặt nó trong loadContent để còn load model vào trong nó để test:
- Code:
int[] modelIDs = new int[8];
modelIDs[0] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(1, 3, 5));
modelIDs[1] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(5, 2, -1));
modelIDs[2] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(10, -4, -1));
modelIDs[3] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(1, 2, -3));
modelIDs[4] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(5, 2, -3));
modelIDs[5] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(10, -4, -3));
modelIDs[6] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(8, 8, -3));
modelIDs[7] = ocTreeRoot.Add(myModel, Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(10, 8, -3));
Lớp OcTreeNode cho phép bạn di chuyển vùng nhỏ đó và kéo theo cả camera:
float time = (float)gameTime.TotalGameTime.TotalMilliseconds/ 1000.0f;
Vector3 startingPos = new Vector3(1, 3, 5);
Vector3 moveDirection = new Vector3(0, 0, -1);
Matrix newWMatrix = Matrix.CreateScale(0.001f) * Matrix.CreateTranslation(startingPos + time * moveDirection);
int modelToChange = 0;
ocTreeRoot.UpdateModelWorldMatrix(modelToChange, newWMatrix);
time luôn tăng (do nó đếm thời gian game đã chạy) => vị trí sẽ thay đổi dần. model ở vùng 0 sẽ di chuyển theo Matrix của nó.
Cuối cùng là Draw từng vùng nếu vùng đó nằm trong sight của camera, các bạn đặt nó trong Draw() Method:
//vùng đc vẽ
ocTreeRoot.ModelsDrawn = 0;
//sight camera
BoundingFrustum cameraFrustrum = new BoundingFrustum(fpsCam.ViewMatrix * fpsCam.ProjectionMatrix);
//vẽ tất cả TreeRoot nếu có trong sight
ocTreeRoot.Draw(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix, cameraFrustrum);
//Method của Class để vẽ vùng thể hiện của từng vùng nhỏ
ocTreeRoot.DrawBoxLines(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix, device, basicEffect);
//Đếm số lưọng vùng đc vẽ
Window.Title = string.Format("Models drawn: {0}", ocTreeRoot.ModelsDrawn);
Tưong tự phần trên, chúng ta sẽ chia cắt terrain để draw những vùng nhìn thấy, các bạn lưu ý phần truớc là Vùng chứa model còn ở đây là vùng chứa terrain dựng bằng file heightmap
Terrain đc dựng từ các node, là các điểm nhấn đc tạo ra từ QTnode, chúng ta sử dụng nó như sau:
//Khai báo biến
- Code:
QTNode rootNode;
//lấy chièu dài và rộng của texture
int width = heightMap.Width;
int height = heightMap.Height;
//lấy thông tin về chiều cao của height map
float[,] heightData = TerrainUtils.LoadHeightData(heightMap);
//Dựng terrain từ heightmap, đầu tiên là vertex
VertexPositionNormalTexture[] vertices = TerrainUtils.CreateTerrainVertices(heightData);
//tiếp đó là indices
int[] indices = TerrainUtils.CreateTerrainIndices(width, height);
//mảng chứa các vertex tạo từ vertex và indices
vertices = TerrainUtils.GenerateNormalsForTriangleStrip(vertices, indices)
//mảng chứa vertex theo 2 chiều dài và rộng của terrain tao từ vertex
VertexPositionNormalTexture[,] vertexArray = Reshape1Dto2D<VertexPositionNormalTexture>(vertices, width, height);
//terrain sẽ đc dựng = khối gốc (chứa tất cả các thành phần khác)
//64 là kick thuớc lớn nhất của mỗi vùng nhỏ
rootNode = new QTNode(vertexArray, device, grassTexture, 64);
}
//method
private T[,] Reshape1Dto2D<T>(T[] vertices, int width, int height)
{
T[,] vertexArray = new T[width, height];
int i = 0;
for (int h = 0; h < height; h++)
for (int w = 0; w < width; w++)
vertexArray[w, h] = vertices[i++];
return vertexArray;
}
protected override void UnloadContent()
{
}
- Code:
protected override void Draw(GameTime gameTime)
{
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1, 0);
//draw coordcross
cCross.Draw(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix);
//sight của camera
BoundingFrustum cameraFrustrum = new BoundingFrustum(fpsCam.ViewMatrix * fpsCam.ProjectionMatrix);
//chưa render Nodes
QTNode.NodesRendered = 0;
//Dựng nó lên
rootNode.Draw(Matrix.CreateTranslation(-250, -20, 250), fpsCam.ViewMatrix, fpsCam.ProjectionMatrix, cameraFrustrum);
//đếm số nodes sẽ vẽ
Window.Title = string.Format("{0} nodes rendered", QTNode.NodesRendered);
base.Draw(gameTime);
}
}
10.Sử dụng hiệu ứng cho camera
Camera chính là con mắt của các bạn khi chơi game, hiệu ứng cho camera cũng giông như là khi bạn đeo thêm 1 cái guơng lên mắt vậy, bạn có thể làm mọi vật nhèo đi hay thay đổi màu sắc của chúng thông qua cái kính đó!
Để sử dụng hiệu ứng chúng ta xây dựng lớp PostProcessor.cs lớp này có nhiệm vụ nhận các tham số của effect cung tên, xử lý nó và truyền cho effect
Để sử dụng lớp này trong Game1.cs của chúng ta, lần luợt làm như sau:
Chúng ta sẽ dùng hiệu ứng đảo màu theo thời gian cho camera làm ví dụ
//khai báo the hiện class postProcessor
//trong phần khai báo biến
//loadContent method
//load effect và load nó vào postProcessor
Effect ppEffect = Content.Load<Effect>("postprocessing");
postProcessor = new PostProcessor(device, ppEffect);
//Draw Method
//Tham số cho Effect
- Code:
float time = (float)gameTime.TotalGameTime.TotalMilliseconds / 1000.0f;
//Thiết đặt cho effect
List<string> ppEffectsList = new List<string>();
//các technique có trong effect
ppEffectsList.Add("Invert");
ppEffectsList.Add("TimeChange");
postProcessor.Parameters["xTime"].SetValue(time);
postProcessor.PostProcess(ppEffectsList);
}
}
}
xTime là biến của effect, chúng ta cần biến đổi nó theo thời gian (lưu ý ở Draw Method cũng có tác dụng Update game!
re
Sao bạn ko up project nên cho anh em tham khảo cho dễ nhỉ
an_chc- Tổng số bài gửi : 13
Điểm : 17
Danh Tiếng : 0
Join date : 09/11/2010
Re: Camera và Tương tác với camera
bạn down tạm code ở đây nhé, mình bận nên chả còn thời gian làm code mẫu cho bạn:
http://apress.com/book/downloadfile/4323
http://apress.com/book/downloadfile/4323
Similar topics
» Tao Camera Góc nhìn thứ 3 (TPS)
» nhac mot doi tuong 3D trong XNA
» Ý tưởng game nhập vai của imagic
» THống nhất ý tưởng cho game
» Model và tuơng tác với Model
» nhac mot doi tuong 3D trong XNA
» Ý tưởng game nhập vai của imagic
» THống nhất ý tưởng cho game
» Model và tuơng tác với Model
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết