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
¡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.
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
You can post code like this:
<code>
Code goes here...
</code>
Or just attach the files if it's too much to post.
Hello yellow
Actually, it's Amarillion, not Amarillo ;-)
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.
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.
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
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?
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.
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.
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 } }
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.
Cheating? Copy/Paste is the life-blood of programmers.
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
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)
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.
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.
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.
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.
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.
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.
Define your class in a cpp file
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.
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?
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.
And since I stop pacman when he touches the wall, with the indications you gave me I have not succeeded.
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.
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.
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] = ' ';
This is the last question about this game.
I have created the ghost and I would like to know how to make pacman detect when it collides with the ghost and restart the game when they collide.
If they overlap, then the distance between is less than zero.
Calculate the distance between. Accounting for radius of pacman and width/height of ghosts.
Also, for your map:
1. Choose mapa1 or mapa2 and remove the other from your code.
2. I would have 2 versions of the map. a constant version and a non constant version.
3. At the start of a game and when it resets after dying, copy the constant version to the non constant.
I have the two maps to know how to do it in both ways, what I'm doing is just a prototype to learn. From what you've told me I haven't understood much, could you show me a bit of code to guide me.
Last night, I was looking at the code for a Pacman game I made. Not quite useful for you.
It's from 2001 and uses Allegro 4.something.
I used a simple 8-bit bitmap for the master map. Another bitmap for the main map. A third bitmap with color-based directions to tell the ghosts' eyes which way to go when they died. The third bitmap was so I didn't have to program path finding to find their starting locations.
In my program, Pacman and the ghosts were the same size as a map cell. To tell if they collided was to tell the distance in the x and y directions
The minimal x distance for them to not touch is 1/2 the width of pacman added to 1/2 the width of the ghost. Same goes for the y, but using height. Measure the distance between them. If the distances are less than the minimal distances in both directions then you have a collision
Thank you very much for all the help, I'm going to leave this game here and start another one. Now I want to make a version of space invader but simplified and with some changes. I'm going to start with the first lines of code and when I have the basics I'll create another thread for this game and start with new questions.
Good luck!