Functions can be called inline — КиберПедия 

Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...

Functions can be called inline

2021-11-25 13
Functions can be called inline 0.00 из 5.00 0 оценок
Заказать работу

Functions can be called on ~ content lines, but can also be called during a piece of content. In this context, the return value, if there is one, is printed (as well as anything else the function wants to print.) If there is no return value, nothing is printed.

Content is, by default, 'glued in', so the following:

Monsieur Fogg was looking {describe_health(health)}.

 

=== function describe_health(x) ===

{

- x == 100:

   ~ return "spritely"

- x > 75:

   ~ return "chipper"

- x > 45:

   ~ return "somewhat flagging"

- else:

   ~ return "despondent"

}

produces:

Monsieur Fogg was looking despondent.

Examples

For instance, you might include:

=== function max(a,b) ===

   { a < b:

          ~ return b

   - else:

          ~ return a

   }

 

=== function exp(x, e) ===

   // returns x to the power e where e is an integer

   { e <= 0:

          ~ return 1

   - else:

          ~ return x * exp(x, e - 1)

   }

Then:

The maximum of 2^5 and 3^3 is {max(exp(2,5), exp(3,3))}.

produces:

The maximum of 2^5 and 3^3 is 32.

Example: turning numbers into words

The following example is long, but appears in pretty much every inkle game to date. (Recall that a hyphenated line inside multiline curly braces indicates either "a condition to test" or, if the curly brace began with a variable, "a value to compare against".)

=== function print_num(x) ===

{

- x >= 1000:

   {print_num(x / 1000)} thousand { x mod 1000 > 0:{print_num(x mod 1000)}}

- x >= 100:

   {print_num(x / 100)} hundred { x mod 100 > 0:and {print_num(x mod 100)}}

- x == 0:

   zero

- else:

   { x >= 20:

       { x / 10:

           - 2: twenty

           - 3: thirty

           - 4: forty

           - 5: fifty

           - 6: sixty

           - 7: seventy

           - 8: eighty

           - 9: ninety

       }

       { x mod 10 > 0:<>-<>}

   }

   { x < 10 || x > 20:

       { x mod 10:

           - 1: one

           - 2: two

           - 3: three

           - 4: four       

           - 5: five

           - 6: six

           - 7: seven

           - 8: eight

           - 9: nine

       }

   - else:    

       { x:

           - 10: ten

           - 11: eleven      

           - 12: twelve

           - 13: thirteen

           - 14: fourteen

           - 15: fifteen

           - 16: sixteen     

           - 17: seventeen

           - 18: eighteen

           - 19: nineteen

       }

   }

}

which enables us to write things like:

~ price = 15

 

I pulled out {print_num(price)} coins from my pocket and slowly counted them.

"Oh, never mind," the trader replied. "I'll take half." And she took {print_num(price / 2)}, and pushed the rest back over to me.

Parameters can be passed by reference

Function parameters can also be passed 'by reference', meaning that the function can actually alter the the variable being passed in, instead of creating a temporary variable with that value.

For instance, most inkle stories include the following:

=== function alter(ref x, k) ===

   ~ x = x + k

Lines such as:

~ gold = gold + 7

~ health = health - 4

then become:

~ alter(gold, 7)

~ alter(health, -4)

which are slightly easier to read, and (more usefully) can be done inline for maximum compactness.

*  I ate a biscuit[] and felt refreshed. {alter(health, 2)}

* I gave a biscuit to Monsieur Fogg[] and he wolfed it down most undecorously. {alter(foggs_health, 1)}

-  <> Then we continued on our way.

Wrapping up simple operations in function can also provide a simple place to put debugging information, if required.

Constants

Global Constants

Interactive stories often rely on state machines, tracking what stage some higher level process has reached. There are lots of ways to do this, but the most conveninent is to use constants.

Sometimes, it's convenient to define constants to be strings, so you can print them out, for gameplay or debugging purposes.

CONST HASTINGS = "Hastings"

CONST POIROT = "Poirot"

CONST JAPP = "Japp"

 

VAR current_chief_suspect = HASTINGS

 

=== review_evidence ===

   { found_japps_bloodied_glove:

          ~ current_chief_suspect = POIROT

   }

   Current Suspect: {current_chief_suspect}

Sometimes giving them values is useful:

CONST PI = 3.14

CONST VALUE_OF_TEN_POUND_NOTE = 10

And sometimes the numbers are useful in other ways:

CONST LOBBY = 1

CONST STAIRCASE = 2

CONST HALLWAY = 3

 

CONST HELD_BY_AGENT = -1

 

VAR secret_agent_location = LOBBY

VAR suitcase_location = HALLWAY

 

=== report_progress ===

{ secret_agent_location == suitcase_location:

   The secret agent grabs the suitcase!

   ~ suitcase_location = HELD_BY_AGENT 

       

- secret_agent_location < suitcase_location:

   The secret agent moves forward.

   ~ secret_agent_location++

}

Constants are simply a way to allow you to give story states easy-to-understand names.

Advanced: Game-side logic

There are two core ways to provide game hooks in the ink engine. External function declarations in ink allow you to directly call C# functions in the game, and variable observers are callbacks that are fired in the game when ink variables are modified. Both of these are described in Running your ink.

Part 4: Advanced Flow Control

Tunnels

The default structure for ink stories is a "flat" tree of choices, branching and joining back together, perhaps looping, but with the story always being "at a certain place".

But this flat structure makes certain things difficult: for example, imagine a game in which the following interaction can happen:

=== crossing_the_date_line ===

*  "Monsieur!"[] I declared with sudden horror. "I have just realised. We have crossed the international date line!"

-  Monsieur Fogg barely lifted an eyebrow. "I have adjusted for it."

*  I mopped the sweat from my brow[]. A relief!

* I nodded, becalmed[]. Of course he had!

* I cursed, under my breath[]. Once again, I had been belittled!

...but it can happen at several different places in the story. We don't want to have to write copies of the content for each different place, but when the content is finished it needs to know where to return to. We can do this using parameters:

=== crossing_the_date_line(-> return_to) ===

...

-  -> return_to

 

...

 

=== outside_honolulu ===

We arrived at the large island of Honolulu.

- (postscript)

   -> crossing_the_date_line(-> done)

- (done)

   -> END

 

...

 

=== outside_pitcairn_island ===

The boat sailed along the water towards the tiny island.

- (postscript)

   -> crossing_the_date_line(-> done)

- (done)

   -> END

Both of these locations now call and execute the same segment of storyflow, but once finished they return to where they need to go next.

But what if the section of story being called is more complex - what if it spreads across several knots? Using the above, we'd have to keep passing the 'return-to' parameter from knot to knot, to ensure we always knew where to return.

So instead, ink integrates this into the language with a new kind of divert, that functions rather like a subroutine, and is called a 'tunnel'.

Tunnels run sub-stories

The tunnel syntax looks like a divert, with another divert on the end:

-> crossing_the_date_line ->

This means "do the crossing_the_date_line story, then continue from here".

Inside the tunnel itself, the syntax is simplified from the parameterised example: all we do is end the tunnel using the ->-> statement which means, essentially, "go on".

=== crossing_the_date_line ===

// this is a tunnel!

...

- ->->

Note that tunnel knots aren't declared as such, so the compiler won't check that tunnels really do end in ->-> statements, except at run-time. So you will need to write carefully to ensure that all the flows into a tunnel really do come out again.

Tunnels can also be chained together, or finish on a normal divert:

...

// this runs the tunnel, then diverts to 'done'

-> crossing_the_date_line -> done

...

 

...

//this runs one tunnel, then another, then diverts to 'done'

-> crossing_the_date_line -> check_foggs_health -> done

...

Tunnels can be nested, so the following is valid:

=== plains ===

= night_time

   The dark grass is soft under your feet.

   +  [Sleep]

          -> sleep_here -> wake_here -> day_time

= day_time

   It is time to move on.

       

=== wake_here ===

   You wake as the sun rises.

   +  [Eat something]

          -> eat_something ->

   +  [Make a move]

   -  ->->

 

=== sleep_here ===

   You lie down and try to close your eyes.

   -> monster_attacks ->

   Then it is time to sleep.

   -> dream ->

   ->->

... and so on.


Поделиться с друзьями:

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.03 с.