Avec ncurses, l'écran sera de 80x24, donc avec ncursesw, en utilisant le code pleine largeur de UTF-8, avec un caractère carré, il y a environ 40 ans de 40x24, PET, MZ-80, CBM-3032, J'ai essayé de réécrire le jeu de PC-8001 (qui a également le mode 80x25). J'ai un peu modifié le jeu "Raging Robots" et l'ai fait "Maneaters".
Je laisserai l'explication détaillée de ncursesw à d'autres articles (Oioi), mais je posterai la liste des programmes. Puisqu'il n'y a aucune explication de ncursesw, j'ai écrit les commentaires aussi soigneusement que possible. Vous verrez comment utiliser les ncurses minimum w.
De plus, la vérification de l'opération était ubuntu18.04 et Debian stretch (9.6). Le package binaire peut être trouvé sur GitHub. https://github.com/fygar256/maneaters/blob/master/maneaters_1.3-1_amd64.deb
~~ Ubuntu libncursesw5 (6.1-1ubuntu1.18.04) et Debian libncursesw5 (6.0 + 20161126-1 + deb9u2) ont un bogue, et même si vous utilisez vim, il est affiché avec un certain symbole de utf-8. Il peut être ébréché ou la largeur des caractères peut ne pas être assez grande. Par exemple, ~~ "◯" (grand cercle: pas un caractère dépendant du modèle, largeur ambiguë) pose un problème, mais "O" (lettre supérieure O, pleine largeur) ne pose pas de problème. A ce propos, siracamus a souligné, "Pour les terminaux Ubuntu, il peut être résolu en changeant" Caractère de largeur ambigu: "dans l'onglet de compatibilité du paramètre Préférences du terminal sur" Pleine largeur ". Donc, quand je l'ai essayé, cela a certainement été résolu dans le jeu (prototype).
~~ Mais vim ne fonctionnait pas correctement. ~~
La police ambiguë (ambiguë d'Asie de l'Est) semble être affichée en demi-largeur ou pleine largeur selon les paramètres régionaux. Encore une fois, selon les informations de siracamus, vim fonctionnait bien avec : set ambiwidth = double
.
Les paramètres du terminal et de vim ont été résolus avec les deux points ci-dessus. Merci, siracamus.
Ce programme est fait sans utiliser de polices ambiguës.
Avant de compiler
sudo apt-get install libncursesw5-dev
Veuillez installer le package en tant que. Comment compiler
cc maneaters.c -o maneaters -lncursesw
est.
maneaters.c
//
//Nostalgique, CBM-Jeux de personnages comme 3032
//Réalisé avec ncursesw.
// Maneaters. Ver 1.3
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Pour utiliser ncursesw, les deux fichiers d'en-tête suivants
#include <ncursesw/ncurses.h>
#include <locale.h>
//Les caractères à afficher sont définis comme des constantes.
#define ENEMY "O"
#define PLAYER "@"
#define ROCK "#"
#define CRASH "X"
#define SPACE " "
//Définition d'une fonction qui génère un nombre aléatoire de 0 à x.
#define rnd(x) (rand()%x)
int enemyl[40]; //Drapeau indiquant si l'ennemi est vivant
int enemyx[40]; //Coordonnées ennemies x
int enemyy[40]; //Ennemi et coordonnée
int rockl[320]; //Drapeau s'il y a un rocher
int rockx[320]; //Coordonnées Rock X
int rocky[320]; //Coordonnée Rock y
int enemymax=12; //Nombre de premiers ennemis
int rockmax=120; //Nombre de premières roches
int playerx,playery; //Coordonnées du joueur
int h,w; //Hauteur de l'écran,width
int xsize,ysize; //Taille de l'écran de jeu.
//Écran 80x25, UTF carré pleine largeur avec police de largeur égale-8
//Et je l'utilise
//Ici, xsize vaut 40.
int gamestat; //Statut du jeu: 0 Lecture en cours
//1 perdre
//3 victoire
/*
*Quand le joueur bouge
*Déterminer si vous frappez quelque chose
*Valeur de retour;1: Collision 0: Rien
*/
int check_player_crash() {
//
//Déterminer si vous frappez un ennemi
//
for(int i=0;i<enemymax;i++) {
if((enemyl[i]==1)&&(playerx==enemyx[i]) && (playery==enemyy[i]))
return(1);
}
//
//Jugement si oui ou non il a heurté un rocher
//
for(int i=0;i<rockmax;i++) {
if((rockl[i]==1)&&(playerx==rockx[i]) && (playery==rocky[i]))
return(1);
}
return(0);
}
/*
*Une fonction qui affiche des caractères à l'écran.
*Puisqu'il est traité en unités pleine largeur
*La coordonnée x est doublée.
*/
int putchara(int x,int y,char *str){
move(y,x*2);
addstr(str);
}
/*
*Initialisation du jeu
*/
int init_game() {
int i;
clear(); //Écran propre
gamestat=0; //Initialiser l'état du jeu
//Prenez la graine du nombre aléatoire du temps et initialisez-la.
srand((unsigned)time(NULL));
//
//Placez une pierre.
//Le 0 est d'éviter la collision entre le joueur et l'ennemi
//Placez le mannequin au centre de l'écran. Par conséquent, le nombre de roches est
// rockmax-Cela devient 1.
//
rockx[0]=xsize/2;
rocky[0]=ysize/2;
rockl[0]=0;
for(i=1;i<rockmax;i++) {
putchara(rockx[i]=rnd(xsize),rocky[i]=rnd(ysize),ROCK);
rockl[i]=1;
}
//Placez l'ennemi de manière à ce qu'il ne touche pas le rocher.
i=0;
while(i<enemymax) {
int ex,ey,f;
ex = rnd(xsize);
ey = rnd(ysize);
f = 0;
for(int j=0;j<rockmax;j++) {
if ((ex==rockx[j])&&(ey==rocky[j]))
f=f|1;
}
if (f==0) {
putchara(enemyx[i]=ex,enemyy[i]=ey,ENEMY);
enemyl[i]=1;
i++;
}
}
//Placez le lecteur au centre de l'écran.
putchara(playerx=xsize/2,playery=ysize/2,PLAYER);
}
/*
*Déplacer les ennemis
*/
void move_maneaters() {
int dx,dy;
int x,y;
for(int i=0;i<enemymax;i++) {
if (enemyl[i]==0) //Passer si l'ennemi est mort
continue;
//
//Demandez la différence pour chasser le joueur
//
dx=0,dy=0;
if (enemyx[i]<playerx) dx=1;
if (enemyx[i]>playerx) dx=-1;
if (enemyy[i]<playery) dy=1;
if (enemyy[i]>playery) dy=-1;
//Disparaître l'ennemi dans la position actuelle
putchara(enemyx[i],enemyy[i],SPACE);
//Trouvez les coordonnées de l'endroit où l'ennemi s'est déplacé
x=enemyx[i]+dx,y=enemyy[i]+dy;
//
//Vérification des collisions entre ennemis
//
for(int j=0;j<enemymax;j++) {
if ((i!=j)&&(enemyl[j]==1) && (x==enemyx[j]) && (y==enemyy[j])) {
enemyl[i]=0; //Abaissez le drapeau indiquant que l'ennemi est vivant.
}
}
//
//Contrôle de collision avec des roches
//
for(int j=0;j<rockmax;j++) {
if ((rockl[j]==1)&&(x==rockx[j]) && (y==rocky[j])) { //As-tu frappé le rocher
rockl[j]=enemyl[i]=0;
putchara(x,y,SPACE); //Effacez le rocher
}
}
enemyx[i]=x,enemyy[i]=y; //Emmenez l'ennemi un peu plus loin
if (enemyl[i]) //Les ennemis sont-ils vivants?
putchara(enemyx[i],enemyy[i],ENEMY); //Dessiner un ennemi
//
//Vérifiez s'il est entré en collision avec le lecteur
//
if ((x==playerx) && (y==playery))
gamestat=1; //Si vous vous heurtez, vous perdez
}
}
//
//Boucle principale du jeu
//
int main_game() {
int f,dx,dy;
while(1) {
/*
*Traitement des joueurs
*/
switch(getch()) { //Entrée clé du joueur et acquisition de la direction du mouvement
case '7': dx=-1,dy=-1; break;
case '8': dx= 0,dy=-1; break;
case '9': dx= 1,dy=-1; break;
case 'u': case '4': dx=-1,dy=0; break;
case 'i': case '5': dx= 0,dy=0; break;
case 'o': case '6': dx= 1,dy=0; break;
case 'j': case '1': dx=-1,dy=1; break;
case 'k': case '2': dx= 0,dy=1; break;
case 'l': case '3': dx= 1,dy=1; break;
default:
continue;
}
//Le joueur sort-il de l'écran?
if (((playerx+dx)>=0) && ((playerx+dx)<xsize) &&
((playery+dy)>=0) && ((playery+dy)<ysize)) {
putchara(playerx,playery,SPACE); //Amenez le joueur un peu plus loin.
playerx+=dx;
playery+=dy;
putchara(playerx,playery,PLAYER);
//Lorsque le joueur frappe un rocher ou un ennemi, le jeu est terminé.
if (check_player_crash()) {
gamestat=1;
return(0);
}
}
/*
*Traitement ennemi
*/
move_maneaters();
if (gamestat!=0) return(0);
/*
*Gagnez si le mangeur d'hommes est anéanti
*/
f=0;
for(int j=0;j<enemymax;j++)
f|=enemyl[j];
if (f==0) {
gamestat=3;
return(0);
}
}
}
/*
*Une fonction qui vous demande si vous souhaitez rejouer
*Valeur de retour; 0: Non 1: Oui
*/
int tryagainp() {
printw("Try Again? [y/n]");
while(1) {
switch(getch()) {
case 'n': return(0);
case 'y': return(1);
default: continue;
}
}
}
/*
*Écran de description du jeu
*
*/
void instruction() {
clear(); //Écran propre
printw("Maneaters Ver 1.3\n"); //Imprimez sur stdscr avec printw.
printw("Mission : kill all maneaters to survive!\n");
printw("%s -- Maneater, chase player step by step.\n",ENEMY);
printw("%s -- Rock, die maneaters and player when touched. \n",ROCK);
printw("%s -- Player, control for maneaters to crash to rock and survive!\n",PLAYER);
printw("\n");
printw("Key control: Tenkey: \n");
printw(" 7 8 9 7 8 9 \n");
printw(" ↖ ↑ ↗ ↖ ↑ ↗ \n");
printw("u← i →o 4← 5→ 6 \n");
printw(" ↙ ↓ ↘ ↙ ↓ ↘ \n");
printw(" j k l 1 2 3 \n");
printw("\n");
printw(" 'i' and '5' move maneater and don't move player.\n");
printw(" Good Luck\n");
printw("hit key\n");
getch(); //En attente de la saisie d'une touche à un caractère.
}
//
//Écran de description du jeu et boucle principale
//
void play_game() {
while(1) {
instruction(); //Appelez l'écran de description du jeu.
init_game(); //Initialisation du jeu
main_game(); //Boucle principale du jeu
if (gamestat==1) { //Le joueur perd
putchara(playerx,playery,CRASH);
move(0,0);
printw("You Lose ");
}
if (gamestat==3) { //Le joueur gagne
move(0,0);
printw("You Win!! ");
}
if (tryagainp()==0) return; //Revenir si non rejoué.
}
}
/*
*fonction principale
*/
int main() {
setlocale( LC_ALL,"" ); //UTF avec ncursesw-Pour utiliser 8
// LC_Mettre tous.
initscr(); //Initialisation de l'écran
noecho(); //Désactiver l'écho du clavier
curs_set(0); //Cachez le curseur.
getmaxyx(stdscr,h,w); //Taille de l'écran, h,Magasin dans w
//Habituellement 80x25
xsize=w/2; //Trouvez la taille d'écran utilisée dans le jeu.
ysize=h; //Trouvez la taille Y de l'écran utilisé dans le jeu.
play_game(); //Lancez le jeu.
endwin(); //Fermez l'écran.
exit(0); //Fini.
}
Recommended Posts