How is this coded? Programming Question

Discussion in 'General Off-Topic Chat' started by jonthedit, Sep 22, 2013.

  1. jonthedit
    OP

    jonthedit GBAtemp Advanced Maniac

    Member
    1,691
    438
    May 30, 2011
    Bangladesh
    I've been learning a lot in software development in this last year, but recently I stumbled upon an iOS app called "Toca Hair Salon." For those who don't know, this app has no real goal and is geared towards younger children to encourage creativeness. When I was browsing videos of iOS applications, I found this video showing gameplay of this "game."

    (Sorry for posting an annoying 'let's waste your time and watch me play' video, but this shows the mechanics of the game.)


    So now that you know what I'm talking about, let me get to the point.

    I do not understand how this is coded. Just basically everything about it. I cannot imagine that using an If, doWhile, doUntil, ForNext, etc could produce the loops of this game.

    What determines what 'hair' goes where or disappears when a certain area is touched...

    I may sound confusing, ill try to explain what I'm asking better tomorrow, but if you understand what I'm asking please share. I'm just completely lost as to how this 'game' would be coded in general.
     
  2. Niksy

    Niksy Advanced Member

    Newcomer
    97
    72
    Oct 23, 2010
    I have done some Android programming and while making an iOS app is different, I think the logic is the same.

    Basically, you have a while(true) loop in which you call all the relevant update methods/functions and at the end of every cycle you call a draw or present (or however you want to call it) function that takes all the updated information and presents it on the screen.

    How does it know what 'hair' goes where or disappears? Well, on Android you have what is called a OnTouchListener. Every time the user touches the screen, a new TouchEvent is fired and you can check the type (Touch.Down, Touch.Up, Touch.Move), the X and Y coordinates and some other information that the TouchEvent provides. So, once the player touches the screen you just do some checks and see whether the beard was pressed and where or maybe the moustache and so on. After that you just add/remove the appropriate image and your done.

    This is a really simple explanation though.
     
    jonthedit likes this.
  3. cracker

    cracker Nyah!

    Member
    3,154
    440
    Aug 24, 2005
    United States
    To add to that:

    The hair is broken up into many different pieces. Each piece has some sort of counter that gets changed after each "cut" and the images are updated to reflect it. The coloring would just be a value set to load from a different set of images. The direction the hair is combed in is probably processed on the fly using a rotations/mirroring of the images.

    I doubt that much of the image processing is done during run time because nowadays space isn't much of a concern that devs even care to consider. :rolleyes:

    If you have the app then rename the .ipa to .zip and open it to see what pre-rendered images it uses.
     
    jonthedit likes this.
  4. pasc

    pasc GBATemps official GBA Freak

    Member
    2,593
    145
    Sep 9, 2006
    Gambia, The
    Germany
    Ah the cracker !

    Haven't seen you around since forever.

    Did you get my PM/Conversation ?
     
  5. jonthedit
    OP

    jonthedit GBAtemp Advanced Maniac

    Member
    1,691
    438
    May 30, 2011
    Bangladesh
    That's the thing... I've looked into the IPA's content, but there is no image files. The only conclusion I came up with was that the images must be encrypted into other files.
     
  6. jonthedit
    OP

    jonthedit GBAtemp Advanced Maniac

    Member
    1,691
    438
    May 30, 2011
    Bangladesh
    Thank you for the detailed reply. I hate to ask this, but if you have a bit of time could you write an example code? I'm not looking for specifics, but rather where what is called when.
     
  7. Niksy

    Niksy Advanced Member

    Newcomer
    97
    72
    Oct 23, 2010
    Here is some pseudo-code in Java:

    class Game implements Runnable{

    GameScreen currentGame;
    long startTime = System.currentTimeMillis();
    public void run(){
    while(true){
    float deltaTime = (System.currentTimeMillis()-startTime);
    startTime = System.currentTimeMillis();
    currentGame.update(deltaTime);
    currentGame.present(deltaTime);
    }
    }
    }

    class GameScreen{

    public long tickTime;
    public void update(long deltaTime){
    //here you check user input and change the player X,Y position
    //also you check for collision
    //maybe AI logic
    //basically you run all your logic here (using functions you have written in other classes of course, the main idea is that they are called in this update() method)

    tickTime += deltaTime;
    while(tickTime > 17) //we use 17 because 17 is 1/60 of a second (not exactly, but close enough) and we want the game to run at 60 frames per second
    {
    tickTime -= 17;
    //do logic here, for example checking the user input and deciding whether hair has to be cut (like in the game), etc.
    }
    }

    public void present(long deltaTime){
    //here you draw the player and all NPCs
    //the deltaTime is not used because you would want the game to render as fast as it can, but it is still part of the method in case you decide to do something with it.
    }
    }

    I hope this answers some of you questions. It's a really basic overview and it's probably not what is considered "best-practice" in the industry. If you are interested in game-development, Android to be more specific, I'd recommend reading Beginning Android Games. It does a good job in outlining what you need for a game and how to code it and it covers OpenGL ES as well (however I do not know how in-depth it goes as I have not yet read that part).
     
    jonthedit likes this.
  8. Coto

    Coto GBAtemp Addict

    Member
    2,365
    415
    Jun 4, 2010
    Chile
    to add that, if I may mr:

    load everything into memory: (3d models, slice of hair #1, #2, touchscreen init, 2d init (send a small code to test the 2d subsystem rotation, matrix (hw algebra testing), draw, scale, write then return 0), 3d init (subsystem test again: 3-d coordinates (z buffer tests, vertex rendering, z slope from x,y), then sound init, maps memory to be used.

    Code:
     
    checksoundbuffer(){
     
    //specific audio hardware stuff, i'm trying to keep things simple.. returns 0 if ready, 1 if busy
     
    }
     
    //2d subsystem drawing
     
    draw{
     
    //if one of the 2d hardware "threads" to put an image is ready, will place it there, or, if the same image is sent will ignore the new issue, and will keep drawing the same image. Otherwise (ie, out of threads will return false)
     
    }
     
    send_audio(){
     
    //will create audio, will return true if audio is emitted, false if not enough buffers/thread, or audio ended.
     
    }
     
    //vars
     
    int script_num=0; //defines the current game's script
     
    int i=0,j=0,z=0,f=0; //loooper
     
    int size_tot_scissors=0; //total of scissors you hold
     
    int size_tot_hair=0; //total of hairstyles you have got at hand
     
    int curr_sciss=0; //current chosen scissor
     
    int curr_hair_indx=0; //current hairtype to be cut chosen
     
    int curr_tilexfrag=0; //current tile x fragment
     
    int curr_tileyfrag=0; //current tile y fragment
     
    //structs
     
    struct currentscissor {
     
    int index=0;
     
    int scissor_x_entry=0; //acts as an entrypoint (coordinate-wise) for (x) currentscissor.index
     
    int scissor_x_limit=0; //acts as a delimiter (coordinate-wise) for (x) currentscissor.index
     
    int scissor_y_entry=0; //same as x entrypoint
     
    int scissor_y_limit=0; //same as x delimiter
     
    }
     
    struct hair{
     
    int index=0; //index, unique value.
     
    int type=0; //0= afro, 1=curly, 2=coily, etc...
     
    int colour=0; //0=blue, 1=green, 2=brown, etc..
     
    }
     
    struct haircut {
     
    int index=comes from index value struct hair has..
     
    int total_fragments=0; //all pieces of hair across a single person's head
     
    int hair_x_entry=0; //acts as an entrypoint (coordinate-wise) for (x) haircut.index
     
    int hair_x_limit=0; //acts as a delimiter (coordinate-wise) for (x) haircut.index
     
    int hair_y_entry=0; //acts as an entrypoint (coordinate-wise) for (y) haircut.index
     
    int hair_y_limit=0; //acts as a delimiter (coordinate-wise) for (y) haircut.index
     
    int hair_tilemap=0; //0 means hair entry on a complete map of hair. every value is delimited by a 16 byte word.
     
    int hair_tilefragment=0; // (hair_fragment_tiley*16)+hair_fragment_tilex), limit for tileY hairfragments is a 16 byte word
     
    //so later round(hair_tilefragment/16) is tileX, and tileY = hair_tilefragment-tileX)
     
    }
     
    //pick current scissor, so it is tied to a certain function, if not chosen returns 1
     
    choose_scissor(curr_sciss,curr_hair_indx){
     
    if(size_tot_scissors==0) return 1; //no scissors were added on the program
     
    //0 cuts little, 1 cuts a chunk
     
    switch (curr_sciss);
     
    case (0);
     
    if(hair.curr_hair_indx!=null){ //hair.curr_hair_indx && haircut.curr_hair_indx are both hair and haircut fragments to be cut
     
    for(z=0;size_tot_hair>z;z++){ //filter the appropiate hair to be cut
     
    for(j=0;j<=haircut.total_fragments;j=j+16){
     
    curr_tilexfrag = round(hair_tilemap[hair_tilefragment+j]/16); //current hair_tileXfragment
     
    curr_tileyfrag = hair_tilemap[hair_tilefragment+j] - curr_tilexfrag;
     
    //with these you can feed the "drawing" to start at given both x and y screen offsets. those will be offered by the drawing engine
     
    draw(curr_tilexfrag,curr_tileyfrag);
     
    //those offsets will be tied to touchscreen x,y
    if((hair.index==haircut.index) == curr_hair_indx)
    {
    if ((touchscreeninput_read() >= hair_x_entry && touchscreeninput_read() <= hair_x_limit) && (touchscreeninput_read() >= hair_y_entry && touchscreeninput_read() <= hair_y_limit))
    {
    //current hair is removed
    haircut.hair_tilemap[hair_tilefragment+j]=0;
    haircut.index=0;
    }
     
    }//close if tied to touchscreen
     
    }// close cicle hair fragment(j)
    return 0;
     
     
    }//close cicle hair fragment(z)
     
    }//end if curr_hair_indx exists
     
     
    else if(curr_hair_indx==size_tot_hair) //last thread, hairstyle not found (who knows, someone got rid of that value even if it was there before)
     
    return 1;
     
    }
    break;
     
    }
     
    scripting(script_num){
     
    //game behaviour
     
    //stages. say, demo mode (0), intro screen(1), select character(2), stage1(3), stage2(4)... gameover(n-1)
     
    switch(script_num);
     
    case(0);
     
    if(checksoundbuffer()==0) //if there's something on sound buffer, it's sent and done to the audio thread, if not busy.
     
    draw("demo_initscreen");
     
    send_audio("audio_1.etc");
     
    if(touchscreeninput_read().startbutton & 0)
     
    scripting(0); //right here the game will loop on demo mode if start is not pressed.
     
    else {
     
    script_num=1
     
    game_engine(); //if start is pressed, game_engine will be called, and will notice script has changed
     
    }
     
    break;
     
    case(1)
     
    draw("demo_basics");
     
    send_audio("audio_2.etc");
     
    if(touchscreeninput_read().startbutton & 0){
     
    //will wait until audio finishes playing
     
    while(send_audio!=false);
     
    script_num=2;
     
    game_engine();
     
    }
     
    else {
     
    script_num=2
     
    game_engine(); //if start is pressed, game_engine will be called, and will notice script has changed
     
    }
     
    break;
     
    case(2)
     
    //will select characters you will use
     
    if(touchscreeninput_read().startbutton & 1){
     
    script_num=3;
     
    game_engine();
     
    }
     
    else { //if not, we're still on the character screen
     
    script_num=2;
     
    game_engine();
     
    }
     
    break;
     
    case(3)
     
    return true;
     
    break;
     
    case(4)
     
    return true;
     
    break;
     
    }
     
    //basically draws, emit sounds, read controls
     
    game_engine(){
     
    //gameover
     
    if(script_num==(n-1)){
     
    draw("gameover.etc");
     
    send_audio("gameover.etc");
     
    scripting(0);
     
    }
     
    //intro mode
     
    else if(script_num==1)
     
    {
     
    draw.moveacross;
     
    draw.characterdies;
     
    //move character, character dies, i don't know what could happen on the intro.
     
    scripting(1);
     
    }
     
    }
     
    //select character
     
    else if(script_num==2)
     
    {
     
    //load lists of characters be it 2d or 3d you may have..
     
    //draws them on screen, play music.
     
    //wait for a button to be pressed to continue.. but for this we need the scripting
     
    scripting(2);
     
    }
     
    //stage 1
     
    else if(script_num==3)
     
    {
     
    //draws the tools you'll use (on screen)
     
    //draws the coordinates those tools should be used, each coordinate will refer to a specific tool, or scissor in this case
     
    where currentscissor holds the ammount of tools (scissors) you have at hand, with their properties.
     
    for(i=0;i<size_tot_scissors;i++){
     
    if(draw.currentscissor.index==i){
     
    currentscissor.scissor_x_entry=draw.valuex; //actual x coordinate that is being draw
     
    currentscissor.scissor_x_limit=draw.sizeof(valuex); //x top
     
    currentscissor.scissor_y_entry=draw.valuey; //actual y coordinate that is being draw
     
    currentscissor.scissor_y_limit=draw.sizeof(valuey); //y top
     
    }
     
    //draw and tie current scissor map with any function, hair "cut" included as well
    choose_scissor();
     
    }
     
    //end stage 1
     
    }
     
    //proceed with other stages
     
    return 1;
     
    }
     
    main(){
     
    video_init(); //if reserved 2d drawing subsystem is not used, will be called (set refresh rate, frames per second, etc), otherwise it isn't called again;
     
    //handles vertical blank or vertical blank interrupt (will tell later the code if this is a cycle for a frame to be drawn, or not).
     
    sound_init(); //same but for the sound subsystem
     
    v_framerefresh(); //will be aware if the current (through a counter) frame is drawn, if not does nothing, else draws a new one)
     
    //enums the ammount of scissors you have at hand
     
    while(draw.currentscissor.index!=null) size_tot_scissors++;
     
    //enums the ammount of hairstyles you have at hand
     
    while(hair.index!=null) size_tot_hair++;
     
    while(game_engine!=1) //the game engine
     
    }
     
    }
     
    
    this is pseudo code, took from 11am to 17pm to finish it.. :lol:

    it's not even complete, but deals with scripting... and what not
     
    jonthedit likes this.
  9. sandytf

    sandytf GBAtemp Regular

    Member
    121
    50
    May 5, 2013
    United States
    I suggest reading a few books dedicated to game development. Toca Hair Salon 2 appears to be a rather simple game, but still requires understanding game development basics. There are books specifically for iOS game development, but I can't comment on their quality. My favorite game programming authors are Andre LaMothe and Jim Adams. Their books are geared towards Windows, but the core concepts are the same.
     
    jonthedit likes this.