Browsed by
תגית: iOS

libGDX Scene2d tutorial – Part 2 – Splash Screen

libGDX Scene2d tutorial – Part 2 – Splash Screen

(חלק 1 נמצא כאן)

עברנו את השלב הראשון – טענו את קבצי התמונות/קול לזיכרון. לפני שאנחנו עוברים למשחק עצמו, אנחנו רוצים להציג את הלוגו של חברת המשחקים שלנו.

משהו כזה:

Splash Screen

כדי לעשות זאת, נשתמש (לראשונה) בספריית Scene2d.

Read More Read More

Two Cars

Two Cars

בהמשך לפוסט הזה, הפעם ניצור משחק.

בקצרה: libGDX היא ספרייה נוחה לשימוש עבור יצירת משחקי 2D. אפשר לראות בפוסט הנ״ל מדריך איך ליצור פרוייקט חדש ולהריץ אותו על פלטפורמות שונות.

ישנו משחק בשם Two Cars – צריך לשלוט בו זמנית על שתי מכוניות בלי להתנגש במכשולים. אני הולך ליצור גירסא שלו, עם שינוי קל. המשחק יראה בסופו של דבר ככה:

ezgif-2403319550

ניצור פרוייקט חדש בשם TwoCars. אין צורך ב- Box2D – לא נשתמש במנוע הפיזיקלי לצורך המשחק הזה.

נתחיל.

מבנה כללי

libGDX היא event-driven – כלומר האירועים השונים הם מה שמניעים אותנו. לדוגמא, בכל פעם שהמסך מתרפרש – תיקרא הפונקציה –

public void render(float delta)

 בה נכתוב מה אנחנו רוצים שיוצג על המסך. (מזכיר קצת את העבודה עם סקריפטים ב- Unity3D, שם העדכונים מגיעים לפונקציית update).

ניצור package חדש בשם helpers, וניצור בו שתי מחלקות – GameWorld, GameRenderer.

GameWorld – בה תהיה הלוגיקה של המשחק. היא תחזיק את ה- State של המשחק, המיקום בו נמצא כל אובייקט על המסך, וניקוד.

GameRenderer – אחראי לצייר על המסך את כל המידע שיש ב- GameWorld.

GameWorld:

public class GameWorld {
    public void update(float delta) {
 
    }
}

GameRenderer:

public class GameRenderer {
    private OrthographicCamera cam;
    private GameWorld gameWorld;
 
    public GameRenderer(GameWorld world){
        this.gameWorld = world;
 
        cam = new OrthographicCamera();
        cam.setToOrtho(true, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
    }
 
    public void render(){
 
    }
}

זה המבנה הבסיסי שיחזור על עצמו בכל משחק. בכל פריים חדש, נקרא ל- GameWorld כדי לעדכן את המצב במשחק, ואז נקרא ל- GameRenderer לעדכן את מה שמוצג.

ב- GameRenderer גם מאתחלים את המצלמה – היא אחראית על איך יראה כל מה שמוצג. נרחיב על כך בהמשך.

Read More Read More

בדיקת completionBlocks עם OCMock

בדיקת completionBlocks עם OCMock

יש לנו מתודה ב- Objective C שנראית כך:

- (void)getFileFromServer:(NSString*)url {
    if ([[URLValidator sharedInstance] isValidUrl:url]) {
        [[ServerConnection sharedInstance] getFromUrl:url withTimeout:12.f onCompletion:^(NSData* data) {
            if (data) {
                [[FilesManager sharedApplication] saveFile:data];
            } else {
                NSLog(@"ERROR. Failed to get file.");
            }
        }];
    }
}

קוד פשוט – המתודה מקבלת url, שולחת לבדיקה שזו כתובת תקינה באובייקט URLVAlidator, ואז עם האובייקט ServerConnection הקובץ מתקבל, ונשמר ב- FilesManager.

עד כאן הכל טוב.

השאלה היא איך כותבים לזה טסט. ליצור mock עבור כל אחד מהאובייקטים (במידת הצורך) זה פשוט. partialMock וכו׳. הבעיה זה לבדוק את ה- completionBlock.

הפתרון הוא להוסיף מייד אחרי הקריאה ל- expect, קריאה לביצוע NSInvocation – כלומר אנחנו מפעילים בעצמנו את הבלוק שהולך להגיע כפרמטר (חשוב לשים לב לאינדקס הנכון!). ואז מסיימים את הפקודה עם הפרמטרים של המתודה:

id serverConnection = [OCMockObject partialMockForObject:[ServerConnection sharedInstance]];
id filesManager = [OCMockObject partialMockForObject:[FilesManager sharedInstance]];
[[[serverConnection expect] andDo:^(NSInvocation *invocation) {
        void (^passedBlock)( BOOL );
        [invocation getArgument: &passedBlock atIndex: 4];
        NSData* data = [[NSData alloc] initWith:""];
        passedBlock(data);
    }]  getFromUrl:url withTimeout:12.f onCompletion:OCMOCK_ANY];
[[filesManager expect] saveFile: OCMOCK_ANY];
[filesManager verify];
[serverConnection verify];
 
[filesManager stopMocking];
[serverConnection stopMocking];