Save
Saving
  • phuocnguyen phuocnguyen

    Interactive Video (Beta version)

    Autor: Kiên ( có gì thắc mắc a/e cứ hỏi Kiên )
    Updator/Composer : Phước

    Hiện tại chỉ là bản sơ khai đọc và play video , còn nhiều giật lag do bản unity 2022 ( 1 số thiết bị yếu sẽ bị giật lag , trên fourum unity cũng có nhiều chủ đề thảo luận về vấn đề này,các bản 2018/2020 play sẽ đỡ lag hơn nhất là bản 2018 rất mượt. A/e tự xử lý tiếp nhé ! )

    cc58e2a4-7f46-48e4-99e1-6d07a59607fd-image.png

    I. Tổng Quát

    • Scene : MonkeyX\Assets\Private\Monkey\MonkeyX\Features\InteractiveVideo\Scripts\DemoScene
      02991518-2683-416f-b854-6510b3d0f32a-image.png

    • Code tất cả nằm ở InteractiveVideo.cs

    B1: Chuẩn bị :

    Load video PrepareVideo() -> hiện tại video được kéo vào ở Scene : DemoScene

    Đọc thông tin các điểm config để tương tác trên video : newSample/config

    e06b4be1-e080-4f69-aa1f-2a79c14127ee-image.png

    + startAt: giây bắt đầu
    + interactType: hiện tại chỉ có hotspot -> loại click
    + hotspotConfig: tọa độ vùng nhấn trên
    + rewindAt: lặp lại ở giây bao nhiêu -> sẽ loop lại.
    

    Đăng ký các sự kiện cần thiết : seekCompleted ( khi tua video xong) , prepareCompleted ( khi đã chuẩn bị video xong)

    B2 : Cơ chế

    • Xử lý trong hàm Update -> Kiểm tra có đến đoạn của interactive video chưa ? Nếu đến rồi thì vẽ vùng nhấn lên trên màn hình ở hàm OnReachPoint

    • Sau đó nếu user nhấn vào vùng nhấn trên màn hình thì sẽ nhảy vào hàm : OnHotspotClicked và seek đến vị trí cần seek , sau khi seek xong thì hệ thống sẽ tự nhảy vào sự kiện SeekComplete

    posted in Knowledge Base read more
  • phuocnguyen phuocnguyen

    I. Tổng Quát

    Các Repo chính :
    https://github.com/eduhub123/monkeyx_main (develop_integration)

    Các Submodules :
    https://github.com/eduhub123/monkeyx_common (develop_intergration)
    https://github.com/eduhub123/monkeyx_yolo (develop_intergration)
    https://github.com/eduhub123/monkeyx_private (develop_intergration)
    https://github.com/eduhub123/monkeyx_puto(develop_integration)

    7bfdbd9a-d2cf-4474-a4f6-9a4bc26fbe18-image.png

    Có hai loại repo như sau :

    a.public repo:

    +main : chứa core project, các phần như: project setting, native library, unity assets, custom
    gradle...

    +common : chứa tất cả source code, assets... cần public ra bên ngoài.

    b.private repo: chứa source code của từng đối tác và monkey.

    1.Chỉ cần clone repo chính :

    ( Hiện tại nên clone thẳng develop_integration để tránh lỗi nhé các anh/em do ở master đang chia khác submodule với develop nên switch branch hay lỗi , ae tự xử lý nhé 😊 , không thì clone thẳng như mình ! )

    git clone --progress --branch develop_integration -v "https://github.com/eduhub123/monkeyx_main" "D:\projects\monkeyx_main"
    

    2. Update submodules :

    git submodule update --init --recursive
    

    II. Cách sử dụng.

    1. Play Mode trong Editor

    Chọn các Scene thông qua menu như trong hình dưới:

    104e7990-8b34-4caa-a796-0bdc605cdf60-image.png

    Bắt đầu play với scene NavigatorScene

    2. Build Unity Only

    Thông thường project sẽ được build tự động kết hợp vỏ app (React Native) và Unity (được build thành library nhúng vào vỏ app), để có thể build độc lập Unity cần thực hiện các bước sau:

    2.1 Switch Platform

    3f6a85fe-79bd-465b-92fa-f9d5abc69ec7-image.png

    2.2 Build Asset Bundle tương ứng hoặc bấm short key Shift + Alt + B

    71a5ccda-2eef-4ff9-b14c-0be1dda7d843-image.png

    2.3 Add Define UNITY_ONLY

    6ca5dbda-ae57-4eb4-a0be-2c8c3dca6b60-image.png

    Sau đó build ra như các project thông thường

    III. Một số chức năng trong debug log

    1. Mở chức năng Debug Log

    Trên editor hoặc trên divice click vào button "Khỉ Monkey" để hiển thị giao diện Debug

    736fe74a-b593-4e33-91b7-d766944a7643-image.png

    Giao diện Debug:

    6c2405e3-2fc4-43f8-bcd6-dd6970242a43-image.png

    2. Các Debug quan trọng

    2.1. General

    On / Off Debug In Game
    Mở / Tắt Debug khi chạy Runtime trên divice

    38123154-8eb8-479f-a11a-64bb78ed4a70-image.png

    Log On / Off
    Mở hoặc tắt Debug Log trên editor cũng như divice
    Chức năng này nhằm tắt Log trong bản release

    2.2. General

    On / Off Select ID Game EE
    Lựa chọn game muốn chơi trong lesson, chú ý đến việc lesson đó có chặn game đó hay không.
    ID game sẽ nằm trong file scene_config_1.json trong project

    55556b72-fb14-4321-86d7-971836c72410-image.png

    Khi lựa chọn game thì luồng học sẽ luôn luôn là game được lựa chọn

    3. Data

    3.1 Nơi lưu trữ Data

    Win : C:\Users\ "your-PC-name"\AppData\LocalLow\Early Start\MonkeyX
    Mac: /Users/"your-MAC-name"/Library/Application Support/Early Start/MonkeyX

    3.2 Các phần quan trọng

    Cần cài đặt DB Browser for SQLite để có thể đọc được database

    3.2.1 user.db

    Nơi lưu trữ các data của user, table quan trọng trong này là Course với colum is_active để có thể sử dụng full tính năng, nên để colum này với giá trị 1, hoặc set như bảng sau :

    3e77e7a9-6399-46fc-b9f6-68bded842fd4-image.png

    3.2.2 Folder zips
    Nơi chứa các asset bundle tải về theo từng phần tương ứng

    3.3 Xóa data (Reset dữ liệu)

    • Clear All PlayerPrefs trong unity
      a026365a-62aa-49e6-b3a8-486031d99b82-image.png

    • Xóa data trong thư mục MonkeyX

    posted in Knowledge Base read more
  • phuocnguyen phuocnguyen

    I. Sơ lượt

    Repo: https://github.com/eduhub123/MonkeyXAssetBunldeBuilder

    1. Tất cả config của phần build asset bundle được define ở : AsssetBundleBuilderData

    public static AsssetBundleBuilderData configData = new AsssetBundleBuilderData();

    Hiện tại gồm 2 config:

    • isSupportAward : xử lý data ảnh cho phần award

    • isGAF100PercentAlpha : xử lý lỗi alpha của animation GAF

    //Sau này cần gì ae thêm vào đây nữa nhé.

    2. Cách build có 2 cách :

    a. Dùng cmd :

    vd build bình thường :

    "C:\Program Files\Unity\Hub\Editor\2022.1.10f1\Editor\Unity.exe" -projectPath "E:\project\MonkeyXAssetBunldeBuilder\AssetBunldeBuilder" -executeMethod CreateAssetBundles.BuildDataToBundles -batchmode -quit

    vd build support phần award:

    "C:\Program Files\Unity\Hub\Editor\2022.1.10f1\Editor\Unity.exe" -projectPath "E:\project\MonkeyXAssetBunldeBuilder\AssetBunldeBuilder" -executeMethod CreateAssetBundles.BuildDataToBundles -isSupportAward true -batchmode -quit

    vd build support truyện gaf bị lỗi alpha:

    "C:\Program Files\Unity\Hub\Editor\2022.1.10f1\Editor\Unity.exe" -projectPath "E:\project\MonkeyXAssetBunldeBuilder\AssetBunldeBuilder" -executeMethod CreateAssetBundles.BuildDataToBundles -isGAF100PercentAlpha true -batchmode -quit

    b. Dùng unity editor:** Asset**/[Tên bên trên hàm đc define trong code]

    vd : "Assets/1.BuildDataToBundles"

    II. Giải thích chi tiết project

    Input folder : Assets/DataFolder

    Output folder : Thư mục Assets/StreamingAssets

    *Lưu ý: Mỗi lần bỏ data mới vào nên clear data ở Input/Output.

    Main:

    Tất cả code hiện tại ở file : Editor/CreateAssetBundles.cs

    Chỉnh 1 phần trong code lib GAF: GAF/[..]/Editor/GAFAssetPostProcessor.cs /GAFAssetPostProcessor

    1. BuildDataToBundles -> Build các thư mục/files ở Input thành những bundle riêng lễ.

    2. BuildDataTo1BundleFile -> Build toàn bộ thư mục/files trong Input thành 1 bundle duy nhất. Tên là data.bundle

    3. Hàm BuildDataToBundlesProcessCommandLineArgs () dành cho đọc tham số lúc build bằng command line -> để xử lý bật tắt những cofig đính kèm.

    4. GetAllCacheFilesForGAFFiles -> Hàm này để lấy những file cache sinh ra lúc build file GAF Animation -> nếu thiếu phần cache này thì GAF ko play được nhé. Path : Assets/GAF/Resources/Cache

    5. ExcludeFileExtensions Loại bỏ những đuôi file ko cần thiết -> hiện tại có .meta và DS_store

    6. CreateRenderTexture / CreateRenderTextureWithAssetGAFPath -> Tạo file Render Texture cho GAF Animation, phục vụ cho phần LRC là chủ yếu.

    7. ChangeTextureSettingsForAward -> Hàm này để thay đổi thuộc tính của texture thành FullRect và cho quyền read/write vào texture.

    8. ChangeGAFShader -> Để fix lỗi GAF Animation bị nhấp nháy -> play 1 shader của monkey tránh ảnh hưởng đến shader của GAF

    posted in Knowledge Base read more
  • phuocnguyen phuocnguyen


    I.Những Phần Cần Chú Ý


    [Serializable]
    public class Word
    {
    	public int word_id;
    	public string path_word; // đường link download word 
    	public string text; // từ 
    	public string name_display; // từ bỏ dấu 
    	public int sentence_type; //  (1 word , 2 sentence , 3 filter_word)
    	public List<Image> image; // Hình Ảnh 
    	public List<Video> video; // Video
    	public List<Audio> audio; //  m thanh 
    	public List<Audio> audio_effect; // audio hiệu ứng âm thanh (VD: tiếng mèo kêu, )
    	public List<string> color; // màu chữ 
    	public List<FilterWord>? Filter_word; // filter word ( nếu dậy câu là tách câu thành từng từ nhỏ và chơi từng từ )
    	public List<Phonic> phonic; // phonic (nếu dậy từ tách từ thành từng âm chơi từng âm )
    	public List<int>? list_not_game; // game không được chơi từ 
    	public List<string>? syllables; -> game dạy phát âm tiết 
    	public List<string>? audioSyllables; -> game dạy phát âm tiết 
    }
    
    

    Mô tả chung:

    1.Chủ yếu các game dùng Word model này để lấy data. Các data chính cần dạy cho 1 game đa phần gồm :

    +Hình ảnh : lấy từ List<Image> image;
    +Âm thanh : lấy từ List<Audio> audio;
    +Video : lấy từ List<Video> video;
    +Text : lầy từ text

    2.Nếu game dạy câu thì sẽ có Word ID là 1 câu , và các từ đi kèm sẽ lấy từ List<FilterWord>? Filter_word; từ Filter Word ID = Word ID -> lấy được Word tương ứng.

    3.List<string>? syllables;/List<string>? audioSyllables;

    [Serializable]
    public class Audio
    {
    	public int id;
    	public string tag_title;
    	public List<SyncData> sync_data; // (1)
    	public int duration;
    	public string name_original;
    	public string voices_id;(2)
    	public int voices_type_id;
    	public string link;
    	public string file_path;
    }
    

    Mô tả chung:

    1.Dữ liệu này như phụ đề karaoke , giây nào sẽ đọc từ/âm nào.

    2.voices_id

    	case AudioType.Slow: id = 59; break; Đọc tốc độ chậm.
    	case AudioType.Normal: id = 60; break; Đọc tốc độ bình thường.
    	case AudioType.Male: id = 34; break; Giọng nam
    	case AudioType.Female: id = 46; break; Giọng nữ.
    	case AudioType.Kid: id = 50; break;  Giọ trẻ em
    	case AudioType.FirstLetter: id = 57; break;  Đọc chữ cái đầu tiên của từ.
    
    [Serializable]
    public class Image
    {
    	public int id;
    	public string file_type;
    	public string title;
    	public int images_categories_id; IMAGE_NONE_BACKGROUND_ID = 116,IMAGE_NATURE_ID = 117;
    	public int text_group_id;
    	public string link;
    	public string file_path;
    }
    

    Mô tả chung:

    images_categories_id :

    case 116: ảnh vẻ,cartoon.	
    case 117: ảnh thật ( ảnh tự nhiên )
    

    I|.Những Phần không quan trọng


    
    [Serializable]
    public class Sentence
    {
    	public int word_id;
    	public string text;// từ
    	public string? path_word;// link download
    	public List<int>? list_not_game; // game không được chơi 
    	public int? type_sentence;// kiểu câu
    	public List<FilterWord>? filter_word; //filter word ( nếu dậy câu là tách câu thành từng từ nhỏ và chơi từng từ )
    
    }
    
    [Serializable]
    public class ListNumberWord
    {
    	public int? word_id;
    	public int? number;
    }
    
    [Serializable]
    public class ListWord
    {
    	public int word_id;
    	public string text;// từ
    	public string? path_word;// link download
    	public List<int>? list_not_game;// game không được chơi 
    	public List<Sentence>? sentence;/ /list câu dùng để chơi game câu 
    	public int? repeats_word;
    	public List<int>? list_flow;
    	public string? name_c;
    	public bool? checkFlow;
    }
    
    [Serializable]
    public class ListWordBk
    {
    	public int word_id;
    	public string text;// từ
    	public string path_word;// link download
    	public List<int>? list_not_game;// game không được chơi 
    	public List<Sentence>? sentence;// list câu dùng để chơi game câu 
    	public int? repeats_word;
    	public List<int>? list_flow;
    }
    
    [Serializable]
    public class LessonData
    {
    	public List<ListWord>? list_word; // list từ sẽ chơi trong bài học 
    	public List<ListWordBk>? List_word_bk; // nếu từ trong list_word không được chơi game đó thì sẽ lấy từ trong list_work_bk
    	public string? flow; //kiểu luồng bài học 
    	public int? key_flow;//key kiểu luồng bài học
    	public List<ListNumberWord>? list_number_word;
    }
    
    

    posted in Others read more
  • phuocnguyen phuocnguyen


    Tổng Quan


    1. Unity version: 2022.1.20f1

    • Như develop đang sử dụng.
    • Nếu update version unity sẽ được thông báo qua các kênh chat telegram/slack....

    2. Git Flow :

    b76643dc-7777-4a29-9943-97a6cedbfede-image.png

    a. master : Luôn ở trạng thái có thể deploy, release ra live users.
    b. hotfixes: Nhánh xử lý những critical bugs, khẩn cấp
    c. release : Release app các version.
    d. develop : nhánh này sẽ là nhánh chính để phát triển và là nơi tất cả các nhà phát triển trong nhóm sẽ làm việc để triển khai các tính năng mới hoặc sửa lỗi trước khi phát hành.

    Những thành viên khi làm feature mới, cần tách 1 branch mới từ develop ra, sau khi hoàn thiện thì sẽ được merge trực tiếp với develop.

    3. Đối với đối tác:

    • Bên OS nên đồng bộ với develop vào mỗi sáng [8h-11h] các ngày làm việc.
    • Nếu cần merge code xử lý gấp cần thông báo qua các kênh chat telegram/slack....

    I.Organization


    [Tên khóa học viết tắt + tên game]
       +---Resources
       |       ....
       +---Scene
       |       [Tên khóa học viết tắt + tên game].unity
       \---Scripts
    		   ....
    

    Vd: Khóa học Early Education và game cần làm là Matching1 => EEMatching1

    +---EEMatching1
       +---Resources
       |       BlankBox.png
       |       Colum.prefab
       +---Scene
       |       EEMatching1.unity
       \---Scripts
               EEM1.cs
               EEM1BlankBox.cs
    

    61c642d2-828b-4be4-94d7-86b397efb3de-image.png

    7deec49b-ae22-4331-b987-9b79c00dd085-image.png 329ad692-ed30-42ba-9251-7e0ab4b0d556-Screen Shot 2022-09-06 at 16.40.56.png


    +Thư mục Resource (số 1) ( image/audio/animation/scriptableobject...) nên sắp xếp theo độ liên quan ( feature ) -> ở đây là liên quan đến chính game cần làm, không chia theo type vì resource của game không quá nhiều và không quá phức tạp.

    Note:Vì hiện tại game là nhánh phân tầng cuối cùng của dự án, các tầng trên đã mix sort by type vs sort by features với nhau nên tầng cuối không phân tầng tránh làm rối project.

    Vd:
    cfed18fe-ac70-494d-acd7-a23dbee56f42-Screen Shot 2022-09-06 at 16.50.11.png
    +Thư mục Scene chứa Scene của game.
    +Thư mục Script chứa mã của game.

    Lưu ý :

    1. Kế thừa GameBase và bật biến _isTestDataEnable = true; lên và gọi hàm LoadData để lấy data test cho các game.

    2. Các data từ cần dạy nằm trong list _wordsForTeach

    3. Các data từ gay nhiễu nằm trong list _wordsForDisturbance

    4. Đọc data dùng hàm MKStorageHelper.ResourceLoad ( vì sau này data sẽ nằm trong appdata ko phải trong asset) / Audio dùng SoundManager.GetInstance().Play(...)

    5. Dùng chung CommonCanvas prefab => cho tất cả các game

    6. Các màu sắc random cho từng game ( đa phần là 6 màu trừ game con cá là 4 màu ) được bỏ ở ScriptableObjects/CommonResource.asset

    7. Target game cho điện thoại là chủ yếu -> canvas đc set theo tỉ lệ logical resolution design của IPhoneX 812x375

    e90b3bac-c3a5-4af9-9648-0ee2af199929-image.png

    1. Resouce asset phải đáp ứng được cho điện thoại độ phân giải HD/HDR
      B1: Nên phải export ảnh trên figma x2/x3 ( vì kích thước mặc định đang là logical resolution design = SD )
      B2: Set Pixel Per Unit hoặc Set size ảnh -> để đảm bảo mật độ điểm ảnh hiển thị trên HDR ko bị mờ và vỡ

    cbfee410-d500-4cdc-8e1a-50e559b6710b-Screen Shot 2022-10-04 at 18.04.22.png


    II. Naming


    1. Project Files

    Bao gồm : ScriptableObject, Image, Audio, Animation, Prefabs, Font, Database...

    • Không dùng Space trong tên .
    • Sử dụng PascalCase

    Vd:EventSystem,GameControlller,SoundPlaceholder...

    • Tránh sử dụng filetype trong tên

    Vd: Thay vì BoxItemBackgroundPng -> nên đặt là BoxItemBackground

    • Sử dụng gạch dưới _ để kết hợp 2 hoặc nhiều khái niệu nếu dùng PascalCase không mô tả được hết

    Vd: EEMBoxNormal_Blue,EEMBoxNormal_Red....

    • Nên bắt đầu tên bằng thứ mà đối tượng đó thuộc về.
      Vd: EEMBoxNormal,EEMGameItem....
    • Phần script/scene/resource của game = [Tên khóa học (viết tắt) + tên game (viết tắt) + Nội dung]
    //Vd: Khóa học Early Education có game Matching thì 
    //EEM1.cs 
    //EEM1GameItem.cs
    

    2. Scene/Hierarchy

    • Cách đặt tên như phần A. Project Files

    • Sử dụng Empty Game Object để làm container khi cần thiết (không sử dụng nếu chúng chỉ chứa 1-2 đối tượng.)
      4e87a6f3-6d5e-4ff2-a3d7-61f06a5e3e1e-image.png

    • Đối với Game/Feature phước tạp. Sử dụng Empty Game Object để đặt tên và phân tách cho các phần xử lý các logic .

    af548e63-933d-488b-a2ac-b838ecad3c4c-image.png


    III.Coding Rules


    • Giữ các fieldsmethods ở chế độ private, trừ khi bạn cần chúng ở chế độ công khai.
    • Nếu bạn muốn hiển thị các trường trong Inspector mà không thực sự làm cho biến có thể truy cập được đối với các lớp khác, hãy sử dụng thuộc tính [SerializeField] và riêng tư, thay vì đặt chúng ở chế độ công khai.
      Lưu ý: Làm như vậy, bạn có thể nhận được cảnh báo "Trường không bao giờ được gán cho, sẽ luôn có giá trị mặc định của nó". Gán giá trị mặc định cho trường với = default.
    • Cố gắng tránh sử dụng Singletons. Thay vào đó nên sử dụng ScriptableObjects cho một lớp tập trung, tương tự có thể được truy cập từ nhiều đối tượng.
    • Không sử dụng var khi khai báo một biến. Luôn viết loại của nó một cách rõ ràng.
    • Tránh sử dụng các biến tĩnh static.
    • Không hardcode những con "số ma thuật" . Ví dụ: Player di chuyển var x = xInput * 0.035f. Tại sao lại là số đó ? Thay vào đó, hãy dùng biến có tên rõ ràng cho nó - và có thể comment mô tả chi tiết về con số đó để người khác có thể hiểu.

    IV.Coding Convention


    1.Tóm tắt


    74531605-0cfe-4e42-a837-64f51d139685-image.png


    2.Quy Định Đặt Tên


    A.Class/Function/NameSpace/Enum/Public Fields/Public Properties

    • Phải được viết dưới dạng StudlyCaps(PascalCase) viết hoa chữ cái đầu của mỗi từ.
    class MyClass
    class MyHero
    class LogicRace
    
    void SetCurrentStep();
    int GetCurrentStep();
    void CreateHero();
    
    enum Direction {
            None,
            Vertical,
            Horizontal,
            Both
     };
    

    B.Variables.

    Gồm local variables, parameters viết dưới dạng camelCase.

    vd:
    
    int _heroHp; 
    
    int enemyCount = 0;
    
    public static int s_currentSceneIndex = 0;
     
    

    Các biến nên được thêm tiền tố ( prefix ) tùy thuộc chúng là :

    • hằng số (constants)
    • biến tĩnh (statics)
    • hay thành viên của class (class members).

    Độ ưu tiên:

    constant > static > member
    
    Loại Prefix Ví dụ
    Constants k_ k_myConstant
    Statics s_ s_myStatic
    Members _ _myMember
    Static Members ms_ myStaticMember

    C.Interface.

    • Luôn sử dụng chữ cái "I" làm tiền tố với tên Interface

    • VD

    public interface IUser
    {
    
    }
    

    3.Naming.


    Tên phải được đặt cẩn thận, rõ ràng để chỉ rõ mục đích của bất cứ điều gì đang hướng đến.

    Đừng ngần ngại sử dụng tên dài.

    vd:

    State _currentState;//State is an enum
    
    std::string GetAbsolutepath();
    
    bool HasChild();
    
    int heroActionsTrackerControl;
    

    Giá trị của biến kiểu boolean phải là câu trả lời, được hỏi từ chính tên của nó. Đừng sử dụng phủ định.

    DO:
    
    bool _isPainting;
    bool _isFound;
    bool hasChild();
    
    
    DON’T
    bool _paint;
    bool _isNotFound;
    bool hasNoChild();
    

    Tương tự ta cũng áp dụng cho các functions/methods trả về kiểu bool.

    a. Các Function/Method nên có một tên rõ ràng để nói rõ những gì chúng làm.

    b. Các phương thức Get/Set chỉ nên GetSet các members và không nên làm thêm bất kỳ tác vụ nào khác.

    DO:
    
    int GetCurrentStep()
    {
        return _curentStep;
    }
    
    DON’T
    
    int GetCurrentStep()
    {
      
        if(_hp>=10)
        {
            _curentStep+=1;
        }
        
        return _curentStep;
    }
    

    Compute/find nên được sử dụng cho các hoạt động tính toán và tìm kiếm.

    Init/Initialize khi khởi tạo một đối tượng (mặc dù tốt hơn nếu các đối tượng được khởi tạo trong constructor).

    Create/Allocate tạo hoặc khởi tạo các đối tượng khác.

    Sử dụng tên hàm cho các hành động ví dụ :
    ```Start/Stop, Pause/Resume, Show/Hide....``


    4.Comment


    Luôn luôn sử dụng //

    Bằng cách này, khi bạn tìm kiếm một cái gì đó bạn sẽ thấy ngay nếu nó đã bình luận hay không.


    5.Formatting


    a.Nên sử dụng khoảng cách bằng Tab , không sử dụng Space.

    b.Dấu ngoặc nhọn

    Nếu có một đoạn mã, thì phải có đóng mở ngoặc nhọn, ngay cả khi đó là một lệnh đơn, vì mình sẽ không biết được liệu còn ai đó có thể thêm một lệnh khác sau đó không ?

    Dấu ngoặc nhọn mở được đặt ở dòng tiếp theo và không nên có mã sau dấu ngoặc đóng (ngoại trừ do while).

    DO:
    
    for (uint32_t i = 0; i < 100; i++) {
        
    }
    
    if (a == 0) {
        
    } else {
        
    }
    
    do
    {
    
    } while (true); // the only statement allowed to follow the closing brace.
    

    c.Switch

    • Trường hợp có nhiều hơn 2 dòng lệnh ở mỗi case , thì ta phải sử dụng dấu ngoặc nhọn cho tất cả các trường hợp.
    • Các case phải được trên dòng riêng của mình.
    switch (State)
    {
    case HeroState::Attack:
    	{
    		DoSomeThing();
    		DoSomeThingElse();
    	}
    	break;
    case HeroState::Run:
    	{
    		DoSomeThing();
    		DoSomeThingElse();
    	}
    	break;
    default:
    	break;
    }
    
    • Trường hợp tất cả các case statemnts , chỉ có một câu lệnh đơn thì ta có thể không cần dấu ngoặc nhọn. Ví dụ :
    switch(x)
    {
        case MyEnum: : MyID1: return "MyID1";
        case MyEnum: : MyID2: return "MyID2";
        default: assert(false); break;
    }
    

    OR

    switch(x)
    {
        case MyEnum: : MyID1: Statement ("MyID1", o_value); break;
        case MyEnum: : MyID2: Statement("MyID2", o_value); break;
        default: assert(false); break;
    }
    

    6.Class

    Trình tự khai báo
    Thứ tự khai báo trong một class body nên như sau:

    Bởi, nhóm tầm nhìn:

    1. public
    2. protected
    3. private

    Sau đó, trong mỗi nhóm:

    1. Typedefs
    2. Constructors
    3. Destructor
    4. Operators
    5. Member functions - Grouped by semantic
    6. Member variables - Grouped by semantic
    Không tạo MEMBER function nếu bạn không truy cập bất kỳ thành viên nào.( cần truy cập mới tạo )
    Chia các hàm lớn thành các phần nhỏ hơn để cải thiện khả năng đọc mã.

    7.Format Code

    Sử dụng chuẩn tương tự dotnet:

    File config đã được export từ bản visual studio 2019 : ( có thể import vào sử dụng trên các IDE như visual stuido, visual sudio code... )

    https://github.com/eduhub123/MonkeyX/blob/develop/MonkeyX/.editorconfig

    Ref:

    posted in Others read more
  • phuocnguyen phuocnguyen

    int gradeID = 216;
    
    auto lessons = ms::LessonManager::getInstance().getAllLessonsByGrade(gradeID);
    
    std::string data = "LESSON ID,CATEGORY ID,LESSON NAME,SHORT DYNAMIC LINKS,DEEP LINKS,DEEP LINKS NAME";
    
    data += "\n";
    
    for (auto lesson : lessons) {
    
        std::string name = lesson.name;
    
        mj::helper::replace_string_all(name, ",", "_");
    
        std::string shortDynamicLink = StringUtils::format("https://monkeystories.page.link/lesrc%d", lesson.lesson_id);
        std::string deeplink = StringUtils::format("https://monkeystories.vn/qrrc?grade=%d&id=%d", gradeID, lesson.lesson_id);
        std::string deeplinkName = StringUtils::format("Reading Comprehension - %d - %s", lesson.lesson_id, name.c_str());
    
        data += (StringUtils::format("%d,%d,%s,%s,%s,%s\n", lesson.lesson_id, gradeID, name.c_str(), shortDynamicLink.c_str(), deeplink.c_str(), deeplinkName.c_str()));
    
    }
    
    FileUtils::getInstance()->writeStringToFile(data, FileUtils::getInstance()->getWritablePath() +  "/hihi2.csv");
    

    // auto popularStories = StoryDataModel::getInstance()->getAllStoriesByLanguage(LANGUAGE_MANAGER->getCurrentLangId());
    // std::string data = "ID[THEO NGON NGU],STORY ID,STORY NAME,SHORT DYNAMIC LINKS,DEEP LINKS,DEEP LINKS NAME";
    // data += "\n";
    // for (auto story : popularStories) {
    //
    // std::string name = story.name;
    //
    // mj::helper::replace_string_all(name, ",", "_");
    //
    //
    // std::string shortDynamicLink = StringUtils::format("https://monkeystories.page.link/story%d", story.story_id);
    // std::string deeplink = StringUtils::format("https://monkeystories.vn/qrstory?id=%d", story.unique_id);
    // std::string deeplinkName = StringUtils::format("Story - %s - %d", name.c_str(), story.story_id);
    //
    // data += (StringUtils::format("%d,%d,%s,%s,%s,%s\n", story.unique_id, story.story_id, name.c_str(), shortDynamicLink.c_str(), deeplink.c_str(), deeplinkName.c_str()));

    // }
    //
    //FileUtils::getInstance()->writeStringToFile(data, FileUtils::getInstance()->getWritablePath() + "/hihi2.csv");

    posted in Tips read more
  • phuocnguyen phuocnguyen

    What is a good internet speed?

    A good download speed is at least 25 Mbps, and a good upload speed is at least 3 Mbps. Some people can get away with fewer Mbps and others need more—but that’s a good internet speed for most people.

    Internet speeds are usually given in terms of download speed—for example, a plan with our recommended 25 Mbps of download speed and 3 Mbps of upload speed would simply be called a 25 Mbps internet speed. We’ll be following this trend, but it is important to pay attention to internet upload speeds as well.

    With 25 Mbps, you can stream Netflix or Youtube, attend Zoom meetings, and play most online games on one or two devices.

    If that doesn’t seem like a good fit for you, use the tool above to get a personalized recommendation or calculate the internet speed you need using the steps below.

    To start things off, here’s a breakdown of common download speed ranges in Mbps and what they’re good for.

     We recommend a minimum download speed of 25 Mbps for all monkey apps. (Monkey Stories, Monkey Junior.._)
    

    Ref:

    posted in Tài liệu public read more
  • phuocnguyen phuocnguyen

    I. Hướng dẫn cài đặt môi trường


    1. Download Cmake cho Window

    7fd2336f-dcd1-42d5-bcb3-0fb1ac939289-image.png

    • Nhớ chọn "Add Cmake to the system PATH for all users"

    d450aaf5-383c-4cd3-a65e-f9f731c9ebf1-image.png

    • Test cmake ,mở CMD lên gõ "cmake"

    99db3f3a-f14f-4497-a2f3-982f01549205-image.png

    2. Tải microsoft/vcpkg (C++ Library Manager for Windows, Linux, and MacOS) hoặc clone về ở link : https://github.com/microsoft/vcpkg

    Mục đích : cho phần login facebook/google trên windows và mac 
    

    3.Cài cpprestsdk theo hướng dẫn [link tham khảo]: https://github.com/microsoft/cpprestsdk

    • Cách 1: gõ lệnh vcpkg install cpprestsdk cpprestsdk:x64-windows
    • Cách 2: gõ lệnh .\vcpkg.exe install cpprestsdk[core,compression]
    • vcpkg install boost:x86-windows

    posted in Monkey Stories read more
  • phuocnguyen phuocnguyen

    • Sử dụng ReplayKit đối với iOS và ProjectionManager trên Android
      • Cần lưu ý việc hỏi và cấp permission trên Android.
      • iOS thì update lên version 13.x để đảm bảo việc hỏi cấp permission cho recorder.

    posted in Monkey Stories read more
  • phuocnguyen phuocnguyen

    • Trên iOS sử dụng StreamingKit https://github.com/tumtumtum/StreamingKit
    • Trên Android sử dụng ExoPlayer của google https://exoplayer.dev
    • Trên Windows và macOS sử dụng lib audio mặc định của Cocos2dx, không hỗ trợ streaming và playlists
    • Việc đọc sync audiobook được đọc từ API (trong trường hợp streaming) hoặc đọc từ tag (trong trường hợp local play). Thư viện đọc tag ID3 là id3v2lib https://github.com/larsbs/id3v2lib
    • Việc tạo, gắn tag và sync audiobook sử dụng aeneas https://www.readbeyond.it/aeneas/ để làm việc. Định dạng sync là JSON do aeneas tạo ra

    posted in Monkey Stories read more