Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile

73 525 1
Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile . Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile Nghiên cứu lập trình đồ họa và xây dựng game 3d cho mobile

TRƯỜNG ĐẠI HỌC SƯ PHẠM ĐÀ NẴNG KHOA TIN HỌC  LUẬN VĂN TỐT NGHIỆP CỬ NHÂN CÔNG NGHỆ THÔNG TIN KHÓA 2009 NGHIÊN CỨU LẬP TRÌNH ĐỒ HỌA VÀ XÂY DỰNG GAME 3D CHO MOBILE Giáo viên hướng dẫn : Th.S TRẦN UYÊN TRANG Sinh viên thực : TRẦN ĐỨC HUY ĐÀ NẴNG THÁNG NĂM 2013 NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN Đà Nẵng, ngày …… tháng …… năm 201… Giáo viên hướng dẫn NHẬN XÉT CỦA HỘI ĐỒNG XÉT DUYỆT Đà Nẵng, ngày …… tháng …… năm 201… Hội đồng xét duyệt Mục lục MỞ ĐẦU Ngày nay, phát triển bùng nổ thiết bị di động có tác động không nhỏ tới đời sống Có thể dễ dàng nhận thấy, thiết bị số di động Smartphone (iPhone, Android,…), tablet (iPad, iPad mini, loại máy tính bảng khác,…) dần trở thành vật bất ly thân người, sử dụng chúng khắp nơi, lúc, học, công sở, chơi với bạn bè, nhà,… Chính phổ biến này, kèm theo phát triển vượt bậc công nghệ phần cứng lẫn phần mềm thiết bị di động biến điện thoại có hình trắng đen, nghe gọi nhắn tin trở thành cỗ máy mạnh mẽ với cấu hình mạnh, hệ điều hành đa nhiệm, đa tác vụ, kết nối internet thường trực 24/24 với công nghệ 3G, wifi Nhờ mà nhu cầu giải trí thiết bị ngày tăng, đồng thời với cạnh tranh hãng sản xuất thiết bị di động cung cấp cho giới lập trình nhiều công cụ để hỗ trợ phát triển sản phẩm công nghệ, giải trí thiết bị di động, nhiều chợ ứng dụng đầu tư phát triển để đảm bảo đầu cho sản phẩm ứng dụng di động, giúp lập trình viên dễ dàng kiếm tiền từ sản phẩm dễ dàng đưa sản phẩm đến thị trường quốc tế cách nhanh chóng, mà không cần phải lo nghĩ nhiều cho việc quảng bá sản phẩm hay đau đầu chiến lược kinh doanh phức tạp Để nắm bắt xu công nghệ giới tận dụng hội lớn này, em cảm thấy cần thiết phải nghiên cứu sâu vào lĩnh vực phát triển ứng dụng di động đầy hấp dẫn này, nên em chọn đề tài Nghiên cứu lập trình đồ họa xây dựng Game 3D cho mobile với mục tiêu có nhìn toàn diện hiểu rõ lập trình đồ họa, game, công nghệ đằng sau đó, để xây dựng cho công cụ mà từ sử dụng để xây dựng game tùy thích cho thiết bị di động (iPhone, iPad, Android phone,…) ứng dụng kiến thức xây dựng game 3D đơn giản lấy đề tài biển đảo Việt Nam với tên gọi: Game Bảo vệ Hoàng Sa Trường Sa Chương 1: CƠ SỞ LÝ THUYẾT Khái niệm đồ họa máy tính Đồ họa máy tính lĩnh vực khoa học máy tính nghiên cứu sở toán học, thuật toán kĩ thuật phép tạo, hiển thị điều khiển hình ảnh hình máy tính Đồ họa máy tính có liên quan nhiều đến số lĩnh vực đại số, hình học giải tích, hình học họa hình, quang học, kĩ thuật máy tính, đặc biệt chế tạo phần cứng (các loại hình, thiết bị xuất, nhập, vỉ mạch đồ họa ) Theo nghĩa rộng hơn, đồ họa máy tính phương pháp công nghệ dùng việc chuyển đổi qua lại liệu hình ảnh hình máy tính Đồ họa máy tính hay kĩ thuật đồ họa máy tính hiểu dạng phương pháp kĩ thuật tạo hình ảnh từ mô hình toán học mô tả đối tượng hay liệu lấy từ đối tượng thực tế Thuật ngữ "đồ họa máy tính" (computer graphics) đề xuất chuyên gia người Mĩ tên William Fetter vào năm 1960 Khi ông nghiên cứu xây dựng mô hình buồng lái máy bay cho hãng Boeing William Fetter dựa hình ảnh chiều mô hình người phi công buồng lái để xây dựng nên mô hình buồng lái tối ưu cho máy bay Boeing Đây phương pháp nghiên cứu vào thời kì Phương pháp cho phép nhà thiết kế quan sát cách trực quan vị trí người lái khoang buồng lái William Fetter đặt tên cho phương pháp computer graphics Lịch sử đồ họa máy tính vào thập niên 1960 đánh dấu dự án SketchPad phát triển Học viện Công nghệ Massachusetts (MIT) Ivan Sutherland Các thành tựu thu được báo cáo hội nghị Fall Joint Computer kiện lần người ta tạo mới, hiển thị thay đổi liệu hình ảnh trực tiếp hình máy tính thời gian thực Hệ thống Sketchpad dùng để thiết kế hệ thống mạch điện bao gồm thành phần sau: • Màn hình CRT • Bút sáng bàn phím bao gồm phím chức • Máy tính chứa chương trình xử lí thông tin Với hệ thống này, người sử dụng vẽ trực tiếp sơ đồ mạch điện lên hình thông qua bút sáng, chương trình phân tích tính toán thông số cần thiết mạch điện người dùng vẽ nên Kỹ thuật đồ họa liên tục hoàn thiện vào thập niên 1970 với xuất chuẩn đồ họa làm tăng cường khả giao tiếp tái sử dụng phần mềm thư viện đồ họa Sự phát triển vượt bậc công nghệ vi điện tử phần cứng máy tính vào thập niên 1980 làm xuất hàng loạt vỉ mạch hỗ trợ cho việc truy xuất đồ họa với giảm giá đáng kể máy tính cá nhân làm đồ họa ngày sâu vào sống thực tế Đồ họa máy tính có nhiều ứng dụng máy tính ước tính đến 80% thông tin xử lí hình ảnh Một số ứng dụng tiêu biểu đồ họa máy tính là: • • • • Tạo mô hình, hoạt cảnh (game, giải trí, ) Hỗ trợ thiết kế đồ họa Mô hình ảnh, chuẩn đoán hình ảnh (trong y tế) Huấn luyện đào tạo ảo (quân sự, hành không, ) Sự phát triển đồ họa di động Ngày nay, với phát triển thiết bị di động, sức mạnh đồ họa ứng dụng di động ngày phát triển Ngay từ thời kì đầu tiên, mà thiết bị di động sử dụng hình trắng đen ứng dụng đồ họa cho điện thoại bắt đầu đầu tư phát triển, từ mục đích ban đầu tạo trò chơi giải trí đơn giản Snake máy di động Nokia Dần dần sau, công nghệ thay đổi, chất lượng hình điện thoại ngày cải tiến, lĩnh vực đồ họa di động lại trỗi dậy với ứng dụng game có chất lượng cao hơn, bên cạnh đồ họa góp phần đem lại bóng bẩy, đại cho sản phẩm di động Game di động vào thời kì hình trắng đen năm 1998 Các game 2D J2ME vào thời kì năm 2004 Vào năm 2005, game 3D bắt đầu xuất chất lượng không cao Năm 2007, game di động chưa có đột phá việc độ phân giải hình tăng cao giúp hiển thị hình ảnh chi tiết Năm 2008, iPhone bắt đầu xuất hiện, kéo theo sức mạnh đồ họa nâng cao, chất lượng hình cảm ứng đột phá đem lại thay đổi rõ rệt cho mặt game di động Angry Birds, sản phẩm giới mở cho kỉ nguyên kinh doanh ứng dụng di động Rovio – hãng sản xuất Angry Birds minh chứng cho việc công ty nhỏ thành lập từ đến người nhanh chóng kiếm hàng triệu đô la trở thành tập đoàn lớn sau đêm Mở thời kì người người, nhà nhà ôm giấc mơ triệu phú từ kinh doanh ứng dụng di động Sức mạnh đồ họa thiết bị dộng ngày cải thiện, vào năm 2011, Infinity Blade số nhiều game mang chất lượng đồ họa game máy tính đến điện thoại di động 10 Sau có lớp quản lý hình tạo hình game, hình game có cấu trúc sau: class GameState { public: virtual void virtual void virtual void virtual void }; Init() = 0; Draw() = 0; Update(float deltaTime) = 0; Destroy() = 0; Ví dụ hình chọn level có cấu trúc sau: class LevelSelectState: public GameState { public: Rectangle bgRect,survivalRect,storyRect; string *story; int currentPage, numPages; float timer; LevelSelectState(void); ~LevelSelectState(void); void void void void Init(); Draw(); Update(float deltaTime); Destroy(); }; Sau đó, bắt đầu xây dựng lớp đối tượng game, gồm có: Cannon súng đại bác Bullet – viên đạn dùng để bắn WarShip – tàu địch Castle – tòa thành HP – máu người chơi Sea – mặt biển Khẩu súng đại bác có cấu trúc đối tượng sau: class Cannon : public Singleton, public Objects { private: unsigned int numBullet;// số đạn có đồng thời số đạn giới hạn bắt đầu chơi public: float angle; //góc quay súng float count; unsigned int reload_time; bool isUnlimited; Cannon(void); ~Cannon(void); void init(); void Draw(); 59 void setBullet(unsigned int);// set num of bullet unsigned int getBullet(void); void Update(float deltaTime); void rotLeft(float deltaTime); void rotRight(float deltaTime); void shock(); void reBegin(); void Fire(float _angle, float _v0); }; Cấu trúc đối tượng viên đạn: class Bullet : public Objects, public Singleton { public: int MAX_POW; int MIN_POW; float increase; float angle;// góc bay viên đạn so với trục Ox float v0;//vận tốc ban đầu viên đạn float time;//thời điểm viên đạn tính từ lúc bắn Vector3 cur_pos;// vị trí ban đầu viên đạn bool isFire; //biến lưu lại trạng thái viên đạn: bắn/chưa bắn Bullet(void); void init(); void reBegin(void); void Fire(float _angle, float _v0); void Update(float deltaTime); ~Bullet(void); }; Lớp HP – hiển thị trạng thái máu người chơi class HP : public Status_Bar, public Singleton { float cur_hit; public: HP(void); void init(); void Draw(); void Update(float deltaTime); void Change(int value); bool getHit(); ~HP(void); }; Lớp WarShip – Định nghĩa tàu quân địch class WarShip : public Objects { int x, y; 60 int dir; // direction of WarShip bool addScoreC, addScoreB; // test add score when colliding Castle or Bullet float leftW, rightW, topW, bottomW, frontW, backW; int num_Rotate; // test warship rotate? float dx, dz, agl; float Angle; // the symbol of angle rotatate around Oy Matrix mLocation; bool isBombed; bool direct ; bool checkColl; int typeColl; public: //bool movePearl; // direction when press button PEARL EnemyBullet* ebullet; int accurate; int timefire; Vector3 pos, rot, cmr; bool isUpdate; int count; WarShip(void); WarShip(int ); void initWS (void); ~WarShip(void); void Rotate( float, float, float, float ); //void Draw(); void UpdateWS1( float ); void UpdateWS2( float ); bool isCollideBullet(void); bool isCollideCastle(void); bool isCollideWS ( WarShip ws ); void Update(float deltaTime); void Draw(); }; Để di chuyển súng đại bác sang trái phải theo kiện nhấn phím bấm vào nút hình Ta xử lý sau: //cannon turn right if (GL2D::IsInRect(holdX, holdY, rectDirectionRight) || GL2D::IsInRect(holdX2, holdY2, rectDirectionRight)) { if (Camera::GetInstance()->getRotation().y >= -0.1) Camera::GetInstance()->Key(deltaTime, 39); cannon->rotRight(deltaTime); #ifdef _ANDROID if (ResourcesManager::GetInstance()->isPlaySound == 1) { StopSound(); PlaySound(2, 0); 61 } #endif LOGI("Turn right\n"); } //cannon turn left if (GL2D::IsInRect(holdX, holdY, rectDirectionLeft) || GL2D::IsInRect(holdX2, holdY2, rectDirectionLeft)) { if (Camera::GetInstance()->getRotation().y Key(deltaTime, 37); cannon->rotLeft(deltaTime); #ifdef _ANDROID if (ResourcesManager::GetInstance()->isPlaySound == 1) { StopSound(); PlaySound(2, 0); } #endif LOGI("Turn left\n"); } Khi người chơi nhấn vào nút Fire, ta điều khiển cho lực bắn tăng lên giảm xuống sau: if (GL2D::IsInRect(holdX, holdY, rectFireBT) || GL2D::IsInRect(holdX2, holdY2, rectFireBT)) { if ( power < ) { bullet->increase *= -1; pow_bar->increase *= -1; } if ( power > bullet->MAX_POW ) { bullet->increase *= -1; //nếu lực bắn đặt tối đa lực bắn giảm xuống tiếp tục nhấn pow_bar->increase *= -1; } power += bullet->increase * (deltaTime * 50); pow_bar->scale += pow_bar->increase * (deltaTime * 50); LOGI("power: %f\tlengh bar: %f\n",power, pow_bar->scale); } Khi thả bắt đầu kiện bắn: if (GL2D::IsInRect(holdX, holdY, rectFireBT) || GL2D::IsInRect(holdX2, holdY2, rectFireBT)) { LOGI("Power: %f\n", power); pow_bar->Reset(); cannon->Fire(cannon->angle, power); //cannon->shock(); #ifdef _ANDROID 62 if (ResourcesManager::GetInstance()->isPlaySound == 1) { StopSound(); PlaySound(1, 0); } #endif power = 0; } 63 Chuyển game máy tính sang điện thoại Để chuyển game từ máy tính sang điện thoại, cần cài đặt công cụ - Android SDK - Android NDK - Cygwin Sau cài đặt hoàn tất môi trường bắt đầu việc chuyển đổi cách tạo Project Android Sau ta cần biên dịch file CPP game cách dùng NDK Cygwin Make Sau file định nghĩa file CPP cần biên dịch cho MAKE LOCAL_MODULE := libgl2jni LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := / /InternshipFW/3DMath.cpp \ / /InternshipFW/Application.cpp \ / /InternshipFW/BoxObject.cpp \ / /InternshipFW/BrokenGlass.cpp \ / /InternshipFW/Bullet.cpp \ / /InternshipFW/Camera.cpp \ / /InternshipFW/Cannon.cpp \ / /InternshipFW/Castle.cpp \ / /InternshipFW/CreditsState.cpp \ / /InternshipFW/EnemyBullet.cpp \ / /InternshipFW/FileSystem.cpp \ / /InternshipFW/FinishLevelState.cpp \ / /InternshipFW/GameLevelState.cpp \ / /InternshipFW/GameOverState.cpp \ / /InternshipFW/Graphic.cpp \ / /InternshipFW/Ground.cpp \ / /InternshipFW/HP.cpp \ / /InternshipFW/IngameState.cpp \ / /InternshipFW/Input.cpp \ / /InternshipFW/LevelSelectState.cpp \ / /InternshipFW/LoadingState.cpp \ / /InternshipFW/LogoScreenState.cpp \ / /InternshipFW/MainMenuState.cpp \ / /InternshipFW/ManageEnemy.cpp \ / /InternshipFW/Model.cpp \ / /InternshipFW/ObjManager.cpp \ / /InternshipFW/Objects.cpp \ / /InternshipFW/ObjectsManager.cpp \ / /InternshipFW/Particle.cpp \ / /InternshipFW/ParticleHP.cpp \ / /InternshipFW/ParticleSystem.cpp \ / /InternshipFW/PearlSkill.cpp \ / /InternshipFW/ResourcesManager.cpp \ / /InternshipFW/SceneManager.cpp \ 64 / /InternshipFW/ScoreManager.cpp \ / /InternshipFW/Sea.cpp \ / /InternshipFW/Shaders.cpp \ / /InternshipFW/StateManager.cpp \ / /InternshipFW/Status_Bar.cpp \ / /InternshipFW/TGA.cpp \ / /InternshipFW/Texture.cpp \ / /InternshipFW/TopScoreState.cpp \ / /InternshipFW/WaitingScreenState.cpp \ / /InternshipFW/WarShip.cpp \ / /InternshipFW/WaterSpark.cpp \ gl_code.cpp \ LOCAL_LDLIBS := -llog -lGLESv2 Sau biên dịch xong, dùng chương trình JNI trung gian làm cầu nối C++ Java Chương trình có nhiệm vụ liên kết file vừa biên dịch với Java để chạy Android #include #include #include #include static static static static static static " / /InternshipFW/Application.h" " / /InternshipFW/Input.h" jobject bridge; jmethodID android_playSound; jmethodID android_playMusic; jmethodID android_stopSound; jmethodID android_stopMusic; JavaVM* jVM; extern "C" { JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_init(JNIEnv * env, jobject obj, jstring sdpath); JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_step(JNIEnv * env, jobject obj, jfloat deltaTime); JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_pointer(JNIEnv * env, jobject obj, jint type, jint x, jint y, jint x2, jint y2); void Java_com_drybones_evate_GL2JNILib_BridgeJ2C( JNIEnv* env, jobject thiz, jobject obj ) { bridge = obj; jclass glViewClass; (jVM)->GetEnv((void**) &env, JNI_VERSION_1_6); bridge = (jobject)(env)->NewGlobalRef( obj); glViewClass = (env)->GetObjectClass( bridge); 65 android_playSound = (env)->GetMethodID(glViewClass, "playSound", "(II)V"); android_playMusic = (env)->GetMethodID(glViewClass, "playMusic", "(II)V"); android_stopSound = (env)->GetMethodID(glViewClass, "stopSound", "()V"); android_stopMusic = (env)->GetMethodID(glViewClass, "stopMusic", "()V"); LOGI("End C call java init"); } int JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv *env; jVM = vm; LOGI("JNI ONLOAD"); if((vm)->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) { return -1; } return JNI_VERSION_1_6; } // Play Sound void PlaySound(int id, int loop) { JNIEnv *env; (jVM)->GetEnv((void**) &env, JNI_VERSION_1_6); (env)->CallVoidMethod(bridge, android_playSound, id, loop); LOGI("\nPlay Sound from jni!!"); }; void PlayMusic(int id, int loop) { JNIEnv *env; (jVM)->GetEnv((void**) &env, JNI_VERSION_1_6); (env)->CallVoidMethod(bridge, android_playMusic, id, loop); LOGI("\nPlay Music from jni!!"); } void StopSound() { JNIEnv *env; (jVM)->GetEnv((void**) &env, JNI_VERSION_1_6); (env)->CallVoidMethod(bridge, android_stopSound); } void StopMusic() { JNIEnv *env; (jVM)->GetEnv((void**) &env, JNI_VERSION_1_6); 66 (env)->CallVoidMethod(bridge, android_stopMusic); } }; JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_init(JNIEnv * env, jobject obj, jstring sdpath) { LOGI("Start JNI Load"); Application::GetInstance()->Init( "/mnt/sdcard/Evate/Resource" ); LOGI("Finish JNI Load"); } JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_step(JNIEnv * env, jobject obj, jfloat deltaTime) { //LOGI("JNI deltaTime: %f", deltaTime); Application::GetInstance()->Render(); Application::GetInstance()->Update(deltaTime); } JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_pointer(JNIEnv * env, jobject obj, jint type, jint x, jint y, jint x2, jint y2) { if (type == 1) Input::GetInstance()->OnPointer(POINTER_DOWN, x, y, x2, y2); if (type == 2) Input::GetInstance()->OnPointer(POINTER_UP, x, y, x2, y2); } Dòng lệnh sau dùng để định đường dẫn load liệu thẻ nhớ cho game Application::GetInstance()->Init( "/mnt/sdcard/Evate/Resource" ); Trong mã nguồn game, có đoạn xử lý kiểm tra, hệ thống Android thực chức riêng biệt, ví dụ: #ifdef _ANDROID if (ResourcesManager::GetInstance()->isPlaySound == 1) { StopSound(); PlaySound(2, 0); } #endif Đoạn chương trình sau kiểm tra hệ thống Android bật âm 67 Một vài hình ảnh demo game Một vài hình ảnh trình xây dựng game sản phẩm hoàn thiện: 68 69 70 71 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN Qua trình làm đồ án, em có hội vận dụng toàn kiến thức học suốt trình học tập trường Đại học, với kiến thức giới thiệu trình Thực tập vừa qua Điều đem lại cho em kinh nghiệm vô quý giá Vì kiến thức có hạn thời gian làm đồ án không dài, nên không tránh khỏi sai sót hạn chế Em mong nhận đóng góp nhiệt tình từ Cô giáo hướng dẫn Hội đồng để em hoàn thiện sản phẩm Về hướng phát triển cho đồ án, em hoàn thiện chức có Game, tập trung cải thiện vấn đề xử lý game nhiều độ phân giải hình cho nhiều dòng điện thoại Android khác nhau, phát triển thêm chức hỗ trợ phát triển game cho tảng di động khác iPad, BlackBerry, Windows Phone,… phát triển thêm để game Bảo vệ Hoàng Sa Trường Sa có thêm chiều sâu nội dung cách chơi hấp dẫn phát hành miễn phí lên chợ ứng dụng AppStore, Play Store để người dễ dàng tải chơi Em xin chân thành cảm ơn Cô Trần Uyên Trang tận tình hướng dẫn em suốt thời gian thực đồ án, em xin cảm ơn thầy cô Khoa Tin trường Đại học Sư phạm Đà Nẵng tận tình dạy dỗ dẫn cho em kiến thức từ nên chuyên sâu suốt năm học để em có tảng kiến thức tốt hoàn thành luận văn 72 TÀI LIỆU THAM KHẢO Giáo trình Lập trình Game 3D với OpenGL ES (tài liệu nội Công ty Gameloft) Website Songhoca (http://songho.ca) Giáo trình môn Lý thuyết đồ họa 73 ... phải nghiên cứu sâu vào lĩnh vực phát triển ứng dụng di động đầy hấp dẫn này, nên em chọn đề tài Nghiên cứu lập trình đồ họa xây dựng Game 3D cho mobile với mục tiêu có nhìn toàn diện hiểu rõ lập. .. lập trình đồ họa, game, công nghệ đằng sau đó, để xây dựng cho công cụ mà từ sử dụng để xây dựng game tùy thích cho thiết bị di động (iPhone, iPad, Android phone,…) ứng dụng kiến thức xây dựng game. .. mạnh đồ họa thiết bị dộng ngày cải thiện, vào năm 2011, Infinity Blade số nhiều game mang chất lượng đồ họa game máy tính đến điện thoại di động 10 Khái niệm 3D Để bắt đầu tìm hiểu lập trình 3D

Ngày đăng: 12/03/2017, 00:12

Từ khóa liên quan

Mục lục

  • NGHIÊN CỨU LẬP TRÌNH ĐỒ HỌA VÀ XÂY DỰNG GAME 3D CHO MOBILE

  • NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN

  • NHẬN XÉT CỦA HỘI ĐỒNG XÉT DUYỆT

  • MỞ ĐẦU

  • Chương 1: CƠ SỞ LÝ THUYẾT

  • Chương 2: PHÂN TÍCH VÀ XÂY DỰNG ĐỀ TÀI

  • KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

  • TÀI LIỆU THAM KHẢO

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan