Allegro.cc - Online Community
Post Reply

Allegro.cc Forums » Programming Questions » My second game, space invader simplified

rss feed Print
My second game, space invader simplified
amstradcpc
Member #23,651
January 2023

//main---------------------------------------------------------------------

#SelectExpand
1#include <iostream> 2#include <allegro5/allegro5.h> 3#include <allegro5/allegro_font.h> 4#include <allegro5/allegro_ttf.h> 5#include <allegro5/allegro_image.h> 6 7#include "jugador.h"; 8#include "enemigo1.h"; 9#include "fondo1.h"; 10 11int main () { 12 //iniciar allegro 13 al_init(); 14 //instalar teclado 15 al_install_keyboard(); 16 //iniciamos fuente de sistema 17 al_init_font_addon(); 18 //iniciamos fuente externa 19 al_init_ttf_addon(); 20 //iniciar imagenes 21 al_init_image_addon(); 22 23 //configuramos ventana en modo ventana 24 al_set_new_display_flags(ALLEGRO_WINDOWED); 25 //creamos ventana(ancho,alto) 26 ALLEGRO_DISPLAY* ventana = al_create_display(640,480); 27 28 //poner titulo a la ventana 29 al_set_window_title(ventana,"space invader"); 30 31 //ocultar raton 32 al_hide_mouse_cursor(ventana); 33 34 //crear eventos 35 ALLEGRO_EVENT_QUEUE* evento_queque = al_create_event_queue(); 36 //crear tiempo para fps(60) 37 ALLEGRO_TIMER* tiempo = al_create_timer(1.0/60.0); 38 39 //registra keyboard 40 al_register_event_source(evento_queque,al_get_keyboard_event_source()); 41 //registra display 42 al_register_event_source(evento_queque,al_get_display_event_source(ventana)); 43 //registra timer 44 al_register_event_source(evento_queque,al_get_timer_event_source(tiempo)); 45 46 47 //iniciamos objetos------------------------------- 48 Jugador jugador{ 300.0f,380.0f }; 49 Enemigo1 enemigo1{ 500.0f,32.0f }; 50 Fondo1 fondo1{ 320.0f,240.0f }; 51 52 bool ejecutar = true; 53 //iniciar tiempo,es obligatorio si no,no se vera la imagen 54 al_start_timer(tiempo); 55 while(ejecutar == true){ 56 57 //variable para eventos 58 ALLEGRO_EVENT evento; 59 //esperar para cada evento 60 al_wait_for_event(evento_queque,&evento); 61 //si pulso abajo o boton para cerrar ventana 62 switch(evento.type){ 63 case ALLEGRO_EVENT_TIMER: 64 //limpiar pantalla a un color 65 al_clear_to_color(al_map_rgb(0,0,160)); 66 67 //pintamos objetos 68 fondo1.pintar(); 69 jugador.pintar(); 70 enemigo1.pintar(); 71 //actualizar pantalla 72 al_flip_display(); 73 break; 74 case ALLEGRO_EVENT_KEY_DOWN: 75 if(evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE){ 76 ejecutar = false; //terminar bucle 77 } 78 break; 79 } 80 } 81 82 al_destroy_display(ventana); //destruir ventana 83 //destruir evento queque 84 al_destroy_event_queue(evento_queque); 85 86 al_uninstall_keyboard(); //desinstalar teclado 87 //destruir evento de tiempo 88 al_destroy_timer(tiempo); 89 90 return 0; 91}

//jugador.h---------------------------------------------------------------------

#SelectExpand
1#pragma once 2#ifndef JUGADOR_H 3#define JUGADOR_H 4 5#include<iostream> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_image.h> 8 9class Jugador{ 10private: 11 //cargar todo tipo de imagenes 12 ALLEGRO_BITMAP* imagen{ al_load_bitmap("jugador.png") }; 13 //variable de estado de teclas 14 ALLEGRO_KEYBOARD_STATE estado_de_teclas{}; 15 float x{}; 16 float y{}; 17 float velocidad{ 5.0f }; 18public: 19 Jugador(float x,float y); 20 21 void pintar(); 22 23 void mover(); 24 25 ~Jugador(); 26}; 27 28#endif //fin jugador

//jugador.cpp---------------------------------------------------------------------

#SelectExpand
1#include "jugador.h"; 2 3//clase jugador-------------------------------------- 4 5Jugador::Jugador(float x,float y){ 6 std::cout<<"iniciamos jugador"<<"\n"; 7 this->x = x; 8 this->y = y; 9} 10 11void Jugador::pintar(){ 12 mover(); 13 //pintamos imagen(imagen,x,y,voltear) 14 al_draw_bitmap(imagen,x,y,0); 15} 16 17void Jugador::mover(){ 18 //obtener el estado de teclas 19 al_get_keyboard_state(&estado_de_teclas); 20 //uso de teclado,recomendable usar dentro de evento de tiempo 21 if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_RIGHT)){ 22 x += velocidad; 23 }else if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_LEFT)){ 24 x -= velocidad; 25 } 26} 27 28Jugador::~Jugador(){ 29 std::cout<<"finalizamos jugador"<<"\n"; 30 //destruir iamgen de bitmap 31 al_destroy_bitmap(imagen); 32} 33//fin clase jugador----------------------------------

//enemigo1.h-------------------------------------------------------------------

#SelectExpand
1#pragma once 2#ifndef ENEMIGO1_H 3#define ENEMIGO1_H 4 5#include<iostream> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_image.h> 8 9class Enemigo1{ 10private: 11 //cargar todo tipo de imagenes 12 ALLEGRO_BITMAP* imagen{ al_load_bitmap("enemigo1.png") }; 13 float x{}; 14 float y{}; 15 float velocidad{ 0.5f }; 16public: 17 Enemigo1(float x,float y); 18 19 void pintar(); 20 21 void mover(); 22 23 ~Enemigo1(); 24}; 25 26#endif //fin enemigo1

//enemigo1.cpp-------------------------------------------------------------------

#SelectExpand
1#include "enemigo1.h"; 2 3//clase enemigo1-------------------------------------- 4 5Enemigo1::Enemigo1(float x,float y){ 6 std::cout<<"iniciamos enemigo1"<<"\n"; 7 this->x = x; 8 this->y = y; 9} 10 11void Enemigo1::pintar(){ 12 mover(); 13 //pintamos imagen(imagen,x,y,voltear) 14 al_draw_bitmap(imagen,x,y,0); 15} 16 17void Enemigo1::mover(){ 18 y += velocidad; 19} 20 21Enemigo1::~Enemigo1(){ 22 std::cout<<"finalizamos enemigo1"<<"\n"; 23 //destruir iamgen de bitmap 24 al_destroy_bitmap(imagen); 25} 26//fin clase enemigo1----------------------------------

//fondo1.h--------------------------------------------------------------------

#SelectExpand
1#pragma once 2#ifndef FONDO1_H 3#define FONDO1_H 4 5#include<iostream> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_image.h> 8#include <allegro5/allegro_font.h> 9#include <allegro5/allegro_ttf.h> 10 11class Fondo1{ 12private: 13 //cargar todo tipo de imagenes 14 ALLEGRO_BITMAP* imagen{ al_load_bitmap("pasto.png") }; 15 //cargamos fuente externa 16 ALLEGRO_FONT* fuente_externa = al_load_ttf_font("StRyde.ttf",25,0); 17 float ancho{ al_get_bitmap_width(imagen) /2.0f }; 18 float alto{ al_get_bitmap_height(imagen) /2.0f }; 19 float x{},y{},rotar{}; 20public: 21 Fondo1(float x,float y); 22 void pintar(); 23 ~Fondo1(); 24}; 25 26#endif //fin fondo1

//fondo1.cpp---------------------------------------------------------------------

#SelectExpand
1#include "fondo1.h"; 2 3//clase fondo1---------------------------------------- 4Fondo1::Fondo1(float x,float y){ 5 std::cout<<"iniciamos fondo1"<<"\n"; 6 this->x = x; 7 this->y = y; 8} 9 10void Fondo1::pintar(){ 11 //imagen(imagen,ancho,alto,x,y,rotacion,voltear) 12 al_draw_rotated_bitmap(imagen,ancho,alto,x,y,rotar,0); 13 //pintar texto 14 al_draw_text(fuente_externa,al_map_rgb(255,255,255),320,32, 15 ALLEGRO_ALIGN_CENTER,"nivel 1"); 16} 17 18Fondo1::~Fondo1(){ 19 std::cout<<"finalizamos fondo1"<<"\n"; 20 //destruir iamgen de bitmap 21 al_destroy_bitmap(imagen); 22 //destruir fuente 23 al_destroy_font(fuente_externa); 24} 25//fin clase fondo1------------------------------------

