Je travaille sur un jeu de puzzle simple basé sur des blocs.
Le jeu consiste à déplacer des blocs dans la zone de jeu, c'est donc une simulation physique triviale. Mon implémentation, cependant, est à mon avis loin d'être idéale et je me demande si vous pouvez me donner des conseils sur la façon de mieux le faire.
J'ai divisé le code en deux domaines: la logique du jeu et l'interface utilisateur, comme je l'ai fait avec beaucoup de jeux de puzzle:
- La logique du jeu est responsable des règles générales du jeu (par exemple, le système de règles formel des échecs)
- L'interface utilisateur affiche la zone de jeu et les pièces (par exemple, échiquier et pièces) et est responsable des animations (par exemple, le mouvement animé des pièces d'échecs)
La logique de jeu représente l'état du jeu sous forme de grille logique, où chaque unité correspond à la largeur / hauteur d'une cellule sur la grille. Ainsi, pour une grille de largeur 6, vous pouvez déplacer un bloc de largeur 2 quatre fois jusqu'à ce qu'il entre en collision avec la frontière.
L'interface utilisateur prend cette grille et la dessine en convertissant les tailles logiques en tailles de pixels (c'est-à-dire en la multipliant par une constante). Cependant, comme le jeu n'a pratiquement aucune logique de jeu, ma couche de logique de jeu [1] n'a pas grand-chose à faire à part la détection de collision. Voici comment ça fonctionne:
- Le joueur commence à faire glisser un morceau
- L'interface utilisateur demande la logique du jeu pour la zone de mouvement légale de cette pièce et permet au joueur de la faire glisser dans cette zone
- Le joueur lâche un morceau
- L'interface utilisateur accroche la pièce à la grille (afin qu'elle soit à une position logique valide)
- L'interface utilisateur indique à la logique du jeu la nouvelle position logique (via des méthodes de mutation, que je préfère éviter)
Je ne suis pas très content de ça:
- J'écris des tests unitaires pour ma couche logique de jeu, mais pas l'interface utilisateur, et il s'est avéré que tout le code délicat se trouve dans l'interface utilisateur: empêcher la pièce d'entrer en collision avec les autres ou la frontière et l'enclencher sur la grille.
- Je n'aime pas le fait que l'interface utilisateur raconte la logique du jeu sur le nouvel état, je préfère qu'il appelle une
movePieceLeft()
méthode ou quelque chose comme ça, comme dans mes autres jeux, mais je ne suis pas allé loin avec cette approche, car la logique du jeu ne sait rien du glissement et de la capture qui sont possibles dans l'interface utilisateur.
Je pense que la meilleure chose à faire serait de se débarrasser de ma couche logique de jeu et de mettre en place une couche physique à la place. J'ai quelques questions à ce sujet:
- Une telle couche physique est-elle courante, ou est-il plus courant que la couche logique de jeu le fasse?
- Est-ce que l'accrochage à la grille et au code de déplacement de pièces appartiendrait à l'interface utilisateur ou à la couche physique?
- Une telle couche physique fonctionnerait-elle généralement avec des tailles de pixels ou avec une sorte d'unité logique, comme ma couche logique de jeu?
- J'ai vu une fois une détection de collision basée sur des événements dans la base de code d'un jeu, c'est-à-dire que le joueur faisait simplement glisser la pièce, l'interface utilisateur le rendait docilement et notifiait le système physique, et le système physique appelait une méthode onCollision () sur la pièce une fois qu'une collision est détectée. Quoi de plus commun? Cette approche ou demander d'abord la zone de mouvement légale?
[1] couche n'est probablement pas le bon mot pour ce que je veux dire, mais le sous-système semble exagéré et la classe est erronée, car chaque couche peut être composée de plusieurs classes.
Réponses:
Je vais essayer de répondre à cette question car je peux comprendre ce que vous demandez, bien que je n'ai pas beaucoup d'expérience en développement de jeux car je suis encore en train d'apprendre.
Comme je le vois, vous devez séparer le code GUI de votre logique de jeu et des objets de domaine, c'est-à-dire les pièces du puzzle. Ce sont en effet trois couches distinctes - et oui,
layer
c'est un terme approprié à mon avis. Il est souvent utilisé pour expliquer les concepts de séparation de chaque niveau d'objets d'un système en sous-systèmes indépendants les uns des autres.En ce qui concerne la programmation orientée objet, chaque objet doit être une classe. Ainsi, chaque pièce de votre puzzle se composera d'une classe en soi, et donc du plateau de jeu. Le plateau de jeu doit contenir X pièces de puzzle en fonction de sa taille et de sa capacité de mouvement que vous souhaitez donner au joueur.
Alors, voici mes réflexions sur le sujet - j'espère que cela vous aidera:
Dans cette architecture, vous auriez la couche GUI montrer au joueur de l'état du jeu, l'emplacement de chaque pièce du puzzle. La couche GUI serait alors chargée d'obtenir les entrées du joueur et de les transmettre à une couche sous-jacente de contrôleur de jeu, qui serait alors responsable de la détection des collisions. S'il n'y en a pas, alors la pièce peut être commandée pour se déplacer dans cette direction d'entrée. Pour ce faire, il suffit d'appeler cette pièce
MoveLeft
,MoveRight
, etc. méthodes pour faire bouger la pièce. Vous pourriez aussi bien faire savoir au plateau de jeu quelle pièce vous voulez déplacer, puis il ordonne par lui-même le mouvement de la pièce, et la pièce se déplace ensuite dans la direction demandée. Cette architecture facilite le test de chaque morceau de code dans les différentes couches, puis vous permet d'effectuer des tests unitaires, des tests d'intégration et des tests fonctionnels.Je sais que cela peut sembler un peu déroutant pour la vue, et Dieu merci, si ce n'est pas le cas! Si vous avez besoin de plus de détails et d'aide, n'hésitez pas à demander, je serai heureux de faire de mon mieux, même si je suis un débutant dans le développement de jeux.
Merci d'avoir lu! =)
la source
Position
fonction d'obtention de propriété, de sorte que le contrôleur de jeu nécessite maintenant l'interface graphique pour afficher cette pièce déplacée à cette nouvelle position.