Win3x.Org

Windows & DOS Community

Postez vos petits programmes en QBasic

Règles du forum

Pour tout sujet impliquant un système d'exploitation daté de 2000 à nos jours, merci de le publier dans la section intitulée « Informatique moderne ».

Répondre   Page 3 sur 5  [ 44 messages ]
Aller sur la page « 1 2 3 4 5 »
Auteur Message
Pierreblinux
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 08 juil. 2009 00:35
 
 
tu fais un truc aléatoire et l'ordi se trompe genre il arrive trop tard :mrgreen:


Haut
Citer
Dr Frankenstein
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 08 juil. 2009 01:45
Membre d'honneur
Hors-ligne
 
Messages : 418
Inscription : 28 oct. 2004 01:31
 
Citation :
Bon, alors, comment afficher des textes dans la form? Car moi je croyais que c'était "Form1.DebugPrint"...
DebugPrint c'est pas à être utilisé sauf en débogage ;) ça le dit, pourtant. Et je crois pas que cette fonction-là soit dans Form de toute façon.

Normalement tu devrais créer des objets Label (si le nom a pas changé avec le temps) tout comme les Button et autres contrôles.

_________________

Introducing Windows 95.
It lets you use more than eight characters to name your files. Imagine that. ~Apple.


Haut
Profil Citer
gm86
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 08 juil. 2009 18:52
Membre inscrit
Avatar de l’utilisateur
Hors-ligne
 
Messages : 628
Inscription : 01 sept. 2008 19:07
 
@0597534
La technique de de dessiner une image, puis de l'effacer avant d'afficher la suivante, a ses limites.
C'est elle qui provoque ce clignotement.
Le mieux est de stocker les deux raquettes et la balle dans trois tableaux différents, avant de démarrer la boucle DO...LOOP.
Il existe pour cela l'instruction graphique GET qui stocke des images rectangulaires dans des tableaux :
GET (x1,y1)-(x2,y2), nom du tableau avec (x1,y1) et (x2,y2) deux coins opposées de l'image
Par exemple,
GET (linex - 5, liney - 40)-(linex + 5, liney + 40), raquette1
GET (linex2 - 5, liney2 - 40)-(linex2 + 5, liney2 + 40), raquette2
GET (x-17,y-17)-(x+17,y+17), balle
Mais avant, ne pas oublier de déclarer les tableaux au début du programme. Pour calculer leurs dimensions, QuickBasic propose une formule, sinon il y a plus simple en mode 16 couleurs :
DIM tableau(longueur * largeur / 2) AS INTEGER
Par exemple,
DIM raquette1(446) AS INTEGER
DIM raquette2(446) AS INTEGER
DIM balle(613) AS INTEGER

Maintenant que les images sont en mémoire, on peut les restituer dans la boucle DO...LOOP grâce à l'instruction PUT:
PUT (x, y) , tableau, action (par défaut XOR, celle qui permet l'animation sur un fond en arrière-plan) avec x et y les coordonnées du coin supérieur gauche de l'image à afficher
Par exemple,
PUT (5, 4), balle
Attention ! Une telle animation est relativement plus rapide que recréer des figures géométriques à chaque fois. Surtout, les deux lignes fixes haute et basse doivent être dessinées avant la boucle ; elles feront alors parties du fond.

Dernière modification par gm86 le 31 mai 2010 10:55, modifié 4 fois.

_________________

C:\ONGRTLNS.W95


Haut
Profil Citer
0597534
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 09 juil. 2009 00:37
 
 
Merci gm86 pour tes précieuses informations! par contre, comment fait-on, questions clavier et commandes, pour que les palettes se déplacent mieux, c-a-d avec plus de fluidité, moins saccadé quand une touche est enfoncé et que ca ne prenne pas 4-5 secondes pour bouger?


Haut
Citer
gm86
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 09 juil. 2009 16:49
Membre inscrit
Avatar de l’utilisateur
Hors-ligne
 
Messages : 628
Inscription : 01 sept. 2008 19:07
 
Avant de répondre à la question, je voudrais préciser que les lignes PUT sont à écrire avant de définir les nouvelles coordonnées puis après. On efface ainsi le dessin précédent à chaque nouveau tracé.
S'agissant de la gestion des touches, voilà un exemple qui utilise les flèches du clavier :
'On définit la vitesse de déplacement.
deplace% = 5
'on affiche un dessin
...
'on enregistre ce dessin en prenant deux coins diagonalement opposés du rectangle capable
GET (dessinx1, dessiny1) - (dessinx2, dessiny2), dessin


DO
  touche$ = INKEY$                'dernière touche frappée
  'le déplacement débute
  FOR i = 1 to  deplace%
    PUT (X, Y), dessin            'on efface le dessin précédent
    SELECT CASE touche$
      CASE CHR$(27)               'touche Echap
        END                       'quitter
      CASE CHR$(0) + CHR$(72)     'touche Haut
        Y = Y - 1
      CASE CHR$(0) + CHR$(80)     'touche Bas
        Y = Y + 1
      CASE CHR$(0) + CHR$(75)     'touche Gauche
        X = X - 1
      CASE CHR$(0) + CHR$(77)     'touche Droite
        X = X + 1
    END SELECT
    PUT (X, Y), dessin            'on affiche le dessin aux nouvelles coordonnées
  NEXT i
  'le déplacement est fini
LOOP

'Ici, il faut, bien sûr, veiller à ce que le dessin ne déborde pas de l'écran.
On déplace le dessin d'une ligne ou colonne à la fois, question de fluidité.
Malheureusement, cet exemple n'est pas optimisé, puisqu'on teste le cas autant de fois que ce que vaut la variable deplace%.
De plus, si celle-ci est grande, on remarquera facilement un problème de mouvement. En laissant appuyé son doigt plus d'une seconde avant de l'enlever, le dessin n'arrêtera pas de suite son mouvement.

P.S. : Pour avoir une image synchronisée avec l'écran, on peut ajouter cette ligne avant celle qui efface le dessin :
WAIT &H3DA, 8
Si elle est très efficace, voire indispensable, l'attente qu'elle provoque peut aggraver le problème cité plus haut.

Le taux de répétition du clavier influe sur la vitesse d'animation. Par défaut, le BIOS la définit à 20 pour un clavier AT et à 21 pour un clavier PS2. Sous Windows, ce paramètre est diminué, ce qui est mieux pour un jeu de ce type, moins bien, par contre, pour naviguer dans un éditeur de texte. Le délai de répétition aussi est diminué, ce qui n'est pas un mal. Dans le cas d'un clavier pour PC/XT, ces deux valeurs sont fixes, tant pis pour le délai.
Pour paramétrer le clavier sous DOS, taper :
MODE CON: RATE=16 DELAY=1

________________
Ajout du 23/07

KEY résoud le problème du taux de répétion. Reste celui du délai de répétition. Voici un exemple légèrement inspiré de PC Warrior :
SCREEN 7
COLOR , 11

'pour un rendu fluide
deplace% = 4            'valeur minimale
'vitesse de l'animation
pas% = 2
'coordonnées d'origine
X = 1
Y = 1
'tableau où est stocké le dessin
DIM dessin(200) AS INTEGER


'Mise en place de l'interception des touches fléchées du clavier numérique
FOR n = 11 TO 14
  KEY(n) ON
NEXT n
ON KEY(11) GOSUB haut
ON KEY(12) GOSUB gauche
ON KEY(13) GOSUB droite
ON KEY(14) GOSUB bas

FOR i = 1 TO 20
  FOR j = 1 TO 20
    READ couleur
    PSET (j, i), couleur
  NEXT j
NEXT i
GET (1, 1)-(20, 20), dessin

'dessiner: ne doit pas être une sous-routine sinon débordement de pile
dessiner:
FOR i = 1 TO deplace%
  'Désactivons la fonction KEY pendant l'effacement et l'affichage
  FOR n = 11 TO 14
    KEY(n) STOP
  NEXT n
  WAIT &H3DA, 8
  PUT (X, Y), dessin           'on efface le dessin précédent
  X = X + changeX%: Y = Y + changeY%
  PUT (X, Y), dessin           'on affiche le dessin aux nouvelles coordonnées
  'Il faudrait, bien sûr, veiller à ce que le dessin ne déborde pas de l'écran.
  FOR n = 11 TO 14
    KEY(n) ON
  NEXT n
NEXT i
DO: LOOP

haut:
      changeX% = 0: changeY% = -pas%
      RETURN dessiner
bas:
      changeX% = 0: changeY% = pas%
      RETURN dessiner
gauche:
      changeX% = -pas%: changeY% = 0
      RETURN dessiner
droite:
      changeX% = pas%: changeY% = 0
      RETURN dessiner

'dessin
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,10,10,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,10,02,02,10,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,02,02,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,04,04,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,03,03,03,03,00,00,00,00,00,00,00,00
DATA 00,00,00,00,07,07,07,03,03,03,03,03,03,03,03,03,00,00,00,00
DATA 00,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,03,03,03,00
DATA 15,15,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,13
DATA 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
DATA 00,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,00
DATA 00,00,00,00,15,15,15,15,15,15,15,15,15,15,15,15,00,00,00,00
DATA 00,00,00,00,00,00,00,00,15,15,15,15,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,15,15,00,00,00,00,00,00,00,00,00

----
Publié : Samedi 25 Juillet 2009 16:02:02

Voilà une animation rapide d'un sprite sur fond étoilé.
Le fond est bleu foncé, les l'étoiles d'arrière plan sont toutes blanches.
L'action par défaut XOR de l'instruction PUT permet de créer très facilement des animations, il suffit de l'appeler pour tracer un dessin ou l'effacer.
Son inconvénient est qu'elle laisse voir « par transparence » des points tracés antérieurement sous le sprite.
Voyons comment on peut faire avec l'action OR. Les points d'arrière-plan ne retrouvent pas leur couleur d'origine lorsqu'on efface le sprite. Il faut donc sauver l'arrière-plan avant de dessiner, puis tout bonnement le restituer.
De plus, il faut utiliser des attributs de couleurs non modifiables par l'action OR. Ainsi, la couleur blanche des étoiles, notée 15, est affecté à l'attribut 1. En effet, x or 1 = x, si x est impair ; tandis que x or 15 = 15 avec x < 16. Il est donc conseillé d'utiliser des attributs impairs pour le sprite.

On aurait pu aussi effacer l'arrière-plan avant de dessiner le sprite.
Le problème est que ce dernier tient dans un rectangle plus grand que lui. Or, il n'est pas réaliste qu'une étoile s'éteigne simplement parce qu'elle se trouve dans ce rectangle.

Il existe une méthode qui résoudrait tous les problèmes précédents. On pourrait vérifier quand les étoiles d'arrière-plan se trouvent dans une zone vide du rectangle. Cependant, l'animation deviendrait trop lente.
'OVNI sur ciel étoilé avec animation de type PUT(x,y), tableau, OR


'== D E B U T ==
SCREEN 7
'on affecte le blanc brillant des étoiles à l'attribut 1...
PALETTE 1, 15   '...car 1 OR x = x avec x impair
'on affecte à l'attribut impair 15 la couleur 8 
PALETTE 15, 8   'car 1 OR 8 = 9 alors que 1 OR 15 = 15
'****
'2(vert) OR 1 = 3(cyan) mais un point cyan sur un dessin vert ne se voit pas,
'idem pour les couleurs 4 et 10.
'Pas de réaffectation d'attributs pour ces trois couleurs
'****
COLOR , 1       'fond du ciel crépusculaire
RANDOMIZE TIMER

's'assurer un rendu fluide
deplace% = 4            'valeur minimale
'vitesse de l'animation
pas% = 2
'coordonnées d'origine
X = 1
Y = 1
'tableau où est stocké le dessin
DIM dessin(200) AS INTEGER
DIM sousdessin(200) AS INTEGER

'Mise en place de l'interception des touches fléchées du clavier numérique
FOR n = 11 TO 14
  KEY(n) ON
NEXT n
ON KEY(11) GOSUB haut
ON KEY(12) GOSUB gauche
ON KEY(13) GOSUB droite
ON KEY(14) GOSUB bas



'== F O N D ==
'ciel étoilé
FOR i = 1 TO 200
  PRESET (320 * RND, 200 * RND), 1
NEXT i
'sauvegarde de l'arrière-plan
GET (X, Y)-(X + 19, Y + 19), sousdessin
'on crée le dessin
FOR i = 1 TO 20
  FOR j = 1 TO 20
    READ couleur
    PSET (j, i), couleur
  NEXT j
NEXT i
'on enregistre le dessin
GET (1, 1)-(20, 20), dessin



'== B O U C L E ==
'"dessiner:" ne doit pas être une sous-routine sinon débordement de pile
dessiner:
FOR i = 1 TO deplace%
  'Désactivons la fonction KEY pendant l'effacement et l'affichage
  FOR n = 11 TO 14
    KEY(n) STOP
  NEXT n
  'synchroniser l'effacement avec le balayage d'écran
  WAIT &H3DA, 8
  'puisque une opération OR ne permet pas une animation comme XOR,
  'on restitue l'arrière-plan préalablement sauvé en guise d'effacement
  PUT (X, Y), sousdessin, PSET
  X = X + changeX%: Y = Y + changeY%
  'on sauve l'arrière-plan avant d'afficher, à cause de l'opération OR
  GET (X, Y)-(X + 19, Y + 19), sousdessin
  'on affiche le dessin aux nouvelles coordonnées
  PUT (X, Y), dessin, OR
  'Il faudrait, bien sûr, veiller à ce que le dessin ne déborde pas de l'écran.
  FOR n = 11 TO 14
    KEY(n) ON
  NEXT n
NEXT i
DO
IF INKEY$ = CHR$(27) THEN SCREEN 0: WIDTH 80: END
LOOP



'== R O U T I N E S ==
haut:
      changeX% = 0: changeY% = -pas%
      RETURN dessiner
bas:
      changeX% = 0: changeY% = pas%
      RETURN dessiner
gauche:
      changeX% = -pas%: changeY% = 0
      RETURN dessiner
droite:
      changeX% = pas%: changeY% = 0
      RETURN dessiner



'== D O N N E E S ==
'dessin avec des attributs impairs de préférence
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,10,10,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,10,02,02,10,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,02,02,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,04,04,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,03,03,03,03,00,00,00,00,00,00,00,00
DATA 00,00,00,00,07,07,07,03,03,03,03,03,03,03,03,03,00,00,00,00
DATA 00,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,03,03,03,00
DATA 15,15,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,13
DATA 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
DATA 00,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,00
DATA 00,00,00,00,15,15,15,15,15,15,15,15,15,15,15,15,00,00,00,00
DATA 00,00,00,00,00,00,00,00,15,15,15,15,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,15,15,00,00,00,00,00,00,00,00,00
Il reste un problème à résoudre : la suppression du délai de répétition du clavier.


Un dernier conseil.
Pour revenir à PONG qui est un jeu en N & B, le mode 2 (CGA 640x200) suffit.

Dernière modification par gm86 le 06 sept. 2010 12:26, modifié 7 fois.

_________________

C:\ONGRTLNS.W95


Haut
Profil Citer
Dr Frankenstein
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 17 déc. 2009 02:44
Membre d'honneur
Hors-ligne
 
Messages : 418
Inscription : 28 oct. 2004 01:31
 
Ta version de Windows est trop récente pour l'archaïque VB6 ? ;p

_________________

Introducing Windows 95.
It lets you use more than eight characters to name your files. Imagine that. ~Apple.


Haut
Profil Citer
Galley-La Compagnie
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 17 déc. 2009 07:37
Membre d'honneur
Avatar de l’utilisateur
Hors-ligne
 
Messages : 609
Inscription : 19 juin 2009 17:30
 
VB 6 ne marche quasiment pas sous Vista.
(Une stratégie de la part de MS pour faire migrer les utilisateurs de VB 6 a VB.NET)

_________________

[ img ]


Haut
Profil Citer
Dr Frankenstein
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 18 déc. 2009 01:15
Membre d'honneur
Hors-ligne
 
Messages : 418
Inscription : 28 oct. 2004 01:31
 
smb2_fan a écrit :
[...](Une stratégie de la part de MS pour faire migrer les utilisateurs de VB 6 a VB.NET)
Je suis pas d'accord avec ça mais c'est mon avis...

_________________

Introducing Windows 95.
It lets you use more than eight characters to name your files. Imagine that. ~Apple.


Haut
Profil Citer
Galley-La Compagnie
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 18 déc. 2009 07:43
Membre d'honneur
Avatar de l’utilisateur
Hors-ligne
 
Messages : 609
Inscription : 19 juin 2009 17:30
 
J'avais lu un article comme quoi MS voulait migrer tous les utilisateurs de VB en VB.NET après chacun son avis :D

_________________

[ img ]


Haut
Profil Citer
gm86
Sujet du message : Re: Postez vos petits programmes pour DOS en QBasic
Publié : 19 janv. 2010 17:34
Membre inscrit
Avatar de l’utilisateur
Hors-ligne
 
Messages : 628
Inscription : 01 sept. 2008 19:07
 
MisterWario a écrit :
J'avais une petite question :
Je sais qu'il est possible d'une façon ou d'une autre de récuperer le chemin d'accès de l'application QBASIC depuis une interruptions ou un autre truc.
Mais comment ont fait ? (curdir$ ne donne que le répertoire actif et non pas celle de l'executable)
Je ne sais pas si j'avais mal compris la question à ce moment-là : faut-il retrouver le chemin du fichier *.BAS lancé par QBasic ?
Si oui, il y a une solution à condition que le programme soit appelé par QBasic depuis la ligne de commande.
Lorsqu'on demande à QBasic de lancer un programme .BAS, il le recherche selon ce qui est indiqué dans les paramètres de ligne de commande. Ainsi,
C>QBASIC D:\BAS\JEUX\MARIO
lui indique le chemin complet.
En revanche, avec
C>QBASIC D:MARIO
il suppose que le fichier est dans le répertoire courant du lecteur D, ou avec
C>QBASIC MARIO
qu'il est dans le répertoire courant du lecteur C, ou encore avec
C>QBASIC ..\MARIO
qu'il est dans le répertoire parent à celui en cours dans le lecteur C, ou enfin avec
C>QBASIC \MARIO
qu'il est dans le répertoire racine du lecteur C.
Il faudrait donc obtenir les paramètres de ligne de commande de QBasic pour que le programme sache où il est.
Ces paramètres demeurent dans la zone DTA. Celle-ci débute à l'adesse 80h du PSP.
On peut situer la DTA grâce à l'assembleur :
mov ah,2Fh
int 21H
qui renvoie directement son adresse dans ES:BX.
Ensuite, le plus dur reste à faire.


----
Publié : Mardi 16 Février 2010 20:09:32

J'espère que 0597534 lira ce message.
Un jour il nous demanda conseil car il trouvait son jeu PONG trop saccadé.
Le clignotement des raquettes fut aisément déterminé.
Le contrôle fluide du clavier pas tout à fait.
De mon côté, j'ai fait une petite animation pour l'aider : diriger un sprite sur tout l'écran grâce aux touches fléchées du pavé numérique.

Dans un premier temps, j'ai proposé la gestion par INKEY$. Cette instruction lisait les caractères ASCII du tampon clavier après chaque affichage du sprite. L'inconvénient du tampon est justement de garder des caractères non traités ce qui provoque un décalage avec l'action clavier. Ce phénomène est amplifiée par la fréquence de répétition du clavier.
Dans un second temps, l'usage de KEY m'eut l'air plus fiable. Cette instruction surveille régulièrement les codes clavier (scancode). BASIC propose d'office quatre configurations de KEY qui interceptent la pression des touches fléchées du clavier numérique. Or, il faut surveiller une touche même pressée en permanence. Cela indusait quelques petits sauts dans le mouvement du sprite. Le délai de répétition du clavier influait aussi sur les changements de direction.
Un jour, j'ai eu l'occasion de lire dans "le guide du programmeur pour PC & PS/2" que le clavier envoie un code pour la pression d'une touche et un autre pour son relâchement. Le premier correspond au scancode de la touche, le second à ce même code mais majoré de 80h (128 en décimal).
J'ai donc décidé d'utiliser ce fait avec KEY.

Voici la logique principale de mon programme d'exemple :
- initialiser le mode graphique et l'affichage ;
- mettre en place l'interception de la pression et de la remontée des touche fléchées du pavé numérique :
  - si une touche est interceptée, on enclenche une routine :
    * modifier le vecteur du mouvement en conséquence ;
    * revenir ;
  - si la touche est relâchée, une autre routine se met en route :
    * annuler le mouvement qu'il lui est attribué entre autres ;
    * revenir ;
- créer une boucle d'affichage : 
  * lire les coordonnées X et Y du vecteur du mouvement ;
  * modifier la position du sprite en conséquence ;
  * recommencer s'il n'y a pas la séquence de sortie dans le tampon du clavier ;
- revenir en mode texte.
Attention ! KEY ne cherche pas un scancode seul. Il veille aussi l'état des touches spéciales.
Les valeurs 15 à 25 de KEY sont disponibles pour l'utilisateur. Par exemple :
KEY, 15, CHR$(drapeau clavier) + CHR$(code clavier)
avec les valeurs suivantes pour chaque drapeau clavier :
&H80  étendu
&H40  verrouillage majuscule
&H20  pavé numérique
&H08  Alt
&H04  Ctrl
&H03  Une des touches Maj
&H02  idem
&H01  idem
ces valeurs pouvant se combiner en s'ajoutant (verr.maj. + verr.num. donnent &H60).
Il faut donc désactiver le verrouillage majuscule et le pavé numérique.
Pour cela on manipule l'octet en mémoire 0040:0017 ou 0000:0417.
Il est fait ainsi :
bits ! drapeau
-----!-------------
7    ! Insert 
6    ! Verr.maj.
5    ! Verr.num.
4    ! Arrêt défil.
3    ! Alt
2    ! Ctrl
1    ! Maj gauche
0    ! Maj droite
Pour éviter de déranger l'utilisateur, il serait bon, une fois le programme terminé, de restituer les drapeaux d'origine. On ne sauve que les 4 bits de poids fort et met ceux de poids faible à zéro :
    xxxxxxxx
and 11110000b (F0h) 
------------
=   xxxx0000
Ensuite, on peut effectuer la modification :
    xxxxxxxx                   xxxxxxxx
and 10011111b (9Fh)   ou   and 10010000b (90h)
------------               ------------
=   x00xxxxx               =   x00x0000
Voyons le programme.
Ce n'est qu'un exemple, mais sa programmation n'a pas nécessité d'astuce pour garder un mouvement fluide contrairement à celle des précédents. Ainsi, plus besoin de variable deplace% qui répéte plusieurs fois un même mouvement pour le rendre linéaire, le sprite est synchrone avec le clavier. Mieux encore, cette technique fonctionne parfaitement dans les autres modes graphiques.
' OVNI sur ciel étoilé animé par opération XOR
' et commandé avec les touches fléchées du pavé numérique.
'
ON ERROR GOTO traiterr
' =====================
' ===== D E B U T =====
' =====================
SCREEN 7        ' EGA 320 x 200, 4 bits (16 attributs parmi 16 couleurs).
COLOR , 1       ' Fond du ciel crépusculaire.
OPTION BASE 1   ' Les tableaux commencent à 1 au lieu de 0.
RANDOMIZE TIMER ' On initialise la liste des nombres pseudo-aléatoires grâce
                ' à l'horloge.


' -----------------------------------------------
' Sauvegarde de l'état clavier avant modification
' -----------------------------------------------
' On manipule la mémoire à partie du segment 0000h.
DEF SEG = 0
' N'enregistre pas l'état d'une éventuelle touche Crtl, Alt ou Maj enfoncée
' en annulant le poids faible (bits 4 à 0).
' Utile surtout si le programme est lancé depuis QuickBasic avec Maj+F5.
drapeaux% = PEEK(&H417) AND &HF0
' Désactive le pavé numérique et le verrouillage majuscule après sauvegarde
' en mettant les bits 7 et 6 à zéro.
POKE &H417, drapeaux% AND &H9F  ' Ou &H90 puisque poids faible mis à jour
                                ' automatiquement par le clavier.
' On restitue absolument le segment BASIC par défaut.
DEF SEG


' ---------------------------------
' On modifie la palette de couleurs
' ---------------------------------
' Couleur des étoiles.
PALETTE 1, 15           ' car  x XOR 1 = x + 1   si x pair
                        ' et   x XOR 1 = x - 1   si x impair
' Regroupements par 2 des attributs en vue d'une opération XOR avec l'attribut
' 1 précédent.
' Attributs sur 16      Couleurs sur 16
' 2 & 3                 2
' 4 & 5                 10
' 6 & 7                 4
' 8 & 9                 5
' 10 & 11               6
' 12 & 13               7
' 14 & 15               8
FOR attribut% = 2 TO 15
  PALETTE attribut%, INT(attribut% / 2 + 1)
NEXT attribut%
PALETTE 4, 10
PALETTE 5, 10


' -------------------------------------
' Initialisation de certains paramètres
' -------------------------------------
touche$ = ""
' Vitesse de l'animation.
pas% = 1        ' 1 : pixel par pixel.
' Coordonnées d'origine.
X = 1
Y = 1
' Tableau où est stocké le dessin.
DIM dessin(122) AS INTEGER      ' équivaudrait à DIM dessin(121) AS INTEGER
                                ' si OPTION BASE avait été laissé à 0
' Les modes EGA affichent 16 couleurs donc 4 bits par pixels.
' Or, en mode 16 couleurs, les carte EGA et VGA utilisent 4 espaces mémoires
' pour pouvoir communiquer avec un segment (64 Ko) à l'emplacement A000h de
' la mémoire de base. On les appelle les plans. Il y a donc 1 bit par plan
' pour chaque pixel.
'   4 + INT((largeur * bit par pixel par plan + 7) / 8 + hauteur * plan
' = 4 + INT((20 * 1 + 7) / 8 + 20 * 4
' = 244 octets
' soit un tableau de 122 entiers.



' --------------------
' Construction du fond
' --------------------
' Ciel étoilé.
FOR i% = 1 TO 400
  PRESET (320 * RND, 200 * RND), 1
NEXT i%


'------------------
' Création du dessin
'------------------
FOR i = 1 TO 20
  FOR j = 1 TO 20
    READ couleur%
    PSET (j, i), couleur%
  NEXT j
NEXT i
' On enregistre le dessin.
GET (1, 1)-(20, 20), dessin


' -------------------------------------------------------------------
' Mise en place de l'interception de la remontée des touches fléchées
' -------------------------------------------------------------------
' CHR$(0) signifie pavé numérique et verrouillage majuscule déscativés.
' + CHR$(&H80 + scancode) : code de relachement d'une touche.
KEY 15, CHR$(&H0) + CHR$(&HC8)  ' &HC8 = &H80 + &H48, haut
KEY 16, CHR$(&H0) + CHR$(&HCB)  ' &HCB = &H80 + &H4B, gauche
KEY 17, CHR$(&H0) + CHR$(&HCD)  ' &HCD = &H80 + &H4D, droite
KEY 18, CHR$(&H0) + CHR$(&HD0)  ' &HD0 = &H80 + &H50, bas
ON KEY(11) GOSUB haut
ON KEY(12) GOSUB gauche
ON KEY(13) GOSUB droite
ON KEY(14) GOSUB bas
ON KEY(15) GOSUB hautfin
ON KEY(16) GOSUB gauchefin
ON KEY(17) GOSUB droitefin
ON KEY(18) GOSUB basfin
' Surveillance des touches fléchées.
FOR n% = 11 TO 18
  KEY(n%) ON
NEXT n%




' =======================
' ===== B O U C L E =====
' =======================
' La boucle principale est celle qui gère l'affichage.
WHILE touche$ <> CHR$(27)
  ' --------------------------------------------------
  ' Synchroniser l'effacement avec le balayage d'écran
  ' --------------------------------------------------
  WAIT &H3DA, 8
  PUT (X, Y), dessin    ' XOR est une opération réversible.
 
  '---------------------------------------------
  ' Afficher le dessin aux nouvelles coordonnées
  '---------------------------------------------
  X = X + changeX%: Y = Y + changeY%
  PUT (X, Y), dessin
  ' Erreur si le dessin déborde de l'écran.
  
  ' -----------------
  ' Tester si quitter
  ' -----------------
  touche$ = INKEY$
WEND


traiterr:       ' On ne s'embête pas !
' =========================
' ===== Q U I T T E R =====
' =========================
SCREEN 0: WIDTH 80
' Restaure l'état du clavier.
DEF SEG = 0
POKE &H417, drapeaux%
DEF SEG
ON ERROR GOTO 0 ' Si une erreur est en cours de traitement à ce moment-là
                ' et que le programme est exécuté sous QuickBasic,
                ' arrêt et affichage d'un message d'erreur.
END




' ===========================
' ===== R O U T I N E S =====
' ===========================
' L'instruction RETURN seule permet de revenir une éventuelle routine appelée
' avant qui ne s'était pas encore terminée.
haut:
	' changeX% = 0          ' supprimer commentaire pour annuler diagonale
	changeY% = -pas%
	RETURN
gauche:
	changeX% = -pas%
	' changeY% = 0          ' supprimer commentaire pour annuler diagonale
	RETURN
droite:
	changeX% = pas%
	' changeY% = 0          ' supprimer commentaire pour annuler diagonale
	RETURN
bas:
	' changeX% = 0          ' supprimer commentaire pour annuler diagonale
	changeY% = pas%
	RETURN
hautfin:
	IF changeY% < 0 THEN changeY% = 0
	RETURN
gauchefin:
	IF changeX% < 0 THEN changeX% = 0
	RETURN
droitefin:
	IF changeX% > 0 THEN changeX% = 0
	RETURN
basfin:
	IF changeY% > 0 THEN changeY% = 0
	RETURN
    


' =========================
' ===== D O N N E E S =====
' =========================
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,02,02,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,04,04,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,04,02,02,04,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,02,02,02,02,02,02,02,02,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,02,02,06,06,02,02,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,02,02,00,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,02,02,02,02,00,00,00,00,00,00,00,00
DATA 00,00,00,00,02,02,02,02,02,02,02,02,02,02,02,02,00,00,00,00
DATA 00,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,00
DATA 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
DATA 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14
DATA 00,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,00
DATA 00,00,00,00,14,14,14,14,14,14,14,14,14,14,14,14,00,00,00,00
DATA 00,00,00,00,00,00,00,00,14,14,14,14,00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00,00,14,14,00,00,00,00,00,00,00,00,00
Pour permettre une animation XOR, la couleur blanche des astres est représentée par l'attribut 1 et les attributs suivants sont regroupés deux par deux.

NOTA : les scancodes des touches relâchées ne sont pas supportés par toutes les anciennes versions de BASIC, comme Olivetti GW-BASIC 3.20 par ex.

P.S. : Dans "Le Macmillan le PC", trois listes de scancodes sont présentées. Il fournit aussi le vocabulaire à employer : code Make pour la pression d'une touche, code Break pour son relâchement.

Dernière modification par gm86 le 17 mars 2010 11:35, modifié 1 fois.

_________________

C:\ONGRTLNS.W95


Haut
Profil Citer
Afficher : Trier par : Ordre :
Répondre   Page 3 sur 5  [ 44 messages ]
Revenir à « Informatique des vieux systèmes » | Aller sur la page « 1 2 3 4 5 »
Aller :