Initialisation de Quintus

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je lis avec intérêt le tutoriel Créer un jeu HTML5 avec Quintus. Je tente de créer le code pendant ma lecture, mais je rencontre un problème dès le début…

J’ai téléchargé un .zip depuis le repo GitHub de Quintus. Lorsque je lance le fichier index.html de l’exemple "Quintus-master\examples\ball", cela ne fonctionne pas, ce qui me semble déjà étrange.

J’ai essayé de créer le code de base pour créer un fond orange, et ça ne fonctionne pas non plus. J’ai essayé en important directement le "quintus-all" depuis le CDN, mais sans succès non plus.

Qu’est-ce que je fais de mal ? Je dois installer un serveur pour que ça fonctionne (pour l’instant je lance l’HTML comme ça) ? Le lien vers la lib n’est pas bon ?

Merci d’avance pour votre aide, et merci pour le tuto :)

Voici mon code :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Quintus</title>
        <link rel="stylesheet" href="style.css" />
        <script src="lib/quintus.js"></script>
        <script src="xian-xiang.js"></script>
    </head>
    <body>
        <canvas id="game" width="300" height="320">
            <p lang="fr">Votre navigateur ne supporte pas la balise canvas.</p>
        </canvas>
    </body>
</html>
body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #F3FBFD;
}
canvas{
    width: 300px;
    height: 320px;
    background-color: #fff;
    border: 1px solid #56B7C1;
    border-left-width: 3px;
    border-top-width: 3px;
    border-radius: 3px;
    margin: auto;
}
p {
    margin: 8px 0;
}
var Q = new Quintus({
    development: true // On lance le mode développement, pour forcer le refresh des assets (images, fichiers JSON…). Attention à bien désactiver cela une fois en production !
})

Q.include([ // On indique quels composants inclure de base
    Quintus.Sprites, // Pour gérer les sprites (les calques en gros)
    Quintus.Scenes, // Pour gérer les scenes (les différentes pages, pour faire simple)
    Quintus.Anim, // Pour gérer les animations (sur des sprites, par exemple)
    Quintus['2D'], // Pour gérer la 2D : permet d'avoir des ennemis qui se déplacent et de détecter les collisions automatiquement
    Quintus.Input, // Pour gérer les contrôles (certains contrôles sont inclus de base, c'est assez pratique)
    Quintus.Touch, // Pour gérer les contrôles via une surcouche tactile (avec un joypad si nécessaire — c'est paramétrable)
    Quintus.UI // Pour afficher des boutons, du texte, etc.
])

var Q = new Quintus(/* Vos paramètres */).include([ /* Les composants */ ]);

/* Le premier paramètre permet d'indiquer l'id de notre canvas, vous pouvez aussi passer directement un objet du DOM ou ne rien spécifier si vous voulez que la librairie crée un canvas pour vous */
Q.setup('game', {
    maximize: false, // Inutile de modifier la taille du canvas (`true` permet d'étendre à toute la surface disponible)
    width: 300, // Largeur de base
    height: 320 // Hauteur de base
});

Q.controls();

Q.touch();

Q.scene('startGame', function(stage) { // On crée une nouvelle scène que l'on nomme. Une fois affichée la fonction sera appelée, avec en paramètre notre objet scène (dont on récupèrera quelques infos et auquel on balancera quelques objets)
    console.log('Écran de lancement affiché');
});

Q.stageScene('startGame', 0); // On affiche notre scène au rang 0, soit tout en bas de la pile (pensez à des calques, comme sous votre logiciel de dessin préféré ou à un z-index en CSS)

var sprite_bg = new Q.Sprite({ x: 0, y: 0, w: Q.width, h: Q.height, type: Q.SPRITE_UI });

sprite_bg.draw = function(ctx) { // Au moment de dessiner le sprite, on récupère le contexte 2D du canvas pour dessiner librement
    ctx.fillStyle = '#e0b232'; // On veut du jaune
    ctx.fillRect(this.p.x, this.p.y, this.p.w, this.p.h); // On dessine un rectangle de la taille du sprite
}