I would like to create a simplified version of space invader with some changes to make it easier for me to program and keep learning.
I have three objects at the moment, the player's ship moving from left to right, the enemy moving down, and the background.
I want to organize the code correctly from the beginning and I am going to create two levels to see how it goes from one to the other when a certain condition is met, what I would like to do now is create level 1 and add those objects.
So how do I create the first level and a structure to manage the levels of the game.

DanielH
Member #934
January 2001
avatar

a little feedback.

// no need '== true', when ejcecutar is a boolean which is already true or false.
//while(ejecutar == true)
while(ejecutar)

// '#pragma once' o '#ifndef JUGADOR_H'. No los dos.
#pragma once
#ifndef JUGADOR_H
#define JUGADOR_H

#SelectExpand
1//bitmaps cannot be preloaded like this. Allegro must be initialized first. Load the bitmap in the constructor if you have to, but after allegro. Bitmaps should also be loaded after the display is created. 2class Jugador{ 3private: 4 //cargar todo tipo de imagenes 5 ALLEGRO_BITMAP* imagen{ al_load_bitmap("jugador.png") }; 6 7// If you separate class declaration and definitions then DO NOT INITIAZLIZE any variables in your class declaration. Unless they are constants. 8 9 //cargar todo tipo de imagenes 10 ALLEGRO_BITMAP* imagen; 11 //variable de estado de teclas 12 ALLEGRO_KEYBOARD_STATE estado_de_teclas; 13 float x; 14 float y; 15 float velocidad; 16 17 // this is ok 18 const float default_velocidad = 5.0f;

#SelectExpand
1/* 2Jugador::Jugador(float x,float y){ 3 std::cout<<"iniciamos jugador"<<"\n"; 4 this->x = x; 5 this->y = y; 6} 7*/ 8 9/* 10initialize your class variables like this. It's more efficient. The initialization list needs to include all class variables (unless derived) and in the exact same order they were declared. 11Not necessary, but I like to prefix the class' member variables with either 'm' or 'm_'. that way you know which variables are member variables and which are not. 12*/ 13Jugador::Jugador(float x, float y) : m_imagen(nullptr), m_estado_de_teclas(), m_x(x), m_y(y), m_velocidad(5.0f) { 14 std::cout<<"iniciamos jugador"<<"\n"; 15}

So how do I create the first level and a structure to manage the levels of the game.

What is it you want it to look like? In the original game, there are 5 rows of aliens. No variations. So I don't know what you mean by level if it's all the same. Unless you want variation in aliens or different placement.

I played a lot of TI Invaders as a kid from the TI4/99a. That was my first experience with a space invaders game. They had the same 5 rows, but a variation of enemies. Each 2 rows was a different alien. Every time you cleared a level, the rows would shift. Meaning, every 2 levels you got a new alien. And they got harder to hit.
613296

Later levels, they would flash, increase/decrease size. Also, each level they got just a bit faster.

amstradcpc
Member #23,651
January 2023

Sorry, I made a mistake in the game. I mean the galaga, I usually play the nes version on an emulator, it's the one I like the most in this style, I don't like the space invader very much.
Regarding the levels, I mean the stages, I think that's how it is said in English, so I want to create two stages, the first with the different enemies and the second level where the enemies appear from different parts of the screen moving along a route or something So.
Well that, I want to know how the code can be structured for two stages, I create the first one and when I eliminate all the enemies it goes to the second stage. I don't know if I explained myself well, it's complicated with the translator.

#SelectExpand
1#ifndef DISPARO_H 2#define DISPARO_H 3 4#include<iostream> 5#include <allegro5/allegro5.h> 6#include <allegro5/allegro_image.h> 7 8class Disparo{ 9private: 10 ALLEGRO_BITMAP* m_imagen; 11 float m_x,m_y,m_velocidad; 12public: 13 Disparo(float x,float y); 14 void pintar(); 15 void mover(); 16 ~Disparo(); 17}; 18 19 20#endif //DISPARO_H

