[ Foro de C ]
Buenas!
Estoy creando un juego para el antiguo sistema Amstrad CPC usando el lenguaje c.
Para ello uso una librería especial para este sistema.
El problema que tengo, es que quiero que aparezcan los enemigos en varios ciclos(100,200,350), pero no aparecen.
He usado mensajes de depuracion en el bloque de switch, y tampoco aparecen.
Este es parte del codigo:
#include <stdlib.h> // Incluye la biblioteca estándar de C
#include <string.h> // Incluye la biblioteca de manipulación de cadenas
#include <stdio.h> // Incluye la biblioteca estándar de entrada y salida
#include "8BP.h" // Incluye la biblioteca 8BP para crear juegos en Amstrad
#include "minibasic.h" // Incluye la biblioteca minibasic.h para usar comandos Basic
#define MALO_BASE 13
// Definir una enumeración para los tipos de enemigos
typedef enum {
METEORITO , // 0
OVNI, // 1
TANQUE // 2
} TipoEnemigo;
// Prototipos de funciones
void initializeVariables();
void presentation();
void showControls();
int waitSelection();
void startGame();
void waitKeyReleased(int key);
void waitEnterReleased();
void showPhaseAndWait(int phase);
void wait(int c);
int routineCollision();
void showCycleGame();
void createEnemies(TipoEnemigo tipoEnemigo); // Funcion para la creacion de enemigos
// Variables globales
int menu, y, x, i, xi, xmalo, last;
int cor = 32;
int cod = 32;
int rescol = 0;
int c; // Ciclo del juego
unsigned int sp, m, malo, lives, phase;
unsigned int score = 0;
char score_str[10]; // Asegúrate de que haya suficiente espacio para la cadena de puntuación
char* cad;
TipoEnemigo tipoHorda[3] = {METEORITO, OVNI, TANQUE}; // Hay 3 tipos de enemigos
int cicloHorda[3] = {100, 200, 350}; // Aparecen en ciclos 100, 200, 350
int index = 0; // Cada vez que se crean los enemigos, el índice aumenta en 1
// Programa principal
int main() {
initializeVariables(); // Llama a la función para inicializar variables
menu = 1; // Variable que controla el menú principal
y = 100;
x = 50;
c = 0;
m = 0;
sp = 0;
last = 0;
lives = 3;
phase = 1;
i = 0;
xmalo = 160;
cor = 32;
cod = 32;
xi = 1;
malo = 13;
rescol = 0;
score = 0;
int index = 0;
_8BP_colspall_2(&cor, &cod);
_8BP_map2sp_1(1);
while (menu) {
presentation(); // Muestra la presentación y el menú principal
menu = waitSelection(); // Espera la selección del usuario
}
return 0; // Completa el programa con éxito
}
// Función para crear enemigos
void createEnemies(TipoEnemigo tipoEnemigo) {
switch (tipoEnemigo) {
case METEORITO:
if (phase == 1) {
_8BP_printat_4(0, 0, 12, "CREANDO METEORITO"); // Depuración
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128); // Estado
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
break;
case OVNI:
if (phase == 1) {
int enemymalo = malo + 1; // Crear enemigos en el ciclo 160
_8BP_setupsp_3(enemymalo, 9, 21);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 2);
_8BP_locatesp_3(enemymalo, 50, 500);
_8BP_printat_4(0, 0, 14, "OVNI CREADO"); // Depuración
}
break;
case TANQUE:
if (phase == 1) {
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 20);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 1);
_8BP_locatesp_3(enemymalo, 50, 160);
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 16 + i, "TANQUE CREADO"); // Depuración
}
}
break;
default:
_8BP_printat_4(0, 0, 40, "DEFAULTO, MANOLO"); // Depuración
_8BP_printat_4(0, 50, 10, "DEFAULTO CASI");
return; // Retorna si no hay un caso válido
}
}
Aqui la parte del ciclo de juego, donde se accede todo el rato, pues c se incrementa todo el rato:
// Ciclo del juego
c++;
for (int i = 0; i < 3; i++) { // Recorre los índices del arreglo cycleHorda.
if (c == cicloHorda[i]) {
TipoEnemigo tipoEnemigo = tipoHorda[i];
createEnemies(tipoEnemigo);
index++; // Incrementa el índice
}
}
Tampoco muestra los mensajes que hay en default dentro del switch
Aunque si cambio :
if (c == cicloHorda[i])
por
if (c >= cicloHorda[i] && c < cicloHorda[i] + 8)
si muestra los mensajes del default, que son:
DEFAULT, MANOLO
DEFAULT CASI
Realmente no entiendo porque ignora el switch
Como se puede ver, uso Typedef enum y arrays al principio del programa
Gracias!
No lo puedo probar, porque faltan fragmentos de fuente y detalles sobre qué compilador/entorno usas, pero en un vistazo rápido se me ocurre que quizá no se recorran todos los ciclos (si no se pasa por ellos uno por uno, sino que se consulta el reloj del sistema) y, en ese caso, como tú mismo has descubierto, deberás mirar si el valor está dentro de un cierto rango, en vez de mirar valores exactos.
Bueno, si quito todo lo referente a:
// Definir una enumeración para los tipos de enemigos
typedef enum {
METEORITO , // 0
OVNI, // 1
TANQUE // 2
} TipoEnemigo;
void createEnemies(TipoEnemigo tipoEnemigo);
TipoEnemigo tipoHorda[3] = {METEORITO, OVNI, TANQUE}; // Hay 3 tipos de enemigos
int cicloHorda[3] = {100, 200, 350}; // Aparecen en ciclos 100, 200, 350
/ Función para crear enemigos
void createEnemies(TipoEnemigo tipoEnemigo) {
switch (tipoEnemigo) {
case METEORITO:
if (phase == 1) {
_8BP_printat_4(0, 0, 12, "CREANDO METEORITO"); // Depuración
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
break;
case OVNI:
if (phase == 1) {
int enemymalo = malo + 1; // Crear enemigos en el ciclo 160
_8BP_setupsp_3(enemymalo, 9, 21);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 2);
_8BP_locatesp_3(enemymalo, 50, 500);
_8BP_printat_4(0, 0, 14, "OVNI CREADO"); // Depuración
}
break;
case TANQUE:
if (phase == 1) {
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 20);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 1);
_8BP_locatesp_3(enemymalo, 50, 160);
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 16 + i, "TANQUE CREADO"); // Depuración
}
}
break;
default:
_8BP_printat_4(0, 0, 40, "DEFAULTO, MANOLO"); // Depuración
_8BP_printat_4(0, 50, 10, "DEFAULTO CASI");
return; // Retorna si no hay un caso válido
}
}
for (int i = 0; i < 3; i++) {
// Recorre los índices del arreglo cycleHorda.
if (c == cicloHorda[i]) {
TipoEnemigo tipoEnemigo = tipoHorda[i];
createEnemies(tipoEnemigo);
y pongo simplemente en el while (lives>0):
while (lives > 0) {
if (phase == 1) {
_8BP_umap_6(20000, 20078, 0, 31000, 0, 31000); // Mapa fase 1
if (c==100){ // Crea el enemigo en el ciclo 100
for (int i = 1; i <= 4; i++) { // Bucle que crea 4 enemigos en fila india
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128); // Estado del enemigo
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
Igualmente, Nacho, aqui comparto 2 archivos para que puedas probarlos en un emulador:
1 llamado ciclo, donde está el archivo con todo (typedef,arrays, switch...) en el que no se crean los enemigos
El otro llamado ciclo1, en el que he borrado todo, y he puesto un:
if (c==100) en el while(lives>0)
https://onedrive.live.com/?cid=3EA6B2C9A286AFE5&id=3EA6B2C9A286AFE5%21s58a0b696f8d44cf29731b4645e519240&parId=root&o=OneUp
https://onedrive.live.com/?cid=3EA6B2C9A286AFE5&id=3EA6B2C9A286AFE5%21sfff53d5e75ce4773a8d55e666d5f8ff3&parId=root&o=OneUp
Gracias!
Olvidé decir que dentro de los archivos comprimidos estan los 2 archivos .c
Tambien decir que usé el compilador sdcc
Igualmente pego aqui las dos fuentes del juego :
1- El que falla en la creacion de enemigos:
#include <stdlib.h> // Incluye la biblioteca estándar de C
#include <string.h> // Incluye la biblioteca de manipulación de cadenas
#include <stdio.h> // Incluye la biblioteca estándar de entrada y salida
#include "8BP.h" // Incluye la biblioteca 8BP para crear juegos en Amstrad
#include "minibasic.h" // Incluye la biblioteca minibasic.h para usar comandos Basic
#define MALO_BASE 13
// Definir una enumeración para los tipos de enemigos
typedef enum {
METEORITO , // 0
OVNI, // 1
TANQUE // 2
} TipoEnemigo;
// Prototipos de funciones
void initializeVariables();
void presentation();
void showControls();
int waitSelection();
void startGame();
void waitKeyReleased(int key);
void waitEnterReleased();
void showPhaseAndWait(int phase);
void wait(int c);
int routineCollision();
void showCycleGame();
void createEnemies(TipoEnemigo tipoEnemigo);
// Variables globales
int menu, y, x, i, xi, xmalo, last;
int cor = 32;
int cod = 32;
int rescol = 0;
int c; // Ciclo del juego
unsigned int sp, m, malo, lives, phase;
unsigned int score = 0;
char score_str[10]; // Asegúrate de que haya suficiente espacio para la cadena de puntuación
char* cad;
TipoEnemigo tipoHorda[3] = {METEORITO, OVNI, TANQUE}; // Hay 3 tipos de enemigos
int cicloHorda[3] = {100, 200, 350}; // Aparecen en ciclos 100, 200, 350
int index = 0; // Cada vez que se crean los enemigos, el índice aumenta en 1
// Programa principal
int main() {
initializeVariables(); // Llama a la función para inicializar variables
menu = 1; // Variable que controla el menú principal
y = 100;
x = 50;
c = 0;
m = 0;
sp = 0;
last = 0;
lives = 3;
phase = 1;
i = 0;
xmalo = 160;
cor = 32;
cod = 32;
xi = 1;
malo = 13;
rescol = 0;
score = 0;
int index = 0;
_8BP_colspall_2(&cor, &cod);
_8BP_map2sp_1(1);
while (menu) {
presentation(); // Muestra la presentación y el menú principal
menu = waitSelection(); // Espera la selección del usuario
}
return 0; // Completa el programa con éxito
}
// Función para crear enemigos
void createEnemies(TipoEnemigo tipoEnemigo) {
switch (tipoEnemigo) {
case METEORITO:
if (phase == 1) {
_8BP_printat_4(0, 0, 12, "CREANDO METEORITO"); // Depuración
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
break;
case OVNI:
if (phase == 1) {
int enemymalo = malo + 1; // Crear enemigos en el ciclo 160
_8BP_setupsp_3(enemymalo, 9, 21);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 2);
_8BP_locatesp_3(enemymalo, 50, 500);
_8BP_printat_4(0, 0, 14, "OVNI CREADO"); // Depuración
}
break;
case TANQUE:
if (phase == 1) {
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 20);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 1);
_8BP_locatesp_3(enemymalo, 50, 160);
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 16 + i, "TANQUE CREADO"); // Depuración
}
}
break;
default:
_8BP_printat_4(0, 0, 40, "DEFAULTO, MANOLO"); // Depuración
_8BP_printat_4(0, 50, 10, "DEFAULTO CASI");
return; // Retorna si no hay un caso válido
}
}
// Inicializa variables necesarias
void initializeVariables() {
// Inicializar variables necesarias
}
// Muestra la presentación y el menú principal
void presentation() {
_basic_ink(2, 26);
_basic_ink(4, 26);
_basic_cls();
// Titulo del juego
_8BP_setupsp_3(0, 9, 28);
_8BP_setupsp_3(0, 0, 1);
_8BP_locatesp_3(0, 50, 25);
_8BP_setupsp_3(1, 9, 29);
_8BP_setupsp_3(1, 0, 1);
_8BP_locatesp_3(1, 50, 44);
_8BP_setupsp_3(2, 9, 30);
_8BP_setupsp_3(2, 0, 1);
_8BP_locatesp_3(2, 60, 36);
_8BP_printat_4(0, 80, 12, "1- CONTROLES");
_8BP_printat_4(0, 100, 12, "2- JUGAR");
_8BP_printat_4(0, 185, 22, " DIV72 2025 - 8BP ");
// Dibujar todos los sprites
_8BP_printspall();
}
// Espera la selección del usuario en el menú principal
int waitSelection() {
int selection = 0;
while (selection == 0) {
if (_basic_inkey(64) == 0) {
showControls();
waitKeyReleased(64);
selection = 1;
}
if (_basic_inkey(65) == 0) {
showPhaseAndWait(phase);
startGame();
waitKeyReleased(57);
selection = 1;
}
for (int pause = 0; pause < 10000; pause++);
}
return 1;
}
// Muestra el menú de controles
void showControls() {
_basic_cls();
_8BP_printat_4(1, 50, 30, "O- IZQUIERDA");
_8BP_printat_4(1, 70, 30, "P- DERECHA");
_8BP_printat_4(1, 90, 30, "Q- ARRIBA");
_8BP_printat_4(1, 110, 30, "A- ABAJO");
_8BP_printat_4(1, 130, 30, "SPC- DISPARO");
_8BP_printat_4(1, 150, 30, "PULSE ENTER PARA VOLVER AL MENU");
waitEnterReleased();
}
// Espera a que se suelte una tecla específica
void waitKeyReleased(int key) {
while (_basic_inkey(key) == 0) {
// Espera hasta que se suelte la tecla especificada
}
}
// Espera a que se suelte la tecla Enter
void waitEnterReleased() {
while (_basic_inkey(18) != 0) {
// Espera hasta que se suelte la tecla Enter (ASCII 18)
}
}
// Inicia el juego
void startGame() {
_8BP_setupsp_3(0,0,0); // Quitamos estado a sprite 0, que es la X del titulo para que no aparezca en pantalla
_basic_cls();
_basic_ink(1, 2);
_basic_ink(1, 3);
_basic_border(0);
_8BP_setlimits_4(5, 73, 0, 200);
// Setup game frame sprites
// Configurar y ubicar el sprite 0
_8BP_setupsp_3(1, 9, 18);
_8BP_setupsp_3(1, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(1, 161, 10 + 36 * i);
}
// Configurar y ubicar el sprite 1
_8BP_setupsp_3(2, 9, 25);
_8BP_setupsp_3(2, 0, 1);
_8BP_locatesp_3(2, 20, 5);
// Configurar y ubicar el sprite 2
_8BP_setupsp_3(3, 9, 26);
_8BP_setupsp_3(3, 0, 1);
_8BP_locatesp_3(3, 156, 5);
_8BP_setupsp_3(4, 9, 27);
_8BP_setupsp_3(4, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(4, 26, 5 + 66 * i);
}
_8BP_printspall_4(0, 0, 1, 0);
// Marcador de vidas
_8BP_setupsp_3(5, 9, 24);
for (int l = 0; l <= 2; l++) {
_8BP_printsp_3(5, 173, 15 + 4 * l);
}
_8BP_printat_4(0, 175, 50, "SC: ");
_8BP_setlimits_4(7, 71, 25, 156);
// Reset sprites
for (int m = 1; m <= 4; m++) {
_8BP_setupsp_3(m, 0, 0);
}
// Setup main character sprite
_8BP_printspall();
_8BP_setupsp_3(31, 9, 16);
_8BP_setupsp_3(31, 0, 1 + 32);
_8BP_locatesp_3(31, 100, 50);
while (lives > 0) {
if (phase == 1) {
_8BP_umap_6(20000, 20078, 0, 31000, 0, 31000); // Mapa fase 1
} else if (phase == 2) {
_8BP_umap_6(20079, 20157, 0, 31000, 0, 31000); // Mapa fase 2
}
// Ciclo del juego
c++;
_8BP_printat_4(0, 0, 0, "CICLO DE JUEGO"); // Mensaje depuración
_8BP_printat_4(0, 1, 1, "C: "); // Mensaje depuración
_8BP_printat_4(0, 5, 1, _basic_str(c)); // Mensaje depuración
for (int i = 0; i < 3; i++) {
// Recorre los índices del arreglo cycleHorda.
// _8BP_printat_4(0, 0, 1, "VERIFICANDO CICLO: "); // Depuración
// _8BP_printat_4(0, 5, 2, _basic_str(cicloHorda[i])); // Depuración de cicloHorda[i]
// Asegurémonos de que cicloHorda[i] tiene los valores esperados
// char buffer[10];
// sprintf(buffer, "cicloHorda[%d] = %d", i, cicloHorda[i]);
// _8BP_printat_4(0, 10, 3, buffer); // Depuración del valor real de cicloHorda[i]
if (c == cicloHorda[i]) {
// if (c >= cicloHorda[i] && c < cicloHorda[i] + 8){ // Compaginalo con el de arriba para testear
// Aquí se verifica si el ciclo actual del juego (c) es igual a alguno de los valores en cycleHorda.
// Si c coincide con alguno de estos valores, entonces es el momento de crear una horda de enemigos.
TipoEnemigo tipoEnemigo = tipoHorda[i];
// Asigna la etiqueta correspondiente de labelHorda a la variable label
_8BP_printat_4(0, 15, 4, "CREAR ENEMIGO: ");
_8BP_printat_4(0, 20, 5, _basic_str(tipoEnemigo)); // Depuración del valor de tipoEnemigo
createEnemies(tipoEnemigo);
// Llama a la función createEnemies con la etiqueta correspondiente.
index++; // Incrementa el índice
_8BP_printat_4(0, 25, 5, "ENEMIGOS CREADOS"); // Depuración
}
}
showCycleGame(); // Muestra el ciclo del juego
_8BP_map2sp_2(0, (c >> 1));
if (_basic_inkey(27) > 0)
goto label_140;
x = x + 2;
if (x >= 60) {
x = 60;
}
goto label_160;
label_140:
if (_basic_inkey(34) > 0)
goto label_160;
x = x - 2;
if (x <= 7) {
x = 7;
}
label_160:
if (_basic_inkey(67) > 0)
goto label_180;
y = y - 4;
if (y <= 25) {
y = 25;
}
goto label_200;
label_180:
if (_basic_inkey(69) > 0)
goto label_200;
y = y + 4;
if (y >= 125) {
y = 125;
}
label_200:
if (c - last < 8)
goto label_270;
if (_basic_inkey(47) > 0)
goto label_270;
sp = 23 + sp % 8;
last = c;
_8BP_setupsp_3(sp, 9, 17); // Disparo
_8BP_setupsp_3(sp, 0, 1 + 8 + 32);
_8BP_locatesp_3(sp, y + 12, x + 10);
_8BP_setupsp_4(sp, 5, 0, 4);
_basic_sound(1, 10, 10, 7, 0, 1, 0);
label_270:
_8BP_locatesp_3(31, y, x);
_8BP_autoall_1(1);
_8BP_colspall();
_8BP_printspall();
if (cor < 32)
rescol = routineCollision();
// Imprimir la puntuación actualizada en cada ciclo
sprintf(score_str, "%d", score);
_8BP_printat_4(0, 175, 60, score_str);
}
}
// Muestra la fase y espera unos segundos
void showPhaseAndWait(int phase) {
_basic_cls();
_8BP_printat_4(0, 80, 30, "PHASE ");
char mensaje[8];
sprintf(mensaje, "%d", phase);
_8BP_printat_4(0, 80, 41, mensaje);
wait(10000);
wait(10000);
}
// Espera un tiempo específico
void wait(int c) {
for (int i = 0; i < c; i++) {
// Un bucle vacío para consumir tiempo
}
}
// Rutina de colisión
int routineCollision() {
if (cor == 31) {
_basic_cls();
xmalo = 160;
cad = "TE HAN ALCANZADO!!! ";
_8BP_printat_4(0, 80, 30, cad);
wait(10000);
cad = " ";
_8BP_printat_4(0, 80, 30, cad);
c = c - 100; // Resta 100 ciclos al ser destruido el sprite 31
return 1;
}
_8BP_setupsp_3(cor, 7, 1); // La secuencia 1 es asignada al colisionador
_8BP_setupsp_3(cor, 0, 5); // El estado 5 (imprimible y animacion) es asignado al colisionador
if (cod < 22) {
_basic_border(7);
_basic_sound(1, 2000, 10, 7, 0, 0, 15);
_8BP_setupsp_3(cod, 7, 1);
_8BP_setupsp_3(cod, 0, 5);
_basic_call(0xbd19);
_basic_border(0);
score += 10;
sprintf(score_str, "%d", score);
_8BP_printat_4(0, 173, 50, score_str);
return 0;
}
return 0;
}
// Imprime el ciclo del juego
void showCycleGame() {
_basic_ink(2, 26);
_basic_ink(4, 26);
_basic_locate(10, 25);
char cycleStr[10];
sprintf(cycleStr, "%d", c);
_8BP_printat_4(0, 10, 60, cycleStr);
}
------------------------------------------------------------------------------------------------------------------------
2- El que funciona quitando cosas:
#include <stdlib.h> // Incluye la biblioteca estándar de C
#include <string.h> // Incluye la biblioteca de manipulación de cadenas
#include <stdio.h> // Incluye la biblioteca estándar de entrada y salida
#include "8BP.h" // Incluye la biblioteca 8BP para crear juegos en Amstrad
#include "minibasic.h" // Incluye la biblioteca minibasic.h para usar comandos Basic
#define MALO_BASE 13
// Definir una enumeración para los tipos de enemigos
// Prototipos de funciones
void initializeVariables();
void presentation();
void showControls();
int waitSelection();
void startGame();
void waitKeyReleased(int key);
void waitEnterReleased();
void showPhaseAndWait(int phase);
void wait(int c);
int routineCollision();
void showCycleGame();
// Variables globales
int menu, y, x, i, xi, xmalo, last;
int cor = 32;
int cod = 32;
int rescol = 0;
int c; // Ciclo del juego
unsigned int sp, m, malo, lives, phase;
unsigned int score = 0;
char score_str[10]; // Asegúrate de que haya suficiente espacio para la cadena de puntuación
char* cad;
// Programa principal
int main() {
initializeVariables(); // Llama a la función para inicializar variables
menu = 1; // Variable que controla el menú principal
y = 100;
x = 50;
c = 0;
m = 0;
sp = 0;
last = 0;
lives = 3;
phase = 1;
i = 0;
xmalo = 160;
cor = 32;
cod = 32;
xi = 1;
malo = 13;
rescol = 0;
score = 0;
int index = 0;
_8BP_colspall_2(&cor, &cod);
_8BP_map2sp_1(1);
while (menu) {
presentation(); // Muestra la presentación y el menú principal
menu = waitSelection(); // Espera la selección del usuario
}
return 0; // Completa el programa con éxito
}
// Inicializa variables necesarias
void initializeVariables() {
// Inicializar variables necesarias
}
// Muestra la presentación y el menú principal
void presentation() {
_basic_ink(2, 26);
_basic_ink(4, 26);
_basic_cls();
// Titulo del juego
_8BP_setupsp_3(0, 9, 28);
_8BP_setupsp_3(0, 0, 1);
_8BP_locatesp_3(0, 50, 25);
_8BP_setupsp_3(1, 9, 29);
_8BP_setupsp_3(1, 0, 1);
_8BP_locatesp_3(1, 50, 44);
_8BP_setupsp_3(2, 9, 30);
_8BP_setupsp_3(2, 0, 1);
_8BP_locatesp_3(2, 60, 36);
_8BP_printat_4(0, 80, 12, "1- CONTROLES");
_8BP_printat_4(0, 100, 12, "2- JUGAR");
_8BP_printat_4(0, 185, 22, " DIV72 2025 - 8BP ");
// Dibujar todos los sprites
_8BP_printspall();
}
// Espera la selección del usuario en el menú principal
int waitSelection() {
int selection = 0;
while (selection == 0) {
if (_basic_inkey(64) == 0) {
showControls();
waitKeyReleased(64);
selection = 1;
}
if (_basic_inkey(65) == 0) {
showPhaseAndWait(phase);
startGame();
waitKeyReleased(57);
selection = 1;
}
for (int pause = 0; pause < 10000; pause++);
}
return 1;
}
// Muestra el menú de controles
void showControls() {
_basic_cls();
_8BP_printat_4(1, 50, 30, "O- IZQUIERDA");
_8BP_printat_4(1, 70, 30, "P- DERECHA");
_8BP_printat_4(1, 90, 30, "Q- ARRIBA");
_8BP_printat_4(1, 110, 30, "A- ABAJO");
_8BP_printat_4(1, 130, 30, "SPC- DISPARO");
_8BP_printat_4(1, 150, 30, "PULSE ENTER PARA VOLVER AL MENU");
waitEnterReleased();
}
// Espera a que se suelte una tecla específica
void waitKeyReleased(int key) {
while (_basic_inkey(key) == 0) {
// Espera hasta que se suelte la tecla especificada
}
}
// Espera a que se suelte la tecla Enter
void waitEnterReleased() {
while (_basic_inkey(18) != 0) {
// Espera hasta que se suelte la tecla Enter (ASCII 18)
}
}
// Inicia el juego
void startGame() {
_8BP_setupsp_3(0,0,0); // Quitamos estado a sprite 0, que es la X del titulo para que no aparezca en pantalla
_basic_cls();
_basic_ink(1, 2);
_basic_ink(1, 3);
_basic_border(0);
_8BP_setlimits_4(5, 73, 0, 200);
// Setup game frame sprites
// Configurar y ubicar el sprite 0
_8BP_setupsp_3(1, 9, 18);
_8BP_setupsp_3(1, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(1, 161, 10 + 36 * i);
}
// Configurar y ubicar el sprite 1
_8BP_setupsp_3(2, 9, 25);
_8BP_setupsp_3(2, 0, 1);
_8BP_locatesp_3(2, 20, 5);
// Configurar y ubicar el sprite 2
_8BP_setupsp_3(3, 9, 26);
_8BP_setupsp_3(3, 0, 1);
_8BP_locatesp_3(3, 156, 5);
_8BP_setupsp_3(4, 9, 27);
_8BP_setupsp_3(4, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(4, 26, 5 + 66 * i);
}
_8BP_printspall_4(0, 0, 1, 0);
// Marcador de vidas
_8BP_setupsp_3(5, 9, 24);
for (int l = 0; l <= 2; l++) {
_8BP_printsp_3(5, 173, 15 + 4 * l);
}
_8BP_printat_4(0, 175, 50, "SC: ");
_8BP_setlimits_4(7, 71, 25, 156);
// Reset sprites
for (int m = 1; m <= 4; m++) {
_8BP_setupsp_3(m, 0, 0);
}
// Setup main character sprite
_8BP_printspall();
_8BP_setupsp_3(31, 9, 16);
_8BP_setupsp_3(31, 0, 1 + 32);
_8BP_locatesp_3(31, 100, 50);
while (lives > 0) {
if (phase == 1) {
_8BP_umap_6(20000, 20078, 0, 31000, 0, 31000); // Mapa fase 1
if (c==100){ // Si el ciclo es 100, se crea el enemigo
for (int i = 1; i <= 4; i++) { // Bucle que crea 4 enemigos en fila india
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128); // Estado del enemigo
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
} else if (phase == 2) {
_8BP_umap_6(20079, 20157, 0, 31000, 0, 31000); // Mapa fase 2
}
// Ciclo del juego
c++;
showCycleGame(); // Muestra el ciclo del juego
_8BP_map2sp_2(0, (c >> 1));
if (_basic_inkey(27) > 0)
goto label_140;
x = x + 2;
if (x >= 60) {
x = 60;
}
goto label_160;
label_140:
if (_basic_inkey(34) > 0)
goto label_160;
x = x - 2;
if (x <= 7) {
x = 7;
}
label_160:
if (_basic_inkey(67) > 0)
goto label_180;
y = y - 4;
if (y <= 25) {
y = 25;
}
goto label_200;
label_180:
if (_basic_inkey(69) > 0)
goto label_200;
y = y + 4;
if (y >= 125) {
y = 125;
}
label_200:
if (c - last < 8)
goto label_270;
if (_basic_inkey(47) > 0)
goto label_270;
sp = 23 + sp % 8;
last = c;
_8BP_setupsp_3(sp, 9, 17); // Disparo
_8BP_setupsp_3(sp, 0, 1 + 8 + 32);
_8BP_locatesp_3(sp, y + 12, x + 10);
_8BP_setupsp_4(sp, 5, 0, 4);
_basic_sound(1, 10, 10, 7, 0, 1, 0);
label_270:
_8BP_locatesp_3(31, y, x);
_8BP_autoall_1(1);
_8BP_colspall();
_8BP_printspall();
if (cor < 32)
rescol = routineCollision();
// Imprimir la puntuación actualizada en cada ciclo
sprintf(score_str, "%d", score);
_8BP_printat_4(0, 175, 60, score_str);
}
}
// Muestra la fase y espera unos segundos
void showPhaseAndWait(int phase) {
_basic_cls();
_8BP_printat_4(0, 80, 30, "PHASE ");
char mensaje[8];
sprintf(mensaje, "%d", phase);
_8BP_printat_4(0, 80, 41, mensaje);
wait(10000);
wait(10000);
}
// Espera un tiempo específico
void wait(int c) {
for (int i = 0; i < c; i++) {
// Un bucle vacío para consumir tiempo
}
}
// Rutina de colisión
int routineCollision() {
if (cor == 31) {
_basic_cls();
xmalo = 160;
cad = "TE HAN ALCANZADO!!! ";
_8BP_printat_4(0, 80, 30, cad);
wait(10000);
cad = " ";
_8BP_printat_4(0, 80, 30, cad);
c = c - 100; // Resta 100 ciclos al ser destruido el sprite 31
return 1;
}
_8BP_setupsp_3(cor, 7, 1); // La secuencia 1 es asignada al colisionador
_8BP_setupsp_3(cor, 0, 5); // El estado 5 (imprimible y animacion) es asignado al colisionador
if (cod < 22) {
_basic_border(7);
_basic_sound(1, 2000, 10, 7, 0, 0, 15);
_8BP_setupsp_3(cod, 7, 1);
_8BP_setupsp_3(cod, 0, 5);
_basic_call(0xbd19);
_basic_border(0);
score += 10;
sprintf(score_str, "%d", score);
_8BP_printat_4(0, 173, 50, score_str);
return 0;
}
return 0;
}
// Imprime el ciclo del juego
void showCycleGame() {
_basic_ink(2, 26);
_basic_ink(4, 26);
_basic_locate(10, 25);
char cycleStr[10];
sprintf(cycleStr, "%d", c);
_8BP_printat_4(0, 10, 60, cycleStr);
}
hola toni
no se como funciona pero te digo lo que
he visto por si te sirve:
cuando inicializas variables en el código
que no funciona defines otra vez index
¿para que inicializas algunas las varialbles
globales antes de la función de inicializar?
personalmente no me gusta usar varibles
globales, al manipularlas desde cualquier
sitio es propensa a errores dificiles de
encontrar
al comparar el código que dices que funciona
con que llamas completo, hay cosas nuevas, pero
solo una que modificas, startGame:
desde -> if (phase == 1) {
hasta -> showCycleGame();
en ese código tienes un else al que preceden dos ifs
quizás esté en el if incorrecto ya que en el que
funciona el _8BP final es de la fase 2 y en el que
tienes problemas es de la fase 1
y como pregunta, ¿ porqué usas goto pudiendo usar
programación estructurada ?
saludos ;-)
hola vicen
Antes que nada decir que no tengo mucha idea de programar en c.
Todo lo estoy haciendo con ayuda de la ia
Aún así, estoy intentando aprender con ella
Aquí van tus preguntas y las respuestas:
cuando inicializas variables en el código
que no funciona defines otra vez index
Tienes razón. Ya lo he cambiado
¿para que inicializas algunas las varialbles
globales antes de la función de inicializar?
Bueno, he cambiado omo lo tenía y he puesto las variables dentro de la funcion "initializeVariables", como puedes ver aqui:
#include <stdlib.h> // Incluye la biblioteca estándar de C
#include <string.h> // Incluye la biblioteca de manipulación de cadenas
#include <stdio.h> // Incluye la biblioteca estándar de entrada y salida
#include "8BP.h" // Incluye la biblioteca 8BP para crear juegos en Amstrad
#include "minibasic.h" // Incluye la biblioteca minibasic.h para usar comandos Basic
#define MALO_BASE 13
#define NUM_ENEMIGOS 3
// Definir una enumeración para los tipos de enemigos
typedef enum {
METEORITO = 1,
OVNI,
TANQUE
} TipoEnemigo;
// Prototipos de funciones
void initializeVariables();
void presentation();
void showControls();
int waitSelection();
void startGame();
void waitKeyReleased(int key);
void waitEnterReleased();
void showPhaseAndWait(int phase);
void wait(int c);
int routineCollision();
void showCycleGame();
void createEnemies(TipoEnemigo tipoEnemigo);
// Variables globales
int menu, y, x, i, xi, xmalo, last;
int cor = 32;
int cod = 32;
int rescol = 0;
int c; // Ciclo del juego
unsigned int sp, m, malo, lives, phase;
unsigned int score = 0;
char score_str[10]; // Asegúrate de que haya suficiente espacio para la cadena de puntuación
char* cad;
int jefeEliminado = 0;
int tipoenemigo[NUM_ENEMIGOS] = {1,2,3}; // Hay 3 tipos de enemigos
int cicloenemigo[NUM_ENEMIGOS] = {100, 200, 350}; // Aparecen en ciclos 100, 200, 350
int index = 0; // Cada vez que se crean los enemigos, el índice aumenta en 1
// Inicializa variables necesarias
void initializeVariables() {
menu = 1;
y = 100;
x = 50;
c = 0;
m = 0;
sp = 0;
last = 0;
lives = 3;
phase = 1;
i = 0;
xmalo = 160;
cor = 32;
cod = 32;
xi = 1;
malo = 13;
rescol = 0;
score = 0;
index = 0;
jefeEliminado = 0;
}
y como pregunta, ¿ porqué usas goto pudiendo usar
programación estructurada ?
Uso goto en el manejo del teclado, ya que si no, al empezar a jugar, la nave que manejo se mueve sola hacia arriba de la pantalla sin parar de disparar.
Aqui un ejemplo en basic:
301 c=c+1 // ciclo de juego
320 '---teclado---
330 IF INKEY(27) THEN 350
340 x=x+3:IF x>=50 THEN x=50:GOTO 370
350 IF INKEY(34) THEN 370
360 x=x-3:IF x<=-2 THEN x=-2
370 IF INKEY(67) THEN 390
380 y=y-5:IF y<=1 THEN y=1:GOTO 410
390 IF INKEY(69) THEN 410
400 y=y+5:IF y>=180 THEN y=179
410 IF c-last<4 THEN 450 // esto es para el tema del disparo
420 IF INKEY(47) THEN 450
430 sp=23+sp MOD 3: last=c:
440 |SETUPSP,sp,9,17:|SETUPSP,sp,0,1+8+32:|SETUPSP,sp,5,-15,0
441 SOUND 1,10,10,7,0,1
450 |LOCATESP,31,y,x // localizacion y,x de la nave
490 GOTO 301 // goto al ciclo de juego
No sé exactamente como hacerlo para c.
al comparar el código que dices que funciona
con que llamas completo, hay cosas nuevas, pero
solo una que modificas, startGame:
desde -> if (phase == 1) {
hasta -> showCycleGame();
en ese código tienes un else al que preceden dos ifs
quizás esté en el if incorrecto ya que en el que
funciona el _8BP final es de la fase 2 y en el que
tienes problemas es de la fase 1
Perdona, no lo entiendo
Todos los |setupsp son exclusivos de la librería
Van bien, pues como dije en un mensaje anterior, solo me aparece la horda de enemigos si en el ciclo de juego (donde c=c+1) pongo:
if (c==100 {
_8BP_printat_4(0, 0, 12, "CREANDO METEORITO"); // Depuración
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
En este ejemplo, se muestra el mensaje de depuracion y aparece el enemigo en el ciclo 100
Lo siguiente es todo lo referente a la creacion de enemigos
antes del main:
#define NUM_ENEMIGOS 3
// Definir una enumeración para los tipos de enemigos
typedef enum {
METEORITO = 1,
OVNI,
TANQUE
} TipoEnemigo;
void createEnemies(TipoEnemigo tipoEnemigo);
int tipoenemigo[NUM_ENEMIGOS] = {1,2,3}; // Hay 3 tipos de enemigos
int cicloenemigo[NUM_ENEMIGOS] = {100, 200, 350}; // Aparecen en ciclos 100, 200, 350
int index = 0; // Cada vez que se crean los enemigos, el índice aumenta en 1
phase = 1;
despues del main:
// Función para crear enemigos
void createEnemies(TipoEnemigo tipoEnemigo) {
switch (tipoEnemigo) {
case METEORITO:
if (phase == 1) {
_8BP_printat_4(0, 0, 12, "CREANDO METEORITO"); // Depuración
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 19); // Sprite de la nave enemiga
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 0); // Ruta
_8BP_locatesp_3(enemymalo, 50, xmalo); // Posición x, y
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 13 + i, "METEORITO CREADO"); // Depuración
}
}
break;
case OVNI:
if (phase == 1) {
int enemymalo = malo + 1; // Crear enemigos en el ciclo 160
_8BP_setupsp_3(enemymalo, 9, 21);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 2);
_8BP_locatesp_3(enemymalo, 50, 500);
_8BP_printat_4(0, 0, 14, "OVNI CREADO"); // Depuración
}
break;
case TANQUE:
if (phase == 1) {
for (int i = 1; i <= 4; i++) {
xi = xi + 1;
int enemymalo = MALO_BASE + (xi % 6);
_8BP_setupsp_3(enemymalo, 9, 20);
_8BP_setupsp_3(enemymalo, 0, 1 + 8 + 2 + 128);
_8BP_setupsp_3(enemymalo, 15, 1);
_8BP_locatesp_3(enemymalo, 50, 160);
_8BP_routesp_2(enemymalo, i * 6);
_8BP_printat_4(0, 0, 16 + i, "TANQUE CREADO"); // Depuración
}
}
break;
default:
// No hacer nada en caso de valor desconocido
break;
}
}
// Inicia el juego
void startGame() {
_8BP_setupsp_3(0,0,0); // Quitamos estado a sprite 0, que es la X del titulo para que no aparezca en pantalla
_basic_cls();
_basic_ink(1, 2);
_basic_ink(1, 3);
_basic_border(0);
_8BP_setlimits_4(5, 73, 0, 200);
// Setup game frame sprites
// Configurar y ubicar el sprite 0
_8BP_setupsp_3(1, 9, 18);
_8BP_setupsp_3(1, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(1, 161, 10 + 36 * i);
}
// Configurar y ubicar el sprite 1
_8BP_setupsp_3(2, 9, 25);
_8BP_setupsp_3(2, 0, 1);
_8BP_locatesp_3(2, 20, 5);
// Configurar y ubicar el sprite 2
_8BP_setupsp_3(3, 9, 26);
_8BP_setupsp_3(3, 0, 1);
_8BP_locatesp_3(3, 156, 5);
_8BP_setupsp_3(4, 9, 27);
_8BP_setupsp_3(4, 0, 1);
for (int i = 0; i <= 1; i++) {
_8BP_printsp_3(4, 26, 5 + 66 * i);
}
_8BP_printspall_4(0, 0, 1, 0);
// Marcador de vidas
_8BP_setupsp_3(5, 9, 24);
for (int l = 0; l <= 2; l++) {
_8BP_printsp_3(5, 173, 15 + 4 * l);
}
_8BP_printat_4(0, 175, 50, "SC: ");
_8BP_setlimits_4(7, 71, 25, 156);
// Reset sprites
for (int m = 1; m <= 4; m++) {
_8BP_setupsp_3(m, 0, 0);
}
// Setup main character sprite
_8BP_printspall();
_8BP_setupsp_3(31, 9, 16);
_8BP_setupsp_3(31, 0, 1 + 32);
_8BP_locatesp_3(31, 100, 50);
while (lives > 0) {
if (phase == 1) {
_8BP_umap_6(20000, 20078, 0, 31000, 0, 31000); // Mapa fase 1
} else if (phase == 2) {
_8BP_umap_6(20079, 20157, 0, 31000, 0, 31000); // Mapa fase 2
}
// Ciclo del juego
c++;
// createEnemies((TipoEnemigo)tipoenemigo);
// Verificar ciclos para crear enemigos
for (int i = 0; i < NUM_ENEMIGOS; i++) {
if (c == cicloenemigo[i]) {
TipoEnemigo tipoEnemigo = (TipoEnemigo)tipoenemigo[i];
createEnemies(tipoEnemigo);
index++;
}
}
este ultimo bloque, como se puede ver, esta dentro de void (startgame) y del while (lives > 0)
Gracias y un saludo!
hola toni
yo tampoco tengo mucha idea de c, pero un poco si.
todos esos gotos se puede sustituir por un switch
y poniendo constantes de las teclas en vez de números
será mucho más legible
tienes una variable 'c' que la usas como global y que
también la defines como variable local
la verdad es que tienes unos cuantos nombres de
variables poco significativos en los que con el nombre
no se adivina para que sirven tal como c, sp, i, xmalo,
xi, m, etc.
esto no ayuda a entender el código, poner nombres
largos está bien si ayudan a entender el código
por ej caracter_leido o tiempo_disparo esto si ayuda a
enteder que hace el código
podrías pasar el código completo actualizado que funcione
y apartir de ahí ver que quieres incorporarle, si te animas a
pasa el código con un enlace de https://www.onlinegdb.com/
o similar, que lo colorea y usa fuentes monoespaciadas, se
entiende mejor
por mi parte miraré de instalarme un emulador de
amstrad, no se cuál usas tú, a ver si puedo ejecutar
el código y ayudarte a avanzar en los cambios
ya me cuentas ...
saludos ;-)
el código que digo que modificas de una versión a
otra, la que dices que no funciona que es completa
y la que dices que si funciona pero le falta código,
en la función startGame le quite los comentarios y
tienes estas diferencias que no se si tienen que ver
con que te funcione o no:
https://imgur.com/a/Q1xrqjj
pense que quizás como el else tiene dos ifs anteriores
puediera estar en el if equivocado, no se ya me dices
suerte ;-)
Bueno, comparto aqui el proyecto.
Es un archivo rar llamado "Proyecto".
Dentro hay varias carpetas de las cuales las que interesan son las de Basic, Asm , C y Output.
Dentro de la carpeta Basic está el loader (cargador) del juego
En la carpeta Asm, está el fichero "Make all my game.asm"
En la carpeta C está el compilador ses.bat para ir compilandoi a medida que vayas cambiando algo en el archivo c, y los 2 ficheros fuentes:
"funciona.c", donde he borrado todo lo referente a arrays, typedef enum,.... y he puesto simplemente if (phase==1 && c=100 y el enemigo a aparecer) que funciona
"nofunciona.c" donde estan los arrays, typedef enum, y demás, que es en donde no aparecen los enemigos.
Carpeta output, donde está un dsk con el juego que funciona, y un video casi tutorial, usando el emulador, compilando, etc....
Para compilar la libreria, aunque yo uso una pestaña que pone Run, funciona simplemente con F9
Por cierto, uso Winape como emulador, pues permite copiar y pegar texto en pantalla, como se puede ver en el video.
https://www.dropbox.com/scl/fi/4eo8lk93behyy18v34cmn/Proyecto.rar?rlkey=3218qre5sjrx6i6a33yjkprlz&st=5c1r8o4u&dl=0
Gracias!
Quiero compartir aquí el proyecto que estoy haciendo para amstrad
Es un archivo rar donde dentro están las siguientes carpetas:
Basic: aquí esta el loader (cargador) del juego
El último CALL es el valor que te da el main del archivo ciclo.map
En este caso:
000010BB _main ciclo
ASM: En esta carpeta hay un archivo llamado make_all_mygame.asm donde se ensambla todo
C: aquí está el archivo ses.bat para compilar el c (escribir compila.bat)
Cada vez que se modifica algo en el juego, hay que compilar
El archivo ha dellamarse ciclo.c
Tambien están 2 archivos c del juego, uno en el que funciona y otro que el que no.
Output: dentro están los siguientes archivos:
funciona.dsk (el juego en el que funciona la aparicion del enemigo)
funciona2.rar ( donde dentro está el archivo c del juego que funciona y el dsk)
Es recomendable usar el emulador Winape si se quiere modificar algo del juego, pues este emulador permite copiar y pegar texto.
He añadido un video de muestra dentro del rar para que esté algo más claro
Gracias!
https://www.dropbox.com/scl/fi/4eo8lk93behyy18v34cmn/Proyecto.rar?rlkey=3218qre5sjrx6i6a33yjkprlz&st=uqima4ek&dl=0
hola toni acabo de ver tu respuesta y he descargado la carpeta
este finde intento instalar todo y te digo cosas
saludos ;-)
Gracias, vicen!
hola toni
he buscado info y hay bastantes cosas en la red, me he instalado winape y también javacpc para probarlos
he encontrado una especie de curso que me ha parecido muy interesante, es de un profesor de la
universidad de alicante y ahora estoy viendo como funcionan los emuladores
el curso está muy bien porque proponen hacer un juego para amstrad sencillo y es una pugna
entre dos programadores, uno lo hace en basic y el otro la misma parte en c, todo desde cero.
además se puede descargar el código de github ellos crean una rama con el código de cada sesión
con lo que se debería tener los mismos resultados que ellos y experimentar desde ahí
creo que también tienen una maquina virtual descargable para vbox con las
instalaciones, eso me pareció que decían pero no estoy tan seguro
son unos 12 videos y son bastante largos, pero se explican bien y se hace ameno
su lista de reproducción es super retrogame sobre todo del z80, ensamblador, basic y c
listas en su canal:
https://www.youtube.com/@ProfesorRetroman/playlists
tutorial que estoy viendo:
https://www.youtube.com/playlist?list=PLmxqg54iaXrhtRxS4-tRwG9HJd0h59uUh
bueno me estoy poniendo al día en como funciona esto, estamos en contacto
ya me dices si te gusta o si estas haciendo algún otro tutorial seguro te gusta
saludos ;-)
Si, vicen, el profesor es Fran Gallego
Es quien organizaba la cpcretrodev, un concurso de creación de videojuegos para amstrad cpc
Sus videos están muy bien. Los de c son entretenidos, sobre todo esos que dices, que hacen un juego en basic y c
Aunque están orientados a cpctelera, que es un game engine, y tiene sus propias funciones.
8bp, también tiene las suyas, y se han hecho varios juegos en c.
En la pagina de 8bp amstrad, donde se descarga la librería, vienen algunos creados en este lenguaje. Algunos vienen en basic y el ciclo de juego está hecho en c
Por cierto, me he creado un IDE para tenerlo todo a mano al crear los proyectos
https://www.imagebam.com/view/MEZ43LQ
En él ya viene el emulador, el editor de texto, las carpetas, un boton que pone c para que se te abra el archivo c, y un boton de compile, para compilar dicho archivo y se cree el ciclo.dsk
El archivo c viene en la carpeta Proyecto
(el archivo ha de llamarse ciclo.c para que pueda compilar, aunque se puede modificar)
https://toni-hernandez.itch.io/ide-8bp
Gracias!