Les raccourcis d'écriture
Écrire moins : comment les commandes sont nommées, les blocs WITH sur les objets du moteur, la notation par point, l'interpolation $"…" et les graphies PureBasic que le compilateur accepte.
En un mot#
L'identifiant d'un sprite est le premier argument de chaque commande de
sprite, et son nom figure dans chaque nom de commande. Les raccourcis de cette
page suppriment cette répétition. Aucun n'est une nouvelle API : le
compilateur réécrit chacun en BASIC ordinaire (appels du catalogue,
concaténations avec Str(), FUNCTION, TYPE) avant de compiler le
programme.
| Raccourci | Vous écrivez | Le compilateur voit |
|---|---|---|
WITH <famille> | \position 100, 200 | SpritePosition(s, 100, 200) |
| notation par point | s.position(100, 200) | SpritePosition(s, 100, 200) |
| interpolation | $"score: {points}" | ("score: " + Str(points)) |
| mots PureBasic | Procedure … EndProcedure | FUNCTION … ENDFUNCTION |
Comment les commandes sont nommées#
Les deux raccourcis de bloc reconstruisent des noms de commande ; ils reposent donc sur une règle.
L'objet d'abord, la propriété ensuite, ni
SetniGet.SpritePosition,SpriteX,MusicVolume,CameraPosition.
| Sorte de commande | Graphie | Exemple |
|---|---|---|
| une propriété qu'on écrit | <Objet><Propriété>(id, valeur…) | SpritePosition(s, 10, 20) |
| une propriété qu'on lit | <Objet><Propriété>(id) | SpriteWidth(s) |
| les deux, sous un seul nom | le nombre d'arguments tranche | SpriteX(s) lit, SpriteX(s, 10) écrit |
| quelque chose naît ou disparaît | le verbe reste en tête | CreateSprite, LoadImage, CloneSprite, DeleteSprite |
C'est la convention de PureBasic, pas celle d'AGK. AGK écrit
SetSpritePosition et GetSpriteX ; ici, ce sont deux commandes inconnues, donc
une erreur de compilation. Retirez le Set ou le Get.
Les exceptions, comptées dans le catalogue :
- Aucune commande ne commence par
Get. - 4 commandes commencent par
Set, parce que le nom nu est déjà une autre commande avec le même nombre d'arguments, que le compte ne peut donc pas départager :SetRandomSeed(à côté deRandomSeed),SetMemblockString(à côté deMemblockString, qui lit),SetCloudDataVariableetSetTerrainBiome. - 29 commandes finissent par
Set(sans compterLSetetRSet, qui complètent des chaînes). 18 sont les écritures de Text :TextPositionSet,TextStringSet,TextXSet,TextSizeSet,TextVisibleSetet treize autres, tandis queTextX,TextStringetTextSizelisent. Les onze autres sontSoundInstanceVolumeSet,SoundInstanceRateSet,MusicOggLoopCountSet,FilePositionSet,HttpHostSet,XmlNodeNameSet,XmlNodeTextSet,XmlAttributeSet,AtmosphereSet,WeatherSetetDayNightSet.
En cas de doute, la référence des commandes est engendrée depuis le catalogue et a sa propre recherche.
Les blocs WITH <famille>#
WITH <FAMILLE> <expression>
\<propriété> [<arguments>] ' en tête d'instruction : écrit
… \<propriété> … ' partout ailleurs : lit
ENDWITH ' ou END WITH
img = LoadImage("hero.png")
s = CreateSprite(img)
WITH SPRITE s
\position 100, 200 ' SpritePosition(s, 100, 200)
\size 64, 64 ' SpriteSize(s, 64, 64)
\x 50 ' SpriteX(s, 50)
x# = \x ' SpriteX(s)
\depth 5 ' SpriteDepth(s, 5)
ENDWITH
Console(Str(x#)) ' 50
La place décide du sens. En tête d'instruction, \prop écrit, et ce qui
le suit sur la ligne sont les arguments, sans parenthèses. Partout ailleurs,
\prop lit. Il n'y a pas de seconde notation à retenir.
- Le nom est reconstruit, puis cherché.
WITH SPRITEplus\positiondonneSpritePosition. Une propriété que le catalogue n'a pas est une erreur de compilation sur-le-champ :Unknown property in WITH SPRITE: \positon. - L'expression peut être quelconque :
WITH SPRITE ships[3],WITH CAMERA 1. WITH hero, en un seul mot, reste le bloc d'enregistrement décrit dans Enregistrements et méthodes. Deux mots, dont le premier est une famille, sélectionnent le catalogue.- Les lignes qui ne commencent pas par
\sont des instructions ordinaires. - Pas d'imbrication. Un
WITHdans unWITHest refusé, enregistrement ou famille.
⚠️ Une écriture ne prend pas de =. Écrivez \x 50. La ligne \x = 50
n'est pas refusée, mais le programme qu'elle produit ne démarre pas.
⚠️ Une écriture doit commencer l'instruction. Dans IF … THEN \visible 1,
le \visible n'est pas en tête : il est pris pour une lecture, et le programme
ne démarre pas. Utilisez un IF en bloc :
s = CreateSprite(0)
WITH SPRITE s
IF \visible = 0
\visible 1 ' SpriteVisible(s, 1)
ENDIF
ENDWITH
s = CreateSprite(0)
WITH SPRITE s
\positon 100, 200 ' refusé : la famille n'a pas cette propriété
ENDWITH
Quelles familles existent#
Une famille n'est pas une liste figée. Tout mot par lequel commencent des
noms de commande du catalogue est une famille : Sprite à cause de
SpriteX, Camera à cause de CameraPosition. Celles qui servent le plus :
| Famille | Quelques propriétés | Une variable la reçoit de |
|---|---|---|
SPRITE | position, x, y, size, angle, depth, visible, color | CreateSprite, LoadSprite, CloneSprite |
TEXT | lecture : x, string, size ; écriture : positionSet, stringSet, sizeSet | CreateText |
OBJECT (3D) | position, positionY, rotation | LoadObject, ou AS Object |
CAMERA | position, rotation, x | AS Camera |
PARTICLES | position, frequency, life, size | CreateParticles |
IMAGE | width, height | LoadImage |
MUSIC | volume | LoadMusic |
EDITBOX | position, text | CreateEditBox |
MEMBLOCK | size, byte, int, float | CreateMemblock |
DICTIONARY | size, has | CreateDictionary |
VIRTUALBUTTON, VIRTUALJOYSTICK | position, size | AS VirtualButton, AS VirtualJoystick |
COMPUTEBUFFER, COMPUTESHADER | size, type, buffer | CreateComputeBuffer, CreateComputeShader |
⚠️ Quelques familles sont globales, pas par objet : VideoPlaying() et
VideoWidth() ne prennent pas d'identifiant, donc une variable de vidéo n'a
rien à mettre devant le point.
Dans l'éditeur, taper \ dans un bloc WITH <famille> complète les
propriétés de cette famille.
La notation par point#
WITH supprime la répétition dans un bloc. La notation par point la supprime
partout : la famille est attachée à la variable.
<var> = Create<Famille>(…) ' ou Load<Famille>(…), Clone<Famille>(…)
<var> AS <Famille> ' quand l'identifiant vient d'ailleurs
<var>.<propriété>(<arguments>) ' un appel : écrit, ou lit avec des arguments
<var>.<propriété> = <valeur> ' une écriture, en instruction entière
… <var>.<propriété> … ' une lecture
img = LoadImage("hero.png")
s = CreateSprite(img) ' s appartient désormais à la famille Sprite
s.position(100, 200) ' SpritePosition(s, 100, 200)
s.visible = 1 ' SpriteVisible(s, 1)
s.x(s.x + 10) ' SpriteX(s, SpriteX(s) + 10)
Console(Str(s.x)) ' 110
- La famille est déduite de
Create<Famille>(,Load<Famille>(ouClone<Famille>(quand c'est tout le membre droit d'une affectation, ou prise dans une déclarationAS <Famille>. - Les lectures dans les arguments d'un appel sont réécrites aussi :
s.position(s.x + 1, s.y)devientSpritePosition(s, SpriteX(s) + 1, SpriteY(s)). - La famille suit le nom de la variable dans tout le programme, corps de
FUNCTIONcompris. - Une propriété inconnue est une erreur de compilation :
Unknown property on sprite: .positon. - Des propriétés seulement.
s.delete()est refusé : écrivezDeleteSprite(s).
| Réécrit | Laissé tel quel |
|---|---|
| une variable dont la famille est connue | une variable sans famille |
s.x, s.x(10), s.visible = 1 | un champ d'enregistrement : hero.health |
| les lectures imbriquées dans les arguments | une méthode de liste ou de dictionnaire : scores.insert(1) |
SELF.champ dans une METHOD | |
l'intérieur d'une chaîne : "sprite.png" |
⚠️ L'écriture avec = recopie son membre droit tel quel. Dans
s.angle = s.angle + 5, le s.angle de droite n'est pas réécrit, et le
sprite reçoit quelque chose qui n'est pas un nombre. Aucune erreur ne
s'affiche. Utilisez la forme d'appel, qui réécrit ses arguments :
s = CreateSprite(0)
s.angle(s.angle + 5) ' SpriteAngle(s, SpriteAngle(s) + 5)
IF s.visible = 0 THEN s.visible(1) ' la forme d'appel marche aussi sur une ligne
⚠️ L'écriture avec = doit être une instruction entière. Après le THEN
d'un IF sur une ligne, utilisez la forme d'appel, comme ci-dessus.
Quand la famille n'est pas déduite#
Certaines commandes de création portent plus que la famille dans leur nom :
CreateObjectBox, CreatePointLight. Elles ne donnent aucune famille à la
variable. Déclarez-la d'abord :
box AS Object
box = CreateObjectBox(1, 1, 1)
box.position(0, 2, 0) ' ObjectPosition(box, 0, 2, 0)
Console(Str(box.positionY)) ' ObjectPositionY(box)
⚠️ CreateObjectSphere fait pire : elle donne à la variable une mauvaise
famille (objectsphere), qui l'emporte sur AS Object. Utilisez la forme qui
prend un identifiant :
ball AS Object
ball = 1
CreateObjectSphere(ball, 1, 16, 16)
ball.position(0, 1, 0) ' ObjectPosition(ball, 0, 1, 0)
Un paramètre typé n'est pas reconnu#
' refusé : Unknown BASIC parameter type: Sprite
FUNCTION Nudge(s AS Sprite)
s.x(s.x + 1)
ENDFUNCTION
Une famille n'est pas un type de paramètre. Prenez le paramètre sans type, et déclarez sa famille à la première ligne du corps :
FUNCTION Nudge(spr)
spr AS Sprite
spr.x(spr.x + 1) ' SpriteX(spr, SpriteX(spr) + 1)
ENDFUNCTION
hero = CreateSprite(0)
Nudge(hero)L'interpolation $"…"#
$"<texte>{<expression>}<texte>…"
{{ et }} ' une accolade { et } littérale
points = 1250
name$ = "Ada"
lives = 3
Console($"{name$} a {lives} vies") ' Ada a 3 vies
Console($"vie suivante à {points + 750}") ' vie suivante à 2000
Console($"{{accolades}} et {Len(name$)}") ' {accolades} et 3
Chaque trou devient Str(expression), et la chaîne devient une
concaténation. Str rend une chaîne inchangée : un trou accepte donc un
nombre ou une chaîne.
Le
$est obligatoire, et ce n'est pas de la décoration. Beaucoup de commandes de monde prennent du JSON écrit à la main, où les accolades sont des données :
CreateTerrain("island", "{\"preset\":\"island\",\"size\":256}")
Une chaîne sans $ est laissée intacte, quoi qu'elle contienne. Le $ doit
toucher le guillemet ouvrant.
- Un trou s'arrête à la première
}. Il ne peut pas contenir de chaîne littérale : un"dans un trou termine toute la chaîne, et le compilateur signale une{non fermée. Mettez d'abord le texte dans une variable. - Un trou peut contenir un appel :
{Upper(name$)},{Str(speed#, 2)}. - Un trou vide
{}ou une{non fermée est une erreur de compilation. Une}seule, hors d'un trou, est gardée telle quelle. - ⚠️ Une variable
AS floataffiche tous les chiffres de sa valeur sur 32 bits :0.1s'affiche0.10000000149011612. Arrondissez dans le trou :{Str(f, 2)}.
n = 1
Console($"oups {n") ' refusé : Unclosed { in interpolated string
AGK, DarkBASIC et PureBasic n'ont pas d'interpolation : ils recollent avec +
et Str(). La graphie $"…" est celle de C#.
Les graphies PureBasic#
Les mots-clés sont insensibles à la casse, si bien que beaucoup de lignes
PureBasic se lisent déjà comme du BASIC : Global, If … ElseIf …
EndIf, Repeat … Until, Select … EndSelect, With … EndWith,
ForEach, NewList v.i() (voir
Tableaux, listes et dictionnaires) et le
raccourci \champ.
Les mots ci-dessous sont acceptés aussi. Chacun est un alias : il est réécrit dans la construction que le compilateur connaît déjà, donc les deux graphies se comportent toujours pareil.
| PureBasic | Équivaut à | Remarques |
|---|---|---|
Procedure nom(…) … EndProcedure | FUNCTION … ENDFUNCTION | un type de retour s'écrit AS <type> après les parenthèses |
ProcedureReturn [valeur] | EXITFUNCTION [valeur] | |
Structure Nom … EndStructure | TYPE … ENDTYPE | aussi sur une ligne : Structure Vec x y EndStructure |
Wend | ENDWHILE | |
Define, Protected | LOCAL | à utiliser dans une Procedure |
Debug(valeur) | Console(valeur) | avec parenthèses |
x.f = 1.5 | x AS float puis x = 1.5 | le suffixe de type sur une variable, voir plus bas |
Structure Vec
x AS float
y AS float
EndStructure
Procedure Twice(n AS integer) AS integer
Protected result = n * 2
ProcedureReturn result
EndProcedure
v AS Vec
v.x = 1.5
count.i = 0
While count < 3
count = count + 1
Wend
Debug(Str(Twice(count))) ' 6
Les alias ne jouent qu'en tête d'instruction. structure = 3 reste une
variable nommée structure, et Print("Procedure") affiche le mot.
Le suffixe de type#
Le premier nom.<suffixe> déclare la variable avec ce type. Ensuite, écrivez
le nom nu. Les types eux-mêmes sont décrits dans
Variables et types.
| Suffixe | Type | Suffixe | Type |
|---|---|---|---|
.b | int8 | .a | uint8 |
.w | int16 | .u, .c | uint16 |
.l, .i | int32 | .q | int64 |
.f | float32 | .d | float64 |
.s | string |
⚠️ .i fait 32 bits ici. Dans PureBasic 64 bits, il en fait 64. Utilisez
.q pour 64 bits.
Ce qui diffère de PureBasic#
| PureBasic | Dans aukimi |
|---|---|
Procedure.i Twice(n) | refusé : écrivez Procedure Twice(n) AS integer |
EndProcedure valeur | refusé : ProcedureReturn valeur, puis EndProcedure |
x.f comme champ de Structure | refusé : écrivez x AS float |
p.Point pour déclarer un enregistrement | refusé : écrivez p AS Point |
Define.i a, b | refusé : écrivez a.i = 0 et b.i = 0 |
n.i sur un paramètre | non typé : écrivez n AS integer |
EnableExplicit | OPTION EXPLICIT |
Repeat … ForEver | DO … LOOP, ou REPEAT … UNTIL |
Default dans un Select | CASE DEFAULT. Un Default nu n'est pas reconnu : il n'est pas refusé non plus, et le Select se comporte mal à l'exécution. |
Shared, Static | refusés |
; commentaire | ce n'est pas un commentaire ici : écrivez ' |
⚠️ Au niveau supérieur du programme, préférez GLOBAL à Define. Une
variable déclarée avec Define (ou LOCAL) hors de toute Procedure, puis
réaffectée, produit pour l'instant un programme qui ne démarre pas. Dans une
Procedure, Define et Protected ne posent aucun problème.
Ce qui n'est volontairement pas repris#
Deux habitudes de DarkBASIC et une fonctionnalité de PureBasic restent dehors, exprès.
Les commandes sans parenthèses. PRINT "hello", SYNC, Debug x : les
parenthèses sont ce qui distingue une commande d'une variable, et ce qui
permet au compilateur de repérer une commande mal orthographiée.
PRINT "hello" ' refusé : BASIC commands require parentheses
Les commandes en plusieurs mots. Le MAKE OBJECT CUBE 1, 10 ou le
SYNC ON de DarkBASIC ne sont pas des instructions ici. Le catalogue écrit
chaque commande en un seul mot : CreateObjectBox(1, 10, 10, 10).
MAKE OBJECT CUBE 1, 10 ' refusé : Not a BASIC statement
Macro … EndMacro. Une macro PureBasic colle du texte à l'endroit de
l'appel. C'est un préprocesseur, pas un alias de mot-clé, et une moitié de
macro ressemblerait à la vraie sans se comporter comme elle. Écrivez une
FUNCTION, ou utilisez le préprocesseur
pour le code conditionnel.
Macro Square(x) ' refusé
x * x
EndMacroLimites et pannes courantes#
SetSpritePositionetGetSpriteXn'existent pas. Retirez leSetet leGet.- Une écriture
WITHne prend pas de=, et commence son instruction. - Une écriture par point avec
=ne réécrit pas son membre droit. Utilisezs.x(s.x + 1). CreateObjectBoxet consorts ne donnent pas de famille. DéclarezAS Objectd'abord.- Une famille n'est pas un type de paramètre. Déclarez-la dans la fonction.
- Le
$contre le guillemet, sinon pas d'interpolation. Pas de chaîne littérale dans un trou. .ifait 32 bits.