#SelectExpand
1#include "disparo.h"; 2 3Disparo::Disparo(float x,float y): m_imagen{al_load_bitmap("disparo.png")}, 4 m_x{x},m_y{y},m_velocidad{1.0f}{ 5 std::cout<<"iniciando disparo"<<"\n"; 6} 7 8void Disparo::pintar(){ 9 mover(); 10 al_draw_bitmap(m_imagen,m_x,m_y,0); 11} 12 13void Disparo::mover(){ 14 m_y -= m_velocidad; 15} 16 17Disparo::~Disparo(){ 18 std::cout<<"finalizar disparo"<<"\n"; 19 al_destroy_bitmap(m_imagen); 20}

#SelectExpand
1//#pragma once 2#ifndef JUGADOR_H 3#define JUGADOR_H 4 5#include<iostream> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_image.h> 8#include "disparo.h"; 9 10class Jugador{ 11private: 12 //m_ -> significa variables miembro de la clase 13 //en los archiivos de cabecera no se inicializa 14 //ninguna variable 15 //cargar todo tipo de imagenes 16 ALLEGRO_BITMAP* m_imagen; 17 //variable de estado de teclas 18 ALLEGRO_KEYBOARD_STATE m_estado_de_teclas; 19 float m_x; 20 float m_y; 21 float m_velocidad; 22 Disparo m_disparo; 23public: 24 Jugador(float x,float y); 25 void pintar(); 26 void mover(); 27 void disparar(); 28 ~Jugador(); 29}; 30 31#endif //fin jugador

#SelectExpand
1#include "jugador.h"; 2 3//clase jugador-------------------------------------- 4//hay que inicializar las variables en el constructor 5//en el mismo orden que estan en el archivo de cabezera 6Jugador::Jugador(float x,float y): m_imagen{al_load_bitmap("jugador.png")}, 7 m_estado_de_teclas{},m_x{x},m_y{y},m_velocidad{5.0f}, 8 m_disparo{32.0f,400.0f}{ 9 std::cout<<"iniciamos jugador"<<"\n"; 10} 11 12void Jugador::pintar(){ 13 mover(); 14 disparar(); 15 m_disparo.pintar(); 16 //pintamos imagen(imagen,x,y,voltear) 17 al_draw_bitmap(m_imagen,m_x,m_y,0); 18} 19 20void Jugador::mover(){ 21 //obtener el estado de teclas 22 al_get_keyboard_state(&m_estado_de_teclas); 23 //uso de teclado,recomendable usar dentro de evento de tiempo 24 if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_RIGHT)){ 25 m_x += m_velocidad; 26 }else if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_LEFT)){ 27 m_x -= m_velocidad; 28 } 29} 30 31void Jugador::disparar(){ 32 al_get_keyboard_state(&m_estado_de_teclas); 33 if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_Z)){ 34 m_disparo = Disparo{32.0f,400.0f}; 35 } 36} 37 38Jugador::~Jugador(){ 39 std::cout<<"finalizamos jugador"<<"\n"; 40 //destruir iamgen de bitmap 41 al_destroy_bitmap(m_imagen); 42} 43//fin clase jugador----------------------------------

I have tried to make the player shoot but it gives me an error, I am creating it in the player's shoot method.

DanielH
Member #934
January 2001
avatar

Every key_down you are loading a bitmap from file.