stage.insert(sprite_bg);

Salut :)

Je dois installer un serveur pour que ça fonctionne (pour l’instant je lance l’HTML comme ça) ?

La réponse est oui : pour que Quintus (comme n’importe quel script JS) puisse charger des fichiers dynamiquement il faut obligatoirement un serveur, pour des raisons de sécurité.

Il existait un réglage à une époque pour certains navigateurs permettant de contourner ça, mais je suis pas sûr que ça existe toujours (et c’est à utiliser uniquement quand on sait ce que l’on fait… donc pas avec du code téléchargé, même si c’est le mien :p )

Salut,

Merci pour ta réponse ultra-rapide ! Je m’en vais donc installer MAMP (si c’est encore ce qu’il est courant d’utiliser ?).

J’étais persuadé que je pouvais lancer du JS comme ça en fait. Mais je n’apprends JS que depuis février donc je n’avais jamais vraiment eu de problème pour ce que je faisais…

+0 -0

Si tu as juste besoin d’un serveur Web sans langage serveur ou BDD, tu peux installer Apache ou Nginx séparément (avec homebrew, vu que tu as l’air d’être sous Mac, ça se fait bien).

Ou utiliser un package Node.js si tu l’as déjà sur ta machine.

Tu peux exécuter du JS sans serveur, mais ton script ne peut pas charger d’autres ressources dynamiquement sans serveur. Quintus a besoin de charger des assets au lancement, d’où l’erreur (que tu devrais voir dans ta console).

@tleb : parce que ça ne répond pas au protocole HTTP, il est donc impossible de garantir la sécurité des fichiers ainsi chargés.

Cela permettrait par exemple à un site corrompu d’accéder directement à tes fichiers locaux s’ils laissaient faire… ;)

Les navigateurs évitent donc de charger des fichiers dynamiquement de la sorte (en autorisant ceux qui sont explicitement demandés par le document en cours s’il est local aussi).

Eh bien, je ne comprends pas. Je viens d’installer MAMP. Je ne lance pas mon code mais directement l’exemple "ball" de Quintus, qui provient du .zip extrait tel quel "http://localhost/Quintus/examples/ball/". Et ça ne fonctionne pas.

Les autres exemples fonctionnent, mais pas "ball". Et le code de mon post initial ne fonctionne pas non plus. :(

Pour l’exemple "ball", l’erreur dans la console est :

Uncaught TypeError: Cannot read property 'length' of undefined
    at Function.Q._generateCollisionPoints (quintus_sprites.js:317)
    at Class.update (quintus_sprites.js:681)
    at Function.<anonymous> (ball.js:64)
    at Q.gameLoopCallbackWrapper (quintus.js:585)

Pour mon code, l’erreur dans la console est :

quintus.js:1342 Uncaught TypeError: Cannot read property 'appendChild' of null
    at Function.Q.setup (quintus.js:1342)
    at xian-xiang.js:19

Une idée ?

+0 -0

Oui en effet je l’avais vu et corrigé depuis. Voici le code qui ne fonctionne pas :

HTML (oui j’ai inclus toute la librairie du coup, mais ça ne fonctionne pas même avec le quintus-all du CDN) :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>KadoKadeo -> 05. Xian-Xiang</title>
    <link rel="stylesheet" href="style.css" />
    <script src="lib/quintus.js"></script>
    <script src="lib/quintus_2d.js"></script>
    <script src="lib/quintus_anim.js"></script>
    <script src="lib/quintus_audio.js"></script>
    <script src="lib/quintus_input.js"></script>
    <script src="lib/quintus_scenes.js"></script>
    <script src="lib/quintus_sprites.js"></script>
    <script src="lib/quintus_tmx.js"></script>
    <script src="lib/quintus_touch.js"></script>
    <script src="lib/quintus_ui.js"></script>
    <script src="extra/quintus_dom.js"></script>
    <script src="extra/quintus_physics.js"></script>
    <script src="extra/quintus_svg.js"></script>
    <script src="xian-xiang.js"></script>
</head>
<body>
    <canvas id="gameCanvas" width="300" height="320">
        <p>Votre navigateur ne supporte pas Canvas. Veuillez installer un navigateur plus moderne afin de jouer.</p>
    </canvas>
</body>
</html>

JS :

/* ----------
// Initialisation et paramétrisation de la librairie Quintus
----------*/

var Q = new Quintus({
    development: true // On lance le mode développement, pour forcer le refresh des assets (images, fichiers JSON…). Attention à bien désactiver cela une fois en production !
});

Q.include([ // On indique quels composants inclure de base
    Quintus.Sprites, // Pour gérer les sprites (les calques en gros)
    Quintus.Scenes, // Pour gérer les scenes (les différentes pages, pour faire simple)
    Quintus.Anim, // Pour gérer les animations (sur des sprites, par exemple)
    Quintus['2D'], // Pour gérer la 2D : permet d'avoir des ennemis qui se déplacent et de détecter les collisions automatiquement
    Quintus.Input, // Pour gérer les contrôles (certains contrôles sont inclus de base, c'est assez pratique)
    Quintus.Touch, // Pour gérer les contrôles via une surcouche tactile (avec un joypad si nécessaire — c'est paramétrable)
    Quintus.UI // Pour afficher des boutons, du texte, etc.
]);

Q.setup('gameCanvas', {
    maximize: false,
    width: 300,
    height: 320
});

Q.controls();
Q.touch();

/* ----------
Écran de démarrage du jeu 
----------*/

Q.scene('startGame', function(stage) {
    console.log('Écran de lancement affiché');
});

Q.stageScene('startGame', 0);

var sprite_bg = new Q.Sprite({ x: 0, y: 0, w: Q.width, h: Q.height, type: Q.SPRITE_UI });

sprite_bg.draw = function(ctx) { // Au moment de dessiner le sprite, on récupère le contexte 2D du canvas pour dessiner librement
    ctx.fillStyle = '#e0b232'; // On veut du jaune
    ctx.fillRect(this.p.x, this.p.y, this.p.w, this.p.h); // On dessine un rectangle de la taille du sprite
}

stage.insert(sprite_bg);

Et pour l’exemple officiel "ball" qui ne fonctionne pas non plus :

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quintus Ball Example</title>
<script src='../../lib/quintus.js'></script>
<script src='../../lib/quintus_sprites.js'></script>

<script src='ball.js'></script>
</head>
<body>
</body>
</html>

JS :

// # Quintus moving ball example
//
// [Run the example](../quintus/examples/ball/index.html)
//
// This is one of the simplest possible examples of using 
// Quintus that doesn't use the scene/stage functionality, 
// but rather just creates a single sprite and steps and 
// draws that sprite
//
// The goal of the example is to demonstrate the modularity
// of the engine and the ability to only include the components
// you actually need.


// Wait for the load event to start the game.
window.addEventListener("load",function() {

  // Create an instance of the engine, including only
  // the `Sprites` module, and then call setup to create a
  // canvas element on the page. If you already have a 
  // canvas element in your page, you can pass the element
  // or it's id as the first parameter to set up as well.
  var Q = window.Q =  Quintus().include("Sprites").setup({ width: 400, height: 400 });

  // The `MovingSprite` class is a descendant of the base `Sprite` class,
  // all it does is add in a step method to Sprite that runs the standard
  // 2D motion equations using properties vx, vy for the velocity and ax, ay 
  // to calculate the new x and y positions.
  Q.MovingSprite.extend("Ball",{
    // Sprites by default expect either a `sheet` or an `asset` property
    // to draw themselves, but by overriding the draw method you can draw a 
    // shape directly on the canvas instead. 
    draw: function(ctx) {
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.arc(-this.p.cx,
              -this.p.cy,
              this.p.w/2,0,Math.PI*2); 
      ctx.fill();

    }
  });

  // Create a new instance of the `Ball` Sprite,
  // passing in the size, position, velocity, and 
  // acceleration
  var ball = window.ball = new Q.Ball({ w:  20,  h:   20, 
                                        x:  30,  y:  300, 
                                       vx:  30, vy: -100, 
                                       ax:   0, ay:   30 });

  // You can start the game loop directly by
  // calling `gameLoop` with a callback and Quintus
  // will set up a requestAnimationFrame powered game loop
  // for you. Most examples don't call `gameLoop` directly as
  // calling `stageScene` will start a game loop that takes care
  // of clearing the canvas and updating and drawing all the stages
  // for you.
  Q.gameLoop(function(dt) {
      // Clear the canvas 
      Q.clear();

      // Move the ball `dt` forward in time
      ball.update(dt);

      // Render the ball onto the canvas context.
      ball.render(Q.ctx);
  });


  // ## Possible Experimentations:
  // 
  // 1. Try adding multiple balls of different positions and sizes
  //    and looping over them manually in game loop
  // 2. Change the clear color of the canvas
  // 3. Add in the `Scenes` module and create and stage a scene.
});

@tleb : Rien ne garantit que le HTML (ou le JS) chargé est de confiance, il pourrait donc accéder aux fichiers locaux et les uploader sur un serveur distant. Ou mapper ton réseau local (ou d’entreprise). https://www.cnet.com/news/javascript-opens-doors-to-browser-based-attacks/ Donc les navigateurs s’embêtent pas à gérer des règles complexes : ils bloquent tout de base vu que ça n’impacte qu’une partie infime de leurs utilisateurs.


@moejul : Sur ton premier code j’ai l’erreur suivante :

Uncaught ReferenceError: stage is not defined

Il faut bouger la fin (lignes 38 et suivantes) dans le bloc Q.scene('startGame', (stage) => {}) (ligne 33 donc).

Le code de la balle fonctionne bien de mon côté… tu es sûr d’avoir bien chargé les dépendances ?

@moejul : Sur ton premier code j’ai l’erreur suivante :

Uncaught ReferenceError: stage is not defined

Il faut bouger la fin (lignes 38 et suivantes) dans le bloc Q.scene('startGame', (stage) => {}) (ligne 33 donc).

Le code de la balle fonctionne bien de mon côté… tu es sûr d’avoir bien chargé les dépendances ?

viki53

À la lecture du tuto, je n’avais pas compris qu’il fallait se mettre dans le bloc Q.scene{}. Donc la fin de mon code doit devenir comme ceci :

Q.scene('startGame', function(stage) {
    Q.stageScene('startGame', 0);

    var sprite_bg = new Q.Sprite({ x: 0, y: 0, w: Q.width, h: Q.height, type: Q.SPRITE_UI });

    sprite_bg.draw = function(ctx) { // Au moment de dessiner le sprite, on récupère le contexte 2D du canvas pour dessiner librement
        ctx.fillStyle = '#e0b232'; // On veut du jaune
        ctx.fillRect(this.p.x, this.p.y, this.p.w, this.p.h); // On dessine un rectangle de la taille du sprite
    }

    stage.insert(sprite_bg);
});

C’est bien ça ?

Par contre, question un peu bête car j’apprends mais… Comment on débug du JS ? Perso je fais clic droit > Inspecter dans chrome, puis j’utilise la console. Est-ce bien là ? Car je n’ai pas la même erreur que toi qui s’affichait.

Et je ne comprends pas non plus pourquoi l’exemple "ball" officiel bugue également. Est-ce le cas chez toi également ?

Merci pour ton aide

+0 -0

Oui tu peux utiliser la console du navigateur pour ton JS front, ça marche très bien avec console.*.

Tu peux aussi utiliser l’instruction debugger pour lancer le débogueur, qui va te permettre d’analyser chaque étape de ton code, tout en ayant une vu d’ensemble du contexte et des valeurs de tes variables.

La démo officielle de la balle fonctionne très bien chez moi… tu testes avec quel navigateur/version ? As-tu vérifié qu’il n’y aurait pas une extension ou un réglage qui bloquerait quelque chose ?

J’utilise Google Chrome Version 89.0.4389.82 (Build officiel) (64 bits). Mais j’ai essayé sur Firefox aussi.

Je me demande si ce n’est pas un problème sur mon PC car la plupart des codes que je teste bug. D’ailleurs j’ai copié-collé le code de ta démo depuis ton tuto : même souci. Mamp serait installé mais bloqué ? Qu’est-ce qui peut le bloquer ?

Rien de spécial au niveau des extensions, j’ai peu d’extensions installées et rien de bloquant. Même avec l’anti-virus désactivé et le pare-feu désactivé, le problème persiste.

Voici l’erreur dans la console pour mon code :

quintus.js:1342 Uncaught TypeError: Cannot read property 'appendChild' of null
    at Function.Q.setup (quintus.js:1342)
    at xian-xiang.js:57
Q.setup @ quintus.js:1342
(anonymous) @ xian-xiang.js:57
+0 -0

Je te résume les 2 codes :

Mon code "xian-xiang.js"

Erreur :

quintus.js:1342 Uncaught TypeError: Cannot read property 'appendChild' of null
    at Function.Q.setup (quintus.js:1342)
    at xian-xiang.js:19

HTML :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>KadoKadeo -> 05. Xian-Xiang</title>
    <link rel="stylesheet" href="style.css" />
    <script src="lib/quintus.js"></script>
    <script src="lib/quintus_2d.js"></script>
    <script src="lib/quintus_anim.js"></script>
    <script src="lib/quintus_audio.js"></script>
    <script src="lib/quintus_input.js"></script>
    <script src="lib/quintus_scenes.js"></script>
    <script src="lib/quintus_sprites.js"></script>
    <script src="lib/quintus_tmx.js"></script>
    <script src="lib/quintus_touch.js"></script>
    <script src="lib/quintus_ui.js"></script>
    <script src="extra/quintus_dom.js"></script>
    <script src="extra/quintus_physics.js"></script>
    <script src="extra/quintus_svg.js"></script>
    <script src="xian-xiang.js"></script>
</head>
<body>
    <canvas id="gameCanvas" width="300" height="320">
        <p>Votre navigateur ne supporte pas Canvas. Veuillez installer un navigateur plus moderne afin de jouer.</p>
    </canvas>
</body>
</html>

CSS :

body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #F3FBFD;
}
canvas{
    width: 300px;
    height: 320px;
    background-color: #fff;
    border: 1px solid #56B7C1;
    border-left-width: 3px;
    border-top-width: 3px;
    border-radius: 3px;
    margin: auto;
}
p {
    margin: 8px 0;
}

JS :

/* ----------
// Initialisation et paramétrisation de la librairie Quintus
----------*/

var Q = new Quintus({
    development: true // On lance le mode développement, pour forcer le refresh des assets (images, fichiers JSON…). Attention à bien désactiver cela une fois en production !
});

Q.include([ // On indique quels composants inclure de base
    Quintus.Sprites, // Pour gérer les sprites (les calques en gros)
    Quintus.Scenes, // Pour gérer les scenes (les différentes pages, pour faire simple)
    Quintus.Anim, // Pour gérer les animations (sur des sprites, par exemple)
    Quintus['2D'], // Pour gérer la 2D : permet d'avoir des ennemis qui se déplacent et de détecter les collisions automatiquement
    Quintus.Input, // Pour gérer les contrôles (certains contrôles sont inclus de base, c'est assez pratique)
    Quintus.Touch, // Pour gérer les contrôles via une surcouche tactile (avec un joypad si nécessaire — c'est paramétrable)
    Quintus.UI // Pour afficher des boutons, du texte, etc.
]);

Q.setup('gameCanvas', {
    maximize: false,
    width: 300,
    height: 320
});

Q.controls();
Q.touch();

/* ----------
Écran de démarrage du jeu 
----------*/

Q.scene('startGame', function(stage) {
    Q.stageScene('startGame', 0);

    var sprite_bg = new Q.Sprite({ x: 0, y: 0, w: Q.width, h: Q.height, type: Q.SPRITE_UI });

    sprite_bg.draw = function(ctx) { // Au moment de dessiner le sprite, on récupère le contexte 2D du canvas pour dessiner librement
        ctx.fillStyle = '#e0b232'; // On veut du jaune
        ctx.fillRect(this.p.x, this.p.y, this.p.w, this.p.h); // On dessine un rectangle de la taille du sprite
    }

    stage.insert(sprite_bg);
});

