Ce document fait partie du projet PV16SOG et est fourni sous licence CC-NC-SA-BY V3.0
auteur: Jacques Deschênes
révision 1.0
Copyright: 2015,2016, Jacques Deschênes
L'ordinateur PV16SOG possède un interpréteur BASIC inspiré de QBASIC. Le code source BASIC est d'abord compilé en bytecode pour être exécuté sur une machine virtuelle à piles. Ce document décris ce langage BASIC et son utilisation.
PV16SOG BASIC est insensible à casse tous les mots réservés et indentificateurs de variables sont convertis en majuscules par le compilateur.
les éléments de syntaxe indiqués entre '[' et ']' sont des éléments optionnels. si le caractère '+' suit le caractère ']' l'élément peut-être répété un nombre abritraire de fois.
le caractère '|' sépare les alternatives
Dans les examples le > au début d'une ligne représente l'invite de la ligne de commande.
expr signifit une expression arithmétique.
expr_list liste d'expression numérique. Les éléments sont séparés par la virgule ','.
cond signifit une condition logique résultant de la comparaison de 2 expr.
log_expr signigit un ensemble de cond reliées par les opérateurs logiques AND et OR.
arg_list est la liste des arguments passés à une sous-routine ou fonction. La virgule ',' est le séparateur de liste.
val_list est une liste de valeur numérique ou chaîne servant à initialiser un tableau lors de sa déclaration.
var représente un nom de variable.
num représente un nombre entier.
const représente une constante numérique.
block groupe d'instructions BASIC.
Cette table montre les opérateurs par ordre de précédence. À précédence égale les opérateurs sont traités de gauche à droite.
opérateur | description |
---|---|
() | Parenthèse de groupement d'expression. Le groupement entre parenthèses est réservé aux expression arithmétiques. Les cond et les log_expr ne peuvent pas être regroupées. |
func() | Les fonctions ont la plus haute priorité dans les expression arithmétiques. |
* / % | multiplication, division entière, modulo |
+ - | addition soustraction |
= >= < <= <> >< | les opérateurs de comparaison utilisés dans les cond |
NOT | négation logique appliquée au résultat d'une cond |
AND | conjonction logique appliqué entre les cond |
OR | alternative logique appliqué entre les cond |
Les noms de variables sont insensibles à la casse. Tous les noms sont convertis en majuscules par le compilateur. Un nom peut avoir un maximum de 31 caractères, doit commencer par une lettre mais peut contenir des chiffres et le caractère '_'. Si le nom de la variable se termine par le caractère '$' il s'agit d'une variable chaîne. Si le nom se termine par le caractère '#' il s'agit d'une variable octet {0-255}. Autrement il s'agit d'une variable de type entier 16 bits dans l'interval de valeurs {-32768 - 32767}. Les tableaux peuvent-être de ces 3 types de données et ne peuvent avoir qu'une seule dimension.
Les variables chaîne sont en fait des constantes, une fois une valeur assignée à une telle variable celle-ci ne peut-être changée sauf en utilisant un truc de programmation avancé.
Les valeurs litérales numérique peuvent-être saisie sous 3 formes:
Les chaînes de caractères sont saisies entre guillemets '"'. Un caractère ASCII est saisie en le précédent de la barre oblique '\'
example:
>print "Hello world"
Hello world
>putc \a
a
>|
Les paramètres des fonctions et sous-routines sont passées par valeur sauf si le nom de la variable est précédé du caractère '@'. Dans ce cas le paramètre doit-être le nom d'une variable qui est passée par référence.
example:
sprite(10,10,8,8,@lem#,@rest#) ' lem# est le nom d'une variable taleau qui contient un sprite.
' ce tableau doit-être passé par référence.
' rest# sauvegarde le fond d'écran couvert par le sprite.
La valeur de retour d'une fonction peut-être ignorée. Si la fonction est appellée comme une commande la valeur de retour est simplement jetée.
example:
>b=-5
>? abs(3*b)
15
>|
index BASIC
example:
if hour>=12 and hour<=17 then print "afternoon" end if
REM si la varialbe hour a une valeur entre 12 et 17 imprime le mot afternoon.
index BASIC
example:
BEEP(440,1000,1)
REM génère une tonalitée de 440Hertz pour une durée de 1 seconde. Suspend l'exécution.
index BASIC
example:
BOX(10,20,100,50,7)
REM boite dont le coin supérieur gauche est à la position {10,20} de largeur 100 pixels,
REM hauteur de 50 pixels avec un ton de gris de 7.
index BASIC
example:
if btest(v1,0) then print "nombre impair" end if
REM si le bit zéro est à 1 il s'agit d'un nombre impair.
if btest(v2,15) then print "nombre negatif" end if
REM si le bit 15 est à 1 il s'agit d'un nombre négatif.
index BASIC
example:
if key()='q' then BYE end if
REM termine l'exécution si la touche 'Q' est enfoncée.
index BASIC
example:
circle(100,100,45,7) 'dessine un cercle de rayon 45 pixels centré sur {100,100}
index BASIC
example:
CLS 7
REM la nouvelle couleur de fond sera 7 et tous les pixels auront cette couleur après cette commande.
index BASIC
example:
COLOR(15,0)
REM caractère blanc sur fond noir.
example:
CONST age=30, salaire=32000, nom$="Capitaine Bonhomme"
REM défini 3 constantes dans la même déclaration.
index BASIC
example:
if curcol()=38 then locate(curline()+1,0) end if
index BASIC
example:
if curline()=20 and curcol()=39 then scrlup(8): locate(curline(),0) end if
index BASIC
example:
DIM v1=34, v2#=234 ' la variable entier 16 bits v1 prend la valeur 34
' la variable octet v2 prend la valeur 234
DIM t1(4)=(1,2,3,4) ' le tableau t1 contient 4 éléments qui sont initialisées.
DIM msg$(3)=("nom","prenom","age") ' tableau de 3 chaînes initialisé.
index BASIC
example:
>i=0 : DO ? i : i=i+1 LOOP UNTIL i=5
0
1
2
3
4
>i=9 : DO ? i : i=i-1 : LOOP WHILE i
9
8
7
6
5
4
3
2
1
index BASIC
example:
ellipse(120,85,120,85,15) ' dessine une ellipse centrée sur {120,85} de largeur 120 et hauteur 85
index BASIC
example:
FOR i=0 TO 10 STEP 2
print i
next i
REM affiche les nombres pairs de 0 à 10
index BASIC
example:
REM cette fonction calcule la factorielle d'un entier
REM méthode récursive
FUNC fact(n)
if n<1 then 1/0 end if ' nombre < 1 génère une exception
if n=1 then return 1 end if
return n*fact(n-1)
END FUNC
REM même fonction mais en utilisant une boucle FOR
FUNC fact(n)
LOCAL f,i
f=1
for i=2 to n
f=f*i
next i
return f
END FUNC
example:
? GETPIXEL(10,20) ' affiche la couleur du pixel à la coordonnée {10,20]
index BASIC
example:
IF btest(4,0) then
? "nombre impair"
ELSE
? "nombre pair"
END IF
REM va imprimé nombre pair
index BASIC
example:
INPUT "Entrez votre prenom et votre age", nom$, age
'ceci apparaît à l'écran:
Entrez votre prenom et votre age
prenom? Arthur
age? 40
>? nom$, age
Arthur 40
index BASIC
contact | valeur |
---|---|
bouton | 1 |
levier vers la droite | 2 |
levier vers la gauche | 4 |
levier vers le bas | 8 |
levier vers le haut | 16 |
example:
select case jstick()
case 1
bye
case 2
? "droite"
case 4
? "gauche"
case 8
? "bas"
case 16
? "haut"
case 18
? "haut et droite"
case else
? "etc"
end select
index BASIC
example:
CASE SELECT key()
case \q 'quitte le programme
bye
case \e ' efface l'écran
cls
case \h ' salutation
print "hello\n" ' \n à l'intérieur d'une chaîne pour imposer un retour à la ligne.
end SELECT
REM j'ai mélanger intentionnellement les mots réservés entre majuscules et minuscules
REM pour montrer que la casse n'a pas d'importance.
index BASIC
example:
>nom$="Arthur Roy"
>? len(nom$)
10
>? len("hello world")
11
>|
index BASIC
example:
LET a=34*5
a=34*5 REM c'est la même chose
REM ça peut aussi être une variable tableau
DIM tab(4)
tab(1)=-1234 ' le premier élément du tableau vaut maintenenat -1234
index BASIC
example:
line(0,0,100,100,15)
index BASIC
example:
LOCATE(10,0) ' le curseur texte est maintenant au début de la 11ième ligne.
index BASIC
example:
>? max(56,30)
56
>|
index BASIC
> ? 32540*8/33
-54 'mauvaise réponse à cause du débordement de la multiplication.
>? mdiv(3540,8,33)
7888 'bonne réponse car le résultat de la multiplication est conservé sur 32 bits.
>REM multiplication d'un nombre par une approximation rationnelle de PI
>? mdiv(5400,355,113)
16964 'erreur < 0,5
index BASIC
example:
>? min(34,-5)
-5
>|
index BASIC
example:
>noise(100) 'produit le bruit d'une chute d'eau durant 0,1 seconde.
index BASIC
example:
if not 3>4 then ? "3 n'est pas plus grand que 4" end if
3 n'est pas plus grand que 4
index BASIC
example:
while 1
if key() or jstick()=1 then bye end if
wend
REM sort de la boucle si une touche ou le bouton du joystik
REM est enfoncé.
index BASIC
example:
>pause(1000) REM l'invite de commande var réapparaître après 1 seconde.
index BASIC
example:
>DIM a=34, msg$="hello world"
>print a, msg$, "bonjour"
34 hello world bonjour
>|
index BASIC
example:
>putc \a : putc 98
ab
>
index BASIC
example:
'colore l'écran avec des pixels au hasard
dim x,y,c
RANDOMIZE()
while not key()
x=abs(rnd())%240
y=abs(rnd())%170
c=abs(rnd())%16
setpixel(x,y,c)
wend
index BASIC
RECT(10,10,20,60,7) ' position {10,10}, largeur 20, hauteur 60, couleur 7
index BASIC
example:
REM ce commentaire se termine a la fin de ligne.
' l'apostrophe peut remplacé le mot REM.
index BASIC
example:
'affiche un sprite
sprite(10,20,16,16,@spr#,@rest#) 'après cette commande rest# va contenir les bits écrans écrasés par le sprite.
'supprime le sprite de l'écran.
remspr(10,20,16,16,@rest#) ' après cet appel le sprite est disparu de l'écran.
index BASIC
example:
srload "moonscape.scr"
restscr(6) ' en supposant que les données écran débute à l'adresse 6 du fichier.
index BASIC
example:
>while not key() : ? rnd() : wend
REM imprime sans arrêt une série de nombre aléatoire.
REM il faut enfoncer une touche du clavier pour arrêter l'exécution.
index BASIC
example:
SAVESCR(0) 'sauvegarde le contenu de l'écran au début de la mémoire SPI RAM.
box(100,120,40,50,5) ' dessine un rectangle plein
RESTSCR(0) ' après la restauration le rectangle est disparu.
index BASIC
example:
> scrlup(8) ' défilement vers le haut de la hauteur d'un caractère.
index BASIC
example:
> scrldn(8) ' défilement vers le bas de la hauteur d'un caractère.
index BASIC
example:
> scrlrt(6) ' défilement vers la droite de la largeur d'un caractère.
index BASIC
example:
> scrllt(6) ' défilement vers la gauche de la largeur d'un caractère.
index BASIC
example:
select case jstick()
case 1 ' bouton du joystick enfoncé
bye
case 2 ' levier à droite
move_right()
case 4 ' levier vers la gauche
move_left()
case 8 ' levier vers le bas
move_down()
case 16 ' levier vers le haut
move_up()
end select
REM contrôle du mouvement d'un sprite à l'écran à l'aide du joystick
index BASIC
example:
setpixel(10,20,4) ' le pixel à la postion {10,20} prend la valeur 4
index BASIC
example:
DIM count
settmr(100) ' minuterie initialisée à 100 millisecondes.
while not timeout()
rem combien de WHILE par seconde?
count=count+1
wend
print "boucle WHILE par seconde: ",10*count
index BASIC
example:
>? shl(4)
8
>|
index BASIC
example:
>? shr(-9)
-5
> REM pensiez-vous que ça donnait -4 ?
>|
index BASIC
example:
dim rest#(8),cross#(8)=($0f,$f0,$ff,$ff,$ff,$ff,$0f,$f0) 'petite croix de 4x4 pixels
' affiche le sprite
sprite(56,24,4,4,@cross#,@rest#)
' supprime le sprite
remspr(56,24,4,4,@rest#)
La couleur noire (0) est une couleur transparente pour les sprites. C'est à dire que les pixels d'un sprite qui ont
cette couleur ne sont pas appliqués à l'affichage.
dim rest#(32)
while 1
sprite(x,y,8,8,@spr#,@rest#) ' affiche un sprite de 8x8 pixels
pause(20) ' pause de 20 millisecondes, cette valeur n'est pas critique.
remspr(x,y,8,8,@rest#) 'efface le sprite
' ici on peut mettre du code pour gérer les collisions
'...
select case jstick() 'lecture du joystick et déplacement dans la direction indiquée.
case 1 ' bouton enfoncé
cls
bye
case 16 'vers le haut
if y>0 then y=y-1 end if
case 8 'vers le bas
if y<170-8 then y=y+1 end if
case 2 'vers la droite
if x<240-8 then x=x+1 end if
case 4 ' vers la gauche
if x>0 then x=x-1 end if
' on peut ajouter des CASE pour gérer les 4 directions diagonales.
'...
end select
wend
index BASIC
example:
srclear(1000) ' efface les 1000 premiers octets de la mémoire SPI RAM.
index BASIC
example:
size=srload "test.spr" ' charge le fichier test.spr et retourne sa grandeur dans size.
index BASIC
example:
DIM i, spr#(32)
srread(0,@i,2) ' lit un entier et le met dans la variable i.
srread(4,@spr#,32) ' lit un bloc de 32 octets à partir de l'adresse 4 dans le tableau spr#
example:
srsave "test.dat", 1024 ' sauvegarde 1024 octets dans le fichier test.dat
index BASIC
example:
DIM i, spr#(32)
srwrite(0,@i,2) ' écrit l'entier i dans la SPI RAM à l'adresse 0.
srwrite(4,@spr#,32) ' écris un bloc de 32 octets à l'adresse 4 à partir du tableau spr#
index BASIC
example:
sub box_madness() ' dessine des boites au hasard
local x,y,w,h,c
while not key() ' arrête lorsqu'une touche est enfoncée.
x=abs(rnd())%240
y=abs(rnd())%170
w=abs(rnd())%240
h=abs(rnd())%170
c=abs(rnd())%16
box(x,y,w,h,c)
wend
end sub
index BASIC
example:
REM utilisation du compteur interne pour mesurer un interval de temps.
t0=ticks()
for i=0 to 10000
next i
? "temps écoulé pour 10000 itération FOR ", ticks()-t0
index BASIC
example:
settmr(1000)
while not timeout()
? "pas encore expiree"
wend
index BASIC
example:
REM ce programme joue les 5 premières notes
REM du thème musical du film rencontre du 3ième type.
dim ce3k#(10)=(13,200,15,200,11,200,1,200,6,200)
for i=1 to ubound(ce3k#) step 2
tone(ce3k#(i)+12,3*ce3k#(i+1),1)
next i
index BASIC
example:
REM activation conditionnelle de trace
for i=1 to 100
if (i=50) then trace(1) end if
? i
next i
REM information qui vont apparaître
REM à l'écran de traçage lors de l'activation
28
R:2
1 : 31726
' 28 est le dernier opcode exécuté et correspond à l'intruction LIT
' R:2 signifit qu'il y a 2 éléments sur la pile rstack
' 1 : 31726 signifit qu'il y a 1 élément sur la pile des arguments
' 31726 est la valeur de cet argument. Il s'agit d'un pointeur
' sur la variable i qui va être imprimé par l'instrution
' suivante.
index BASIC
example:
>dim vector(100)
>? ubound(vector)
100
>|
index BASIC
example:
use "joystick.inc" ' fichier définissant des constantes pour le joystick
use "lem.spr" ' fichier définissant un sprite appellé LEM.
' code du programme principal
.
.
.
index BASIC
example:
sub test(n)
local t0
cls
if n then 'rapide
t0=ticks()
video(0)
box(0,0,240,170,4)
video(1)
? ticks()-t0, "msec"
else 'lent
t0=ticks()
box(0,0,240,170,4)
? ticks()-t0, "msec"
end if
end sub
> test(0)
55 msec
> test(1)
32 msec
index BASIC
example:
>putc waitkey()
r
>|
REM l'utilisateur a enfoncé la touche 'r'
index BASIC
example:
dim i=0
while i<100
? i
i=i+1
wend
0
1
2
...
99
index BASIC
example:
xorpixel(10,20,4) ' si la valeur de ce pixel était 6 après cette opération elle sera 2.
index BASIC
Ce premier example est une implémentation du jeux de la vie du mathématicien John H. Conway. En dépit de son nom il ne s'agit pas d'un jeux mais d'une simulation d'automate cellulaire à 2 dimensions. Au démarrage un curseur en forme de croix apparaît au centre de l'écran. Il s'agit de créer une configuraton de départ. On déplace le curseur à l'aide des flèches du clavier. La touche C ajoute une cellule à la position du curseur et la touche ESPACE supprime une cellule existante. Pour démarrer la simulation on utilise la touche ENTER. On regarde évoluer cet univers d'automates cellulaires d'une génération à l'autre. Le nombre de générations est affiché dans le coin inférieur gauche. Même si ce BASIC ne permet que la définition de tableaux à 1 seule dimension ce programme simule un tableau d'octets à 3 dimensions g#(1368) qui est la grille univers dans lequel évoluent les automates cellulaires.
Vous pouvez vous représenter cette grille comme une feuille de papier quadrillé dont certains carrés seraient noircis. Ces carrés noircis représenteraient les cellules vivantes. Pour chaque carré de la feuille on compte le nombre de cellules vivantes qui l'entoure et on applique les règles suivantes:
Ces règles sont très simples et pourtant elles donnent lieu à une évolution qui peut-être très complexe dépendant de la configuration de départ.
rem John H. Conway's game of life
rem simulation automate cellulaire 2D
dim rest#(24) ' pour restaurer le fond d'ecran
dim cursor#(24)=(
$00,$70,$00,
$00,$70,$00,
$00,$70,$00,
$77,$77,$70,
$00,$70,$00,
$00,$70,$00,
$00,$70,$00,
$00,$00,$00)
const width=38 ' dimension horizontale de grille
const height=18 ' dimension verticale de la grille
const cell=127 ' caractère utilisé pour représenter les cellules
const empty=32 ' caractère position grille vide
const k_up=141 ' valeur touche flèche vers le haut
const k_down=142 ' valeur touche flèche vers le bas
const k_left=143 ' valeur touche flèche vers la gauche
const k_right=144 ' valeur touche flèche vers la droite
const odd=684 ' déplacement grille génération impaire
dim g#(1368) 'grille univers
gen=0 'compteur de génération
src=0 ' déplacement grille source
des=odd 'déplacement grille destination
' sous-routine d'effacement de la grille
sub clear_grid()
local i
for i=1 to ubound(g#)
g#(i)=empty
next i
end sub
' sous-routine d'affichage de la grille
sub display_grid()
local x,y
for x=1 to 38
for y=1 to 18
locate(y,x)
putc g#((y-1)*width+x+src)
next y
next x
locate(20,0)
print gen ;
end sub
' initialisation de la grille
' avec le modèle de départ.
sub set_grid()
local k,x,y
x=width/2+1
y=height/2+1
cls
locate(21,0)
? "<SPACE>,<C>,<ENTER>";
gen=0
src=0
des=odd
k=0
clear_grid()
while k<>13
locate(0,0)
? "x:",x," y:",y," ";
locate(y,x)
putc g#((y-1)*width+x)
sprite(x*6,y*8,6,8,@cursor#,@rest#)
while not k : k= key() : wend
remspr(x*6,y*8,6,8,@rest#)
select case k
case k_up
if y>1 then y=y-1 end if
case k_down
if y<height then y=y+1 end if
case k_left
if x>1 then x=x-1 end if
case k_right
if x<38 then x=x+1 end if
case 32
g#(width*(y-1)+x)=empty
case 67,99
g#((y-1)*width+x)=cell
end select
if k<>13 then k=0 end if
wend
cls
? "<ESC> quit, 'r' new grid";
end sub
' compte le voisinage d'une cellule
func countn(x,y)
local n,x0,y0,ofs
n=0
for x0=max(x-1,1) to min(38,x+1)
for y0=max(y-1,1) to min(18,y+1)
if x0<>x or y0<>y then
ofs=(y0-1)*width+x0+src
if g#(ofs)=cell then
n=n+1
end if
end if
next y0
next x0
return n
end func
' calcule les valeurs de la prochaine
' génération.
sub next_gen()
local n,x,y,ofs
for x=1 to 38
for y=1 to 18
n=countn(x,y)
ofs=(y-1)*width+x
select case n
case 2
g#(ofs+des)=g#(ofs+src)
case 3
g#(ofs+des)=cell
case else ' 0,1,4,5,6,7,8
g#(ofs+des)=empty
end select
next y
next x
gen=gen+1
src=odd-src
des=odd-des
end sub
' boucle principal
' du programme
set_grid()
r=1
while r
display_grid()
next_gen()
select case key()
case 27
r=0
case \r,\R
set_grid()
end select
wend
cls
début
spred.bas, (sprite editor) est un éditeur de figurine pour les jeux vidéo. On peut définir des sprites directement en BASIC comme montré dans l'example précédent avec le cursor mais ce n'est pas très commode. Cet éditeur simple permet de les créer et de les sauvegarder sous forme de fichier binaire.
Au démarrage le programme demande le nom du fichier sous lequel le sprite doit-être sauvegarder ou le nom d'un fichier existant
qui peut-être chargé pour modification. Ensuite les dimensions du sprite sont demandées. width est la largeur en pixels et
height la hauteur. La grandeur maximale est de 32x32 pixels. Une fois ces informations saisies un rectangle apparaît au centre de l'écran avec un x qui représente
le curseur. Ce rectangle est la zone d'édition zoommée 4X. En haut à gauche apparait les coordonnées du curseur et sous les coordonnées apparaît
la représentation taille réelle du sprite.
Les commandes sont entièrement au clavier.
Il s'agit donc d'un programme très simple. On ne peut éditer qu'un seul sprite par session. Cette limitation est du au fait que ce BASIC considère les chaînes de caractères comme des constantes donc la valeur de name$ ne peut-être modifiée une fois initialisée par la commande INPUT en début de programme. Pour éditer un autre sprite il faut sortir du programme et le relancer avec la commande run spred.bas. Cette limitation peut-être contournée, je vous laisse ce problème à titre d'exercice pratique.
REM editeur de sprite
' nom, largeur, hauteur, couleur pixel
dim name$, w, h, c=0
' tableau contenant le sprite
dim spr#(512) ' contient le sprite à dessiner
dim rest#(8) ' données de restauration fond ecran pour curseur
' sprite curseur
dim c#(8)=($f0,$0f,
$0f,$f0,
$0f,$f0,
$f0,$0f)
' x offset, y offset, x, y
dim xo,yo,x,y
const psize=4 'dimension pixel zoomé
const xres=240 'résolution écran horizontale
const yres=170 ' résolution écran verticale
cls
' saisie des paramètres
input "sprite name", name$
input "sprite width", w
input "sprite height", h
'dessine le rectangle d'édition
sub draw_bounds()
cls
xo=(xres-psize*w)/2
yo=(yres-psize*h)/2
rect(xo-1,yo-1,psize*w+2,psize*h+2,7)
x=w/2
y=h/2
end sub
'affiche les coordonnées {x,y} du curseur
sub prtxy()
locate(0,0)
print "x:",x," y:",y ;
end sub
'sauvegarde du sprite
'dans un fichier binaire
sub save_sprite()
srwrite(0,@w,2)
srwrite(2,@h,2)
srwrite(4,@spr#,w*h/2)
srsave name$,w*h/2+4
locate(19,0)
? name$ ,"saved"
? w,"x",h,"pixels";
end sub
'dessine le sprite
'dans le rectangle d'édition
sub fill_canevas()
local i,x,y,c
for x=0 to w-1
for y=0 to h-1
i=(y*w+x)/2+1
if btest(x,0) then
c=spr#(i)%16
else
c=spr#(i)/16
end if
box(xo+x*psize,yo+y*psize,psize,
psize,c)
setpixel(10+x,10+y,c)
next y
next x
end sub
'charge un fichier binaire
'sprite
sub load_sprite()
local size
size=srload name$
if size then
srread(0,@w,2)
srread(2,@h,2)
srread(4,@spr#,size-4)
draw_bounds()
fill_canevas()
locate(19,0)
? name$, "loaded"
? "width",w,"height",h ;
else
locate(19,0)
? "load failed";
end if
end sub
'assigne la couleur du pixel
'{x,y} dans le tableau
sub let_pixel(x,y,c)
local idx
idx=(y*w+x)/2+1
if btest(x,0) then 'impair
spr#(idx)=spr#(idx)/16*16+c
else ' pair
spr#(idx)=spr#(idx)%16+c*16
end if
end sub
draw_bounds()
' boucle principale du programme
while 1
prtxy()
sprite(xo+x*psize,yo+y*psize,psize,
psize,@c#,@rest#)
pause(20)
remspr(xo+x*psize,yo+y*psize,psize,
psize,@rest#)
k=key()
if k>=\a then k=k-32 end if
select case k
' sélection couleur 0-9
case \0,\1,\2,\3,\4,\5,\6,\7,\8,\9
c=k-\0
' sélection couleur A-F
case \A,\B,\C,\D,\E,\F
c=k-\A+10
case 32 ' ESPACE = colore le pixel
box(xo+x*psize,yo+y*psize,psize,
psize,c)
setpixel(10+x,10+y,c)
let_pixel(x,y,c)
case 141 ' déplacement vers le haut
if y>0 then y=y-1 end if
case 142 ' déplacement vers le bas
if y<h-1 then y=y+1 end if
case 143 ' déplacement vers la gauche
if x>0 then x=x-1 end if
case 144 ' déplacement vers la droite
if x<h-1 then x=x+1 end if
case 27 ' ESC = quit
cls
bye
case \S ' sauvegarde sprite
save_sprite()
case \L ' charge sprite
load_sprite()
end select
wend
début
Ce démo montre comment utiliser le joystick pour déplacer un sprite à l'écran. Il utilise la directive USE pour inclure 2 fichiers. joystick.inc contient la définitions des constantes pour faciliter l'utilisation du joystick. lem.spr contient le code basic pour un sprite appelé LEM (Lunar Expedition Module).
rem fichier: joystick.inc
rem constantes pour le joystick
const button=1
const up=16
const down=8
const right=2
const left=4
const upleft=20
const upright=18
const downleft=12
const downright=10
rem fichier: lem.spr
rem définition d'un sprite appellé LEM
rem Lunar Expedition Module
' sprite LEM
dim lem#(128)=(
$00,$00,$00,$ff,$ff,$00,$00,$00,
$00,$00,$0f,$f0,$0f,$f0,$00,$00,
$00,$0f,$ff,$ff,$ff,$ff,$f0,$00,
$00,$ff,$ff,$ff,$ff,$ff,$ff,$00,
$00,$f0,$00,$00,$00,$00,$0f,$00,
$f0,$f0,$ff,$ff,$ff,$ff,$0f,$0f,
$0f,$f0,$ff,$00,$00,$ff,$0f,$f0,
$00,$f0,$ff,$00,$00,$ff,$0f,$00,
$0f,$f0,$ff,$ff,$ff,$ff,$0f,$f0,
$f0,$f0,$00,$00,$00,$00,$0f,$0f,
$00,$ff,$ff,$ff,$ff,$ff,$ff,$00,
$00,$ff,$ff,$ff,$ff,$ff,$ff,$00,
$00,$0f,$00,$f0,$f0,$00,$f0,$00,
$00,$f0,$0f,$00,$0f,$00,$0f,$00,
$0f,$f0,$00,$00,$00,$00,$0f,$f0,
$ff,$00,$00,$00,$00,$00,$00,$ff
)
REM fichier: jstick.bas
REM ce démo montre comment
REM utiliser le joystick pour
rem déplacer un sprite à l'écran
use "lem.spr"
use "joystick.inc"
cls
dim rest#(128) ' pour restauration fond écran.
dim x=112,y=77 'position du sprite
'déplacement vers la gauche
sub move_left()
if x>0 then x=x-1 end if
end sub
'déplacement vers la droite
sub move_right()
if x<224 then x=x+1 end if
end sub
'déplacement vers le haut
sub move_up()
if y>0 then y=y-1 end if
end sub
'déplacement vers le bas
sub move_down()
if y&tl;154 then y=y+1 end if
end sub
'boucle principale du programme
while 1
sprite(x,y,16,16,@lem#,@rest#)
pause(20)
remspr(x,y,16,16,@rest#)
select case jstick()
case UP
move_up()
case DOWN
move_down()
case RIGHT
move_right()
case LEFT
move_left()
case UPRIGHT
move_up()
move_right()
case UPLEFT
move_up()
move_left()
case DOWNRIGHT
move_down()
move_right()
case DOWNLEFT
move_down()
move_left()
case BUTTON 'termine démo
cls
bye
end select
wend