// jugador.h
  if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_Z)){
    m_disparo = Disparo{32.0f,400.0f};

// disparo.h
Disparo::Disparo(float x,float y): m_imagen{al_load_bitmap("disparo.png")}

How many times per second is mover called? How many bitmaps are you loading?

Do not load/unload bitmaps in the middle of the game or you will get delays.

Two ways:
1. Make an array somewhere else in the game of all needed bitmaps. Load/unload at the start/end of the program. Supply array to Disparo for use.
2. Make the bitmap static. Also, load/unload at the start/end of the program.

Here is a static example.

#SelectExpand
1//disparo.h 2 3class Disparo{ 4private: 5 float m_x,m_y,m_velocidad; 6public: 7 Disparo(float x,float y); 8 void pintar(); 9 void mover(); 10 ~Disparo(); 11 12 static bool load_image(); 13 static void unload_image(); 14 15 static ALLEGRO_BITMAP* m_imagen; 16};

#SelectExpand
1#include "disparo.h"; 2 3ALLEGRO_BITMAP* Disparo::m_imagen = nullptr; 4 5Disparo::Disparo(float x,float y): m_x{x},m_y{y},m_velocidad{1.0f}{ 6 std::cout<<"iniciando disparo"<<"\n"; 7} 8 9void Disparo::pintar(){ 10 mover(); 11 al_draw_bitmapDisparo::m_imagen,m_x,m_y,0); 12} 13 14bool Disparo::load_image() 15{ 16 return (!(Disparo::m_imagen = al_load_bitmap("disparo.png"))); 17} 18 19void Disparo::unload_image() 20{ 21 if (Disparo::m_imagen) 22 { 23 al_destroy_bitmap(Disparo::m_imagen); 24 Disparo::m_imagen = nullptr; 25 } 26}

Lastly, check to see if current bullet is active/not active before creating a new one.

amstradcpc
Member #23,651
January 2023

I'm going to try to do it but I have some questions. Why do you use static. The Shooting class is created in the player class so when I load and unload the graphics and where, I load them in the player constructor and download it in the destructor or in the main file .
When you say an array of shots you mean this -> Shot shot[];
Or to this -> std::vector<Shot> shot;

this confuses me -> return (!(Disparo::m_imagen = al_load_bitmap("disparo.png")));
There is no clearer way to write it.

DanielH
Member #934
January 2001
avatar

I was more conncerened with this function:

void Jugador::disparar(){
  al_get_keyboard_state(&m_estado_de_teclas);
  if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_Z)){
    m_disparo = Disparo{32.0f,400.0f};
  }
}

How many times a second are you trying to call Disparo? Every time you call the Disparo constructor, you are also calling al_load_bitmap.

Instead, load the bitmap once. either outside your class or inside your class. Static allows you to keep it in the class share between every Disparo.

amstradcpc
Member #23,651
January 2023

#SelectExpand
1#ifndef DISPARO_H 2#define DISPARO_H 3 4#include<iostream> 5#include <allegro5/allegro5.h> 6#include <allegro5/allegro_image.h> 7 8class Disparo{ 9private: 10 float m_x,m_y,m_velocidad; 11 bool activo; 12public: 13 ALLEGRO_BITMAP* m_imagen; 14 Disparo(float x,float y); 15 void pintar(); 16 void mover(); 17 ~Disparo(); 18}; 19 20 21#endif //DISPARO_H

#SelectExpand
1#include "disparo.h"; 2 3Disparo::Disparo(float x,float y):m_x{x},m_y{y}, 4 m_velocidad{1.0f},activo{true}{ 5 std::cout<<"iniciando disparo"<<"\n"; 6} 7 8void Disparo::pintar(){ 9 mover(); 10 al_draw_bitmap(m_imagen,m_x,m_y,0); 11} 12 13void Disparo::mover(){ 14 m_y -= m_velocidad; 15} 16 17Disparo::~Disparo(){ 18 std::cout<<"finalizar disparo"<<"\n"; 19 //al_destroy_bitmap(m_imagen); 20}

#SelectExpand
1//#pragma once 2#ifndef JUGADOR_H 3#define JUGADOR_H 4 5#include<iostream> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_image.h> 8#include "disparo.h"; 9 10class Jugador{ 11private: 12 //m_ -> significa variables miembro de la clase 13 //en los archiivos de cabecera no se inicializa 14 //ninguna variable 15 //cargar todo tipo de imagenes 16 ALLEGRO_BITMAP* m_imagen; 17 //variable de estado de teclas 18 ALLEGRO_KEYBOARD_STATE m_estado_de_teclas; 19 float m_x; 20 float m_y; 21 float m_velocidad; 22 Disparo m_disparo[]; 23public: 24 Jugador(float x,float y); 25 void pintar(); 26 void mover(); 27 void disparar(); 28 ~Jugador(); 29}; 30 31#endif //fin jugador

#SelectExpand
1#include "jugador.h"; 2 3//clase jugador-------------------------------------- 4//hay que inicializar las variables en el constructor 5//en el mismo orden que estan en el archivo de cabezera 6Jugador::Jugador(float x,float y): m_imagen{al_load_bitmap("jugador.png")}, 7 m_estado_de_teclas{},m_x{x},m_y{y},m_velocidad{5.0f}, 8 m_disparo[0]{32.0f,400.0f}{ 9 std::cout<<"iniciamos jugador"<<"\n"; 10 m_disparo[0].m_imagen = al_load_bitmap("disparo.png"); 11} 12 13void Jugador::pintar(){ 14 mover(); 15 disparar(); 16 m_disparo[0].pintar(); 17 //pintamos imagen(imagen,x,y,voltear) 18 al_draw_bitmap(m_imagen,m_x,m_y,0); 19} 20 21void Jugador::mover(){ 22 //obtener el estado de teclas 23 al_get_keyboard_state(&m_estado_de_teclas); 24 //uso de teclado,recomendable usar dentro de evento de tiempo 25 if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_RIGHT)){ 26 m_x += m_velocidad; 27 }else if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_LEFT)){ 28 m_x -= m_velocidad; 29 } 30} 31 32void Jugador::disparar(){ 33 al_get_keyboard_state(&m_estado_de_teclas); 34 if(al_key_down(&m_estado_de_teclas,ALLEGRO_KEY_Z)){ 35 if(m_disparo[0].activo == true){ 36 m_disparo[0] = Disparo{32.0f,400.0f}; 37 } 38 } 39} 40 41Jugador::~Jugador(){ 42 std::cout<<"finalizamos jugador"<<"\n"; 43 //destruir iamgen de bitmap 44 al_destroy_bitmap(m_imagen); 45 al_destroy_bitmap(m_disparo[0].m_imagen); 46} 47//fin clase jugador----------------------------------

You told me to use an array for the shot class but I have not achieved anything, and since I have never made an array of objects either, I don't really know how to do it and I have done what occurred to me but it is clear that it is wrong and it is not I can think of how to do it.

DanielH
Member #934
January 2001
avatar

1. What is the problem? What is happening or not happening that we should focus on. You're not saying much. I can try to guess and see what might be a problem. Are you getting errors or is it compiling? Is the game crashing?

2. I said to create an array of IMAGES for all your images of the game. Not an array of shots. Remove the array indexing on m_disparo.

3. In your Jugador constructor, you call this function to load the image for m_disparo. That is valid code.

m_disparo.m_imagen = al_load_bitmap("disparo.png");

4. However, this line in Jugador::disparar is a problem

m_disparo = Disparo{32.0f,400.0f};

Try to understand what you are doing with this line.

5. Timing needs adjusted. In the event handling, jugador.pintar is called 60 times a second based on your timing speed. You have not taken that into consideration. In that function, it calls pintar. Pintar ONLY checks if a key is down and immediately increases or decrease velocity.

this confuses me -> return (!(Disparo::m_imagen = al_load_bitmap("disparo.png")));

The ! should not be there. Removing the ! returns true if loaded or false if not.

amstradcpc
Member #23,651
January 2023

ALLEGRO_BITMAP* imagenes[10];
std::vector<ALLEGRO_BITMAP*> v_imagenes;

//recorrer array y vector de imagenes
  for(int iterar{0};iterar < v_imagenes.size();++iterar){
      v_imagenes[iterar] = al_load_bitmap("graficos/"+std::to_string(iterar)+".png");
  }
  
  for(int iterar{0};iterar < 10;++iterar){
    imagenes[iterar] = al_load_bitmap("graficos/"+std::to_string(iterar)+".png");
  }

I have added the images to a folder and I have changed the name by numbers so that it is easier to go through with a loop. I have created an array and a vector of images to see which one is easier to use and when going through the loop I add it the images to the array or vector but when I convert to string it gives me an error. I got this idea by searching the internet because since I don't know how to do it, I have to look for answers somewhere and this is the result, which is not knowing what I am doing

DanielH
Member #934
January 2001
avatar

You can append a char string to the end of a std::string because std::string has that functionality.

However, char string does not have the functionality to append a std::string to it.

std::string() + "blah" // good
"blah" + std::string() // bad

Get around that by making "graficos/" a std::string. Then you're appending a std::string to std::string.

std::string path = "graficos/";

//recorrer array y vector de imagenes
for(int iterar{0};iterar < v_imagenes.size();++iterar){
    v_imagenes[iterar] = al_load_bitmap(path+std::to_string(iterar)+".png");
}
  
for(int iterar{0};iterar < 10;++iterar){
  imagenes[iterar] = al_load_bitmap(path+std::to_string(iterar)+".png");
}

Also, you need to convert std::string to char* for Allegro functions.

use the .cstr() method function of std::string;

amstradcpc
Member #23,651
January 2023

DanielH, don't bother what I'm going to tell you, but every time I ask a question, instead of giving me a solution explaining it to me, you just give me little clues and in the end I have no choice but to look for the solution outside the forum When I find something, I show it to you and it gives me a little clue again. As I already said, I recently finished a c++ course and I'm starting to practice with allegro, so I'm very green with c++ and totally green with allegro and I need a lot of help and that each thing be explained to me step by step because I don't know. I appreciate you bothering to answer me but instead of helping me I ended up quite dizzy and without knowing where to go so I don't know whether to continue with this or start with something else.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

DanielH
Member #934
January 2001
avatar

Sorry, but I don't want to tell you everything. Then I'd be writing your game and not you. And the way I write my programs might not be the way you write yours.

All I can do, without more info, is look at your code and tell you what I see is wrong or needs to be changed.

If you want a direct answer:

m_disparo = Disparo{32.0f,400.0f};

In this line, you are overwriting the values in m_disparo with the values in the constructor. This means, m_image is now invalid because it wasn't defined.

// This is what you get when you call Disparo{32.0f,400.0f}
m_x = 32.0f; // set to 32.0f;
m_y = 400.0f; // set to 400.0f;
m_velocidad = 1.0f; // set to 1.0f from constructor initialization
activo = true; // set to true from constructor initialization
m_imagen = ?????; // undefined

// then you copy those values, even the undefined m_imagen, to m_disparo;
m_disparo = Disparo{32.0f,400.0f};

One way around this is to not call the constructor. Just change the member variables (x,y, active, etc) of m_disparo.

amstradcpc
Member #23,651
January 2023

Thanks for all the help DanielH, and I know you don't want to tell me everything so that I'm the one to do it, but if I don't know how to do it and I've never done it, I can't get information from where there isn't any. It's as if I wanted to drive a car without Nobody would have taught me before, that's impossible. I need them to teach me how to create games before I create them myself, that's why I'm going to look for another library and video tutorials on YouTube to learn, if I don't find anything then I'll learn how to use unity or unreal engine that there are many tutorials. Thank you for your help and for your time, greetings.

DanielH
Member #934
January 2001
avatar

Sorry that you decide to leave. In my opinion, the projects you picked were not suitable for beginners. I would recommend smaller targets. Make a tic-tac-toe game. Get the basics down with drawing graphics/primitives with Allegro, handling user input, etc.

Yes, we need more tutorials. However, not necessarily the tutorials on game design or game concepts. There are many many out there. They might not use Allegro, but it's the concepts beginners need.

The tutorials needed are how to use Allegro.

Please remember that Allegro is a low level library. Meaning, it doesn't have all the bells and whistles like Unity or others. That saying, you have more control with Allegro, but have to put in more effort.

Higher abstraction <--> less control
Lower abstraction <--> hard work

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I think the problems you are having with writing games are really just inexperience with C and C++. Try tutorials on C++ before you start game making tutorials. There are many, many example programs that come with allegro, including 3 1/2 demos. Take a look at their source code, and see how much you understand.

Like DanielH said, we're not going to give you a full tutorial on a full game, but we are more than willing to help you when you get stuck and can't progress. If you give up now on Allegro, you'll probably give up when you get to other libraries. Keep trying.

Edgar

amstradcpc
Member #23,651
January 2023

I know that I lack experience in these languages and surely the approach that I have made in my questions is not the correct one but the help that I need is too much and I know that everyone has their job, family, etc. And they are not going to dedicate their time to teach another person from scratch, for me it is not enough that they correct my code because what I need is that they teach me how to do things because I don't know how to do anything. That's why I think it would be better to watch video tutorials from other libraries and learn the basics and maybe then go back to allegro, I don't need to be shown a complete tutorial of a game either, what I should have done is create a topic for each question, ask a single thing that someone teach me how to do it and then copy, replicate, practice until you understand or even ask questions until you master it and then move on to the next thing, maybe I was also wrong with the language and I should have used c instead of c++ or maybe another simpler language. I like allegro and I want to learn how to use it but right now I don't know how to do anything and I need someone to take me by the hand and since that is asking a lot, that's why the best thing would be the video tutorials, the language doesn't help much either because I don't know much English. I'm sorry I made you waste your time, regards

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

amstradcpc
Member #23,651
January 2023

Thank you. :)

Post Reply
Go to: