Fichiel TailleAttachéLpar

bohref="http://mijge.unice.fr/@api/deki/fie s/78/=Tutospals_Blitzmax.docx>o 1.5pt;fie link" titng="Tutospals Blitzmax.docx>>0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;mt-"bordocx>oalt="" /": 9.5pt;nae: td; tdo 1.5pt;der3"> bohref="http://mijge.unice.fr/@api/deki/fie s/78/=Tutospals_Blitzmax.docx>o 1.5pt;fie link" titng="Tutospals Blitzmax.docx>>Tutospals Blitzmax.docx;nae ;&:p r>>0cm 0c 1.5pt;d sc="bo"orderfie D scDisplay_78>>0cm 0c 1.5pt;nod scripnt-fViAucass=d scripnt-fnt-size: 9.5pt;an styltd; tdo 1.5pt;der4> 86.48 Koyltd; tdo 1.5pt;der5Vi10:06non9 Fév 2009bztd; tdo 1.5pt;der6"> bohref="/User:JonathanBarouh>o 1.5pt;linkstylrgbrelt;infatn rg>JonathanBarouh;nae: td; tdo 1.5pt;der7"> bohref="#>o 1.5pt;ds">arrow a54, 9z-nu" onclick="returkaFie M-nu.show(th: > '6839e0ce5d65503d005b63679ce42a88'> '78'> falsg> falsg> falsg> ''> trueont-A54, 9s;nae: td; /tr>

0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;gp rery" alt="" /": 9.5pt ;  1.5pt;="bo">eferen ;  1.5pt;unwetyle"orderntensCouno">(0)nt-size: 9.5pt;an style=""yle=""yle="" ycolor rg"jgeGp reryWrapVibcolo 1.5pt;nofie sVia>

0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;commt-fe"oalt="" /": 9.5pt ;  1.5pt;="bo">Commt-fail"s (0)nt-size: n style=""yle=""yle="" ycolor rgcommt-fe"ibcolo 1.5pt;commt-fFl,r/oVousLdcvez bohref="/bsp;x.php?titng=Special:Userlogin&returktotitng=Intranet+de+Mich:l+Buffa%2FProjet+Blitzmax+EPU+2009><êtl" conn=cté;nae tro 1.5pt;bottom"> tdovuae=tt;=op>o 1.5pt;lefyVibltd; tdovuae=tt;=op>o 1.5pt;rtyleVibbr/ibcolo 1.5pt;w_bot_fie shads"Via>

0cm 0>Powered by bohref="http://www.mbsptouch.com>o 1.5pt;produon">MbspTouch Deki Open Soilce Edint-fntae v.8.08: 9.5pt;an styltd; /tr> var _esptims =gnew Date().getTims(); var _ndpa =g334054": 9cripn> cle="" bcoloonclick="z-nuBubing=true;"orderz-nuInfo"o 1.5pt;dz-nu" m 1pt;"display:="tex"> bcolo 1.5pt;dz-nu-=op>>cle="" bcolo 1.5pt;dz-nu-body">
  • bohref="/Special:LttyRss">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;lttyrse"oalt="" /": 9.5pt;  1.5pt;="bo">Flux RSS: 9.5pt;nae: li> li> bohref="/User:">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;lttytylre"oalt="" /": 9.5pt;  1.5pt;="bo">Utilttatlaus: 9.5pt;nae: li> li> bohref="/Template:">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;templatesroot"oalt="" /": 9.5pt;  1.5pt;="bo">Modèe s: 9.5pt;nae: li> lip 1.5pt;separatos"e: li> li> bohref="/Special:Sitemap">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;sitemap"oalt="" /": 9.5pt;  1.5pt;="bo">Pla5vduisite: 9.5pt;nae: li> li> bohref="/Special:PopularperenVibcm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;popularperenVoalt="" /": 9.5pt;  1.5pt;="bo">Peren populail"s: 9.5pt;nae: li> li> bohref="/Special:Abouo">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;abouo" alt="" /": 9.5pt;  1.5pt;="bo">A propos: 9.5pt;nae: li> /ur> cle="" bcolo 1.5pt;dz-nu-bottom">cle="" cle="" bcoloonclick="z-nuBubing=true;"o 1.5pt;dz-nu" r rg"jgeM-nuC-ftt-f"om 1pt;"display:="tex"> bcolo 1.5pt;dz-nu-=op>>cle="" bcolo 1.5pt;dz-nu-body">
  • bohref="#>o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;watch-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Surveiller: 9.5pt;nae: li> li> bohref="#attachFl,r/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;attach-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Attachelafichielaougntenstentre unae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;l"strict-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Accès l"streinftentre unae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;move-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Déplacer: 9.5pt;nae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;delete-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Supprimsr: 9.5pt;nae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;tag-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Motmipaés: 9.5pt;nae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;"jgeemail-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">Envoyelanaanenstentre unae: li> li> bohref="#/o 1.5pt;disdingd" onclick="z-nuOff('"jgeM-nuC-ftt-f');returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;"jgeproperties-disdingd" alt="" /": 9.5pt;  1.5pt;="bo">PropriétésLdcunaanenstentre unae: li> li> bohref="/Talk:Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009>o 1.5pt;" onclick="z-nuOff('"jgeM-nuC-ftt-f');">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;"jgetalkVoalt="" /": 9.5pt;  1.5pt;="bo">Pere /ur> cle="" bcolo 1.5pt;dz-nu-bottom">cle="" cle="" bcoloonclick="z-nuBubing=true;"o 1.5pt;dz-nu" r rgz-nuBacklink" m 1pt;"display:="tex"> bcolo 1.5pt;dz-nu-=op_m>>cle="" bcolo 1.5pt;dz-nu-body_m"> cle="" bcolo 1.5pt;dz-nu-bottom_m">cle="" cle="" bcoloonclick="z-nuBubing=true;"o 1.5pt;dz-nu" r rgz-nuPensCoftt-f"om 1pt;"display:="tex"> bcolo 1.5pt;dz-nu-=op_m>>cle="" bcolo 1.5pt;dz-nu-body_m" r rgz-nuToc"> ccolo 1.5pt;"jgeToc">
    Tdingpansrmatièl"s: h5> li> olom 1pt;"ltty style-typ=:="texrmargin-lefy:0px sancr_z;-lefy:15px "> li> -size1.1.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Tutospals_Blitzmaxgbrelt;infatn rg>Tutospals Blitzmaxa>

    /er>

  • li> 9.5pt2.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Le_concept_de_machine_.c3.a0_.c3.a9tafe"orelt;infatn rg>L" concept o:ptsa>

    li> 9.5pt3.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#La_sy-faxe"orelt;infatn rg>Lausy-faxe> li> 9.5pt4.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_motm_clef_.2f_typ=s_de_sonn.c3.a9e"orelt;infatn rg>L"s qotmipaef / typ=sLdcusonnschou">oe> li> 9.5pt5.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_varidings_et_ngs_c-fsta-fae"orelt;infatn rg>L"s varidingsnetsnemip-fsta-fae> li> 9.5pt6.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_ 1.5pae"orelt;infatn rg>L"s 1.5pae> li> 9.5pt7.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_fo="#unke"orelt;infatn rg>L"s fo="#unke> li> 9.5pt8.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_faefe"orelt;infatn rg>L"s faefe> li> 9.5pt9.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_bouclae"orelt;infatn rg>L"s bouclae> li> 9.5pt10.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_ olle"#unke"orelt;infatn rg>L"s olle"#unke> li> 9.5pt11.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Le_premier_affichens" relt;infatn rg>L" premier affichens> li> 9.5pt12.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_formes_basiquae"orelt;infatn rg>L"s formes basiquae> li> 9.5pt13.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_iferenVorelt;infatn rg>L"s iferen> li> 9.5pt14.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_anima#unke"orelt;infatn rg>L"s anima#unke> li> 9.5pt15.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#La_ren4, 95du_tempe"orelt;infatn rg>La ren4, 9vduitempe> li> 9.5pt16.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Mini-jeu_.e2.80.93_Premi.c3.a8res_ r.c3.a9a#unke_et_ren4, 95du_tempe"orelt;infatn rg>Mini-jeu – Premi&euvisp.l"s couale="foant-fsnetsren4, 9vduitempe> li> 9.5pt17.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#La_ r.c3.a9a#unk_dLa couale="foant-fad li> 9.5pt18.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Le_d.c3.a9placemt-f5du_joueurgbrelt;infatn rg>Le&0ais on pnlacemt-fvdui oueur> li> 9.5pt19.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#La_r">>&nbsVorelt;infatn rg>La r">>&nbs> li> 9.5pt20.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Le_scroll_z;_(d.c3.a9fie mt-f)gbrelt;infatn rg>Le&scroll_z; (0ais on pfie mt-f)> li> 9.5pt21.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_fraj(54oil"s"orelt;infatn rg>L"s fraj(54oil"s> li> 9.5pt22.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Mini-jeu_.e2.80.93_D.c3.a9placemt-f5du_joueurgbrelt;infatn rg>Mini-jeu – Dais on pnlacemt-fvdui oueur> li> 9.5pt23.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Le_mouvemt-f5dLenmouvemt-fad li> 9.5pt24.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_projectilae"orelt;infatn rg>L"s projectilae> li> 9.5pt25.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_ ollisunke"orelt;infatn rg>L"s ollisunke> li> 9.5pt26.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Mini-jeu_-_Gameplaygbrelt;infatn rg>Mini-jeu - Gameplay> li> 9.5pt27.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#La_puiss nca_dLa puiss ncaad li> 9.5pt28.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Couleur.2c_transpan nca.2c_lumi.c3.a8reVorelt;infatn rg>Couleur> transpan nca, lumi&euvisp.l"> li> 9.5pt29.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Mo4, 9_ silgbrelt;infatn rg>Mo4, 9" silclae: li> li> 9.5pt30.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_cules"orelt;infatn rg>L"s pjel>culesa>

    li> 9.5pt31.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Les_litzes_sp.c3.a9ciaux_dL"s litzesns<-align: aiauxad

    li> 9.5pt32.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Perfl,r ncanVorelt;infatn rg>Perfl,r ncana>

    li> 9.5pt33.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Cz pilant-fVorelt;infatn rg>Co pilant-fa>

    li> 9.5pt34.: 9.5pt ;bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009#Taille_du_code.2c_conv<Taillevduicode, conv<

    /er>cle="" cle="" bcolo 1.5pt;ui-msg-wrapV r rgMTMessens"om 1pt;"display: ="tex"> bcolo 1.5pt;ui-msg ui-errl,rsgV r rgMTMessensS 1pt"> bcolo 1.5pt;ui-msg-opn"> cul"> li> bohref="#/o 1.5pt;dismise"oonclick="returkaMTMessens.Hids();">litacerpaeoz-ssensclae: li>> li> bohref="#/o 1.5pt;de:pilsV r rgMTMessensDe:pilsLink" onclick="returkaMTMessens.ShowDe:pils(th: );">voiladé:pilsclae: li>> /ur> ccolo 1.5pt;ui-msg-autoclost"> Ceoz-ssenspaisparaitraadLentemporttatlau ele=""> ecolo 1.5pt;ui-msg-headerVpr rgMTMessensHeaderVible=""> ecolo 1.5pt;ui-msg-d scV r rgMTMessensDescVible=""> ecolo 1.5pt;ui-msg-d scV r rgMTMessensDe:pilsV m 1pt;"display: ="tex"> ep>Affichens Dé:pils:Couri ele=""> yle="">L e=""ycolor rgz-nuFillerVible=""ycolor rgbodyHetyleVible=""yscripn src="http://www.google-an rytics.com/urchin.js" typ=y0: 9cripn>yscripn typ=y0_uacct = "UA-68075-16";urchinTracker();: 9cripn>

    Accueil > Intranet Michel Buffa > Projet Blitzmax EPU 2009

    Projet Blitzmax EPU 2009

    De $1

     

     

    Tutoriels Blitzmax 

     

     

    Nous avons créé un jeu-vidéo complet pour découvrir autant que possible les fonctionnalités qu’offre Blitzmax en matière de programmation orientée jeux-vidéo. Notre jeu, Vibz, est un shoot them up 2D vertical. Nous aspirons à partager notre expérience à travers ce tutoriel. Celui-ci est le premier que nous écrivons et espérons qu’il est adapté. Tout conseil pour l’améliorer est bienvenu !  

    Nous allons vous présenter les aspects que l’on retrouve dans beaucoup de jeux tels que la création d’un avatar pour le joueur, son déplacement, sa capacité à agir sur son environnement, etc. Cette présentation se fera à chaque fois sur plusieurs niveaux : d’abord la base, ce que Blitzmax permet de faire en quelques lignes de code, puis ce que nous avons implémenté dans notre jeu. 

    Tout au long du tutoriel, des concepts de base de la programmation seront abordés de manière assez simplifiée. Les lecteurs ayant une bonne expérience de la programmation pourront passer ces rappels et se concentrer sur les exemples de code. Le meilleur moyen d’apprendre étant d’expérimenter, il ne faut pas hésiter à passer les bouts de code indépendants dans BlitzMax pour en éprouver le comportement.  

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Les bases de la programmation 

     

     

    Cette partie du tutoriel est un peu à part. Elle traite surtout de la syntaxe et de la manière de programmer en BlitzMax. Il n’est pas nécessaire de la connaître en entier avant de faire son premier jeu en BlitzMax, même si c’est conseillé. Cependant, de nombreux exemples du tutoriel feront référence à des notions présentes dans cette section.  

     

    BlitzMax est un langage mixte : pour utiliser les termes techniques, il est possible de l’utiliser de manière procédurale et orientée objet à la fois. Il est donc possible de définir des variables, des fonctions, des tests et des objets comme dans de nombreux langages de programmation haut-niveau. Voyons cela au cas par cas. 

     

    Le concept de machine à états 

     

    BlitzMax (comme OpenGL), peut se voir comme une machine à états. En clair, on travaille en permanence avec un certain nombre d’états (la couleur, le mode et le coefficient de transparence, la rotation, l’échelle, la police de caractère …) qui s’appliquent à chaque objet affiché. Nous les verrons en détail plus loin dans ce tutoriel. 

     

    Ces états ne changent que si on le demande explicitement et ne sont jamais remis automatiquement à leur valeur par défaut. Il faut donc toujours garder en tête dans quel état se trouve la machine avant chaque affichage et optimiser les changements d’états, qui sont coûteux pour le processeur graphique.  

    La syntaxe 

     

    Pour que l’ordinateur comprenne les instructions et informations qu’on lui donne, il faut respecter une certaine grammaire. Avant de voir le nécessaire au cas par cas, voici un aperçu de cette syntaxe, pour commencer sans se perdre. 

     

    Tout d’abord, à la fin de chaque action, il faut soit un retour à la ligne (dans la plupart des cas), soit un point-virgule, lorsque l’on veut enchaîner plusieurs actions sur une même ligne. 

     

    Comme en mathématiques, il est possible de regrouper certaines informations à l’aide de parenthèses.  

     

    Il est possible d’écrire des commentaires dans notre code, c’est-à-dire des informations qui ne seront pas interprétées par l’ordinateur. Elles ne servent qu’aux programmeurs, c’est-à-dire vous ou ceux qui vous succéderont, pour prendre des notes ou autre. Les commentaires peuvent s’écrire sur une ligne à l’aide d’une apostrophe ou sur plusieurs lignes à l’aide des mots clé  Rem et End Rem. 

     

    Afin de rendre le code plus facile à lire et à comprendre, il est fortement conseillé de l’indenter correctement. Indenter signifie décaler l’écriture du code, un peu comme les alinéas lorsque l’on écrit un texte. Le décalage se fait en général à l’aide de tabulations. Par convention, on décale le code d’une tabulation à chaque fois que l’on rentre dans un contexte indépendant. Par exemple, dans une fonction, une déclaration de classe, dans un test ou dans une boucle. A noter que les contextes tels que les boucles, les tests et autres définitions de classes ou de méthodes sont fermés non pas par des accolades mais par des End suivis du type de contexte (If, While, Type, Function, Method ...) en général. En effet, certaines exceptions sont à noter, comme nous le verrons par la suite. 

     

    Une particularité très importante de BlitzMax est qu’il n’est PAS case sensitive. Cela veut dire que vous pouvez écrire exactement le même code avec des majuscules n’importe où, il fonctionnera quand même. Il est toutefois conseillé de respecter les conventions classiques d’écriture de code pour qu’il soit plus simple à relire. 

     

    Voici un exemple de code valide regroupant ces différentes notions : 

     

    Rem   
    
    Voici un exemple de commentaire   
    
    sur plusieurs lignes  
    
    End Rem  
    
      
    
    ' commentaire sur une ligne  
    
    action1() ; action2(var1,var2,var3)   
    
    If (test())  
    
    action3(var4) ' un niveau d'indentation  
    
    If (var1 = 3)  
    
    action4(var1) ' deux niveaux d'indentation  
    
    End If' fin de contexte avec ou sans espace  
    
    EndIf ' les deux fonctionnent

    Les mots clef / types de donnée 

     

    Il existe des mots clef réservés en BlitzMax qui désignent des types ou des fonctions de base. Il est impossible de s’en servir pour désigner autre chose. Nous parlerons de certaines fonctions au cours du tutoriel. Il est tout de même important de connaître les types de donnée de base : 

     

    Syntaxe 

    Description 

    Raccourci 

    Byte 

    Entier non signé de 8 bits 

    @ 

    Short 

    Entier non signé de 16 bits 

    @@ 

    Int 

    Entier signé de 32 bits 

    % 

    Long 

    Entier signé de 64 bits 

    %% 

    Float 

    Réel de 32 bits 

    # 

    Double 

    Réel de 64 bits 

    ! 

    String 

    Chaîne de caractère unicode de 16 bits 

    $ 

    ElementType[] 

    Tableau d’éléments d’ElementType 

     

    TypeName 

    Objet du type spécifié 

     

    VariableType Ptr 

    Pointeur sur une variable 

     

    VariableType Var 

    Variable 

     

     

    Les variables et les constantes 

     

    Une variable, comme en mathématique, peut se voir comme un nom représentant une information. Cette information peut être modifiée au cours de la vie du programme et la variable associée suivra. Cela peut servir, entre autres, à stocker des informations à une place où l’on pourra les retrouver facilement.  

     

    Une variable peut être globale ou locale. Les variables globales sont « visibles » à n’importe quel endroit du programme alors que les variables locales ne le sont que dans le contexte où elles ont été définies. 

    Il est également possible de définir des constantes. Cela permet de stocker une information qu’il sera impossible de modifier dans le programme sans erreur à la compilation. 

     

    En BlitzMax, les variables ont un type qu’il faut préciser à leur création. Voici un exemple de création et d’utilisation de variables en BlitzMax : 

     

    Const longueur:Float = 15.5 ' constante 

    Global largeur:Float = 10 ' variable globale 

    Local aire:Float = longueur*largeur ' variable locale 

    Les classes 

     

    BlitzMax, en tant que langage orienté objet, permet la définition de classes. Les classes représentent un concept, une catégorie d’objets. Les objets, ou instances de classe, peuvent correspondre à des objets du monde réel (par exemple notre bâtiment des Templiers de l’Ecole Polytech’Nice), les classes correspondent à une entité abstraite de niveau supérieur (en l’occurrence le concept de « bâtiment »). Les  classes rassemblent les attributs (définissant l’état) et les méthodes (définissant les comportements) communs à une catégorie d’objets. 

     

    Les classes en BlitzMax peuvent être abstraites et dériver d’autres classes. Elles peuvent posséder des attributs et des méthodes qui leur sont propres. 

     

    Par exemple, voici la classe TEnemyExplosion qui dérive de la classe TExplosion dans Vibz :  

     

    Type TEnemyExplosion Extends TExplosion  

     

        Function Make(x,y,MaxRadius# = 10, growSpeed = 1) 

            Local Explosion:TEnemyExplosion = New TEnemyExplosion 

           explosion.x = x 

           explosion.y = y+60 

           IfRand (1,2) = 1  

               explosion.image = explosionAnimImage 

           Else  

               explosion.image = explosionAnimImage2 

           EndIf 

           explosionlist.AddLast (explosion)       

        EndFunction 

     

    EndType

    Les fonctions 

     

    Les fonctions sont des programmes dans le programme. Elles servent en général à donner un résultat dépendant de la ou des valeur(s) entrée(s) dans celle-ci. Cela peut être explicite ou implicite. En effet, parfois, il n’y a pas de valeur d’entrée ni de sortie indiquée. Dans ces cas-là, le plus souvent, une action est appliquée aux valeurs globales du programme ou aux attributs de classe. 

     

    En BlitzMax, de nombreuses fonctions de base existent déjà. Elles sont répertoriées et expliquées dans la documentation. 

     

    Voici un code très simple de fonction valide (et inutile ; c’est pour l’exemple !). Elle retourne le résultat de l’addition des variables a, b et c.  

     

    Function add%( a% , b% , c% = 0 ) 

        Return a + b + c 

    EndFunction 

     

    Pour l’utiliser dans le code, il est nécessaire de donner au moins deux arguments, et possible d’en donner un troisième. En effet, si l’on n’affecte pas de valeur à l’argument « c », il aura par défaut la valeur 0. Par exemple, result vaudra ici 16 : 

     

    Local a%=1 

    Local result% = add(a,15) 

    Les tests 

     

    On utilise un test lorsqu’on veut vérifier si une condition est bien remplie et effectuer une action en fonction du résultat. Avant d’écrire la première condition d’un test, il faut écrire If. Avant de tester d’autres conditions, on écrit Else If. Enfin, avant d’effectuer l’action par défaut, on écrit Else. Il peut être utile d’utiliser Then après une condition pour indiquer que l’on va effectuer une action par la suite (notamment si l’on veut le faire sur la même ligne). Pour fermer un test, on écrit EndIf ou End If. 

     

    Pour simplifier, il n’est pas nécessaire de finir les tests comportant seulement un If par un EndIf. Voici par exemple comment l’on change la difficulté du jeu en appuyant sur une touche dans le menu : 

     

    IfKeyHit(KEY_1) Then Difficulty = 1 

    IfKeyHit(KEY_2) Then Difficulty = 2  

    IfKeyHit(KEY_3) Then Difficulty = 3 

     

    Les boucles 

     

    Une boucle permet d’exécuter une action un certain nombre de fois. Elle est composée de la condition de sortie et de l’action elle-même. La condition de sortie peut se présenter de plusieurs manières et cela donne le type de boucle : 

     

    a.     Les boucles for : 

     

    Il y a trois manières de les utiliser : avec To, Until ou EachIn. Les deux premiers sont des conditions sur des valeurs numériques. Avec To, la condition de sortie est atteinte lorsque la valeur testée atteint la valeur de test. Avec Until, la sortie est atteinte à l’itération précédant la valeur de test. Il est possible de définir un pas (Step), un décalage (par défaut 1) pour ces boucles. Enfin, avec EachIn, l’action de la boucle s’effectue sur tous les membres d’une collection. 

     

    ForLocal x% = 0 To 20 Step 2 

        Print x/2 

    Next 

     

    ForLocal x% = 0 Until 11 

        Print x 

    Next

     

    Local array[]=[0,1,2,3,4,5,6,7,8,9,10] 

    ForLocal x% = EachIn array 

        Print x 

    Next 

     

     

    b.     Les boucles while : 

     

    Les boucles while s’exécutent tant que leur condition n’est pas atteinte. 

     

    Local x% = 0 

    While x < 11 

        Print x 

        x:+1 

    Wend 

     

     

    c.      Les boucles repeat : 

     

    Ce sont exactement les mêmes que les boucles while sauf que la condition de sortie s’écrit à la fin. A la place de la condition de sortie, on peut utiliser Forever pour que la boucle s’exécute indéfiniment. 

     

    Local x%=0

    Repeat  

        Print x 

        x:+1 

    Until x = 11

     

    Cependant, quelque soit le type de boucle, il est toujours possible de changer de type de boucle en réécrivant la condition de sortie pour obtenir exactement le même résultat, comme dans les exemples précédents. 

     

    Pour finir sur les boucles, il faut savoir que dans un programme BlitzMax, on utilisera en général une boucle principale qui ne se terminera que lorsque l’utilisateur voudra fermer le programme. Cette boucle principale sera exécutée systématiquement en fonction de la fréquence de rafraîchissement de l’application. Nous parlerons de « tour de boucle » dans la suite du tutoriel pour représenter une exécution de cette boucle principale. 

    Les collections 

     

    Les collections servent à stocker plusieurs variables au même endroit. En BlitzMax, il existe trois collections de base : les tableaux, les listes et les maps. Leur utilisation reste très classique.  

     

    Les tableaux se définissent et s’utilisent ainsi : 

     

    Local nameList$["alpha","bravo","charlie","delta","echo"] ' Crée un tableau composé de 5 Strings 

    Local a$ = nameList[0] ' La variable a aura la valeur alpha 

     

    Comme souvent, les tableaux sont indexés à partir de 0. Les variables du tableau sont toutes du même type, défini selon le tableau. A noter qu’il peut également exister des tableaux à plusieurs dimensions. 

     

    Les listes  se définissent et s’utilisent ainsi :  

     

    Global alphabet:TList = CreateList() 

    alphabet.addFirst("b") 

    alphabet.addLast("c") 

    alphabet.addFirst("a") 

    alphabet.addLast("d") 

     

    Cette liste aura dans l’ordre les caractères a, b, c et d. On peut entre autres supprimer les éléments d’une liste, vérifier qu’elle contient un élément donné et boucler facilement dessus avec EachIn.  

     

    Les maps se définissent et s’utilisent ainsi théoriquement : 

     

    Global alphabetMap:TMap = CreateMap() 

    alphabet.insert(2,"b") 

    alphabet.insert(3,"c") 

    alphabet.insert(1,"a") 

    alphabet.insert(4,"d")  

     

    Nous avons précisé ici « théoriquement » car nous n’avons pas réussi à créer de maps bien qu’elles existent dans la documentation. Peut-être n’existent-elles que dans la dernière version de BlitzMax que nous ne possédons pas. 

     

     

     

     

    Je veux créer ! 

     

    Bien, maintenant que nous sommes d’accord sur la syntaxe et les détails du langage, passons aux choses sérieuses. Nous allons voir comment obtenir rapidement un aperçu de la puissance de BlitzMax par l’affichage simple de graphismes. 

    Le premier affichage 

     

    Commençons par afficher une fenêtre avec une résolution de 800 par 600 pixels. Nous voulons qu’elle reste affichée tant qu’on ne ferme pas le programme. Pour cela, trois lignes de code !  

     

    Graphics 800,600 ' Affichage de la fenêtre 

     

    Repeat' Boucle principale 

    ' ... Ici, les futurs affichages 

    UntilAppTerminate() ' Condition de fin : lorsque l'utilisateur ferme la fenêtre 

     

    A noter que la fonction Graphics peut avoir plus d’arguments : mode fenêtré ou non, taux de rafraîchissement des images ... 

     

    Il faut également noter que le système de coordonnées est le suivant : l’origine se trouve dans le coin supérieur gauche de la fenêtre. L’abscisse augmente donc vers la droite et l’ordonnée vers le bas. 

    Les formes basiques 

     

    BlitzMax permet de dessiner des rectangles, des ovales, des lignes, des points et du texte, respectivement à l’aide des fonctions : DrawRect, DrawOval, DrawLine, Plot et DrawText. Il faut leur renseigner les dimensions et la position de la forme. 

     

    Deux petites subtilités. Tout d’abord, pour afficher effectivement ces formes, nous allons, à chaque tour de boucle, effacer le contenu actuel de l’écran et afficher son nouveau contenu. Cela se fait respectivement à l’aide des fonctions Cls (pour clear screen) et Flip. 

     

    Ensuite, nous allons utiliser une fonction intéressante de BlitzMax qui nous renvoie la position actuelle du curseur pour positionner notre rectangle par exemple. Voici comment tout cela fonctionne : 

     

    Graphics 800,600 ' Affichage de la fenêtre 

     

    Repeat' Boucle principale 

     

        Cls 

            

        DrawRectMouseX(), MouseY(), 20,20 ' Position puis dimension 

        DrawOval 20,200,50,100 ' Position puis dimension 

        DrawLine 0,0,800,600 ' Positions des deux extrémités 

        Plot 50,500 ' Position du point 

        DrawText"What's up World ?",30,400 ' Chaîne de caractères puis position 

         

        Flip 

     

    UntilAppTerminate() ' Condition de fin 

    Les images 

     

    Pour afficher des images, il faut au préalable charger l’image concernée dans un objet de type TImage, puis l’afficher simplement avec DrawImage. 

     

    Graphics 800,600 ' Affichage de la fenêtre 

     

    Global image:TImage = LoadImage("music_tribal.jpg") ' Chargement de l'image dans un objet 

     

    Repeat' Boucle principale 

     

        Cls 

            

           DrawImage image,300,200 ' Affichage de l'image 

         

        Flip 

     

    UntilAppTerminate() ' Condition de fin 

     

    Pour travailler l’affichage de ces images à l’aide de BlitzMax, de nombreuses fonctionnalités vous sont proposées. Faites un tour dans la section effets spéciaux pour y trouver votre bonheur ! 

    Les animations 

     

    Les animations en BlitzMax sont tout simplement des parties d’images indexées. Il n’y a pas de moyen simple en BlitzMax de faire des interpolations de mouvement ou de déformation. Leur utilisation est rigide mais cela a l’avantage d’être facile à comprendre et à gérer. 

     

    Pour créer une animation, il suffit de charger une image d’un format quelconque (bmp, jpg, png …) en précisant les dimensions d’une « frame » de l’animation, l’index de la première frame qu’on utilisera dans cette image pour l’animation et l’index de la dernière.  

     

    Pour l’utiliser, il suffit de dessiner l’image comme précédemment mais en précisant la frame que l’on utilise. Pour faire défiler les frames, il est possible d’utiliser de nombreuses astuces. Créer sa propre classe d’animation, gérer la fréquence de défilement en fonction des tours de boucles ou du temps de jeu, etc. 

     

    Voici un exemple simple d’animation qui se répète : 

     

    Graphics 800,600 ' Affichage de la fenêtre 

     

    Global explosion:TImage = LoadAnimImage("explosion.png",200,250,0,12)  

    ' Chargement de l'animation dans un objet 

    Global loopsCount% ' Compteur de tours de boucles 

     

    Repeat' Boucle principale 

     

        Cls 

        loopsCount :+ 1  

        DrawImage explosion,300,200, loopsCount/6 Mod 12  

           ' Affichage de l'animation, défilement de frames tous les 6 tours de boucle 

        Flip 

     

    UntilAppTerminate() ' Condition de fin 

     

    La gestion du temps 

     

    Elle est facilitée par la fonction Millisecs() qui renvoie le temps courant en millisecondes comme son nom l’indique. Cela peut être utile pour afficher la durée d’une partie, gérer des « timers », des délais d’action, et bien d’autres. Voyons tout de suite un exemple de gestion du temps dans le mini-jeu que nous vous proposons d’implémenter dans ce tutoriel. 

     

    Mini-jeu – Premières créations et gestion du temps 

     

    Essayons de créer des plateformes pour notre mini-jeu. Il va nous falloir une structure pour les stocker et les afficher à chaque tour de boucle. Pour les représenter, nous utiliserons simplement des rectangles. 

     

    Pour gérer le temps, nous utiliserons une variable globale définie au lancement du jeu par la valeur de Millisecs(). Le temps courant de la partie sera donc le temps courant, Millisecs(), moins la valeur d’origine. Ajoutons également une variable pour garder le meilleur score du joueur au clavier. Nous les afficherons ensuite dans la boucle principale. 

     

    Attention : il faut bien réfléchir à ce que l’on met dans la boucle principale pour ne pas surcharger la mémoire ou engendrer des comportements indésirables. Pour simplifier la lecture du code, nous allons placer au maximum les actions dans les classes utilisées. 

     

    Graphics 800,600 

     

    ' Liste des plateformes 

    Global platforms:TList = CreateList() 

    'Gestion du temps 

    Global timeOrigin= MilliSecs() 

    Global survival = 0 

     

     

    'Classe pour les plateformes 

    Type Platform 

        Field x% 

        Field y% 

        Field height% = 20 

        Field width% = 200 

         

        ' Fonction de création des plateformes 

        Function create(x,y,w,h) 

           pf:Platform = New Platform 

           pf.x = x ; pf.y = y 

           pf.width = w ; pf.height = h 

           platforms.addLast(pf) 

        EndFunction 

     

        Function Update() 

           ForLocal pf:Platform = EachIn platforms 

               DrawRect (pf.x,pf.y,pf.width,pf.height) 

           Next  

        EndFunction   

         

    EndType 

     

    ' Création des plateformes 

    Platform.create(0,500,800,20) 

    Platform.create(10,450,50,10) 

    Platform.create(500,450,50,10) 

    Platform.create(300,350,50,10) 

    Platform.create(200,400,50,10) 

     

    ' Boucle principale 

    Repeat 

     

        Cls 

     

        Platform.Update()' Affichage des plateformes 

         

        DrawText"Survival time : " + (MilliSecs() - timeOrigin)/1000 + " seconds", 20, 30 

        DrawText"Survival record : " + survival + " seconds", 20, 10 

     

        Flip 

     

    UntilAppTerminate()  

    La création dans Vibz 

     

    Dans Vibz, les chargements de toutes les images et animations se font dans des fichiers spécifiques. La plupart sont stockées dans des variables globales, que l’on peut utiliser dans le code à tout moment. Ainsi, elles ne sont chargées qu’une fois. 

     

    La plupart des objets possèdent leur propre méthode Update, appelée à chaque tour dans la boucle principale, qui régit leur comportement et leur affichage. Il existe différentes méthodes pour structurer un programme, n’hésitez pas à en tester plusieurs et à choisir celle qui vous correspond le mieux. 

     

     

    Après un essai de gestion automatique des animations par une classe spéciale, il s’est avéré plus simple de gérer les animations « à la main » dans les classes qui les utilisaient. 

     

    Voir les fichiers Effets.bmx et Classes.bmx. 

     

    Je veux du mouvement ! 

     

    Le déplacement du joueur 

     

    Il existe encore une fois beaucoup de façons de gérer le mouvement dans BlitzMax. Voulez-vous utiliser le clavier ou la souris ? Ces événements sont extrêmement simples à gérer, voyons cela tout de suite.  

     

    A la souris : comme vu plus haut, on peut connaître à tout moment la position du curseur à l’aide des fonctions MouseX() et MouseY(). Il est alors très simple de modifier la position d’un objet en modifiant son attribut en fonction de la position de la souris. Par exemple :  

     

    DrawOvalMouseX(), MouseY(), 20,20 

     

    Au clavier : le plus simple est d’effectuer un déplacement du joueur à chaque appui sur une touche. Par exemple, pour les touches directionnelles :

     

        IfKeyDown (Key_Right) Then player.x :+ player.speed 

        IfKeyDown (Key_Left) Then player.x :- player.speed 

        IfKeyDown (Key_Up) Then player.y :- player.speed 

    IfKeyDown (Key_Down) Then player.y :+ player.speed 

     

     

    La rotation 

     

    La rotation dans Vibz se gère à l’aide de la machine à états. En d’autres termes, lorsque la rotation aura été modifiée, elle s’appliquera à tous les objets affichés jusqu’à ce qu’on la remette à zéro. Dans BlitzMax, la rotation s’exprime en degrés. Le rectangle dessiné ici sera incliné de 45 degrés. 

     

    SetRotation 45 

    DrawRectMouseX(), MouseY(), 20, 20 

    SetRotation 0

    Le scrolling (défilement) 

     

    Ajoutons à présent un fond à notre écran. Il suffit de dessiner une image de la taille de la fenêtre en premier dans notre boucle principale pour ne pas cacher les autres objets. 

     

    Nous pouvons ensuite le faire bouger par exemple en fonction du temps ou en fonction des déplacements du joueur. Cela s’appelle le scrolling. BlitzMax permet de réaliser le scrolling automatiquement en appelant simplement la fonction TileImage à la place de la fonction DrawImage. Par exemple, avec bg1 l’objet TImage du fond : 

     

    TileImage bg1,200 + mapX,mapY 

     

     Pour que l’effet soit réussi, il faut que le fond d’écran soit raccordable, c’est-à-dire qu’il n’y ait pas de frontière visible lorsque l’on accole ce fond à lui-même, comme dans une mosaïque. La plupart des éditeurs graphiques possèdent des algorithmes pour rendre une image raccordable. 

    Les trajectoires 

     

    Les trajectoires des objets peuvent encore une fois être gérées de nombreuses manières. Nous verrons ici comment les implémenter de manière simple. 

     

    Le principe d’implémentation de la trajectoire consiste à mettre à jour la position de l’objet concerné en fonction du temps (ou ici, des tours de boucle). On peut alors jouer avec les fonctions mathématiques pour donner des trajectoires linéaires, sinusoïdales, circulaires ou autres aux objets. 

    Mini-jeu – Déplacement du joueur 

     

    Il faut pour cela rajouter dans notre jeu une classe « joueur », une variable globale qui instancie cette classe, et sa fonction de mise à jour dans la boucle principale. Notre joueur sera représenté par un cercle blanc. 

     

    Avant la boucle principale : 

     

    Global player:TPlayer = New TPlayer 

     

    ' Classe pour le joueur 

    Type TPlayer 

        Field x# = 400 

        Field y# = 300 

        Field speed = 15 

         

        Function Update() 

           IfKeyDown (Key_Right) Then player.x :+ player.speed 

           IfKeyDown (Key_Left) Then player.x :- player.speed 

           IfKeyDown (Key_Up) Then player.y :- player.speed 

           IfKeyDown (Key_Down) Then player.y :+ player.speed 

           DrawOval player.x,player.y,20,20 

        EndFunction   

     

    EndType 

      

    Dans la boucle principale : 

     

       TPlayer.Update() ' Gestion du joueur 

     

    Le mouvement dans Vibz 

     

    Dans Vibz, le joueur se déplace à l’aide du clavier, d’une manière similaire à ce que l’on vient de voir. Le vaisseau possède sa propre vitesse qui ne change jamais. 

     

    Les ennemis utilisent des trajectoires complexes, les B-Splines. Ils suivent ces trajectoires à vitesse constante. Ces trajectoires sont calculées à partir de points donnés dans les fichiers des différents niveaux du jeu. 

     

    Le fond d’écran défile en permanence à la verticale et défile horizontalement avec le déplacement du joueur. Le fond d’écran est en fait composé de deux fonds superposés dont les vitesses de défilement diffèrent, afin de donner un effet de profondeur à l’ensemble. 

     

    Une des grandes originalités de Vibz est le système de ralenti porté au gameplay des shoot them up. En effet, en appuyant sur Shift gauche, on active le mode ralenti, ce qui ralentit tout l’environnement du joueur (projectiles et vaisseaux ennemis, défilement du paysage), mais pas le joueur, qui a alors un avantage conséquent pour une durée limitée. 

     

    Voir les fichiers xml des niveaux ainsi que Vibz.bmx et Classes.bmx . 

     

     

    Je veux de la puissance ! 

     

    Les projectiles 

     

    Pour gérer des projectiles, vous aurez besoin de types spécifiques. Ils auront au minimum leur position en attribut et une fonction pour calculer leur trajectoire et les afficher. Un timer est nécessaire si vous voulez que le joueur ne puisse tirer qu’avec un délai. A vous de voir si vous avez besoin de plus !  

     

    Les stocker dans une liste facilite leur mise à jour, à l’aide d’une boucle. Les projectiles seront supprimés de la liste s’ils sortent de l’aire de jeu. Il faudra ensuite tester les collisions avec les cibles à chaque tour de boucle.   

     

    Voici un exemple qui peut servir de base pour vos projectiles. Celui-ci crée un projectile avec une direction aléatoire et une trajectoire linéaire. N’oubliez pas de définir une liste qui contiendra ces projectiles. 

     

    Global projectiles:TList = CreateList()

     

    Type TProjectile 

     

        Field x# 

        Field y# 

        Field angle# 

        Field speed# = 10 

     

        Function create(x,y) 

           bulletTimer = MilliSecs() 

           proj:TProjectile = New TProjectile 

           proj.x = x 

           proj.y = y 

           proj.angle = Rand(0,8) * 45 

           projectiles.addLast(proj) 

        EndFunction 

         

        Function update() 

           For proj:TProjectile = EachIn projectiles 

               proj.x :+ proj.speed * Cos(proj.angle)  

               proj.y :+ proj.speed * Sin(proj.angle)  

               DrawOval proj.x,proj.y,20,20 

               If proj.x<0 Or proj.x>GraphicsWidth() Or proj.y<0 Or proj.y>GraphicsHeight() Then projectiles.remove(proj) 

           Next 

        EndFunction 

     

    EndType 

     

    Pour l’utiliser, il faudra appeler la fonction create à partir d’un événement clavier par exemple : 

     

    IfKeyDown (Key_Space) And bulletTimer < MilliSecs()-1000 Then TProjectile.create(player.x, player.y) 

     

    Ici, le projectile part du joueur et il faut attendre une seconde avant de pouvoir tirer à nouveau. Il faudra donc ajouter le bulletTimer quelque part, en variable globale par exemple. Il faudra ensuite appeler la fonction update de la classe dans la boucle principale : 

     

    TProjectile.update()  ' Gestion des projectiles 

    Les collisions 

     

    Ce paragraphe aurait pu se trouver tout aussi bien dans la partie « Mouvement » car nous allons parler à présent de tous types de collisions : collisions entre le joueur et le paysage, collisions entre des projectiles et des cibles, etc. 

     

    Comme à l’accoutumée, plusieurs façons de faire : 

     

    A la main :  

     

    Penchons-nous sur la collision la plus simple : lorsque deux rectangles se touchent ou se chevauchent. Voici une manière rudimentaire de l’implémenter :  

     

    Function rectsOverlap(x0, y0, w0, h0, x2, y2, w2, h2) 

        If x0 > (x2 + w2) Or (x0 + w0) < x2 ThenReturnFalse 

        If y0 > (y2 + h2) Or (y0 + h0) < y2 ThenReturnFalse 

        ReturnTrue 

    EndFunction 

     

    Pour l’utiliser, il faut bien sûr donner la position et la dimension de chaque rectangle impliqué. Au passage, on voit avec cette fonction deux subtilités : quand on ne déclare pas de type en BlitzMax, le type par défaut est Int. Deuxième subtilité, un booléen en BlitzMax n’est autre qu’un Int avec False = 0 et True = autre chose.  

     

    Un peu plus complexe, la collision entre un rectangle et un cercle :  

     

    Function circRectsOverlap(x0, y0, w0, h0, cx, cy, r) 

        testX=cX 

        testY=cY 

        If TestX < x0 Then TestX=x0 

        If TestX > (x0+w0) Then TestX=(x0+w0) 

        If TestY < y0 Then TestY=y0 

        If TestY > (y0+h0) Then TestY=(y0+h0) 

     

        Return ((cX-TestX)*(cX-TestX)+(cY-TestY)*(cY-TestY))<r*r 

    EndFunction 

     

    Les tests à la main peuvent être utiles, soit pour expliciter le code (mais on peut considérer que les fonctions fournies par BlitzMax sont déjà assez explicites), soit pour faire des tests que BlitzMax ne fait pas de base, comme par exemple des tests de collision sur une seule arête d’un rectangle, etc. 

     

    ImagesCollide :  

     

    Cette fonction teste si deux images entrent en collision au pixel près ! Voici sa sil près ! Voici sa sil près ! Voici sa sil prèsr; wf"> x#ci miluri8oNormal" style="text-align: justify;"> 

    Function rectsOverlap(x0, y0, w0, h0, x2, y2, w2, h2)&nbsan>

    ratioassez em="font-u joueur (pute;clare pas dn styn>

    xmlns:o="extvoie="">Ici, le projectile part du joueur et il style=""> avec fa y IntImagesCollide :  

    Imagetion: n: Cown"> 

    A la main :  

    &nbstyl stylla mai

    Un peu plus complexe, la collision entre un rectangle et un cercle :  

    Un peu plus complexe, la collision entre un rectangle et un cercle :  Intnere un rectangSyle="">Un peu plus complexe, la collision entre un rectastyle="font-size: 9.5pt; font-family: Courier; color: black;"> 

     Intnere un rectangEcr le c;A la main : IntCe paragraphA la main :  

     

    Un peu plus complexe, la collision entre un rectangle et un cercle :  Un peu plus complexe, la collision entre un rectastyle="font- x#ci miluri8oNormal" style="text-align: justify;">Function&nbsan>

      

     Un peuentre un rectangle et un cercle :  

    Ce paragraphen style="=""i"0);;">&ntyle="">Intbsp;Mo(54, aule="font-family: Courier;">Intrre">LeCe paragtionse gxrgb(0, l" "tylee d&rsqcreax sont d&">&ne d&n: justify;ilas,rgb(0, l" n>

    d;<,al" style sur la cfamiifispan style="tyle="">Int. Lspan>rgb(0, l" eff Co>e d&n: justi:p xa marxtvoyCe paragrtz;IntInt 

    Un peut en collision au pixel près ! Voici sa sil près ! Voici sa sil près ! Voici sa sil prèsr; wf"> x#ci miluri8oNormal" style="textier; coloEcr

    EndFunction 

    Then TestY=(y0+h0) 

    Function rectsOverrier; color: black;"> TestY=(y0+h0) 

      

    Then TestY=(y0+h0)        proj:TProjectile = Then TestY=(y0+h0) 

    Then TestY=(y0+h0) 

    x#ci miluri8oNormal" style="texto:p>

     

    Function
    rectsOverlap(x0, y0, w0, h0, x2, y2, w2, h2)&nbsn>

    Function rectsOverlap(x0, y0, w0, h0, x2, y2, w2, h2)&nbsn>

     

    Function
    rectsOverlap(x0, y0, w0, h0, x2, y2, w2,s:o="#unknown"> 

     

    ImagesCollide :  

    Imagetion: ndecorwn"> 

    A la main :  

    n#unknodo;ubsp;»(ne boucle. Les prne;"> 

    nbspposse; p, ilne boucle. Les prcombinndre ont supous tion: ndecorwr &agration: n: Coo0, 160aalemeeoassez em=";"an>

    Un peu plus complexe, la collision entre un rectangle et un cercle :  Un peu plus complexe, la collisiont; font-family: Courier; color: black;">Function Un peuentre un rectangAr l’ut> rasur la costy,rave;n>

    n>

    o:p>>  ' Gestion des projectiles 

    Les collisions 

    Intwn"> 

    Un peu plus complexe, la collision entre un rectangle et un cercle :  Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0)  pan style="">     KeyDp;:lass="MsoIntebulletTimer < If

    If TestY < y0 Function Testeditable">Les collisions 

    ass="MsoIntelt;  

     Un peuentre un rectangditable">Les collisions 

    Un peu plus complexe, la collision entre un rectangle et un cercle :  

    <utiliser,le="font-family: Courier;">Intwdueaquo;&class="rclass="MsoNormal" style="text-align: justify;">Un peu plus complexe, la collision entre un rectangle et un cercle :  Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0)  pan style="">     MouseDp;:lass="MsoIntebulletTimer < Then TestY=(y0+h0) &nbsn>

    TestY=(y0+h0)  pan style="">     MouseXlass="MsoIntebulletTimer < If MouseXlass="MsoIntebulletTimer < If MouseYlass="MsoIntebulletTimer < If MouseYlass="MsoIntebulletTimer <

    TestY=(y0+h0) &nbsn>

    TestY=(y0+h0)  DrawTyle= lang="EN-USrier; color: black;"> TestY=(y0+h0)  TestY < y0

    If TestY < y0 Then TestY=y0 

    TestY=(y0+h0)  pan style="">   

    If TestY < y0

    Then TestY=y0 

    Function rectsOverlap(x0, y0, w0, h0, x2, y2, w2,s:o="#unknown"> 

    Then 

     

    ≮ >  ' Gestion des projectiles 

    sancr_z; sancrtz;

    Les collisions 

    xinknocinql faudra ux typ sbla; au"iCe paragrtroutys,&eacubombyle=tmeacutiro; cnemi". Cyle">lor: bla;lla mag faudra rCe paragrtzjoueulign: jum pluncclass="MsoNormal" style="text-align: justify;">Un peu plus complexe, la collision entre un rectangle et un cercle :  

    p;<,anrim&ur (traor: oir-ulieCe paragr le /o:p>e voit see="tstp> encclass="MsoNormal" style="text-align: justify;">Un peu plus complexe, la collision entre un rectangle et un cercle :  

    cha,&eale 0);srouty

    pospanx),ext-decormet#unkecoow,c). C="font-os-decoeacutp>e avalp>chatzMamini-">lor: bla;lanimCe paragrtlp>cpe par d &nbsNp;&"r q="MsoIntnnerlble 0)a, 160);">FunctionUn peu plus complexe, la collision entre un rectangle et un cercle :  

    cha,&eale 0);srouty

    C&oait paont-os-de". Cyle">lor: bla;lla 0); oir-utrleutiliser,le="font-fa 0,le=ncclass="Mont-familxemp0); oreb. C="tesr,ne boid; sMontterroNor 0,jeuy:"ext-indent: 0ce="texo="#unkCz expcparagrtlp>cnospan strgraveir->utilise,cno;pavo;paoffmagce"#ual" style="textssmaan>"MsoNormal"s style="text-aliagrtzjouerebxa maroIntnnerlbl,plu op/span>IntUn peu plus complexe, la collision entre un rectangle et un cercle :  Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0)&>

    ≮ >    

    .t ... 9.5pt; font-faan>

    wn">  TestY < y0  

    wn">  TestY < y0

     

     

    wn">  TestY < y0

     

      pan style="">    w: 9.5pt;   on: n: Colass="MsoIntebulletTimer < Then< lang=.tzMax)* TestY=y0 

    >&nbs style="font-faan>

     

     Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0)<as&ergb>asy:"ext-indent: 0ce="texo="#unkrsqcr dInt TestY=(y0+h0)Un peu plus complexe, la collision entre un rectangle et un cercle :  Un peuentre un rectangditable">Les collisions 

     known67le=91, 222)

    Jepouaxa marlitzeeaspspan>  

    Ltiles 

    xinknocinql faudra ux typnql marxumaan>f">utilises l" /tclinalaverpaee machinatzMamini-"o:p>Un peu plus complexe, la collision entre un rectangle et un cercle :  

    cha,&eale 0);srouty

    rsqcr dsomaan>corwr &agratmais on pfini/spaculfulmil, lieCeefficiep unktz;&(54,vynodo ourier;">IntUn peuentre un rectangditable">Les collisions 

    TestY=(y0+h0)  pan style="">     

    TestY=(y0+h0)  pan style="">    x#ci miluri8oNormal" style="texto:p> pan style="">    x#ci miluri8oNormal" style="texto:p> pan style="">    Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) utilise bouciler ompknodo;aal" sleorvan: ndeergbmais on pfoe="al" sty> o:p><. Lan>"Mo 160)pknodo;ad-family: Cou">wn">  TestY < y0 0,le="fulmil, 0,0 ourier;">tY "al" sthhoune. Ldle="font-familyd-family: Cou">wn">  TestY < y0 poueefficiep uan trustn>wn">  TestY < y0 paculfn styleees),doi sparrelbjel>span style=/>Un peuentre un rectangditable">Les collisions 

    ddingstyll"#u"_z;="0"styllancr_z;="0"sid; bo="1"s collisionTdingGrid"es&lapsier">&lapsispan Cou">wn">  span pspan pspan pdiv style="border-solid; border-col1pto1pto1ptoor:7"mlsancr_z; Cou">wn">  

     wn">  

     wn"> 

    utilises unce"#amilyr&laqd&lsupspan> 

     wn">  

     wn"> 

    Int" sleor

     

     wn">  

     wn"> 

    utilises er trustn><-serwupan>/xgrouty"seead 

     wn">  

     wn"> Ce paetylessdculfulmila marop clpaal" se="fo>utilise bo;jouecelaoyll sa marop clpamais on pj;jouecelarouty"seead 

     wn">  

     wn"> Ce paetylessdculfulmila marop clpaal" smultipr: bla;llaiagait">Ltiles 

    sancr_z;Les collisions 

    ass="MLation: n: Coo0, 160mo4, 9 blur"ed">nan>parlitze i-f Co,;e ured="seees),Censuty,rl" /tclin><. C=rlass="Msectiummais on pn>Intnodoe/span>Int TestY=(y0+h0)bjel>rsdcu;-align: s,ant-fa 0,sa&"MsoNormal"y:">Un peu plus complexe, la collision entre un rectangle et un cercle :  

    cha,&eale 0);srouty

    Dlsul" sp;Int TestY=(y0+h0)bjel>rsdspan>utilise boetsdspan>utilise by:">Un peu plus complexe, la collision entre un rectangle et un cercle :  

    cha,&eale 0);srouty pan style="">     

     pan style="">    TestY=y0 

     pan style="">    w: 9.5pt;   on: n: Colass="MsoIntebulletTimer < TestY=y0 

     pan style="">   

    TestY=y0 

     pan style="">    TestY=y0 

    TestY=y0 

    Then<1-csul="x style="font-size: 9.5pt; font-family: Coulap(x0, y0, w0, h0, x2, y2, w2,s:o="#unknown"> 

     

     

     

     pan style="">    Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

    x#ci miluri8oNormal" style="texto:p> pan style="">    TestY < y0  pan style="">    Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

     pan style="">     Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

    &&nbsendpan style="">≮ x#ci miluri8oNormal" style="texto:p> pan style="">    &&nbsendpan style="">≮ x#ci miluri8oNormaxmlns:o="#unknown"> wsize: 9.5pt; fondecvivalo=fmnbsp;     pan style="">     

    sancr_z;culesVibzmedium 1.5pt; padding: 0cm 0cm 1pt;"> Lan>culesa id="Les_collisions">

    Les collisions Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0)cule nparagrtlp>c; <o:ppmaroI l"r qlesa id="Les_collisions">

     <-o:p>

     style="">Test> variaTest> wetyleo:">Test> an sty7e-t stye-hetyleo:">Test> an s-ad="#u:e="textnbsp;stretcho:">Test>0ce="text-indent: 0cNormalNormalNormalNormalont-size: 9.5pt; 9.5pt;!--[ensti]--/o:p>culet-duiesonn=rlass=van: n/initialeiser,nsbsoattributagrtzjaan>Intculeby:">Un peu plus complexe, la collision entre un rectangle et unLttyPar" /tphCxSpLast miluri8oNormaxmlns:o="#unknown"> <-o:p>

     style="">Test> variaTest> wetyleo:">Test> an sty7e-t stye-hetyleo:">Test> an s-ad="#u:e="textnbsp;stretcho:">Test>0ce="text-indent: 0cNormalNormalNormalNormalont-size: 9.5pt; 9.5pt;!--[ensti]--/o:p>Intr cnemi"ostiitr cnemitffich:,nrtzjoue0ais on ptrurrelauliduoe/span>Un peu plus complexe, la collision entre un rectangle et un cercle :  

    ;&"r qotlau="#uvisp. cule ont-znimpred=t-fnaooNormal" mt-feadInt TestY=(y0+h0) 

    wn">  TestY < y0 Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

     

    <: 9.5pto:p> 

    >&nbsv ttify;">>&nbs style="font-faan>

     

     

     

     

     

    TestY=y0&span>

    TestY=y0&le=""> pan style="">    TestY=y0 

    TestY=y0 

    TestY < y0 TestY < y0 TestY < y0 TestY < y0 TestY=y0 

    TestY=y0 

    TestY < y0 TestY=y0 

     pan style="">    Un peu plus complexpt; font-family: Courier; color: black;lack;"> TestY=y0 

    TestY=y0 

    TestY=y0 

    &&nbsendpan style="">≮ TestY=y0 

    &&nbsendpan style="">≮ >&nbs style="font-size: 9.5pt; fondecvivalo=fmnbsp;    TestY=y0 

     pan style="">    TestY=y0 

     pan style="">    Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

     pan style="">    TestY=y0 

    >&nbs style="font-fondecvivalo=fmnbsp;    TestY=y0&le=""> pan style="">    ThengVoici sa sil près ! Voici sa sil prèsr; wf"> x#ci miluri8oNormal" style="texto:p>

    x#ci miluri8oNormal" style="texto:p>

    x#ci miluri8oNormal" style="texto:p>

    ThengCreateSculead≮ x#ci miluri8oNormal" style="texto:p>

     pan style="">    TestY < y0 TestY=y0 

     pan style="">    TestY < y0 TestY < y0 TestY=y0 

    TestY=y0 

    Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

    TestY < y0 Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

    TestY < y0 Un peu plus complexpt; font-family: Courier; color: black;"> TestY=(y0+h0) 

    TestY < y0 TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY < y0 TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY=y0 

    TestY=y0 

    []=[: 9.5pt; nbsp; TestY < y0 TestY < y0 TestY < y0 TestY=y0 

     pan style="">    TestY < y0 TestY=y0 

    TestY=y0 

    &span>

    TestY=y0&span>

    TestY=y0 w; &nbsendpan style="">≮  

    sancr_z; Lan>litzesns<-align: aiauxad

    Les collisionsDsupous tutl"s qotlaus="#uvisp. culesns>&nnimpoNormal" mt-fNormal" sadcules flotta-faead lspan>Un peu plus complexe, la collision entre un rectangle et un cercle :  

    lspan>uUn peu plus complexe, la collision entre un rectangle et un cercle :  

     yle:167non91, 222)

    Rais on pfy;">Les collisions 

     

     Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://www.blitzbasic.com/bmsocs/socs.php" titng="http://www.blitzbasic.com/bmsocs/socs.php"nown"> 

     

     Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://blitzmax.org/bsp;x.php?titng=Main_Pens" titng="http://blitzmax.org/bsp;x.php?titng=Main_Pens"nown"> 

     

      tr&euvisp.paa n:" o:pilssdcusy-faxe>Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://en.wikibook .org/wiki/BlitzMax/Lbspuens" titng="http://en.wikibook .org/wiki/BlitzMax/Lbspuens"nown"> 

     

     <Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://www.blitzbasic.com/Cz eunity/topics.php?fore-=112s" titng="http://www.blitzbasic.com/Cz eunity/topics.php?fore-=112s"nown"> 

     

     obfo:,netssaetraduont-faearFran&cc-usl;ain>Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://www.truplo.com/socs/Beginn=rsGuideToBlitzMax10.pdf" titng="http://www.truplo.com/socs/Beginn=rsGuideToBlitzMax10.pdf"nown"> 

    &nbsnbsp;<; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://ben.kicks-.5p.net/BlitzMaxGuide.txt" titng="http://ben.kicks-.5p.net/BlitzMaxGuide.txt"nown"> 

    &span>

     

    &nbsnbsp;<; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://www.2dgamecreators.com/tutospals/gameprouvimm_z;/" titng="http://www.2dgamecreators.com/tutospals/gameprouvimm_z;/"nown"> 

     

     Un peu plus complexe, la collision entre un rectangle et un cerclenown"> <; bo 1.5pt; xfatn rgbrelt; xfatn re="follow" target="_ stnk" href="http://rveilleux.google 

     

     

     

     

     

     yle:167non91, 222)

    Cz parain-faenccle sotutl"srnbspjgestUS" style="font-size: 9.5pt; font-family: Couriele="">Ltiles 

    sancr_z; Perfl,r ncana id="Les_collisions">

    Les collisions 

    sancr_z; Cz pilant-fa id="Les_collisions">

    Les collisions 

    sancr_z; Taillevduicode, conv<

    Le>RécupéréLdcpuis " bohref="http://mijge.unice.fr/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009> ycolo 1.5pt;"jgeInfo"> Motmipaés:"edtrong> -color rg"jgeTagnVibcolo 1.5pt;"jgeTagLttyVibcolo 1.5pt;item taglttyVible=""yle=""yle="" yle="" yle="" ycolo 1.5pt;b-attachmt-fe"orderattachmt-fe"> ycolo 1.5pt;fie sheaderVibcolo 1.5pt;fie sfl,rlink"> bohref="/Intranet_de_Mich:l_Buffa/Projet_Blitzmax_EPU_2009>o 1.5pt;disdingd" onclick="returkafalsg: 0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;attach" alt="" /": 9.5pt;  1.5pt;="bo">Attachelafichielaougntenstentre unae: e=""ycolo 1.5pt;fie sheaderbgVibcolo 1.5pt;fie sheaderrtyleVibcolo 1.5pt;fie sheader="bo">0cm 0c 1.5pt;ic-fVibimg src="/skins/common/ic-fs/ic-f-trans.gif>o 1.5pt;fie " alt="" /": 9.5pt ;  1.5pt;="bo">Fichiels ;  1.5pt;unwetyle"orderfie Couno">(1)nt-size: 9.5pt;an style=""yle=""yle="" ycolor rg"jgeFie sVibcolo 1.5pt;fie sc-ftt-f"orderattachFie sVibcolo 1.5pt;dding:orderattachTding: 0ddingo 1.5pt;dding:oder-c="100%>o ell9.5cisp;<0>o ellancr_z;;<0>oid; bo;<0>>