L’exemple "ball" officiel

Erreur :

Uncaught TypeError: Cannot read property 'length' of undefined
    at Function.Q._generateCollisionPoints (quintus_sprites.js:317)
    at Class.update (quintus_sprites.js:681)
    at Function.<anonymous> (ball.js:64)
    at Q.gameLoopCallbackWrapper (quintus.js:585)

HTML :

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quintus Ball Example</title>
<script src='../../lib/quintus.js'></script>
<script src='../../lib/quintus_sprites.js'></script>

<script src='ball.js'></script>
</head>
<body>
</body>
</html>

JS :

// # Quintus moving ball example
//
// [Run the example](../quintus/examples/ball/index.html)
//
// This is one of the simplest possible examples of using 
// Quintus that doesn't use the scene/stage functionality, 
// but rather just creates a single sprite and steps and 
// draws that sprite
//
// The goal of the example is to demonstrate the modularity
// of the engine and the ability to only include the components
// you actually need.


// Wait for the load event to start the game.
window.addEventListener("load",function() {

  // Create an instance of the engine, including only
  // the `Sprites` module, and then call setup to create a
  // canvas element on the page. If you already have a 
  // canvas element in your page, you can pass the element
  // or it's id as the first parameter to set up as well.
  var Q = window.Q =  Quintus().include("Sprites").setup({ width: 400, height: 400 });

  // The `MovingSprite` class is a descendant of the base `Sprite` class,
  // all it does is add in a step method to Sprite that runs the standard
  // 2D motion equations using properties vx, vy for the velocity and ax, ay 
  // to calculate the new x and y positions.
  Q.MovingSprite.extend("Ball",{
    // Sprites by default expect either a `sheet` or an `asset` property
    // to draw themselves, but by overriding the draw method you can draw a 
    // shape directly on the canvas instead. 
    draw: function(ctx) {
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.arc(-this.p.cx,
              -this.p.cy,
              this.p.w/2,0,Math.PI*2); 
      ctx.fill();

    }
  });

  // Create a new instance of the `Ball` Sprite,
  // passing in the size, position, velocity, and 
  // acceleration
  var ball = window.ball = new Q.Ball({ w:  20,  h:   20, 
                                        x:  30,  y:  300, 
                                       vx:  30, vy: -100, 
                                       ax:   0, ay:   30 });

  // You can start the game loop directly by
  // calling `gameLoop` with a callback and Quintus
  // will set up a requestAnimationFrame powered game loop
  // for you. Most examples don't call `gameLoop` directly as
  // calling `stageScene` will start a game loop that takes care
  // of clearing the canvas and updating and drawing all the stages
  // for you.
  Q.gameLoop(function(dt) {
      // Clear the canvas 
      Q.clear();

      // Move the ball `dt` forward in time
      ball.update(dt);

      // Render the ball onto the canvas context.
      ball.render(Q.ctx);
  });


  // ## Possible Experimentations:
  // 
  // 1. Try adding multiple balls of different positions and sizes
  //    and looping over them manually in game loop
  // 2. Change the clear color of the canvas
  // 3. Add in the `Scenes` module and create and stage a scene.
});
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte