Allegro.cc - Online Community
Post Reply

Allegro.cc Forums » Programming Questions » I'm new

rss feed Print
 1   2 
I'm new
amstradcpc
Member #23,651
January 2023

Hi, I'm Spanish and I don't know almost anything about English, so I'm going to use the google translator.

I am about to finish a modern c++ course and I would like to use allegro to create simple classic games like pong, arkanoid, asteroid, space invader, donkey kong, pacman etc...

I have never created a videogame and with c++ because I am a beginner who wants to start using it with the creation of games but I don't know how to make them, I would like to know if you can help me learn about allegro/c++ and the creation of games.

I'm starting from scratch, I was looking at the vivace tutorial, but apart from showing a graph I haven't known much else what to do and I don't understand anything that is explained either. Greetings and I look forward to your response and to be part of this community and learn everything that i can

amarillion
Member #940
January 2001
avatar

¡Hola, bienvenidos! Hablo un poquito de Español, para emergencias, pero probablemente es mas facil usar el traslador de google.

Welcome on your voyage to learning C++ and Allegro. There aren't many tutorials. The best way is probably to set yourself a simple goal and just try things out.

Why not start by picking a classic game that you like? Pacman is a good choice.

Pacman involves a tilemap. A simple way to encode a tilemap is using a long string, using 'X' to represent a wall, '.' to represent a pill, '*' to represent invincibility, 'S' to represent your starting space.

For any programming project, the approach should be to divide the problem into smaller and smaller sub-problems, until the sub-problem is so small that you know how to solve it.

So here are some sub-problems.

  • Can you make the game draw a map?

  • Can you find the starting position 'S' in your map and place pacman there?

  • Can you make pacman move left when you press the left cursor key?

  • Can you make the pills disappear after you move over one?

  • Can you draw 4 ghosts on the map?

  • Can you make the ghosts move?

Try the first one or two steps, and post your code back here, and we can give hints and suggestions.

amstradcpc
Member #23,651
January 2023

Hello yellow, thanks for the suggestions, I'll try some steps and then post the code for tips.
But I don't know whether to post it in this thread or create another one for this game, I don't see any option to post code either, maybe I just put it here as if it were text. Regards

torhu
Member #2,727
September 2002
avatar

You can post code like this:

<code>
Code goes here...
</code>

Or just attach the files if it's too much to post.

amarillion
Member #940
January 2001
avatar

Hello yellow

Actually, it's Amarillion, not Amarillo ;-)

amstradcpc
Member #23,651
January 2023

#SelectExpand
1#include <iostream> 2#include <string> 3#include <allegro5/allegro5.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6#include <allegro5/allegro_primitives.h> 7 8/*mapa nivel primero------------------------------ 9 x -> pared 10 . -> pildora 11 * -> invencibilidad 12 s -> pacman 13*/ 14std::string mapa1[]{ 15 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 16 "x..........................................x", 17 "x..........................................x", 18 "x.. ..x", 19 "x.. xxxxxxxxxxxxx * xxxxxxxxxxxxx ..x", 20 "x.. ..x", 21 "x..........................................x", 22 "x.. ..x", 23 "x.. xxxxxxxxxxxxx xxxxxxxxxxxxx ..x", 24 "x.. ..x", 25 "x..........................................x", 26 "x.. ..x", 27 "x.. xxxxxxxxxxxxx s xxxxxxxxxxxxx ..x", 28 "x.. * ..x", 29 "x..........................................x", 30 "x..........................................x", 31 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 32}; //fin del mapa nivel primero---------------------- 33 34//clase pacman------------------------------------ 35class Pacman{ 36private: 37 //variable de estado de teclas 38 ALLEGRO_KEYBOARD_STATE estado_de_teclas{}; 39 float x{}; 40 float y{}; 41 float velocidad{ 3.0f }; 42public: 43 Pacman(float x,float y){ 44 std::cout<<"iniciamos pacman"<<"\n"; 45 this->x = x; 46 this->y = y; 47 } 48 49 void pintar(){ 50 mover(); 51 //pintamos un circulo relleno(x,y,radio,color) 52 al_draw_filled_circle(x,y,20.0f,al_map_rgb(180,180,0)); 53 } 54 55 void mover(){ 56 //obtener el estado de teclas 57 al_get_keyboard_state(&estado_de_teclas); 58 //uso de teclado,recomendable usar dentro de evento de tiempo 59 if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_RIGHT)){ 60 x += velocidad; 61 }else if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_LEFT)){ 62 x -= velocidad; 63 } 64 65 if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_DOWN)){ 66 y += velocidad; 67 }else if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_UP)){ 68 y -= velocidad; 69 } 70 } 71 72 ~Pacman(){ 73 std::cout<<"finalizamos pacman"<<"\n"; 74 } 75}; //fin clase pacman----------------------------- 76 77int main () { 78 //iniciar allegro 79 al_init(); 80 //instalar teclado 81 al_install_keyboard(); 82 //iniciamos fuente de sistema 83 al_init_font_addon(); 84 //iniciamos fuente externa 85 al_init_ttf_addon(); 86 //iniciar primitivas 87 al_init_primitives_addon(); 88 89 //configuramos ventana en modo ventana 90 al_set_new_display_flags(ALLEGRO_WINDOWED); 91 //creamos ventana(ancho,alto) 92 ALLEGRO_DISPLAY* ventana = al_create_display(640,480); 93 94 //poner titulo a la ventana 95 al_set_window_title(ventana,"pacman"); 96 97 //ocultar raton 98 al_hide_mouse_cursor(ventana); 99 //mostrar raton 100 101 //crear eventos 102 ALLEGRO_EVENT_QUEUE* evento_queque = al_create_event_queue(); 103 //crear tiempo para fps(60) 104 ALLEGRO_TIMER* tiempo = al_create_timer(1.0/60.0); 105 106 //registra keyboard 107 al_register_event_source(evento_queque,al_get_keyboard_event_source()); 108 //registra display 109 al_register_event_source(evento_queque,al_get_display_event_source(ventana)); 110 //registra timer 111 al_register_event_source(evento_queque,al_get_timer_event_source(tiempo)); 112 113 //cargamos fuente externa 114 ALLEGRO_FONT* fuente_externa = al_load_ttf_font("StRyde.ttf",25,0); 115 116 Pacman pacman{ 300.0f,360.0f }; 117 118 bool ejecutar = true; 119 //iniciar tiempo,es obligatorio si no,no se vera la imagen 120 al_start_timer(tiempo); 121 while(ejecutar == true){ 122 123 //variable para eventos 124 ALLEGRO_EVENT evento; 125 //esperar para cada evento 126 al_wait_for_event(evento_queque,&evento); 127 //si pulso abajo o boton para cerrar ventana 128 switch(evento.type){ 129 case ALLEGRO_EVENT_TIMER: 130 //limpiar pantalla a un color 131 al_clear_to_color(al_map_rgb(0,0,160)); 132 133 al_draw_text(fuente_externa,al_map_rgb(0,255,0),320,32, 134 ALLEGRO_ALIGN_CENTER,"ejemplo pacman"); 135 136 pacman.pintar(); 137 138 //actualizar pantalla 139 al_flip_display(); 140 break; 141 case ALLEGRO_EVENT_KEY_DOWN: 142 if(evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE){ 143 ejecutar = false; //terminar bucle 144 } 145 break; 146 } 147 } 148 149 al_destroy_display(ventana); //destruir ventana 150 //destruir evento queque 151 al_destroy_event_queue(evento_queque); 152 al_destroy_font(fuente_externa); //destruir fuente 153 al_uninstall_keyboard(); //desinstalar teclado 154 //destruir evento de tiempo 155 al_destroy_timer(tiempo); 156 157 return 0; 158}

This is what I have for pacman, a class to manage pacman and a string for the map. But I don't know how to show the map from that string and I don't know how to place pacman in the letter "s", another thing that I don't know how to give it the same movement that the pacman game has.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I don't speak Spanish, but hello and good luck on your journey. There are a fair number of Spanish speakers around who can help you, like amarillion.

EDIT
I don't know if Neil Roy ever published the source code to his pacman games, but it would be worth looking at. Deluxe Pacman is what it is called.

https://nitehackr.github.io/games_index.html

amstradcpc
Member #23,651
January 2023

Hi Edgar Reynaldo, thanks for showing me that game, I'll look at the code but I don't think I'll understand anything, I'm just starting out in video game programming. I was looking at the game in the allegro vivace tutorial and I didn't understand anything. greeting

amarillion
Member #940
January 2001
avatar

Good, looks like you're off to a solid start.

But I don't know how to show the map from that string and I don't know how to place pacman in the letter "s", another thing that I don't know how to give it the same movement that the pacman game has.

Remember, if a problem is too difficult, you have to split it into smaller problems until you know how to solve them.

  • If I tell you x=10 and y=5 - so the 10th column of the 5th row - can you tell me which character is at that position in the string?

  • Can you create a nested loop that passes each x and each y of the map?

  • Can you check each x,y in the map if it is the letter "s" or not?

  • Can you check each x,y in the map, and draw a blue rectangle on the screen if it is a wall?

amstradcpc
Member #23,651
January 2023

I think the answer to the first question is "x" but I'm not sure, I haven't practiced with nested loops.
To find out if where I'm going to paint pacman it would be map[x][y] == "s", I don't know if that's it, maybe I have to cheat and look for answers on the internet, I'm going to try and see if I get something.

DanielH
Member #934
January 2001
avatar

Your string layout is mapa1[y][x] not mapa1[x][y].

Think that each mapa1[y] is a string and [x] is the index in that string.

Personally, I would just single char array.

#SelectExpand
1char mapa1[] = 2 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 3 "x..........................................x" 4 "x..........................................x" 5 "x.. ..x" 6 "x.. xxxxxxxxxxxxx * xxxxxxxxxxxxx ..x" 7 "x.. ..x" 8 "x..........................................x" 9 "x.. ..x" 10 "x.. xxxxxxxxxxxxx xxxxxxxxxxxxx ..x" 11 "x.. ..x" 12 "x..........................................x" 13 "x.. ..x" 14 "x.. xxxxxxxxxxxxx s xxxxxxxxxxxxx ..x" 15 "x.. * ..x" 16 "x..........................................x" 17 "x..........................................x" 18 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

Access the array like this

char c = mapa1[x + y * width];

Also, think about the map itself. Think of it as one contiguous chunk of memory. It is more efficient to access memory next to each other. Otherwise there is a delay due to unloading and reloading memory into cache. It depends on the page size and what that delay is. For a simple game such as this, the time delay is negligible. However, it is better practice. Start learning better practice up front to make it a habit.

Your strings may or may not be contiguous in memory. Still, the same concept applies.

If you keep it as mapa1[y][x], the draw loop should draw row by row not column by column.

// access row by row
for <int y = 0; y < height; ++y)
{
    // for each row draw each index of that row.
    for <int x = 0; x < width; ++x)
    {
        // draw cell
    }
}

amarillion
Member #940
January 2001
avatar

Maybe I have to cheat and look for answers on the internet

Well this isn't exam so I wouldn't call it cheating.

All programmers sometimes check for answers on the internet. The trick is that you need to understand the examples you find on the internet so you can adapt them to your own project.

DanielH
Member #934
January 2001
avatar

Cheating? Copy/Paste is the life-blood of programmers. ;D

amstradcpc
Member #23,651
January 2023

#SelectExpand
1/*mapa nivel primero------------------------------ 2 x -> pared 3 . -> pildora 4 * -> invencibilidad 5 s -> pacman 6*/ 7std::string mapa1[]{ 8 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 9 "x..........................................x", 10 "x..........................................x", 11 "x.. ..x", 12 "x.. xxxxxxxxxxxxx * xxxxxxxxxxxxx ..x", 13 "x.. ..x", 14 "x..........................................x", 15 "x.. ..x", 16 "x.. xxxxxxxxxxxxx xxxxxxxxxxxxx ..x", 17 "x.. ..x", 18 "x..........................................x", 19 "x.. ..x", 20 "x.. xxxxxxxxxxxxx s xxxxxxxxxxxxx ..x", 21 "x.. * ..x", 22 "x..........................................x", 23 "x..........................................x", 24 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 25}; 26 27void mostrar_mapa1(int ancho_celda,int alto_celda){ 28 for(int y{ 0 };y < sizeof(mapa1[0]).size();++y){ 29 for(int x{ 0 };x < sizeof(mapa1[y]).size();++x){ 30 std::cout<<mapa1[y][x]<<" "; 31 if(mapa1[y][x] == 'x'){ 32 al_draw_filled_rectangle(y*ancho_celda,x*alto_celda,(y+1)*ancho_celda,(x+1)*alto_celda, al_map_rgb(255,255,255)); 33 } 34 } 35 } 36} 37//fin del mapa nivel primero---------------------- 38 39//mapa 2------------------------------------------- 40char mapa2[]{ 41 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 42 "x x" 43 "x ........................................ x" 44 "x . xxxxx xxxxx . x" 45 "x . xxxxx * xxxxx . x" 46 "x . xxxxx xxxxx . x" 47 "x ........................................ x" 48 "x . xxxxx xxxxxx xxxxxx . x" 49 "x . xxxxx xxxxxx xxxxxx . x" 50 "x . xxxxxx . x" 51 "x ........................................ x" 52 "x . xxxxxxx . x" 53 "x . xxxxxx x s x xxxxxxx . x" 54 "x . x x x x x * x . x" 55 "x ........................................ x" 56 "x x" 57 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 58}; 59 60void mostrar_mapa2(int ancho_celda){ 61 for(int y{ 0 };y < sizeof(mapa2[0]);++y){ 62 for(int x{ 0 };x < sizeof(mapa2[y]);++x){ 63 std::cout<<mapa2[x+y*ancho_celda]<<" "; 64 char caracter = mapa2[y+x*ancho_celda]; 65 if(caracter == 'x'){ 66 al_draw_filled_rectangle(y*ancho_celda,x*ancho_celda,(y+1)*ancho_celda,(x+1)*ancho_celda, al_map_rgb(255,255,255)); 67 } 68 } 69 } 70} 71//fin del mapa nivel segundo----------------------

I've been trying a lot of things and looking at some examples on char from an old book on c but I haven't gotten much.
The first example uses a string array but it doesn't work with size() or length() and since it doesn't have a fixed size, it's more complicated, I've only managed to show a piece.
The second example uses a char array as DanielH told me (thanks), but I have only managed to display a square, then there is the fact that in order for something to be displayed I had to put the function in the timer event where I have the method pacman. paint but it seems that it is not very optimal. I don't know what else to do

DanielH
Member #934
January 2001
avatar

for the first example, I'm surprised this even compiled

sizeof(mapa1[0]).size()

sizeof(mapa1[0]) returns an unsigned int. Then you call size() on that.

Use the length of the string. If it is all 8-bit chars, you could use size as well.

for(int y{ 0 }; y < mapa1[0].size(); ++y)
  for(int x{ 0 }; x < mapa1[y].size(); ++x)

For the second example, what is wrong with this line?

for(int y{ 0 };y < sizeof(mapa2[0]);++y)

What is mapa2[0]? It is a char. What is a sizeof a char?

What I would do would hardcode length and width.

// in your class
const int map_width = 46;
const int map_height = 17;

