If chooses what happens next
Imagine the player has 30 health. Your game can show a different message when health is low or reaches zero. Each condition is a Boolean question. SMILE takes the first true branch, then continues after End If.
Dim Health As Number
Health = 30
If Health <= 0 Then
Print "Game over"
Else If Health < 10 Then
Print "Find a potion"
Else
Print "Ready for adventure"
End If
The order matters. A health value of zero is also below ten; checking zero first makes the game-over rule win. Else If and Else are optional, but every multiline If needs End If.
Select Case matches one value to several choices
Use Select Case when you are comparing the same value with a menu of alternatives. This example chooses an action from text already stored in Choice; it does not ask the player to type.
Dim Choice As Text
Choice = "Attack"
Select Case Choice
Case "Attack"
Print "You swing your sword."
Case "Defend"
Print "You raise your shield."
Case Else
Print "Choose Attack or Defend."
End Select
A matching branch runs without falling through into the next one. Case Else catches values with no listed match. The selector and case values must have matching types. Enums work well here once your game's states have names.
For repeats a known number of times
A For loop counts through whole Number values. Both endpoints are included. The first loop below prints 1, 2, 3; the second prints 3, 2, 1.
Dim Turn As Number
For Turn = 1 To 3
Print Turn
End For
For Turn = 3 Down To 1
Print Turn
End For
Use To to count upward by one and Down To to count downward by one. For an array of three elements, count from 0 To 2. Exit For leaves the nearest active For loop early.
Do repeats until you are finished
A Do ... Loop Until loop checks its stopping condition at the bottom. That means its body runs at least once. This small countdown prints 3, 2, 1.
Dim Countdown As Number
Countdown = 3
Do
Print Countdown
Countdown = Countdown - 1
Loop Until Countdown = 0
Sometimes the loop must check a rule before taking another turn. Put an If and Exit Do near the top. This version starts at 30 health, takes damage in chunks of ten, and stops before taking another turn at zero:
Dim Health As Number
Health = 30
Do
If Health <= 0 Then
Exit Do
End If
Health = Max(0, Health - 10)
Print "Health: "; Health
Loop
Use Do, Loop, Loop Until, and Exit Do in SMILE 2.0. A While ... End While block or Do While is not part of this documented language surface. Also, old BASIC console Input, data-list Data, and Read statements are not implemented. Keyboard game input is covered below.
A loop needs a way to finish or keep the game responsive. Forgetting to update a stopping value can make the same instructions run forever. In a graphical game, input, updating, drawing, and Show Screen belong together in the main loop.
Give a group of instructions a name
A Sub performs an action. A Function calculates and returns a value. Parameters are named inputs; arguments are the values supplied in a call.
Dim Score As Number
Dim Reward As Number
Score = 10
Call GiveBonus(Score)
Reward = PointsFor(3)
Print Score
Print Reward
Sub GiveBonus(ByRef Total As Number, Optional Amount As Number = 5)
Total = Total + Amount
End Sub
Function PointsFor(TurnNumber As Number) As Number
Dim Result As Number
Result = TurnNumber * 10
Return Result
End Function
GiveBonus uses ByRef, so Total refers to the caller's actual Score variable. The call adds five points to Score. PointsFor(3) returns 30. Storing that result in Reward makes it available for printing, adding to a score, or inspecting in the debugger.
| Feature | Meaning |
|---|---|
Call Name(...) | Run a Sub. |
Name(...) in an expression | Use a Function's returned value. |
Return Value | Finish a Function and send its result back. |
ByVal, or no mode written | Pass the value. For Number, Boolean, Text, Double, Enum and Type, changing the parameter does not change the caller's value. |
ByRef | Pass a writable location of exactly the declared type. A literal such as 10 cannot be a ByRef destination. |
Routine-local Dim | A variable visible from its declaration through the end of that routine. |
A Function declares its result type using As. For a calculated return value, this guide follows SMILE's formatting convention: calculate into a named local variable, then return that variable. Keeping the steps separate makes the value easy to inspect.
Optional and named arguments make calls readable
An Optional parameter supplies a default when the caller leaves it out. A named argument uses the parameter's name followed by :=.
Call Announce(65)
Call Announce(Caption:="Round score", Value:=65)
Sub Announce(Value As Number, Optional Caption As Text = "Score")
Print Caption + ": "; Value
End Sub
The first call prints Score: 65; the second prints Round score: 65. In the second call, the names explain each argument even though the order differs from the declaration.
- Put all required parameters before optional parameters.
- Give each optional parameter an explicit type and a compile-time default.
- Optional parameters are ByVal; they cannot be ByRef.
- If you mix positional and named arguments, put positional arguments first.
- Supply a parameter at most once. Named arguments belong to user routines and member routines; built-in functions use positional arguments.
- Explicit arguments are evaluated once, in the order written in the call.
Class values have shared-reference behavior even with ByVal. Learn that distinction in Types and Classes before passing objects around.
A game reads keys one frame at a time
Get Key Key puts a queued key event into a Number variable. Key_Held(KEY_RIGHT) asks whether Right is currently held. Use events for a one-time action such as accepting a menu choice; use held state for continuous movement.
This is a fragment for inside a Game Window loop, with Key and PlayerX declared as Number. The Star Collector lesson provides the complete runnable game around it.
Get Key Key
If Key = KEY_ESCAPE Then
Exit Do
End If
If Key_Held(KEY_RIGHT) Then
PlayerX = PlayerX + 4
End If
Movement of four pixels per loop is fine for understanding the rule. A larger game should use elapsed time so speed does not depend on frame rate. Escape exits the loop; the program can then release resources and finish.
Try all the rules together
Download the complete turns example. Compile it as a single source, as shown on the start page. It demonstrates If, Select Case, both counting directions, Exit Do, a Function, ByRef, optional parameters, and named arguments.
Check the expected output
Ready for adventure
You swing your sword.
Round score: 65
Health: 20
Health: 10
Health: 0
Countdown: 3
Countdown: 2
Countdown: 1Your mission: a bigger bonus
Change the default bonus from 5 to 20 by supplying a named argument at the call site. Keep the Sub's default unchanged. Predict the final score.
Reveal one solution
Call GiveBonus(Total:=Score, Amount:=20)The three turn rewards are 10 + 20 + 30 = 60. This call adds 20, so the announced score becomes 80.