Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to make balls coming from the top?

Credits go to CGamesPlay, Johan Halmén, miran, and Paul whoknows for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
How to make balls coming from the top?
vilafranca
Member #8,647
May 2007

Hey buddies, I have the following program that I made [college homework]

1#include <stdio.h>
2#include <stdlib.h>
3#include <allegro.h>
4 
5#define RESOLUCAO_X 800
6#define RESOLUCAO_Y 600
7#define COR 16
8#define RAIO 15
9 
10int inicia(void);
11void abertura(void);
12void principal(void);
13void finaliza(void);
14 
15int main (void)
16{
17 
18 if (!inicia())
19 {
20 finaliza();
21 exit(-1);
22 }
23 
24 principal();
25 
26 finaliza();
27 exit(0);
28 
29}
30 
31 END_OF_MAIN();
32 
33int inicia (void)
34{
35 allegro_init();
36 
37 install_keyboard();
38 install_mouse();
39 
40 set_color_depth(COR);
41 set_gfx_mode(GFX_AUTODETECT, RESOLUCAO_X, RESOLUCAO_Y, 0, 0);
42 
43 if (set_gfx_mode(GFX_AUTODETECT, RESOLUCAO_X, RESOLUCAO_Y, 0, 0) < 0)
44 {
45 puts("Erro no modo gráfico!");
46 return (FALSE);
47 }
48 
49 return (TRUE);
50 
51}
52 
53void principal (void)
54{
55 int i;
56 
57 abertura();
58 
59 BITMAP *buffer;
60 buffer = create_bitmap(RESOLUCAO_X, RESOLUCAO_Y);
61 
62 while (!(key[KEY_ESC]))
63 {
64 for(i=0; !(key[KEY_ESC]); i=i+1)
65 {
66 circlefill(buffer, i, i, RAIO+8, makecol(200,0,10));
67 circlefill(buffer, mouse_x, mouse_y, RAIO, makecol(0,120,160));
68 textprintf_right_ex(buffer, font, 515, 10, makecol(255,255,255), 0, "Posicao X: %3.0d Posicao Y: %3.0d", mouse_x, mouse_y);
69 draw_sprite(screen, buffer, 0,0);
70 clear(buffer);
71 if ((mouse_x == i) && (mouse_y == i))
72 {
73 finaliza();
74 exit(-1);
75 }
76 }
77 }
78}
79 
80void finaliza (void)
81{
82 while(!keypressed());
83 allegro_exit();
84}
85 
86void abertura (void)
87{
88 textprintf_centre_ex(screen, font, RESOLUCAO_X/2, 250, makecol(255,255,255), 0, "Aperte uma tecla para INICIAR");
89 textprintf_centre_ex(screen, font, RESOLUCAO_X/2, 350, makecol(255,255,255), 0, "OBJETIVO: Acerte a bola AZUL em qualquer uma das bolas VERMELHAS");
90 while(!keypressed());
91}

*** My doubt is in the "Void Principal" part of the program! [take a look, please]
They want us to have a blue ball moved by the mouse cursor [ok, i did that]... and at the same time they want red balls coming from the TOP of the screen [ONE by ONE] going to different directions! The program will finish when we hit the blue ball in one of the red balls... that's when my doubt starts! I created a FOR command for the red ball... but this For command never stops, so, the next red ball never comes! I'd like a help of you to make the next balls come from the top of the screen... and if u also could take a look at what I did in the IF command I opened to make the program finishes when the red ball is hit by the blue one! I think it's not right at all! Please, help me!!!

Thank u so much!!! :-[

Paul whoknows
Member #5,081
September 2004
avatar

Use code tags [CODE][/CODE](tags must be in lower case). Also, it would be nice if you translate your variables and functions names to English.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

vilafranca
Member #8,647
May 2007

Hey Paul, thanks for your help!
But I'm very new to allegro, so I don't understand this tags =/

Could u explain that to me, or someone else?!
:-[

Mark Oates
Member #1,146
March 2001
avatar

in the text box where you reply to posts, click the help button. It'll show you there a tag for source code. You should edit your first post and use the code tags. It makes it easier to read :)

vilafranca
Member #8,647
May 2007

Ok, I edited it :P

Now, could u help meeeeee?! :-/

Paul whoknows
Member #5,081
September 2004
avatar

Remove the while (!(key[KEY_ESC]) in principal(). Does that work?

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

CGamesPlay
Member #2,559
July 2002
avatar

1void principal (void)
2{
3 int i;
4 
5 abertura();
6 
7 BITMAP *buffer;
8 buffer = create_bitmap(RESOLUCAO_X, RESOLUCAO_Y);
9 
10 while (!(key[KEY_ESC]))
11 {
12 for(i=0; !(key[KEY_ESC]); i=i+1)
13 {
14 circlefill(buffer, i, i, RAIO+8, makecol(200,0,10));
15 circlefill(buffer, mouse_x, mouse_y, RAIO, makecol(0,120,160));
16 textprintf_right_ex(buffer, font, 515, 10, makecol(255,255,255), 0, "Posicao X: %3.0d Posicao Y: %3.0d", mouse_x, mouse_y);
17 draw_sprite(screen, buffer, 0,0);
18 clear(buffer);
19 if ((mouse_x == i) && (mouse_y == i))
20 {
21 finaliza();
22 exit(-1);
23 }
24 }
25 }
26}

This is the code in question. It is called your "main loop". If you look at what's happening, it's not at all what you need to be happening.

The while part is good. You want your code to run until the escape key is pressed. In other words, while the escape key is not pressed. That's fine. Inside the loop, You need to separate your code into logic and drawing.

First, make a list of what you need to keep track of. In this case, it's the ball's position. Store these variables outside of the loop:

// ...
int ball_x, ball_y;
while(!(key[KEY_ESC]))
{
    // Logic:
    // Drawing:
}

Then, in the logic section, move the ball by changing ball_x and ball_y. Also check if the player has moved the mouse over the ball in this section. And finally, in the drawing section, draw the player's ball using mouse_x and mouse_y and draw the ball using the stored ball_x and ball_y.

I hope that all makes sense. Don't worry if the ball zooms off-screen faster than you can hover over it. You'll need to get into timers to fix that issue.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

vilafranca
Member #8,647
May 2007

Actually, there's no error when I compile the program!
The only problem is... since I made this FOR command for the red ball moves on the screen

    for(i=0; !(key[KEY_ESC]); i=i+1)
    {
      circlefill(buffer, i, i, RAIO+8, makecol(200,0,10));
      circlefill(buffer, mouse_x, mouse_y, RAIO, makecol(0,120,160));
      textprintf_right_ex(buffer, font, 515, 10, makecol(255,255,255), 0,  "Posicao X: %3.0d  Posicao Y: %3.0d", mouse_x, mouse_y);
      draw_sprite(screen, buffer, 0,0);
      clear(buffer);
      if ((mouse_x == i) && (mouse_y == i))
      {
        finaliza();
        exit(-1);
      }
    }

When the red ball disappears of the screen, it must appear a new one! But this for command seems never stop, so, when i create another for command for another red ball, it doesn't work, cos the 1st FOR is still running... so the next ball never comes... that's the problem! what do i do? is there a way to do these balls coming one by one without using FOR?!

Paul whoknows
Member #5,081
September 2004
avatar

Try this:

1int i = 0;
2while (!(key[KEY_ESC]))
3 {
4 i++;
5 if(i > 640) i = 0;
6 if ((mouse_x == i) && (mouse_y == i))
7 {
8 finaliza();
9 exit(-1);
10 }
11 clear(buffer);
12 circlefill(buffer, i, i, RAIO+8, makecol(200,0,10));
13 circlefill(buffer, mouse_x, mouse_y, RAIO, makecol(0,120,160));
14 textprintf_right_ex(buffer, font, 515, 10, makecol(255,255,255), 0, "Posicao X: %3.0d Posicao Y: %3.0d", mouse_x, mouse_y);
15 draw_sprite(screen, buffer, 0,0);
16
17 }

However, this:

if ((mouse_x == i) && (mouse_y == i))
    {
      finaliza();
      exit(-1);
    }

won't work as a collision detection.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

vilafranca
Member #8,647
May 2007

Doesn't work Paul!
Actually, there's no error... but this code just makes the same ball coming always in the same direction... and the right thing should be the ball coming in a direction... when it disappears of the screen, another ball comes in another direction... and it goes till we hit one of them with the blue ball [which is the mouse cursor]

My gosh, I have no IDEA how to do that...

:'( :'(

Paul whoknows
Member #5,081
September 2004
avatar

Quote:

but this code just makes the same ball coming always in the same direction

Yes of course, what did you expect? I posted that just to 'stop' your neverending for(). If you want balls in different directions you should use vectors, something like this:

double theta = angle;
x =  x_start_position + cos(theta) * distance;
y =  y_start_position + sin(theta) * distance;
distance++;

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

vilafranca
Member #8,647
May 2007

Hey buddies, I fixed some part of the program!
Now, the next red ball is coming... I made something to finish the FOR command, so it can stop now for the following red ball appears on the screen! :D

The matter now is... the program must finish when the blue ball [mouse cursor] hits the red ball! I made this instruction for it:

if ((mouse_x == i) && (mouse_y == j))
      {
        finaliza(); /* calls the end of the program */
        exit(-1);
      }

But this command will only work if the mouse cursor hits EXACTLY the center of the red ball (coordinates i,j), which is not pretty good! the best thing to do is to finish the program if the blue ball hits ANY part of the red ball, not exactly the center, cos it makes more difficult to hit it!

Any help to fix it, please?! ;D

Paul whoknows
Member #5,081
September 2004
avatar

Put a bounding box in each ball, do the collision detection between both boxes using this function:

x1,y1             
   +----+
   |RED |
   |BALL|
   +----+x2,y2
xx1,yy1             
   +----+
   |BLUE|
   |BALL|
   +----+xx2,yy2

inline bool collide(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2)
{
     if (x2 <= xx1) return false;
     else if (x1 >= xx2) return false;
     else if (y2 <= yy1) return false;
     else if (y1 >= yy2) return false;
     else return true;
}

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

miran
Member #2,407
June 2002

@paul: That's just stupid. Why would you use bounding box collision detection for detecting collisions between circles? Use circle/circle collision detection for that instead:

1. calculate distance between the centre of red ball and blue ball
2. if the calculated distance is smaller than the sum of the balls' radii, there was a collision

float x1, y1, r1;
float x2, y2, r2,

float dx = x2 - x1;
float dy = y2 - y1;

float d = dx*dx + dy*dy;

if (d <= (r1+r2)*(r1+r2)) {
   // collision!
}

@vilafranca: Do EXACTLY what CGamesPlay tells you to do and get completely and totally rid of your for loop!

--
sig used to be here

Paul whoknows
Member #5,081
September 2004
avatar

Quote:

That's just stupid. Why would you use bounding box collision detection for detecting collisions between circles?

Box collision is easier to understand than circle/cirlcle collision, that's why I showed him the b. box collision function. Also, I think he does not need so much precision in his program.
However, Miran's code is the best way to solve this problem, obviously.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

miran
Member #2,407
June 2002

Quote:

Box collision is easier to understand than circle/cirlcle collision, that's why I showed him the b. box collision function. Also, I think he does not need so much precision in his program.

Uhm, maybe that's just me, but circle-circle collision is the simplest, easiest, most basic type of collision test there is.

--
sig used to be here

Johan Halmén
Member #1,550
September 2001

No, it's me too. Even when you go into bouncing reaction, the circle-circle thing is not very difficult. You can define a line from one circle to the other (middle points), you can find out the collision point on this line, you can define the tangential line through this point. Now you have an imaginary wall that both circles collide against. And so on.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Paul whoknows
Member #5,081
September 2004
avatar

Quote:

Uhm, maybe that's just me, but circle-circle collision is the simplest, easiest, most basic type of collision test there is.

Damn! you got me.>:( I just wanted to draw some ASCII boxes! are you happy now? :P

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

Johan Halmén
Member #1,550
September 2001

Yes.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

Try this:

Hmm, give a man a fish, teach a man to fish...

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

Hmm, give a man a fish, teach a man to fish...

My thought exactly.
Break the problem down into sub-problems until you reach something you can't divide any further. If you can solve it, do so. If you can't, come back here.

Here are a few things to google / forum-search:
- main loop
- collision detection
- separate logic and drawing
and more generally:
- game programming

Set up a main loop. This should do logic and drawing.
Logic needs to:
- update player position
- update ball position
- check if ball hits player -> end game
- check if ball is outside screen -> reset ball coordinates and speed
Drawing is just drawing.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Paul whoknows
Member #5,081
September 2004
avatar

Quote:

Quote:

Try this:

Hmm, give a man a fish, teach a man to fish...

A fish is better than nothing. Also, learning to fish takes some time, meanwhile, he needs something to eat.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

Hey buddies, I have the following program that I made [college homework]

...

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Tobias Dammers
Member #2,604
August 2002
avatar

That reads: OMG WTF PLZ DO MY HOMEWORK 4 ME LOLZ

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

vilafranca
Member #8,647
May 2007

No Tobias, I didn't ask anyone to DO my homework... I just asked for HELP!
That's different, ok? >:(

Anyway, I wanna thank everyone who came here to gimme a help!
I made some changes and now the program's workin' perfectly!

Thank u guys... 8-)

 1   2 


Go to: