How is this coded? Programming Question

jonthedit

Well-Known Member
Member
Joined
May 30, 2011
Messages
1,682
Trophies
0
XP
969
Country
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.
 

Niksy

Well-Known Member
Newcomer
Joined
Oct 23, 2010
Messages
97
Trophies
0
XP
218
Country
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.
 
  • Like
Reactions: jonthedit

cracker

Nyah!
Member
Joined
Aug 24, 2005
Messages
3,546
Trophies
0
XP
1,852
Country
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.
 
  • Like
Reactions: jonthedit
P

pasc

Guest
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.

Ah the cracker !

Haven't seen you around since forever.

Did you get my PM/Conversation ?
 

jonthedit

Well-Known Member
Member
Joined
May 30, 2011
Messages
1,682
Trophies
0
XP
969
Country
Bangladesh
If you have the app then rename the .ipa to .zip and open it to see what pre-rendered images it uses.

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.
 

jonthedit

Well-Known Member
Member
Joined
May 30, 2011
Messages
1,682
Trophies
0
XP
969
Country
Bangladesh
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.

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.
 

Niksy

Well-Known Member
Newcomer
Joined
Oct 23, 2010
Messages
97
Trophies
0
XP
218
Country
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.

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).
 
  • Like
Reactions: jonthedit

Coto

-
Member
Joined
Jun 4, 2010
Messages
2,774
Trophies
0
XP
1,831
Country
Chile
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.

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
 
  • Like
Reactions: jonthedit

sandytf

Well-Known Member
Member
Joined
May 5, 2013
Messages
130
Trophies
0
Age
42
XP
553
Country
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.
 
  • Like
Reactions: jonthedit

Site & Scene News

General chit-chat
Help Users
  • Flame @ Flame:
    @Psionic Roshambo what you been up to as of late?
  • Flame @ Flame:
    any new Chinese cheap stuff?
  • Veho @ Veho:
    Chinese stuff isn't cheap any more.
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Well a new phone battery case thing I love it.
  • Flame @ Flame:
    which phone do you own now?
  • Psionic Roshambo @ Psionic Roshambo:
    And yeah Veho is right with COVID destroying China everything is messed up
  • Psionic Roshambo @ Psionic Roshambo:
    Galaxy Note 9 right now.
  • Psionic Roshambo @ Psionic Roshambo:
    Well and Redmi Note 9 and 10 too
  • B-Blue @ B-Blue:
    nice vag
  • James_ @ James_:
    @ mods someone posted nsfw in general
  • DinohScene @ DinohScene:
    picture above?
  • B-Blue @ B-Blue:
    8===D
  • MORSHU8KRTXON @ MORSHU8KRTXON:
    The picture is incomprehensible
  • DinohScene @ DinohScene:
    idek what I'm looking at but if it's actually NSFW, please say so
  • DarthMotzkus tempBOT:
    DarthMotzkus has left the room.
  • linuxares @ linuxares:
    not sure what i'm looking at
  • Veho @ Veho:
    It's from Neural Blender, it generates random images: https://neuralblender.com/
  • Veho @ Veho:
    Remember that deep dream AI thing? This is similar.
  • DinohScene @ DinohScene:
    figured that much haha
  • kenenthk @ kenenthk:
    @Veho, I've been having dreams that feel so realistic lately probably over
    new drugs though most are nightmareish
  • Veho @ Veho:
    Don't do drugs :teach:
  • kenenthk @ kenenthk:
    Big pharma says it's okay
  • Flame @ Flame:
    Drugs are Bad, Mkay?
  • kenenthk @ kenenthk:
    Cheaper then street prices and can fuck you up quicker then a McJizzle
    kenenthk @ kenenthk: Cheaper then street prices and can fuck you up quicker then a McJizzle