Messagerie

  • Xenon3K
    Merci Manu, il faut que je trouve un peu de temps pour regarder ça.
    Xenon3K - 16/03/2024 00:03:19
  • Emmanuel
    Bonjour ATTENTION sur le site il y a des lien Néfaste.
    Emmanuel - 24/04/2024 10:24:51
  • Hydrill
    Oui et j'ai l'impression qu'il y a pas mal de faux comptes crées par des IA ces derniers temps...
    Hydrill - 30/04/2024 16:35:07
  • Xenon3K
    Les IA connaissent TGF apparement (c'est la question pour s'inscrire). D'ailleurs pour le futur du site j'aurai besoin de modérateur et de redacteurs.
    Xenon3K - 01/05/2024 10:30:19

Programmer les consoles rétro.

Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mardi 1 août 2017 à 04:40
Chapitre 11 : Cela va couper chérie !
11em chapitre à l'initiation de codage de la mégadrive en basic. Vous savez quoi ? vous avez pas mal de quoi faire un petit jeu avec tout ça ! Enfin presque.

Vous savez poser un tile à l'écran, poser un sprite, modifier les couleurs, les boucles, les conditions, la gestion de la manette de jeu ! Ils nous manque un petit truc, l'organisation du programme ! Et oué un chapitre qui va être chientôs mais indispensable.

Pour le moment, votre code est pratiquement compacté. Nous allons voir comment le décompacter pour créer des modules.  Nous allons voir les Procédures, et les Fonctions qui sont plus moins la même chose.

La même chose avec deux nom différent ?
Bon, ok. Alors une procédure c'est un morceau code qui sera appelé dans votre programme.

Regardez cette effet !


p_test
While 1
Wend

Declare Sub p_test()
Print "Hello World"
End Sub


On début avec p_test qui n'est pas une variable. Ensuite on entre dans la boucle "vide" mais peux importe.

Plus bas on a un morceau de code.

Declare Sub p_test()
...
End Sub

Cela permet de créer un bloc
quand on écrit dans exemple p_test, on va chercher la procédure du même nom pour l’exécuter et donc afficher "Hello World" à l'écran pour cette exemple.

Il y a un truc de cool avec les procédures, c'est le passage de paramètre. Regarder nous allons voir si votre megadrive sait faire une multiplication. (A vrais dire non , il doit ruser pour vous sortir un résultat d'une multiplication.)


P_Test 5,2

While 1
Wend

Declare Sub  P_Test(x As Integer,y As Integer)

Print x*y
     
End Sub


Nous avons entrée deux paramètre avec P_Test 5,2
Et enfin dans la procédure nous les avons récupéré pour afficher une multiplication. Voila vous avez appris ce que c'est qu'une procédure.

Cela peut aussi permettre de découper son programme.
Une procédure pour afficher la map
Une procédure pour afficher le joueur...

Ceci dit des fois nous aimerions récupérer le résultat de la procédure, Cela se nomme une fonction.
Regardez un peu cette fonction.

Local R As Integer
R=F_Test(5,2)
Print R
While 1
Wend

Declare Function F_Test(x As Integer,y As Integer) as integer
Return x*y     
End Function



La variable R va récupérer la fonction F_Test et passer en argument 5 et 2. (On place ici des parenthèses)
A la place de Declare Sub on déclare une Function et un end Function
Puis Return qui retourne tous simplement le résultat dans le R du début.

On affiche R et le tour est joué.

Valeur Global
Regardez ce petit programme !

Local X As Integer
X=10

Print X
F_Test
Print X

Declare Sub F_Test()
Print X
End Sub


Le premier X affiche 10. Bon ok.
Mais le deuxième 0 et le 3em affiche bien 10.
C'est normale. Nous avons déclaré X en Local. Cela ne fonctionne pas dans les  procédures et fonction.  Nous pouvons passer une variable en Global avec

Global nom_variable_ as type _de_variable.

Global X As Integer
X=10

Print X
F_Test
Print X

Declare Sub F_Test()
Print X
End Sub

Maintenant les trois Print afficherons 10 et c'est le même X pour tous. Dans la procedure/fonction, ce n'est q'une variable intermédiaire.


Les procédures et les fonctions sont super puissant donc pour découper votre programme, et regrouper en un seul endroit un morceau de code qui doit être appelé fréquemment.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mardi 1 août 2017 à 12:24
nice ça, le logiciel ide est  capable de lire des fichiers binaires comme des "datas".
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mercredi 2 août 2017 à 05:10
Chapitre  12 : Data
Nous savons faire pas mal de chose sur la mégadrive. Nous savons (de Marseille) utiliser un joystick, afficher un sprite à la position que nous voulons à l'écran, poser un Tiles, faire des boucles, des conditions, un peu utiliser les tableaux, nous allons entrer dans les DATA.

Les Data c'est le bien en basic ! C'est une suite de valeur (ou de chaîne) mise en mémoire et qui peut être appelé par le programme. Sur la mégadrive c'est tout simple des donnés qui sont codés dans la ROM. (La cartouche heins).
Nous avons déjà vu ça avec les Datalong pour mémoriser les graphismes,et  les Dataint pour mémoriser une palette de couleur, mais il existe aussi les data simple.

Première approche des Data avec Data


Premièrement pour n'importe qu'elle suite de data, il faut une étiquette pour l'identifier.
L'étiquette se compose d'un nom suivie des deux points. Notons que j'ai l'habite de débuter mes noms d'étiquettes par un E_

E_data:

Maintenant nous allons placer notre suite de data l'un après l'autre.
Nous allons débuter avec une chaîne de caractère

Data "Chat","Chien","Ours"
Data "Oiseau","Humain","Panda"

J'ai placé 6 animaux dans cette liste sur deux lignes de Data (oué nous sommes au point de vu biologique des animaux !) Chaque éléments est séparé par une virgule et comme c'est une chaîne (des lettres quoi), je place l'élément entre deux guillemets droit. "Elements". A la fin de la ligne je ne place pas de virgule ! C'est important.

Maintenant nous allons afficher à l'écran de la mégradrive les 6 noms d’animaux ! Pour cela il faut :
=> Une commande pour se brancher que l'étiquette.
=> Une commande pour lire la donnée Data
=> Une commande pour afficher à l'écran la donnée Data.

Pour se brancher sur une étiquette 'Data'  c'est la commande Restore nom de l'étiquette.
Donc dans notre exemple :

Restore E_Data
Maintenant pour lire une donnée data c'est la commande Read variable.
Dans dans notre exemple
Read N$
je place un $ aprés la variable car c'est une variable qui va mémoriser une chaîne de caractère. (Des lettres quoi)
Maintenant nous n'avons plus à afficher à l'écran la variable N$ avec print

Ce qui fait :

Restore E_Data
Read N$
Print N$

E_data:
Data "Chat","Chien","Ours"
Data "Oiseau","Humain","Panda"


Normalement si tous se passe bien, vous devez avoir =>Chat à l'écran.
Dupliquont le Read N$ et Print N$.


Restore E_Data
Read N$
Print N$
Read N$
Print N$

E_data:
Data "Chat","Chien","Ours"
Data "Oiseau","Humain","Panda"

Chat et Chien s'affiche bien.
En fait autre que le nom de l'étiquette, il y a aussi in compteur invisible. (Index), et à chaque fois que Read est utilisé, le compteur est modifié de 1 prêt à lire la prochaine donné, et avec un Restore  on re initie le compteur à 0 sur l'étiquette voulu !

Bon faire à chaque fois  Read machin c'est lourd, nous allons pour l'exemple utiliser une Boucle ! nous savons qu'il y a 6 données, nous allons donc utiliser pour cette exemple une boucle For !

Restore E_Data

For X=0 to 5
Read N$
Print N$
Next

E_data:
Data "Chat","Chien","Ours"
Data "Oiseau","Humain","Panda"

Et voila le travaille. (Notons que pour cette exemple je n'ai pas initié les variables, Le second basic ne le demande pas nativement, mais je vous conseille de la faire quand vous entrez en mode production de jeu véritablement.
Attention ou vous placez votre boucle ! C'est après le restore sinon vous allez à chaque boucle revenir au début de l'étiquette avec un index à 0. (Piège à con)

Data permet aussi de mémoriser des valeur numérique. Exemple :

Restore E_Data

For X=0 to 5
Read N
Print N
Next

E_data:
Data 52,45,6000
Data 84564,412451,754125

Cette fois si, N ne porte pas le $ car ce n'est pas une chaine.

Attention si c'est des valeurs/variable codé sur 32 bits (des longs), il faut  bien utiliser le sigle & à la fin de la variable.
n&

Datalong et Dataint
Si vous voulez (et ça sera souvent le cas) des donnée de type int ou long vous pouvez utiliser les Dataint et Datalong, cela marche pareil que les data simples. Pour lire ce type de data c'est tous simplement Readint et Readlong. Exemple avec notre suite numérique.

Restore E_Data

For X=0 to 5
Readint N
Print N
Next

E_data:
Dataint 52,45,6000
Dataint 84564,412451,754125

Note : A la place de Restore vous pouvez aussi utiliser Reload. Cela fait la même chose

C'est avec les Data que vous allez mémoriser dans la rom de votre cartouche les donnés brutes de votre jeu, comme l'agencement d'un niveau.  Regardez un peu ce petit morceau de data pour illustrer l'exemple :



E_Map:

Data 1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,1,0,0,1
Data 1,0,0,0,1,0,2,0,1,0,0,1
Data 1,0,0,0,1,0,0,0,0,0,0,1
Data 1,1,1,0,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1

[/code


Des 0, des 1 et des 2 sur des lignes data. Chaque valeur numérique c'est un tile. Chaque ligne est une ligne horizontale.
Une zone de 12 tiles sur 11.
Je décide (arbitrairement pour l'exemple) que 0 c'est le sol, 1 le mur et 2 un coffre. Et j'a ma map !
Je dois maintenant aller chercher les données de la map pour la foutre en mémoire, et poser mes tiles en fonction de valeur tous simplement. Je vais juste vous montrer un morceau de code pour placer ça en mémoire !



[code]

Rem ******************************************************
Rem * Déclaration des variables et du tableau de mémoire *
Rem ******************************************************

Dim T_Ram_MAP(12,11) As Integer
Local ID_MAP As Integer,X As Integer, Y As Integer


Rem *************************
Rem * Se brancher sur E_MAP *
Rem *************************
Restore E_Map

Rem *******************************************************************************
Rem * Deux boucle pour lecteur et mémorisation dans le tableau de la valeur voulu *
Rem *******************************************************************************

For Y=0 To 10
For X=0 To 11
Read ID_MAP
T_Ram_Map(X,Y)=ID_MAP

Next
Next

Rem ************************
Rem * Lecteur de T_Ram_map *
Rem ************************

For Y=0 To 10
For X=0 To 11
Locate Y,X
Print T_Ram_Map(X,Y)

Next
Next




Rem *************************
Rem * Les données de la rom *
Rem *************************

E_Map:
Data 1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,1,0,0,1
Data 1,0,0,0,1,0,2,0,1,0,0,1
Data 1,0,0,0,1,0,0,0,0,0,0,1
Data 1,1,1,0,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1






Voila, nous en avons fini avec les datas pour cette fois si. Vous savez quoi ? Avec tous ça vous êtes capable de débuter la création de petit jeu ou de moteur de jeu ! Le prochaine article sera un déplacement case par case d'un sprite avec collision contre les murs, Et vous savez quoi ? A l'heure actuel vous avez tout en main pour faire ça !
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
jeudi 3 août 2017 à 04:48
Chapitre 13, un début de Mazin Game
C'est partie, nous allons entrer dans le dur ! la création d'un début de mazin game avant toute chose  nous allons créer un cahier des charges pour ce début !

-Il faut un niveau qui représente la zone de jeu
  Mémoriser le niveau en Rom
  Mettre en mémoire les cases qui bloquent ou pas en Ram.

-Ce niveau sera composé de plusieurs élément graphique.
  Des  <<sols>> qui sont praticable.
  Des <<murs>> qui bloque le passage.

-Il nous faut le personnage qui sera présenté par un sprite.
  Ce personnage peut bouger dans les 4 directions
  Il ne peut pas faire de mouvement sur une case qui comporte un mur.
    Donc il faut gérer cette colision

-Il nous faut donc gérer les commandes du jeu.
  Haut,Bas,Droite,Gauche

Voici donc un début de moteur sur mégadrive à réaliser...  Avant de regarder la suite, je vous conseille de tester par vous même à réaliser ce petit moteur...


La Boucle du jeu !
Nous n'avons pas le choix, il faut faire la boucle du jeu ! Pour cela une simple boucle While infini est suffisante !
Le code : While 1... Wend fait l'affaire.
Nous allons aussi mettre en place une commande d'attente  avant de reboucler.

voici le morceau de code de départ !


Rem **************
Rem * MazinDrive *
Rem **************

' -----------------
' - Boucle du jeu -
' -----------------
While 1

Sleep 1,TvBlank
Wend



Nous allons débuter avec la gestion du pad  et écrire une procédure pour la gestion des directions.
Nous allons enregistrer dans une variable unique, (G_Direction) une valeur.
4 si la touche gauche est utilisée, 6 pour la touche droite, 8 pour la touche haut,2 pour la touche bas 0 pour aucune touche.
J'utilise souvent 8/6/2/4 ! Pour me r'appeller la valeur, regardez un peu votre pavé numérique de votre pc !


C'est fréquemment ma méthode. Je n'aime pas directement faire si la touche gauche est utilisé alors déplace toi par la gauche. Il y a plusieurs avantage à faire ça. C'est du basic, le code est donc portable plus ou moins facilement sur d'autre support.
La pour modifier les commandes, j'ai juste à modifier la procedure dédié au commande que dans tous le programme ou je dois tester les commandes du pad....

Peut importe le langage utilisé voir même le logiciel. (Fusion, Construct...) si votre programme utilise le clavier et manette, ça évite à chaque fois les conditions du type si le joueur est au clavier ou à la manette dans tous le programme ! Juste faire ça à un petit endroit et c'est bouénos. ET si plus tard une manette x ou y n'est pas géré de la même manière, la modification de ce bout de programme est facile. Repasser sur tout le programme pour adapter la nouvelle manette ...  Et puis savoir que la direction = 4 est plus parlant que de savoir si la direction = machin chose . 2 ou autre. 

La commande pour tester une touche du pad c'est joypad(x).y comme nous l'avons vu dans un autre chapitre.
X est le numéro du pad. 0 ou 1.
et y le "bit" à tester pour savoir qu'elle touche du pad est utilisé.

Voici donc la procedure P_Commande que j'ai écrit pour l'exemple :

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub

J'ai dans le "sinon/else) passé une autre variable à 0. Nous verrons plus tard pourquoi.

Au début du programme, il faut initier les deux variables global.
' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer

Et enfin dans la boucle, on appelle au début la procedure P_Commande et on test le pad pour voir si tous fonctionne. voici de nouveau le morceau de code au complet.

Rem **************
Rem * MazinDrive *
Rem **************

' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer


' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
Print G_Direction

Sleep 1,TvBlank
Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub

Voila une bonne chose de réalisé. La prochaine étape c'est la création et l'affichage de notre joueur sur l'écran.  Nous allons pour ce tuto, nous inspirer de ses graphismes.

Elles appartiennent à surt sous divers licences. Lien

On va commencer à encoder le personnage pour que cela soit un sprite ! Mais avant il va falloir créer notre palette de couleur. Nous allons décrypter ce perso !


Il possède 4 couleurs.

Le noir pour le fond #000000
Une couleur pour la peau #C8913e
Une couleur pour les bottes #5828b8
Une couleur pour le vêtement #699efc

Les couleurs que je présente, se sont des couleurs 24 bits (PC)
Il faut maintenant trouver plus ou moins sont équivalant sur mégadrive.
Pour cela on va garder la premier valeur de chaque teint.
Exemple sur la peau. La peau c'est #C8913E soit Rouge = C8 Vert=91 et Bleu= 3E
Je r'appelle que ce sont des valeurs Hexadécimal.  Ce fait donc #C93
Maintenant sur mégadrive, il faut inverser le Rouge et le Bleu et ajouter un 0 au début !
Ce qui fait donc : #039C
Maintenant au niveau code couleur, il faut que chaque teinte soit une valeur paire. Donc le Bleu à 3 ça ne marche pas.
soit c'est 2 ou soit c'est 4. Le 9 ça marche pas. Soit c'est 9 ou soit c'est A(10). Mais C ça fonctionne (12). Nous avons donc plusieurs possibilités pour nous approché de notre teinte de base.
#028C
#02AC
#048C
#04AC

J'ai recomposé les 4 couleurs avec le logiciel palette contenu dans second basic.


Les couleurs sont dans l'ordre.
Vous avez plus cas comparer ce qui semble le plus proche et qui vous convient.
#02AC sembe pas trop mal. Nous allons faire pareil avec les autres couleurs.
Les bottes  #5828b8 => #52B =>#0A24
Le Vêtement #699efc=>#69F=>#0EA6

Cela semble pas trop mal nous allons donc mettre le début de cette palette en rom.

E_Palette_A:
  DATAINT $0000,$0000,$02AC,$0A24,$0EA6,$0000,$0000,$0000
  DATAINT $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000



Alors concrètement avec cette palette :
0 = La couleur transparente.
1 = La couleur noir.
2= La peau
3= Les bottes
4= Les vêtement.

C'est bien beau d'avoir placé les couleurs en rom, il faut maintenant mettre ça en mémoire vidéo.
Juste avant notre boucle principale du jeu, on va faire un  :
Palettes E_Palette_A,0,0,16
Notre palette est en mémoire. Passons maintenant au codage de notre petit personnage...
Notre perso fait 16px sur 16px. Un Tiles fait 8px sur 8px. Il est donc composé de 4 Tiles. Nous allons donc encoder ça en conséquence avec les numéros de couleur. :D
Je vais juste inscrite les suites de valeur hexadécimale pour représenter notre warrior !

Le PJ agrandie avec une grille, chaque carré est donc représenté par une valeur entre 0 et F ce qui recompose notre graphismes.Chaque valeur c'est tout simplement le numéros de couleur de notre palette !

1111111111111111
1111111221111111
1111111221111111
1111111221111111
1111244114421111
1111244114421111
1112224444222111
1112112222112111
1122114444112211
1122144444412211
1111122112211111
1111221111221111
1111331111331111
1111311111131111
1113311111133111
1111111111111111


Je ne dois pas être trop mal. Ceci dit attention, ce n'est pas du tout bon si on entre tout ça en rom !  Maintenant il va falloire organiser le code en sachant que pour un sprite de 16px sur 16px, le mégadrive pose en premier  le premier tiles en haut à gauche, puis en bas à gauche, puis en en haut à droite puis en bas à droite... Il faut donc redécouper ça correctement dans les datas longs.


E_PJ:
Rem Pose Haut Gauche
Datalong $11111111
Datalong $11111112
Datalong $11111112
Datalong $11111112
Datalong $11112441
Datalong $11112441
Datalong $11122244
Datalong $11121122

Rem Pose Bas Gauche
Datalong $11221144
Datalong $11221444
Datalong $11111221
Datalong $11112211
Datalong $11113311
Datalong $11113111
Datalong $11133111
Datalong $11111111

Rem Pose Haut Droite
Datalong $11111111
Datalong $21111111
Datalong $21111111
Datalong $21111111
Datalong $14421111
Datalong $14421111
Datalong $44222111
Datalong $22112111

Rem Pose Bas Droite
Datalong $44112211
Datalong $44412211
Datalong $12211111
Datalong $11221111
Datalong $11331111
Datalong $11131111
Datalong $11133111
Datalong $11111111



Maintenant, nous n'avons plus cas mémoriser les données de la rom dans la mémoire vidéo. Juste après l'initation de la palette et avant le boucle de jeu. Nous allons mémoriser ça à la position 300. Cela devrais le faire.

LoadTiles E_PJ,4,300
Maintenant nous allons préparer le sprite.  Au début du code on déclare notre variable du sprite avec un
Global sp1 As Integer.
Ensuite juste après  le load tile on va faire ce morceau de code.

sp1=AddSprite(2,2)
PropSprite sp1,300,0


Et on va tester le sprite dans la boucle avec
MoveSprite sp1,128,128


Le code source jusque la !
Rem **************
Rem * MazinDrive *
Rem **************

' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer,sp1 As Integer


' --------------------------
' - Initation du programme -
' --------------------------
Palettes E_Palette_A,0,0,16

' * PJ *
LoadTiles E_PJ,4,300
sp1=AddSprite(2,2)
PropSprite sp1,300,0


' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
Print G_Direction
MoveSprite sp1,128,128
Sleep 1,TvBlank
Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub




' ----------------
' - Donné en Rom -
' ----------------


' * Palette de couleur *
E_Palette_A:
  DataInt $0000,$0000,$02AC,$0A24,$0EA6,$0000,$0000,$0000
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
 
' * Sprite du joueur *

E_PJ:
Rem Pose Haut Gauche
DataLong $11111111
DataLong $11111112
DataLong $11111112
DataLong $11111112
DataLong $11112441
DataLong $11112441
DataLong $11122244
DataLong $11121122

Rem Pose Bas Gauche
DataLong $11221144
DataLong $11221444
DataLong $11111221
DataLong $11112211
DataLong $11113311
DataLong $11113111
DataLong $11133111
DataLong $11111111

Rem Pose Haut Droite
DataLong $11111111
DataLong $21111111
DataLong $21111111
DataLong $21111111
DataLong $14421111
DataLong $14421111
DataLong $44222111
DataLong $22112111

Rem Pose Bas Droite
DataLong $44112211
DataLong $44412211
DataLong $12211111
DataLong $11221111
DataLong $11331111
DataLong $11131111
DataLong $11133111
DataLong $11111111




Notre petit bout choux s'affiche bien. Sympathique non ?
La prochaine étape c'est de le faire bouger de case.


Déplacer le sprite !
Nous allons déclarer en Global deux nouvelles variables pour mémoriser la case ou se trouve notre personnage. La case sera identifier par la valeur X et Y. Donc PJ_X et PJ_Y.
Maintenant dans la fonction MoveSprite nous allons ajouter un(PJ_X*16)+128 et un (PJ_Y*16)+128
N'oulibez pas que le Haut à Gauche à pour coordonné 128,128 pour les sprites machines.

maintenant le but du jeu c'est de modifier PJ_X et PJ_Y en fonction de la touche utilisé. Pour cela une nouvelle Procedure, des conditions, et des éditions, soustraction.


Global PJ_X As Integer, PJ_Y As Integer
La déclaration des variables adéquates.

' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()
If G_Direction = 6 Then
  PJ_X=PJ_X+1
ElseIf G_Direction = 4 Then
  PJ_X=PJ_X-1
ElseIf G_Direction = 8 Then
  PJ_Y=PJ_Y-1
ElseIf G_Direction = 2 Then
  PJ_Y=PJ_Y+1

End If


End Sub

La Procedure pour modifier la valeur PJ_X et PJ_Y.
Si G_Direction est égale à 6 donc si la touche Droite est utilisé. La valeur de la variable PJ_X est augmenté de 1.
oué X+1 = Gauche. Pour aller à droite c'est X-1. En principe tous le monde pige ça. C'est avec Haut et Bas qui peut poser des problèmes.  Il faut retirer 1 à Y pour "monter" et l'inverse pour descendre.

Dans la boucle de jeu on appelle P_Deplacement après les commandes et avant d'afficher le sprite.
' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
P_Deplacement


MoveSprite sp1,128+(PJ_X*16),128+(PJ_Y*16)
Sleep 1,TvBlank
Wend

Vous pouvez tester  (N'oubliez pas donner le focus en cliquant dessus avec la sourie !) Ceci dit le perso se déplace trop rapidement ce n'est pas agréable pour ce type de jeu. C'est la que va intervenir la variable.  G_Direction_Down
Nous allons placer une "double" condition. Le mouvement peut se faire à la condition que la variable  G_Direction_Down soit égale à 0. Et quand un déplacement s’effectue, on place la valeur 1 dans cette variable. Mais elle revient à 0 quand il n'y a pas de touche de direction utilisé. (Déja programmé ça )

La nouvelle procedure.

' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

If G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1
ElseIf G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1
ElseIf G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1
ElseIf G_Direction = 2 Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub

Nous allons aussi  initier au début PJ_X et PJ_Y pour le placer sur une autre case au début. Et voici donc  le code complet à cette étape.

Rem **************
Rem * MazinDrive *
Rem **************

' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer,sp1 As Integer
Global PJ_X As Integer, PJ_Y As Integer


' --------------------------
' - Initation du programme -
' --------------------------
Palettes E_Palette_A,0,0,16

' * PJ *
LoadTiles E_PJ,4,300
sp1=AddSprite(2,2)
PropSprite sp1,300,0
PJ_X=0
PJ_Y=0

' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
P_Deplacement


MoveSprite sp1,128+(PJ_X*16),128+(PJ_Y*16)
Sleep 1,TvBlank
Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub


' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

If G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1
ElseIf G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1
ElseIf G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1
ElseIf G_Direction = 2 Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub



' ----------------
' - Donné en Rom -
' ----------------


' * Palette de couleur *
E_Palette_A:
  DataInt $0000,$0000,$02AC,$0A24,$0EA6,$0000,$0000,$0000
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
 
' * Sprite du joueur *

E_PJ:
Rem Pose Haut Gauche
DataLong $11111111
DataLong $11111112
DataLong $11111112
DataLong $11111112
DataLong $11112441
DataLong $11112441
DataLong $11122244
DataLong $11121122

Rem Pose Bas Gauche
DataLong $11221144
DataLong $11221444
DataLong $11111221
DataLong $11112211
DataLong $11113311
DataLong $11113111
DataLong $11133111
DataLong $11111111

Rem Pose Haut Droite
DataLong $11111111
DataLong $21111111
DataLong $21111111
DataLong $21111111
DataLong $14421111
DataLong $14421111
DataLong $44222111
DataLong $22112111

Rem Pose Bas Droite
DataLong $44112211
DataLong $44412211
DataLong $12211111
DataLong $11221111
DataLong $11331111
DataLong $11131111
DataLong $11133111
DataLong $11111111




La prochaine étape maintenant c'est de mémoriser une tuile qui représente le Sol, et une tuile qui représente un mur !

Une début de Tilset !

Bon nous allons encoder un sol. Celui la.

Nous allons faire comme le sprite, rechercher une teinte pour l'ajouter à la palette de couleur, et coder l'image.
Au niveau des teintes nous avons le noir, et un gris. Le gris #525252  ce qui fait #555 donc soit #444 ou #666.
#666 semble le mieux s'adapter à ce que nous voulons.  On le r'ajoute donc à notre palette. C'est la valeur 5.
E_Palette_A:
  DataInt $0000,$0000,$02AC,$0A24,$0EA6,$0666,$0000,$0000
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000


Les tiles ne sont pas entrelacer. Donc l'ordre est Haut Gauche, Haut Droite, Bas Gauche, Bas droite. Nous allons maintenant placer nos 1 pour le point noir et 5 pour le gris. Notons que pour l'exemple, je ne cherche pas à optimiser les datas. Le tile Sol c'est  4 fois le mêmes tiles.



DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551



Pour le mur en question, je vais modifié un peu les graphismes, et l'encoder.

Il possède deux couleurs.

Le rouge #822e24
et un jaune #c8913e

Voici donc une nouvelle modification de la palette. Je vais utiliser 22c pour le rouge (Index 6) et  2EC( index 7) pour le jaune. (J'adapte finalement)

Voici donc les datas pour les deux tiles.

E_Tiles:
Rem * Tiles du sol *
DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

Rem * Tiles du sol *
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776


Maintenant nous allons les placer en mémoire. Comme d'habe juste avant le while :
Nous allons donc mettre en mémoire 8 tiles (2 gros tiles composé de 4 portions) a partir de 255.
Donc un beau
LoadTiles E_Tiles,8,255
Donc Le tile sur Sol se trouve à id 255
et le tile du mur à 259. (Et non 256 attention !!!)

Directement dans le While nous allons tester d'afficher les deux tiles en question avec

DrawTilesInc 255,4,4,2,2 (pour afficher le tile 255 à la position 4-4 de 2 tiles horizontale et 2 tiles verticale
et DrawTilesInc 259,4,2,2,2

Cela fonctionne vous pouvez même tester le déplacement du perso.



Voici le code complet jusque la.

Rem **************
Rem * MazinDrive *
Rem **************

' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer,sp1 As Integer
Global PJ_X As Integer, PJ_Y As Integer


' --------------------------
' - Initation du programme -
' --------------------------
Palettes E_Palette_A,0,0,16

' * PJ *
LoadTiles E_PJ,4,300
sp1=AddSprite(2,2)
PropSprite sp1,300,0
PJ_X=0
PJ_Y=0

' *tile*
LoadTiles E_Tiles,8,255

' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
P_Deplacement
DrawTilesInc 255,4,4,2,2
DrawTilesInc 259,4,2,2,2

MoveSprite sp1,128+(PJ_X*16),128+(PJ_Y*16)
Sleep 1,TvBlank
Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub


' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

If G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1
ElseIf G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1
ElseIf G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1
ElseIf G_Direction = 2 Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub



' ----------------
' - Donné en Rom -
' ----------------


' * Palette de couleur *
E_Palette_A:
  DataInt $0000,$0000,$02AC,$0A24,$0EA6,$0666,$022c,$02EC
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
 
' * Sprite du joueur *

E_PJ:
Rem Pose Haut Gauche
DataLong $11111111
DataLong $11111112
DataLong $11111112
DataLong $11111112
DataLong $11112441
DataLong $11112441
DataLong $11122244
DataLong $11121122

Rem Pose Bas Gauche
DataLong $11221144
DataLong $11221444
DataLong $11111221
DataLong $11112211
DataLong $11113311
DataLong $11113111
DataLong $11133111
DataLong $11111111

Rem Pose Haut Droite
DataLong $11111111
DataLong $21111111
DataLong $21111111
DataLong $21111111
DataLong $14421111
DataLong $14421111
DataLong $44222111
DataLong $22112111

Rem Pose Bas Droite
DataLong $44112211
DataLong $44412211
DataLong $12211111
DataLong $11221111
DataLong $11331111
DataLong $11131111
DataLong $11133111
DataLong $11111111

E_Tiles:
Rem * Tiles du sol *
DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

Rem * Tiles du sol *
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776


Maintenant nous allons gérer une petite map !

La création de la map
Nous allons simuler un niveau, une simple map. Comme les sprites et les tiles, il faut entrer ça dans la rom. Pour ça les Datas sont idéal. Nous allons utiliser de simple data.
Nous allons faire une map de 16 sur 12.
Nous allons décider que 0 c'est le vide, 1 c'est le sol et 2 et le mur.

Réalisons  notre map en data et sans éditeur de map !


E_Map1:

Data 0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0
Data 0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,0
Data 0,1,1,1,2,0,0,0,0,1,1,1,1,0,0,0
Data 0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,0
Data 0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,2,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
Data 0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,0
Data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


Voici une map exemple. Maintenant nous allons poser les tiles avec une simple routine qui fait intervenir deux boucles For. L'une pour les lignes (Y) et l'autre pour (X)
Nous allons créer une nouvelle Procédure.

' *********************************
' * Routine pour afficher une map *
' *********************************
Declare Sub DrawMap()
Restore E_Map1
  For Y=0 To 11
  For X=0 To 15
  Read ID

  If id=1 Then
    DrawTilesInc 255,x*2,y*2,2,2

  ElseIf id=2 Then
    DrawTilesInc 259,x*2,y*2,2,2

  End If

  Next
  Next

End Sub

Alors, Restore permet de se brancher sur une étiquette pour la lecture des Datas qui est ici, E_Map1 (notre map test)
Les deux boucles For  Y et X) permet donc d'afficher les lignes et les colonnes.
Dans chaque boucle on va chercher la nouvelle valeurs des datas avec Read id. (id est une variable)
Maintenant avec les conditions on affiche le tiles en question avec un *2 à X et Y car un tile c'est 2 tiles horizontale et verticale.
X*2 et Y*2 est calqué sur la boucle X et Y.

Enfin juste avant le while pour notre exemple, on va chercher cette procedure. ET on efface nos deux affichages de tiles test. Voici le code source actuel !

Rem **************
Rem * MazinDrive *
Rem **************

' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer,sp1 As Integer
Global PJ_X As Integer, PJ_Y As Integer


' --------------------------
' - Initation du programme -
' --------------------------
Palettes E_Palette_A,0,0,16

' * PJ *
LoadTiles E_PJ,4,300
sp1=AddSprite(2,2)
PropSprite sp1,300,0
PJ_X=0
PJ_Y=0

' *tile*
LoadTiles E_Tiles,8,255


DrawMap
' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
P_Deplacement


MoveSprite sp1,128+(PJ_X*16),128+(PJ_Y*16)
Sleep 1,TvBlank
Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else
  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub


' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

If G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1
ElseIf G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1
ElseIf G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1
ElseIf G_Direction = 2 Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub

' *********************************
' * Routine pour afficher une map *
' *********************************
Declare Sub DrawMap()
Restore E_Map1
  For Y=0 To 11
  For X=0 To 15
  Read ID

  If id=1 Then
    DrawTilesInc 255,x*2,y*2,2,2

  ElseIf id=2 Then
    DrawTilesInc 259,x*2,y*2,2,2

  End If

  Next
  Next

End Sub

' ----------------
' - Donné en Rom -
' ----------------


' * Palette de couleur *
E_Palette_A:
  DataInt $0000,$0000,$02AC,$0A24,$0EA6,$0666,$022c,$02EC
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
 
' * Sprite du joueur *

E_PJ:
Rem Pose Haut Gauche
DataLong $11111111
DataLong $11111112
DataLong $11111112
DataLong $11111112
DataLong $11112441
DataLong $11112441
DataLong $11122244
DataLong $11121122

Rem Pose Bas Gauche
DataLong $11221144
DataLong $11221444
DataLong $11111221
DataLong $11112211
DataLong $11113311
DataLong $11113111
DataLong $11133111
DataLong $11111111

Rem Pose Haut Droite
DataLong $11111111
DataLong $21111111
DataLong $21111111
DataLong $21111111
DataLong $14421111
DataLong $14421111
DataLong $44222111
DataLong $22112111

Rem Pose Bas Droite
DataLong $44112211
DataLong $44412211
DataLong $12211111
DataLong $11221111
DataLong $11331111
DataLong $11131111
DataLong $11133111
DataLong $11111111

E_Tiles:
Rem * Tiles du sol *
DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

Rem * Tiles du sol *
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776


E_Map1:

Data 0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0
Data 0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,0
Data 0,1,1,1,2,0,0,0,0,1,1,1,1,0,0,0
Data 0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,0
Data 0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,2,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
Data 0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,0
Data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0




Ce n'est pas une belle map mais osef
Nous pouvons nous amuser à nous déplacer sur la map mais pas de collision encore, c'est notre prochaine manipe !

La grille de colision en Ram
Nous allons mettre en mémoire la grille de collision. Un tableau va nous servir à cela. Un tableau de la taille de notre map même.

Voyon voir la déclaration du tableau. Nous allons donc déclarer le tableau T_Map_Colision avec pour dimension (15,11) ce qui représente la taille de notre map. (16,12 n’oubliez pas qu'un tableau en basic débute par 0.) Nous allons faire un tableau global.

Donc :
Global T_Map_Collision(15,11) as integer

Maintenant un petit retour la ou on affiche la map ! Nous allons mémoriser la valeur 1 au mur et dans le vide. Nous allons modifier un petit perux le code.


' *********************************
' * Routine pour afficher une map *
' *********************************
Declare Sub DrawMap()
Restore E_Map1
  For Y=0 To 11
  For X=0 To 15
  Read ID

  If id=0 Then
T_Map_Collision(X,Y)=1

  ElseIf id=1 Then
    DrawTilesInc 255,x*2,y*2,2,2
    T_Map_Collision(X,Y)=0

  ElseIf id=2 Then
    DrawTilesInc 259,x*2,y*2,2,2
    T_Map_Collision(X,Y)=1

  End If

  Next
  Next

End Sub



On ajoute la condition id=0
on ajoute le else avant le if de l'id 1
et on mémorise en fonction de ce que nous voulons une valeur dans le tableau en fonction de X et Y qui est aussi en fonction de la boucle.
T_Map_Colision(X,Y)=0

et haut dans le code, j'ai modifié le PJ_X et PJ_Y à 1 pour éviter que le pj débute dans une case bloquante.

PJ_X=1
PJ_Y=1


Bloquer le déplacement du joueur
Maintenant à chaque fois que nous allons tester le déplacement du joueur, nous allons regarder dans qu'elle case qu'il doit se déplacer et voir si c'est une case "sol" donc  0 dans le tableau, ou  une case mur/vide (donc 1).

C'est très simple, on test dans le tableau la prochaine case.
Exemple si le joueur doit se déplacer à droite : le tableau doit être à (PJ_X+1,PJ_Y)=0 si c'est 1 la condition sera fausse et le code du mouvement ne se fait pas.


' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

' * Déplacement Droite *
If  T_Map_Collision(PJ_X+1,PJ_Y)=0 And G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1

' * Déplacement Gauche *
ElseIf T_Map_Collision(PJ_X-1,PJ_Y)=0 And G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1

' * Déplacement Haut *
ElseIf T_Map_Collision(PJ_X,PJ_Y-1)=0 And G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1

' * Déplacement Bas *
ElseIf T_Map_Collision(PJ_X,PJ_Y+1)=0 And G_Direction = 2  Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub

Et voila vous avez un moteur de déplacement case par case sur mégadrive avec gestion des collisions. (A la case bien sur)
La position en case du joueur, se ballade virtuellement donc dans le tableau et avec ça vous pouvez aussi récupérer des informations sur la case ou se trouve le PJ pour déclencher des événements...

De la finition
Le perso avec son fond noir c'est caca vous ne trouvez pas ? Remplacez les 1 du sprites du perso par des 0. Et nous avons le fond transparent.
E_PJ:
Rem Pose Haut Gauche
DataLong $00000000
DataLong $00000002
DataLong $00000002
DataLong $00000002
DataLong $00002440
DataLong $00002440
DataLong $00022244
DataLong $00020022

Rem Pose Bas Gauche
DataLong $00220044
DataLong $00220444
DataLong $00000220
DataLong $00002200
DataLong $00003300
DataLong $00003000
DataLong $00033000
DataLong $00000000

Rem Pose Haut Droite
DataLong $00000000
DataLong $20000000
DataLong $20000000
DataLong $20000000
DataLong $04420000
DataLong $04420000
DataLong $44222000
DataLong $22002000

Rem Pose Bas Droite
DataLong $44002200
DataLong $44402200
DataLong $02200000
DataLong $00220000
DataLong $00330000
DataLong $00030000
DataLong $00033000
DataLong $00000000

Pour pas perdre de temps, faite une selection des datas du sprites, menu Edit replace. Dans find faite 1 et replace with 0. Le tour est joué.

La couleur du perso ne se marie pas avec le sol (ou l'inverse) vous pouvez y remédier en la modifiant directement dans la palette par exemple remplacez le bleu claire par un vert, $0066 et les bottes par un rouge  $020C?
Code Source 1.0


' ****************************************
' * Nom ............ : megazin.sbs      *
' * Role ........... : Exemple Megadrive *
' * Auteur ......... : Loïc Lété (Monos) *
' * Version ........ : V1 du 28/07/17    *
' * Licence ........ : CC-BY            *
' * Compilateur .... : Second Basic      *
' ****************************************


' = Crédit des graphismes :
' * Surt *  sous licence :
'                CC-By 3.0
'                GPL 3.0
'                GPL 2.0
' https://opengameart.org/content/loveable-rogue



' -----------------------------
' - Déclaration des variables -
' -----------------------------
Global G_Direction As Integer,G_Direction_Down As Integer,sp1 As Integer
Global PJ_X As Integer, PJ_Y As Integer

Global T_Map_Collision(15,11) As Integer

' --------------------------
' - Initation du programme -
' --------------------------
' * Mise en mémoire vidéo de la palette *
Palettes E_Palette_A,0,0,16

' * Mise en mémoire vidéo du sprite du joueur *
LoadTiles E_PJ,4,300
sp1=AddSprite(2,2)
PropSprite sp1,300,0
PJ_X=1
PJ_Y=1

' * Mise en mémoire vidéo des 2 tiles *
LoadTiles E_Tiles,8,255

' * Affichage de la map du jeu *
DrawMap

' -----------------
' - Boucle du jeu -
' -----------------
While 1

P_Commande
P_Deplacement
MoveSprite sp1,128+(PJ_X*16),128+(PJ_Y*16)
Sleep 1,TvBlank

Wend

' -----------------------
' - Gestion du joypad 0 -
' -----------------------
Declare Sub P_Commande()

' // Direction Haut //
If JoyPad(0).0=1 Then
  G_Direction=8
 
' // Direction Bas //
ElseIf JoyPad(0).1=1 Then
  G_Direction=2
 
' // Direction Gauche //
ElseIf JoyPad(0).2=1 Then
  G_Direction=4
 
' // Direction Droite //
ElseIf JoyPad(0).3=1 Then
  G_Direction=6
 
' // Aucune Direction //
Else

  G_Direction=0
  G_Direction_Down=0
EndIf


End Sub


' -------------------------
' - Déplacement du joueur -
' -------------------------
Declare Sub P_Deplacement()

If  G_Direction_Down=0 Then

' // Déplacement Droite //
If  T_Map_Collision(PJ_X+1,PJ_Y)=0 And G_Direction = 6 Then
PJ_X=PJ_X+1
G_Direction_Down=1

' // Déplacement Gauche //
ElseIf T_Map_Collision(PJ_X-1,PJ_Y)=0 And G_Direction = 4 Then
PJ_X=PJ_X-1
G_Direction_Down=1

' // Déplacement Haut //
ElseIf T_Map_Collision(PJ_X,PJ_Y-1)=0 And G_Direction = 8 Then
PJ_Y=PJ_Y-1
G_Direction_Down=1

' // Déplacement Bas //
ElseIf T_Map_Collision(PJ_X,PJ_Y+1)=0 And G_Direction = 2  Then
PJ_Y=PJ_Y+1
G_Direction_Down=1
End If
End If

End Sub

' *********************************
' * Routine pour afficher une map *
' *********************************
Declare Sub DrawMap()
Restore E_Map1
  For Y=0 To 11
  For X=0 To 15
  Read ID

  If id=0 Then
T_Map_Collision(X,Y)=1

  ElseIf id=1 Then
    DrawTilesInc 255,x*2,y*2,2,2
    T_Map_Collision(X,Y)=0

  ElseIf id=2 Then
    DrawTilesInc 259,x*2,y*2,2,2
    T_Map_Collision(X,Y)=1

  End If

  Next
  Next

End Sub

' ----------------
' - Donné en Rom -
' ----------------

' * Palette de couleur *
E_Palette_A:
  DataInt $0000,$0000,$02AC,$020C,$0066,$0666,$022c,$02EC
  DataInt $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
 
' * Sprite du joueur *

E_PJ:
Rem Pose Haut Gauche
DataLong $00000000
DataLong $00000002
DataLong $00000002
DataLong $00000002
DataLong $00002440
DataLong $00002440
DataLong $00022244
DataLong $00020022

Rem Pose Bas Gauche
DataLong $00220044
DataLong $00220444
DataLong $00000220
DataLong $00002200
DataLong $00003300
DataLong $00003000
DataLong $00033000
DataLong $00000000

Rem Pose Haut Droite
DataLong $00000000
DataLong $20000000
DataLong $20000000
DataLong $20000000
DataLong $04420000
DataLong $04420000
DataLong $44222000
DataLong $22002000

Rem Pose Bas Droite
DataLong $44002200
DataLong $44402200
DataLong $02200000
DataLong $00220000
DataLong $00330000
DataLong $00030000
DataLong $00033000
DataLong $00000000



' * Tiles *

E_Tiles:
Rem * Tiles du sol *
DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

DataLong $11111111
DataLong $15551555
DataLong $15551555
DataLong $15551555
DataLong $11111111
DataLong $55515551
DataLong $55515551
DataLong $55515551

Rem * Tiles du sol *
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666
DataLong $66666666

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776

DataLong $77767776
DataLong $77767776
DataLong $66666666
DataLong $67776777
DataLong $67776777
DataLong $66666666
DataLong $77767776
DataLong $77767776

' * Map Exemple *

E_Map1:

Data 0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0
Data 0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,0
Data 0,1,1,1,2,0,0,0,0,1,1,1,1,0,0,0
Data 0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,0
Data 0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,2,1,1,1,1,1,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0
Data 0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
Data 0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,0
Data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


Et voila, ce premier gros "tuto" dédié à la création d'un moteur touche à sa fin ! Maintenant c'est à vous de vous amuser avec.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
vendredi 4 août 2017 à 04:11
Chapitre 14 : améliorons les conditions avec des cases !!!

Il est fréquent que nous utilisons de multiple If combiné avec elseif pour tester une même variable pour faire des "effets différents".  Il y a moyen d'éviter les if imbriqué à gogo avec les Select Case.

c'est très simple, on "teste" une variable et en fonction de sa valeur on fait jouxjoux avec.

Regardez cette exemple :
Local Vie As Integer
Vie=0

Select Case Vie
Case 0
Print "Vous n'avez plus de vie"
Exit Select

Case 1
Print "C'est votre dernière vie"
Exit Select

Case Else
Print "Vous êtes large en vie !!!"
Exit Select

End Select

Select Case <nom_variable>
va récupérer les données de variable choisis. Ensuite on test juste la valeur voulu avec
Case <Valeur>
On réalise la programmation que vous voulez et n'oubliez pas le Exit Select avant de passer à la Case suivante ou au End Select qui  termine cette méga condition.

<Case Else> permet tous simplement de faire jouer un morceau de code si le reste n'est pas valide ! Ce n'est pas obligatoire de placer un Case Else bien sur.

Dans notre gros exemple d'avant, dans la procedure DrawMap() on teste la variabe id pour poser la tuile et placer une valeur dans un tableau. Nous utilisons des if et des elseif. Cela fonctionne bien mais avec des cases voici ce que ça peut donner !


If id=0 Then
  T_Map_Collision(X,Y)=1

ElseIf id=1 Then
  DrawTilesInc 255,x*2,y*2,2,2
  T_Map_Collision(X,Y)=0

ElseIf id=2 Then
  DrawTilesInc 259,x*2,y*2,2,2
  T_Map_Collision(X,Y)=1

End If



Select Case id
 
  Case 0
    T_Map_Collision(X,Y)=1
  Exit Select

  Case 1
    DrawTilesInc 255,x*2,y*2,2,2
    T_Map_Collision(X,Y)=0
  Exit Select

  Case 2
    DrawTilesInc 259,x*2,y*2,2,2
    T_Map_Collision(X,Y)=1
  Exit Select

End Select


C'est donc une autre manière de faire et peut être beaucoup plus lisible.
Voila pour ce petit article sur les Cases.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
samedi 5 août 2017 à 04:46
Chapitre 15 :  Constante et Gosub


Une constante
Oué encore un chapitre qui n'est pas vraiment lié à la mégadrive. Mais bon, c'est important aussi. Nous allons parler des constantes dans le logiciel second basic. Un truc qui peut simplifier la vie.

Alors nous allons prendre un exemple concret encore une fois tiré de notre programme moteur de déplacement case par case !

Nous s'avons que tiles de mur se trouve à la position 259 de la vidéo ram !
Donc à chaque fois que nous voulons jouer avec un mur, il faut inscrire 259. C'est lourding non ?  Il y a une première possibilité, c'est de mémoriser 259 dans une variable et appeler simplement la variable mur qui va ressortir la valeur 259 dans le Drawtile par exemple. Sauf que ba voila c'est de nouveau 2 octets de mangé ! Alors sur un petit programme comme ça ce n'est pas bien grave. Mais quand  vous voulez faire un gros jeu, il se peut que vous allez avoir besoin de place ! Et c'est la que les constantes entre en jeu les amis !

Const #nom = valeur
On déclare une constante.
Const #mur = 259

Et dans notre drawtiles
DrawTilesInc #mur,x*2,y*2,2,2

Que ce passe t'il ? A la compilation, le compilateur va tous simplement remplacer les #mur par 259 ! #mur n'est pas une "variable" donc ne mange pas les 2 ou 4 octets ! C'est un travaille du compilo !

Elle n'est pas belle la vie ?

Goto et Gosub !
Nous allons remonter le temps, quoi c'est pas déjà fait ! Voici un petit article culture général du basic j'ai envie de dire et je vous présente deux vielles commande en basic qui fonctionne bien sur sur Second Basic, mais qui honétement sont à éviter le plus possible maintenant.  Je vous présente GOTO et GOSUB !

Débutons avec GOTO
QUand le le programme rencontre Goto + étiquette ,  il va se connecter à l'étiquette en question.  Exemple :


Print "Chat"
Goto E_1
Print "Chien"
E_1:
Print "Oiseau"
Print "éléphant"


La chat est affiché à l'écran
Il rencontre Goto E_ on saute à E_1
Oiseau est affiché et le programme continue.

Mais le truc c'est avec goto, c'est du programme dit spaghetti ! Le code n'est pas trés bien organisé. Bref à éviter le maximum.

Gosub
C'est gosub c'est mieux, c'est comme les procédures et les fonctions, cela permet de découper son programme.


Print "Nemau veux programmer sur la game boy"
Gosub E_1
Print "Les ombres d'Aëdemphia ne sont pas réalistes"
End

E_1:
Print "Nous sommes dans une sous routine"
Return


Le code va afficher le premier text ! Ensuite rencontre un gosub et va dont en E_1 pour travailler le code en affichant :Nous sommes dans une sous routine. Une fois qu'il rencontre Return, il retourne au programme principale et continue sa route ! Affiche Les ombres d'Aëdemphia ne sont pas réalistes.

Il peut y avoir plusieurs Sous routine "Gosub" imbriqué mais il faut bien penser à finir avec un return.

Ceci dit maintenant avec les procédures et les fonctions, les gosub ne serve plus à grand chose. Mais cela reste votre choix de codage.
L'avantage de travailler avec que des Gosub, c'est de ne pas avoir besoin de déclarer les variables globals. Le désavantage c'est de ne pas vraiment pouvoir faire passer des paramètres et jouer de nouveau avec des tonnes de variables à en perdre son assembleur ! Bref un choix personnelle de comment coder votre jeu !
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
samedi 5 août 2017 à 04:48
J'attend de l'aide pour installer le SDK de la colecovision ! Je partagerais ma connaissance sur ça aussi.
J'ai des outils aussi à créer avec fusion pour encoder des graphismes sur megadrive (ou autre)

j'ai du déja en parler mais ce qui est cool c'est du moins sur mégadrive,  il n'y pas de formule mathématique à la con pour la représation des graphismes comme sur amstrad ou c'est à se tirer les cheveux xd
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
dimanche 6 août 2017 à 04:12
Pal et NTSC
Aller, on va toucher à un truc sensible... Il y a des jeux PAL et des jeux NTSC et quand c'est bien fait, les jeux peuvent d'adapter au deux format !

C'est quoi Pal et NTSC au faite ?

PAL c'est Phase Alternating Line. C'est un mode d'affichage d'écran, et nous en France quand on acheté une console rétro c'était des consoles en format PAL. Elles affichaient pour faire simple, 50 images par seconde.  (50hz)

Dans beaucoup d'autre pay, c'était le format NTSC National Television System Committee. Ce mode affiche 60 images par seconde (60hz) (USA-JAP)

Les jeux NTSC sont réputés pour tourner "plus vite" que les jeux pal. Sur Sonic mégadrive, la version NTSC du jeu est bien plus rapide que notre version pal de chez nous (en france).

La mégadrive peut être Switcher pour passer en NTSC/PAL avec du bricolage comme pas mal de console...

Le format PAL/NTSC n'influe pas seulement sur le "nombre" d'image d'affichable à l'écran. Il influe aussi sur le nombre de ligne possible à affichable sur l'écran.

Un petit tour dans la définition des écrans tien :
Le nombre de tiles affichable à l'écran latéralement est de 40 en mode native de second basic.
Un tile c'est 8 points sur 8. Donc 40*8 = 320 points.

En hauteur, ba la ca va dépend si vous êtes en PAL ou en NTSC et pour changer le mode c'est la commande
TVset 0
-pour NTSC (Réglage native) et
TVset 1
-pour du pal.


En mode 0 donc NTSC vous pouvez afficher à l'écran 28 Tiles de 8*8 points.
Soit une définition de 28*8=224 points

ET en mode PAL vous pouvez afficher à l'écran 2 tiles de plus. Soit 16 points de plus ce qui fait 240 points.

Donc la  définition d'écran est de : 320*224 en NTSC et 320*240 en PAL.

C'est pour ça que sur beaucoup de jeu chez nous en France ce n'est pas vraiment du pleine écran et qu'il y a des bandes noirs ! Les développeurs utilisent la plus petite résolution pour que cela passe partout en gros.  (A moins d'avoir une TV en 60hz compatible NTSC ah ah)

Mode 32 tiles en latéral
Il est possible de faire du  256*224 en NTSC et 256*240 en pal. Ce qui permet d'afficher 32 tiles au lieu de 40.
Pour cela la commande est
VidMode, Vid32Cell
VidMode, Vid40Cell
pour 32 / 40 tiles.

Pourquoi passer en 32 tiles ? (soit 16 tiles de 16*16pts) pour peut être mieux gérer les scrolling. Car quand on parle d'affichage à l'écran c'est belle et bien le nombre de point/tiles que le joueur peut voir à l'écran. La mégadrive permet d'afficher des tiles, et des sprites Hors écran ! Mais ça on verra tout ça dans un autre article ! Cela devient cool non ?
ah ah.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
lundi 7 août 2017 à 04:26
Sega Genesi Tile Designer

A l'heure actuel nous avons photoshop, Gimp, Paint.Net (je parle bien du point net), Photofiltre, et d'autre logiciel pour créer des graphismes 2d.

Nous avons vu que sur mégadrive, il faut encoder ses graphismes en une suite de valeur hexadécimal qui appelle un index de couleur.

Exemple $1051F059
qui veux dire ! Couleur 1, Couleur transparente, Couleur 5...
Un morceau de graphismes c'est une Tiles de 8 pixel horizontal,, et 8 pixel vertical. Nous avons des commandes pour poser plusieurs tiles sur la map en même temps pour nous simplifier la vie ! Les sprites sont aussi des tiré de la bank de sper heu sprite pardon.  Jusque la nous encodons à la main tous ça pour "apprendre" la base ! Mais il existe des logiciels pour nous simplifier la vie. (Voous vous voyez utiliser paint tous le temps vous alors qu'il existe des logiciels avec des calques, des grilles pour poser votre pixel, des outils plus adapté ?) Bas sur  megadrive c'est pareil. Le logiciel ce nomme Saga Genesis Tile Designer !!!

Lien
Je vais vous faire un petit tour du proprio.




Voici la gueule du bignouf !


Nous allons débuter avec la barre des menus du haut.


Cette option permet d'avoir un nouveau fichier. Attention ça efface complètement le travaille en cour sans prévenir. (ça c'est carrément con !)

ouvrir un fichier qui a était enregistré en .txt. C'est pour retrouvé votre travaille.

Pour sauvegarder votre fichier en .txt
Pour ne pas perdre votre travaille.


Exporter vos tiles ! (Flèche en bas)
Cela permet d'exporter votre travaille pour votre logiciel de codage. Nous allons y revenir plus tard !


La c'est pour importer les donnés data dans le logiciel en question.


Activer ou désactiver la Grille visuel ! C'est pratique les gens !


Niveau de Zoom, hey hey. Attention en mono tiles il y a une limitation de zoom minimum.


Paramétrage du nombre de tiles latérale. (1 à 8 tiles)
Cela évite de créer vos sprites ou décors qui doit faire plus d'un tiles, (8*8px) sur un morceau de tiles.

Nativement c'est paramétré sur 2.


Cette fois si c'est Verticalement !


Cette option permet d'ouvrir le menu de la gestion des palettes de couleur.


Cette option permet d'ajouter un nouveau doccument vide en dessous du tiles séléctionné. (Il ne se places pas à la fin !)


Cette fois si c'est au dessus !!!


Pour effacer le tiles selectionné.


Pour copier le tiles en mémoire.


Pour coller le tiles en mémoire dans un autre "document" du logiciel.

(Le copie/colle ne fonctionne que pour ce logiciel)

Voyons la barre de gauche.


Le Crayon, pour poser votre morceau de pixel


La pipette, pour mesurer votre taux d'alcool dans le sang en programmant.... Non c'est pour sélectionner une couleur dans le document.


Pot de peinture, pour remplacer des pixels qui se touche et de même couleur, par une autre que vous avez choisis dans l'index !


Aucune idée semble ne pas fonctionner.


Pour déplacer le tiles d'un pixel à Droite/Gauche/Haut/bas. Pratique ça.


Pour faire une rotation du tiles de 90 degrés à droite. (1/4 de tour quoi)


Retourner le tiles par apport à un axe verticale. (Le coté droit, se retrouve à gauche pour faire simple)


Retourne le tiles par apport à un axe Horizontale. (Le coté Haut se retrouve en bas !)


En bas, vous avez le nuancier des couleurs. Les deux petites flèches au dessus de palette 0 permet de choisir une autre palette. -Entre 0 et 3)

Pour sélectionner une teinte, c'est simple vous cliquez sur le nuancier avec la sourie ! Vous pouvez mémoriser trois couleurs avec la sourie !
Bouton Gauche : L
Bouton Droite : R
Bouton du milieu : M

Pratique non ?


Voici la fenêtre de l'éditeur de palette.
Pour le môment vous avez les 16 mêmes teintes qui se répettes sur les 4 palettes.

Les lignes 00 (palette 0)
à 30 (palette 3)
Puis les couleurs de 0 à F.

En bas vous avez trois curseur ! Red (rouge) Green (Vert) Blue(Bleu.)
Vous pouvez créer votre teinte avec les trois curseurs après avoir selectionner un emplacement plus haut !

RGB c'est le code couleur au format 24 bits
et Sega Code c'est le code couleur pour la mégadrive. (Le blan pure FF-FF-FF en 24bits c'est encodé 0EEE)
Il n'y a que 512 teintes possible sur la mégadrive !

Export Palette c'est pour exporter facilement vos palettes de couleur. Mais ne pas utilisé cooome ça, il faut valider vos modifications avec ok. Sinon en exportant ça ne prendra pas en compte les nouvelles modifications.


la zone d'exportation.
Vous pouvez exporter dans plusieurs format :
-En Basic qui vous donne comme dans la capture d'écran le code à copier/coller dans l'ide
-Exporter en fichier binaire (ça c'est cool j'en parlerais dans une autre leçon)
-En assembleur. (Même idée qu'en basic)
-En C (Même idée qu'en basic)
-En Kenedaa's MMM (dont je ne sais pas c'est quoi comme format)

Vous pouvez sélectionner le tiles de départ de fin.

D'abord il faut générer les data et enfin exporter en fichier ou / et faire un copier/coller du listing proposé.

C'est la même chose avec l'exportation de palette !


Voici la fenêtre d'import vous pouvez importer l'exportation de la Ram Vidéo faite avec l'emutateur Gens Kmod
Vous pouvez faire la même chose avec la CRAM (Les palettes de couleurs)

Vous pouvez importer un fichier binaire dédié pour les tiles et la palettes.

Il y a une option Swap Bytes à cocher ou pas :
Et trois options lié au tiles :

Sprites Orientation : Pour calquer ça sur les sprites  (Sur un sprites de 4 tiles, (2*2) c'est Haut-Gauche / Bas Gauche / Haut-droite / Bas-Droite

Start Offet :
Number of 8*8 Tiles.. Nombre de tiles à importer.

Nous avons fait le tour du log. Une démo d'exportation d'un tiles !

Voici un "tiles" que j'ai fais en toute simplification.


Avec l'exportation en Data basic j'ai cette cette suite donc je place une étiquette til.

  til:

        DATALONG $11111111 '  Tile: 0
DATALONG $11132112
DATALONG $13322212
DATALONG $31333333
DATALONG $11113333
DATALONG $11133333
DATALONG $11133333
DATALONG $11133335
DATALONG $11133356 '  Tile: 1
DATALONG $11333836
DATALONG $11333896
DATALONG $11333856
DATALONG $11333366
DATALONG $113A3322
DATALONG $13AB3362
DATALONG $C3DE33F6
DATALONG $23111111 '  Tile: 2
DATALONG $22111231
DATALONG $24222333
DATALONG $33211113
DATALONG $33331111
DATALONG $33333111
DATALONG $33333311
DATALONG $53333111
DATALONG $65733711 '  Tile: 3
DATALONG $63873711
DATALONG $89873711
DATALONG $88817111
DATALONG $66337311
DATALONG $2233A331
DATALONG $2633BA31
DATALONG $6F33EE43


Je fais pareil avec la palette de couleur :

E_pal:
DataInt $0000,$0000,$0268,$0244,$0422,$048A,$06AC,$0224 '  Pallette: 0
DataInt $08AC,$0A46,$0680,$08A0,$0664,$0C4A,$0C6C,$0C64


J'écris le reste du programme dans SEcond basic.

        Palettes E_pal, 0, 0, 16

LoadTiles til, 4, 300 ' load the tiles starting at 100
DrawTilesInc2 300,0,0,2,2

E_pal:
DataInt $0000,$0000,$0268,$0244,$0422,$048A,$06AC,$0224 '  Pallette: 0
DataInt $08AC,$0A46,$0680,$08A0,$0664,$0C4A,$0C6C,$0C64

til:
DataLong $11111111 '  Tile: 0
DataLong $11132112
DataLong $13322212
DataLong $31333333
DataLong $11113333
DataLong $11133333
DataLong $11133333
DataLong $11133335
DataLong $11133356 '  Tile: 1
DataLong $11333836
DataLong $11333896
DataLong $11333856
DataLong $11333366
DataLong $113A3322
DataLong $13AB3362
DataLong $C3DE33F6
DataLong $23111111 '  Tile: 2
DataLong $22111231
DataLong $24222333
DataLong $33211113
DataLong $33331111
DataLong $33333111
DataLong $33333311
DataLong $53333111
DataLong $65733711 '  Tile: 3
DataLong $63873711
DataLong $89873711
DataLong $88817111
DataLong $66337311
DataLong $2233A331
DataLong $2633BA31
DataLong $6F33EE43




Et voila, le tour est joué.

Note: Une petite nouveauté dans le code source. Depuis le début, je vous avez habitué à utiliser DrawTilesInc.
La il y a un 2 a la fin
DrawTilesInc2

Cela permet de changer le "parterne" d'affichage  d'un tile comme dans un sprite.
sur un tiles de 4 cases, cela fait donc dans l'encodage : Haut Gauche / Bas Gauche / Haut Droite /Bas Droite.
Si on garde le premier Draw tile, le log affichage d'abord les deux tiles de Haut et enfin les deux tiles du bas.
On se retrouve le Bas Gauche à droite du Haut Gauche.

Exemple :


A vous d'harmoniser l'encodage des tiles et / ou de corriger ça dans les datas...
Maintenant vous avez un truc simple pour faire des tiles et des sprites ah ah
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mardi 15 août 2017 à 09:36

un test sur coleco.
Déplacement de perso et projectil + collision.

Bon graphiquement c'est du super proxy mais ça marche.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
samedi 30 décembre 2017 à 17:39
Beaucoup de truc à dire ah ah. Déja depuis ce matin je regarde la master system. Une console de coeur.
J'ai voulu comme ça installer le SDK et paf ! ça marché.

Sega Master System en C
Ce matin j'ai pour le fun voulu installer un SDK pour programmer la master system en C ! L'installation se fait sans douleur ça c'est cool !

Lien du sdk
En gros on télécharge est installe le SDCC si ce n'est pas fait, on télécharge le SDK. on place des DLL dans le SDCC. (ou / et dans le dossier du projet car moi ça fonctionné comme ça). on créer un fichier cmd/bat.

@echo off

sdcc -c -mz80 --peep-file peep-rules.txt main.c
sdcc -o main.ihx -mz80 --no-std-crt0 --data-loc 0xC000 crt0_sms.rel main.rel SMSlib.lib
ihx2sms main.ihx main.sms

echo End post-build
echo ========================================================
pause

Et le tour est pratiquement joué. Dans le lien du SDK le mode d'emplois d'installation est fourni...

Ce matin j'ai donc regardé un peu comment afficher un tiles un sprite et les palettes de couleur car peux importe la machine , avec les commandes (pad) et ses trois trucs il y a souvent que ça vraiment à apprendre au début pour faire un jeu !



Le gros quadrillage c'est des tiles et le carré qui s'en détache c'est le sprite.
Source
Code source en C et le fichier smc pour lire le programme sur un émulateur master system. Le carré se déplace !

La gestion de la mémoire vidéo est un peu bisars. L'encodage linéraire du tiles se fait avec deux couleurs possible sinon c'est  une gymnastique !

un tiles c'est 8 pixels sur 8.
Chaque ligne est encodé sur 4 octets. donc 32 octect par tiles/sprite
(La mémoire vidéo de la ms est de  16ko mais j'ai pas encore regardé / compris la map de la mémoire vidéo)
Une ligne est donc 4 octets. 1 octet c'est 8 bits donc pour chopper l'index de couleur du pixel !

Ligne 1:
Octet 1 : ABCDEFGH
Octet 2 : ABCDEFGH
Octet 3 : ABCDEFGH
Octet 4 : ABCDEFGH

Alors c'est une seul ligne de 8 pixel la.
L'index de couleur du 1er pixel :  Ba c'est la recomposition de tous les bits A de chaque octet !
exemple :
0b 10000000
0b 10000000
0b 10000000
0b 10000000

Le pixel 1 c'est l'index 0x1111  soit l'index 15
Le pixel 2 c'est l'index 0x0000 soit l'index 0

Sur master system il a une palette de 64 couleurs, 4 niveaux de Rouge, 4 niveaux de Vert, 4 niveau de bleu. Et on peux créer deux palettes de couleurs. 16 couleurs pour les tiles, et 16 couleurs pour les sprites. Donc on range touis ça dans des index de 0 à 15  tous simplement.

Contrairement à la nes, la master ne semble pas avoir de contraire du nombre de couleur sur un sprite et un tiles. (A vérifier pour les sprites quand même mais je crois que non).

La nes à plein de contrainte d'affichage...

Au niveau d'affichage de sprite 8*8, la MS ne peut afficher que 8 sprites sur la même ligne, (soit 64px) mais il existe des astuces pour contourner le problème. (Les fameux clignotement de sprite de la nes aussi présent sur ms). Il faut alterner l'affichage des sprites à chaque boucle tout simplement.



Mémoire vidéo Memory map :


$0  :Mémorisation du parterne des tiles soit 256 tiles (0 => 255)
$2000 : Mémorisation du parterne des sprites : 191 sprites (8*8) 256 => 447
$3800 : Affichage écran : 32*28 tiles(8*8px) soit 256*224px
$3F00 : Table des sprites avec position X,Y et index du tiles
$4000 : Fin

Note : Les tiles ne se pose pas au pixel près mais dans un quadrillage comme pratiquement toutes les consoles rétro.

================================================
Sinon sur Megadrive j'avance tranquillement mes test en C avec le SDGK de stef. Scrolling et mapping.
Test de mapping :


C'est super passionnant de s'intéresser à tout ça.

Sur Master System sur beaucoup de jeu, il existe une fine bande à gauche. Ba c'est simple, contrairement en hauteur, il n'y pas de zone qui existe sur le coté dans la master system alors on peux "cacher" une zone à gauche de 8px pour permettre d'afficher des tuiles et créer un scrolling latéralement.

L
Seyjin
1471 messages
Fusion 2.5 Dev
Exporteur Android Exporteur HTML5 Fusion 2.5+
samedi 30 décembre 2017 à 18:05

Note : Les tiles ne se pose pas au pixel près mais dans un quadrillage comme pratiquement toutes les consoles rétro.

Je crois que dans un autre univers, des gens appellent ça une grille virtuelle  :P
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
samedi 30 décembre 2017 à 18:45
Roo chute xd
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
dimanche 31 décembre 2017 à 11:16
Sur Master System, il faut se taper le makefile à la main pour ajouter les fichier à compiler et à assembler. Je me suis donc fait un utilitaire avec fusion pour ça.


Télécharger

Emmanuel
2393 messages
Fusion 2.5 Dev Fusion 2.5
Firefly Exporteur UWP Exporteur iOS Exporteur Android Exporteur HTML5 Fusion 2.5+
lundi 1 janvier 2018 à 12:07
Cool monos code encore sous fusion  8)
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
lundi 1 janvier 2018 à 13:24
C'est pratique et rapide pour ce genre de truc xd
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mercredi 3 janvier 2018 à 06:48
Ce matin avant de partir affronter Carmen dans les vignes, j'ai ajouté des petites tuiles d'une autre couleur autour du pion joueur pour lui indiquer ou il peut se déplacer.

B3 avec la fonction
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
dimanche 14 janvier 2018 à 19:53
Je pense re faire la programmation de Prisonnier mais en mieux avec les nouvelles connaissances dont je viens d'apprendre ce week end.

Je "participe" a une game Jam sur le site de Gamecodeur (Certain connaisse) Je suis normalement Hors catégorie vu que je n'utilise pas un langage qu'il apprend mais j'osef. Cela me permet d'apprendre plein de truc.


Ce matin j'ai enfin convertie proprement enfin façon de parler une image pc pour l'afficher sur une master system. Prise de tête au début mais rien de sorcier finalement. Il n'y a pas de tuto en Français donc c'est un peu dermerde toi à apprendre à manier en ligne de commande les compilateur, et la gestion de logiciel en fichier bat ! Et oui pas d’interface xd mais finalement on s'en passe facilement. Bon c'est un test mais ça fonctionne !


Un niveau.

Bon n'étant pas un fan de ce jeu, la création de niveau me botte pas du tout. Mais il y a beaucoup de truc à apprendre sur ce genre de projet.

J'ai réunis dans un seul tableau en 1 dimenssions tous les niveaux.


const unsigned char level[] = {


// Level 0
0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,
0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,
0,0,0,0,1,6,5,6,5,6,1,0,0,0,0,0,
0,0,0,0,1,5,5,1,5,1,1,0,0,0,0,0,
0,0,1,1,1,5,4,2,5,2,1,0,0,0,0,0,
0,0,1,2,2,5,5,4,3,5,1,0,0,0,0,0,
0,0,1,5,5,5,5,4,5,7,1,0,0,0,0,0,
0,0,1,5,5,5,1,1,5,5,1,0,0,0,0,0,
0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
0,0,2,2,2,2,2,2,2,2,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,


// Level 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,
0,0,0,1,2,2,2,2,2,2,2,1,0,0,0,0,
0,0,0,1,5,5,6,6,6,5,5,1,0,0,0,0,
0,0,0,1,5,5,5,5,5,5,5,1,0,0,0,0,
0,0,0,1,5,5,5,5,5,5,5,1,0,0,0,0,
0,0,0,1,5,5,4,4,4,5,5,1,0,0,0,0,
0,0,0,1,5,5,5,5,5,5,5,1,0,0,0,0,
0,0,0,1,5,5,5,7,5,5,5,1,0,0,0,0,
0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,
0,0,0,2,2,2,2,2,2,2,2,2,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
....
};







Avec de simple formule on navigue facilement pour retrouver tout ça.  Je n'arrive pas à rendre un tableau en plusieurs dimension en variable global en C. Je ne sais pas pourquoi  ça ne fonctionne pas. Donc bon.

La c'est des constantes, cela veux dire que les suites de valeurs sont enregistré sur la cartouche et n'y bouge pas... Si je place pas le mot clef constante, je crois que le tableau va se charger dans la "Ram" de la console, et la c'est pas trop bon.

Je fais un tableau "buffer" du niveau en cours ce qui me permet de le modifier pour savoir ou se trouve les caisses qui sont bougés...

Bon un case = 1 octet de Data sur la cartouche.. Donc un niveau c'est 16*12 cases.  192 octets par niveau.
Une "cartouche" standard sans banck switching c'est 32ko.
A l'heure actuel je suis à 19348 octets (19-20ko)
Et il y a une petit musique pourrie au début. C'est une avancé de la journée. J'ai réussis à intégrer de la "musique". yeah.

Bref j'avance.

Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
jeudi 18 janvier 2018 à 20:03
Nom du jeu : Sokoban pour la game Jam 2018 n
Support : Séga Master System
Programmeur : Jean Monos
Graphismes : Jean Monos
Musique et son : Jean Monos.
Moteur : DevkitSMS
Type : Petit Puzzle.
Lien :Lien sur itch.io


Yopla voici un Sokoban sur Sega Master pour la Game Jam de chez Gamecodeur. Enfin je dois être hors concours mais pas grave.



Lien

Le jeu est un proto qui marche sur Master System de chez Sega. Les sources sont dedans.
Codé en C.
Il y a 9 niveaux.

C'est sans  grande prétention mais ça ma permis de voir un peu le DevkitSMS qui est fort sympathique.
Voilou bon test.
Monos
2713 messages
Fusion 2.5 Dev
Fusion 2.5+ Exporteur Android Exporteur HTML5
mardi 6 février 2018 à 09:57
26 sur 51 pour le soko et la gam jam...

Sinon je suis en train de travailler les graphismes de Prisonnier sur Master System. Je vais re coder le jeu proprement avec les nouvelles connaissance du kitdev.

Pour le moment je fais un travaille graphique sur pc de la zone de jeu.
Utilisateurs en ligne
  • Aucun utilisateur en ligne
  • 13 visiteurs au total

Derniers messages