// in drawing method
for(int y{ 0 }; y < map_height; ++y)
{
  for(int x{ 0 }; x < map_width; ++x)
  {
  }
}

Lastly, look at your draw line parameters. Then look at what they should be. You swapped x and y.

void al_draw_filled_rectangle(float x1, float y1, float x2, float y2,
   ALLEGRO_COLOR color)

amstradcpc
Member #23,651
January 2023

#SelectExpand
1const int ancho_celda{ 44 }; 2const int alto_celda{ 17 }; 3 4std::string mapa1[]{ 5 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 6 "x..........................................x", 7 "x..........................................x", 8 "x.. ..x", 9 "x.. xxxxxxxxxxxxx * xxxxxxxxxxxx ..x", 10 "x.. ..x", 11 "x..........................................x", 12 "x.. ..x", 13 "x.. xxxxxxxxxxxxx xxxxxxxxxxxx ..x", 14 "x.. ..x", 15 "x..........................................x", 16 "x.. ..x", 17 "x.. xxxxxxxxxxxxx s xxxxxxxxxxxxx ..x", 18 "x.. * ..x", 19 "x..........................................x", 20 "x..........................................x", 21 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 22}; 23 24void mostrar_mapa1(){ 25 for(int y{ 0 };y < alto_celda;++y){ 26 for(int x{ 0 };x < ancho_celda;++x){ 27 if(mapa1[y][x] == 'x'){ 28 al_draw_filled_circle(x*15.0f,y*29.5f,14.0f,al_map_rgb(200,200,200)); 29 } 30 } 31 } 32} 33//fin del mapa nivel primero---------------------- 34 35//mapa 2------------------------------------------- 36char mapa2[]{ 37 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 38 "x x" 39 "x ........................................ x" 40 "x . xxxxx xxxxx . x" 41 "x . xxxxx * xxxxx . x" 42 "x . xxxxx xxxxx . x" 43 "x ........................................ x" 44 "x . xxxxx xxxxxx xxxxxx . x" 45 "x . xxxxx xxxxxx xxxxxx . x" 46 "x . . x" 47 "x ........................................ x" 48 "x . xxxxxxx . x" 49 "x . xxxxxx x s x xxxxxxx . x" 50 "x . x x x x x * x . x" 51 "x ........................................ x" 52 "x x" 53 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 54}; 55 56void mostrar_mapa2(){ 57 for(int y{ 0 };y < alto_celda;++y){ 58 for(int x{ 0 };x < ancho_celda;++x){ 59 char caracter = mapa2[x+y*ancho_celda]; 60 if(caracter == 'x'){ 61 al_draw_filled_circle(x*15.0f,y*29.5f,14.0f,al_map_rgb(200,200,200)); 62 } 63 } 64 } 65} 66//fin del mapa nivel segundo----------------------

I finally got it, although the result doesn't convince me much, but something is something. Now I would like to know how I can place pacman in the letter "s" and how can I make pacman detect collisions with walls and stop, why not I have seen that allegro brings nothing for collision detection.

DanielH
Member #934
January 2001
avatar

Allegro is not a game engine.

Allegro Low Level Graphics (or Game) ROutines

---

You have to program collision on your own. Or use a map system with built-in collision detection.

1. If 's' is going to be in different places per level. Then run through the map and find 's'. Determine x and y of map position from that. Then scale it up to width and height.

#SelectExpand
1void find_starting_point(int& px, int& py) 2{ 3 for(int y{ 0 };y < alto_celda;++y) 4 { 5 for(int x{ 0 };x < ancho_celda;++x) 6 { 7 if (mapa1[y][x] == 's') 8 { 9 px = x * ancho_celda; 10 py = y * alto_celda; 11 return; 12 } 13 } 14 } 15} 16 17// somewhere else in your initialization 18find_starting_point(pacman.x, pacman.y);

2. Determine if a square is solid or not should be straightforward.

bool is_solid(int x, int y)
{
    return (mapa1[y][x] == 'x');
}

3. What state is pacman. Pacman has 4 main states.

#SelectExpand
1enum Pacman_Directions = 2{ 3 PACMAN_STOPPED, 4 PACMAN_LEFT, 5 PACMAN_RIGHT, 6 PACMAN_UP, 7 PACMAN_DOWN 8}; 9 10enum Pacman_States = 11{ 12 PACMAN_CLOSED, // Mouth closed 13 PACMAN_OPENING, // opening (1/2 open/close on the open side) 14 PACMAN_OPEN, // fully open 15 PACMAN_CLOSING // closing (1/2 open/close on the close side) 16};

Each 'frame', you need move him a 1/4 move (1/4 of the cell size) and increase the state and keep repeating.

When I say frame, I don't mean game frame. You need a timer on him to determine the rate he moves.

He is fully in a square when his mouth is closed. Only at that state and before you move again. Determine the square he is in by dividing my ancho_celda, alto_celda. Then check the next cell based on direction he is moving. If that cell is closed then stop him from moving.

int x = pacman.x / ancho_celda;
int y = pacman.y / alto_celda;

if (pacman.dir == PACMAN_LEFT && is_solid(x - 1, y))
{
  // stop moving
  pacman.dir = PACMAN_STOPPED;
}

// do the same for other directions.

You could also simplify it

int mx[4] = {-1, 1, 0, 0};
int my[4] = {0, 0, -1, 1};

if (pacman.dir != PACMAN_STOPPED && pacman.state == PACMAN_CLOSED)
{
  if (is_solid(pacman.x + mx[pacman.dir - PACMAN_LEFT], pacman.y + my[pacman.dir - PACMAN_LEFT]))
  {
    pacman.dir = PACMAN_STOPPED;
  }
}

Remember, just because I might do it this way doesn't mean it's the only way.

amstradcpc
Member #23,651
January 2023

Thank you very much for the help DanielH, I'll try. :)

I would like to bring this code to a ".h" header file for the prototype and a ".cpp" file for the implementation, because the code is growing and I am starting to mess with so much code. I have tried but I get errors for everywhere, can you tell me how to do it correctly.

#SelectExpand
1const int ancho_celda{ 44 }; 2const int alto_celda{ 17 }; 3 4std::string mapa1[]{ 5 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 6 "x x", 7 "x ........................................ x", 8 "x . . x", 9 "x . xxxxxxxxxxxxx * xxxxxxxxxxxx . x", 10 "x . . x", 11 "x ........................................ x", 12 "x . . x", 13 "x . xxxxxxxxxxxxx xxxxxxxxxxxx . x", 14 "x . . x", 15 "x ........................................ x", 16 "x . . x", 17 "x . xxxxxxxxxxxxx s xxxxxxxxxxxx . x", 18 "x . . x", 19 "x ........................................ x", 20 "x x", 21 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 22}; 23 24void mostrar_mapa1(){ 25 for(int y{ 0 };y < alto_celda;++y){ 26 for(int x{ 0 };x < ancho_celda;++x){ 27 if(mapa1[y][x] == 'x'){ 28 al_draw_filled_circle(x*15.0f,y*29.5f,14.0f,al_map_rgb(200,200,200)); 29 } 30 } 31 } 32} 33 34void colocar_en_posicion_s_mapa1(float& posicionX,float& posicionY){ 35 for(int y{ 0 };y < alto_celda;++y){ 36 for(int x{ 0 };x < ancho_celda;++x){ 37 if(mapa1[y][x] == 's'){ 38 posicionX = x*15.0f; 39 posicionY = y*29.5f; 40 return; 41 } 42 } 43 } 44} 45//fin del mapa nivel primero---------------------- 46 47//mapa 2------------------------------------------- 48char mapa2[]{ 49 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 50 "x x" 51 "x ........................................ x" 52 "x . xxxxx xxxxx . x" 53 "x . xxxxx * xxxxx . x" 54 "x . xxxxx xxxxx . x" 55 "x ........................................ x" 56 "x . xxxxx xxxxxx xxxxx . x" 57 "x . xxxxx xxxxxx xxxxx . x" 58 "x . . x" 59 "x ........................................ x" 60 "x . xxxxxxx . x" 61 "x . xxxxxx x x xxxxxxx . x" 62 "x . x x x s x x x . x" 63 "x ........................................ x" 64 "x x" 65 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 66}; 67 68void mostrar_mapa2(){ 69 for(int y{ 0 };y < alto_celda;++y){ 70 for(int x{ 0 };x < ancho_celda;++x){ 71 char caracter = mapa2[x+y*ancho_celda]; 72 if(caracter == 'x'){ 73 al_draw_filled_circle(x*15.0f,y*29.5f,14.0f,al_map_rgb(200,200,200)); 74 } 75 } 76 } 77}

DanielH
Member #934
January 2001
avatar

1. Declarations go in header files
2. Definitions go in source files

There are exceptions, such as templates. Templated classes and functions have to be in the header file. But that is a bit advanced coding.

Declare your class in its own header file with declarations only. Use header guards or '#pragma once' to safeguard your headers.

#SelectExpand
1// pacman.h 2#ifndef _MY_PACMAN_CLASS_HEADER_ 3#deinfe _MY_PACMAN_CLASS_HEADER_ 4 5class Pacman{ 6private: 7 //variable de estado de teclas 8 ALLEGRO_KEYBOARD_STATE estado_de_teclas; 9 float x; 10 float y; 11 float velocidad; 12public: 13 Pacman(float x, float y); 14 ~Pacman(); 15} 16 17#endif

Define your class in a cpp file

#SelectExpand
1// pacman.cpp 2#include "pacman.h" 3 4Pacman::Pacmman(float x, float) : x(x), y(y) 5{ 6 std::cout<<"iniciamos pacman"<<"\n"; 7} 8 9Pacman::~Pacman() 10{ 11 std::cout<<"finalizamos pacman"<<"\n"; 12} 13 14// methods as well

I would also make a class with header and source for your map/grid as well.

Variables can be declared in headers, but do not define variables in header files. You can declare variables in header files with the keyword 'extern'

// test.h
extern int my_variable;




// test.cpp
#include "test.h"
int my_variable = 0;

Of course, variables defined in the global scope are frowned upon. Global scope means defining variables outside a class or function.

amstradcpc
Member #23,651
January 2023

#SelectExpand
1bool pared_es_solida(int x,int y){ 2 if(mapa1[y][x] == 'x'){ 3 return true; 4 }else{ 5 return false; 6 } 7} 8 9//clase pacman------------------------------------ 10class Pacman{ 11private: 12 //variable de estado de teclas 13 ALLEGRO_KEYBOARD_STATE estado_de_teclas{}; 14 float velocidad{ 3.0f }; 15 int direccion{}; 16public: 17 float x{}; 18 float y{}; 19 enum class Estado{parado,izquierda,derecha,arriba,abajo}; 20 21 Pacman(float x,float y){ 22 std::cout<<"iniciamos pacman"<<"\n"; 23 this->x = x; 24 this->y = y; 25 } 26 27 void colocar_en_posicion_s_mapa1(float& posicionX,float& posicionY){ 28 for(int y{ 0 };y < alto_celda;++y){ 29 for(int x{ 0 };x < ancho_celda;++x){ 30 31 if(mapa1[y][x] == 's'){ 32 posicionX = x*15.0f; 33 posicionY = y*29.5f; 34 return; 35 } 36 } 37 } 38 } 39 40 void colision_pared(){ 41 float pararX = x/15.0f; 42 float pararY = y/29.5f; 43 if(direccion == static_cast<int>(Estado::izquierda) && pared_es_solida(pararX-1,pararY)){ 44 direccion = static_cast<int>(Estado::parado); 45 } 46 } 47 48 void colocar_en_posicion_s_mapa2(float& posicionX,float& posicionY){ 49 for(int y{ 0 };y < alto_celda;++y){ 50 for(int x{ 0 };x < ancho_celda;++x){ 51 char caracter = mapa2[x+y*ancho_celda]; 52 if(caracter == 's'){ 53 posicionX = x*15.0f; 54 posicionY = y*29.5f; 55 return; 56 } 57 } 58 } 59 } 60 61 void pintar(){ 62 mover(); 63 colision_pared(); 64 //pintamos un circulo relleno(x,y,radio,color) 65 al_draw_filled_circle(x,y,15.0f,al_map_rgb(180,180,0)); 66 } 67 68 void mover(){ 69 //obtener el estado de teclas 70 al_get_keyboard_state(&estado_de_teclas); 71 //uso de teclado,recomendable usar dentro de evento de tiempo 72 if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_RIGHT)){ 73 x += velocidad; 74 direccion = static_cast<int>(Estado::derecha); 75 }else if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_LEFT)){ 76 x -= velocidad; 77 direccion = static_cast<int>(Estado::izquierda); 78 }else{ 79 direccion = static_cast<int>(Estado::parado); 80 } 81 82 if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_DOWN)){ 83 y += velocidad; 84 direccion = static_cast<int>(Estado::abajo); 85 }else if(al_key_down(&estado_de_teclas,ALLEGRO_KEY_UP)){ 86 y -= velocidad; 87 direccion = static_cast<int>(Estado::arriba); 88 }else{ 89 direccion = static_cast<int>(Estado::parado); 90 } 91 92 if(direccion == static_cast<int>(Estado::arriba)){ 93 velocidad = 0; 94 } 95 } 96 97 ~Pacman(){ 98 std::cout<<"finalizamos pacman"<<"\n"; 99 } 100}; //fin clase pacman-----------------------------

I'm in a mess, I can't get pacman to stop when he hits the wall. I've set the speed to zero but it doesn't work.

void colocar_en_posicion_s_mapa1(float& posicionX,float& posicionY){
  for(int y{ 0 };y < alto_celda;++y){
    for(int x{ 0 };x < ancho_celda;++x){
      if(mapa1[y][x] == 's'){
        posicionX = x*15.0f;
        posicionY = y*29.5f;
        return;
      }
    }
  }
}

In this function, why do you use return and not in the others where you use the for?

DanielH
Member #934
January 2001
avatar

Once you find s and set the start position, then your done. No need to keep looking. So I return out of the function.

As for pacman stopping. What I told you earlier was a basic movement of 1/4 cell per frame. No velocity. If you want velocity, that is another problem altogether. And there are quite a few different options.

amstradcpc
Member #23,651
January 2023

And since I stop pacman when he touches the wall, with the indications you gave me I have not succeeded.

DanielH
Member #934
January 2001
avatar

My example was based on constant speeds and integers.

With floats and velocities, it can be done. However, slightly more difficult.

One option would be to calculate your position to the wall that is facing the direction you're looking. If distance is less than velocity, then you hit wall. Reset position next to wall and reset velocity.

amstradcpc
Member #23,651
January 2023

void mostrar_pildora_en_mapa1(){
  for(int y{ 0 };y < alto_celda;++y){
    for(int x{ 0 };x < ancho_celda;++x){
      if(mapa1[y][x] == '.'){
        al_draw_filled_circle(x*15.0f,y*29.5f,5.0f,al_map_rgb(180,0,180)); 
      }
    }
  }
}

How do I remove the pills in both map1 of string and map2 of char.

amarillion
Member #940
January 2001
avatar

How do I remove the pills in both map1 of string and map2 of char.

You can make assignments to a std::string.

For example,

if (mapa1[y][x] == '.') { mapa1[y][x] = ' '; }

The same goes for mapa2, but you'll have to calculate the index:

mapa2[x+y*ancho_celda] = ' ';

Post Reply
 1   2 


Go to: