[urgent] 2-d Side Scroller Game in CPP
varynoob

Hello everyone,

I am new to game programming, i am looking to code a 2-d side scroller which could do such things :
As the game begins, the ball starts rolling from left to right, and speeds up as the time goes on.
In its path, it faces obstacles like Triangles and Squares and combination of the two at random distances.
The player needs to jump the ball over the obstacles, suppose he hits the triangle he loses a life and stops if he hits a square and needs to jump over it, roll on the top and go ahead.
I need to code this very urgently, and i am confused in the proper C++ and ALLEGRO coding for
1. JUMP
2. Random Triangles and Squares.

Waiting for your replies.

Arvidsson

Why is this urgent?

There are many threads in this forum on how to implement jumping in platformers. Try to do a search and see if that helps you.

What do you mean by random triangles and squares? Do you know how to generate random numbers?

Also: showing some code always helps.

varynoob

I need to submit this in 4 days!

By random Triangles and Squares, i mean. when a ball rolls from right to left, triangles and squares and their combinations such as triangle-triangle, triangle-square etc are encountered as obstacles, and the player needs to jump over these to move ahead.

Yes i know the SRAND dunction, but how tu use it for these figures, is still cryptic.

I'll search again for JUMP, was looking for a simpler logic so as to understand it quickly and apply easily.

jmasterx

You can do jumping simply by having a vector to represent the velocity of a ball going in a direction. What you do is, when the player jumps, the Y value of the vector is increased. Each frame, the position of the ball increases by this vector. In addition, each frame the Y value of the vector is affected thus producing the parabola of jumping. To make sure the player doesn't keep jumping, you can figure out if he is on top of an object by finding the normal or some other hackish way. You only let the ball jump when it is on top of something.

For the other part, if your level is a plane, you could move by random increments along the plane and at each stop, if random number is 0, put triangle, else, put square or something.

Arvidsson

So this is homework?

As I have recently been implementing some jump mechanics myself, I took the time to produce a short tutorial covering one technique on how to implement jumping. It's based on some code you could have found if you had done a search :P I hope it's of use to you!

I guess you meant the rand() function. If you can generate random numbers within a range, you should then be able to generate the coordinates for your triangles and squares, and also what order they should come in.

It's easier to help if you show some code, and explain in more detail what you're having problem with.

varynoob

Thank you so much to both of you, will try and implement things and will post the code asap with the help needed.

PS : It is not a homework, i am an engineering graduate. So no more curriculum studies for now, but it is more of a demo kind of game, i need to submit. Your help may prove of a career paving path for me.

The code i have been stuck at :

PRESSING SPACE KEEPS THE BALL IN AIR!! REQUEST YOU TO CORRECT ME:-/

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_primitives.h> 3 4 5const int WIDTH = 1000; 6const int HEIGHT = 400; 7enum KEYS{LEFT, RIGHT, SPACE}; 8 9int main(void) 10{ 11 bool done = false; 12 bool redraw = true; 13 14 int pos_x = 30; 15 int pos_y = 370; 16 bool keys[3] = {false,false,false}; 17 18 int FPS = 60; 19 20 21 ALLEGRO_DISPLAY *display = NULL; 22 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 23 ALLEGRO_TIMER *timer; 24 //Initialization Functions 25 if(!al_init()) //initialize Allegro 26 return -1; 27 28 display = al_create_display(WIDTH, HEIGHT); //create our display object 29 30 if(!display) //test display object 31 return -1; 32 33 al_init_primitives_addon(); 34 al_install_keyboard(); 35 36 event_queue = al_create_event_queue(); 37 timer = al_create_timer(1.0/FPS); 38 39 40 al_register_event_source(event_queue, al_get_keyboard_event_source()); 41 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 42 43 al_start_timer(timer); 44 45 while(!done) 46 { 47 ALLEGRO_EVENT ev; 48 al_wait_for_event(event_queue, &ev); 49 50 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 51 { 52 switch(ev.keyboard.keycode) 53 { 54 /*case ALLEGRO_KEY_UP: 55 keys[UP] = true; 56 break; 57 case ALLEGRO_KEY_DOWN: 58 keys[DOWN] = true; 59 break;*/ 60 case ALLEGRO_KEY_LEFT: 61 keys[LEFT] = true; 62 break; 63 case ALLEGRO_KEY_RIGHT: 64 keys[RIGHT] = true; 65 break; 66 case ALLEGRO_KEY_SPACE: 67 keys[SPACE] = true; 68 break; 69 } 70 71 } 72 else if(ev.type == ALLEGRO_EVENT_KEY_UP) 73 { 74 switch(ev.keyboard.keycode) 75 { 76 case ALLEGRO_KEY_LEFT: 77 keys[LEFT] = false; 78 break; 79 case ALLEGRO_KEY_RIGHT: 80 keys[RIGHT] = false; 81 break; 82 case ALLEGRO_KEY_ESCAPE: 83 done=true; 84 case ALLEGRO_KEY_SPACE: 85 keys[SPACE] = false; 86 break; 87 } 88 } 89 90 else if(ev.type == ALLEGRO_EVENT_TIMER) 91 { 92 pos_x -=keys[LEFT] * 7; 93 pos_x +=keys[RIGHT] * 7; 94 if(keys[SPACE] == false) 95 { 96 pos_y = 370; 97 } 98 if(pos_y>=330) 99 pos_y -=keys[SPACE] *40; 100 redraw = true; 101 } 102 103 104 if(redraw && al_is_event_queue_empty(event_queue)) 105 { 106 redraw= false; 107 al_draw_filled_circle(pos_x,pos_y,20,al_map_rgb(255,0,255)); 108 al_flip_display(); 109 al_clear_to_color(al_map_rgb(0,0,0)); 110 } 111 112 } 113 114 115 al_destroy_display(display); //destroy our display object 116 117 return 0; 118}

jmasterx

You really should do it with vectors. Your hack is hard to visualize. Also, it's not a good idea to multiply by a Boolean, because in theory a true Boolean only needs to be non zero, it does not have to be 1.

Dizzy Egg

for a start you don't break after:

case ALLEGRO_KEY_ESCAPE:
  done=true;

Arvidsson

Try using velocities (i.e. vectors) as I've done in my tutorial and other people have suggested.

I'm not sure if you want to be able to control the jumping height or not.

If not, then it's simply this:

  • when the player pressed up, set dy to a negative value.

  • if player is not on ground, increase dy with a positive value (gravity)

  • update y using dy: y += dy

If you want controlled jumping height, see my tutorial I posted.

Steve Terry

wow... good luck man :P

varynoob

The ball bounces, but if the jump key is pressed, it bounces in the mid air.

All Triangles are generated in a small place, i.e all 4 triangles show up overlapping or inside each other, no random distance! :(:-/

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_primitives.h> 3#include "objects.h" 4 5const int WIDTH = 1000; 6const int HEIGHT = 400; 7const int NUM_TRIANGLES = 4; 8 9enum KEYS{LEFT, RIGHT, SPACE}; 10 11 12 13//prototypes 14 15void InitTriangle(Triangle shapeT[], int size); 16void DrawTriangle(Triangle shapeT[], int size); 17void UpdateTriangle(Triangle shapeT[], int size); 18 19 20int main(void) 21{ 22 bool done = false; 23 bool redraw = true; 24 bool jumping = false; 25 26 int pos_x = 30; 27 int pos_y = 380; 28 int speed =0; 29 30 float dx =1, dy = 1; 31 32 bool keys[3] = {false,false,false}; 33 34 int FPS = 60; 35 36 37 Triangle shapeT[NUM_TRIANGLES]; 38 39 40 ALLEGRO_DISPLAY *display = NULL; 41 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 42 ALLEGRO_TIMER *timer; 43 //Initialization Functions 44 45 46 47 if(!al_init()) //initialize Allegro 48 return -1; 49 50 display = al_create_display(WIDTH, HEIGHT); //create our display object 51 52 if(!display) //test display object 53 return -1; 54 55 al_init_primitives_addon(); 56 al_install_keyboard(); 57 58 59 srand(time(NULL)); 60 InitTriangle(shapeT, NUM_TRIANGLES); 61 62 event_queue = al_create_event_queue(); 63 timer = al_create_timer(1.0/FPS); 64 65 66 al_register_event_source(event_queue, al_get_keyboard_event_source()); 67 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 68 69 al_start_timer(timer); 70 71 while(!done) 72 { 73 ALLEGRO_EVENT ev; 74 al_wait_for_event(event_queue, &ev); 75 76 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 77 { 78 switch(ev.keyboard.keycode) 79 { 80 /*case ALLEGRO_KEY_UP: 81 keys[UP] = true; 82 break; 83 case ALLEGRO_KEY_DOWN: 84 keys[DOWN] = true; 85 break;*/ 86 case ALLEGRO_KEY_LEFT: 87 keys[LEFT] = true; 88 break; 89 case ALLEGRO_KEY_RIGHT: 90 keys[RIGHT] = true; 91 break; 92 case ALLEGRO_KEY_SPACE: 93 keys[SPACE] = true; 94 break; 95 } 96 97 } 98 else if(ev.type == ALLEGRO_EVENT_KEY_UP) 99 { 100 switch(ev.keyboard.keycode) 101 { 102 case ALLEGRO_KEY_LEFT: 103 keys[LEFT] = false; 104 break; 105 case ALLEGRO_KEY_RIGHT: 106 keys[RIGHT] = false; 107 break; 108 case ALLEGRO_KEY_ESCAPE: 109 done=true; 110 break; 111 case ALLEGRO_KEY_SPACE: 112 keys[SPACE] = false; 113 break; 114 } 115 } 116 117 // pos_y -=keys[UP] * 10; 118 // pos_y +=keys[DOWN] * 10; 119 else if(ev.type == ALLEGRO_EVENT_TIMER) 120 { 121 pos_x -=keys[LEFT] * 7; 122 pos_x +=keys[RIGHT] * 7; 123 /*if(keys[SPACE] == false) 124 { 125 pos_y = 370; 126 } 127 if(pos_y>=330) 128 pos_y -=keys[SPACE] *40;*/ 129 130 if(keys[SPACE] && pos_y>=350) 131 { 132 dy= -10; 133 jumping = true; 134 } 135 136 if(pos_y < 380) 137 dy += 0.5; 138 139 if (keys[SPACE] && pos_y <=380 && dy > 0) 140 dy -= 0.1; // got to be LESS than 0.5 in this example 141 142 if(dy>5) 143 dy = 5; 144 145 speed +=0.5; 146 pos_x +=speed; 147 pos_y +=dy; 148 149 if(pos_y > 380) 150 pos_y = 380; 151 152 153 redraw = true; 154 } 155 156 157 if(redraw && al_is_event_queue_empty(event_queue)) 158 { 159 redraw= false; 160 al_draw_filled_circle(pos_x,pos_y,20,al_map_rgb(255,0,255)); 161 DrawTriangle(shapeT,NUM_TRIANGLES); 162 //al_draw_triangle(100,400,120,360,140,400,al_map_rgb(255,0,255),2); 163 //al_draw_rounded_rectangle(180,340,260,400,5,5,al_map_rgb(255,255,255),3); 164 al_flip_display(); 165 al_clear_to_color(al_map_rgb(0,0,0)); 166 167 } 168 169 } 170 171 //al_rest(5.0); 172 173 al_destroy_display(display); //destroy our display object 174 175 return 0; 176} 177 178void InitTriangle(Triangle shapeT[], int size) 179{ 180 for(int i=0; i<size; i++) 181 { 182 shapeT[i].ID = TRIANGLE; 183 shapeT[i].pos_x1 = 100 + rand() % 700; 184 shapeT[i].pos_y1 = 400; 185 shapeT[i].pos_x2 = 120 + rand() % 700; 186 shapeT[i].pos_y2 = 360; 187 shapeT[i].pos_x3 = 140 + rand() % 700; 188 shapeT[i].pos_y3 = 400; 189 } 190} 191 192void DrawTriangle(Triangle shapeT[], int size) 193{ 194 for(int i=0; i<size; i++) 195 { 196 197 al_draw_triangle(shapeT[i].pos_x1,shapeT[i].pos_y1,shapeT[i].pos_x2,shapeT[i].pos_y2, 198 shapeT[i].pos_x3,shapeT[i].pos_y3,al_map_rgb(255,0,255),2); 199 } 200} 201 202//void UpdateTriangle(Triangle &shapeT, int size) 203//{ 204//}

Arvidsson
if (pos_y >= 380) { // means the ball is on the ground right?
    if(keys[SPACE]) {
        if (jumping) {
            dy= -10;
            jumping = false;
        }
    }
    else
        jumping = true;
}
// a more proper name for the jumping variable would be canJump, or mayJumpAgain

Regarding the triangle problem, I would generate random numbers for just one xy-coordinate and create the other two vertices by using that coordinate. This way you can easily change the size of the triangles if you want to.

varynoob

Whoa, thanks a lot :) The bounce is working now! But i am getting the obstacles of the game(have been testing only on triangles for now) all wrong. Have attached an image.

Have modified, only x1 of the triangle and its way better now, but i get overlapping triangles!!

{"name":"605625","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/2\/9235031d8a61a4cb19d0ed47e6b819cb.jpg","w":1015,"h":122,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/2\/9235031d8a61a4cb19d0ed47e6b819cb"}605625

void InitTriangle(Triangle shapeT[], int size)
{
  for(int i=0; i<size; i++)
  {
  shapeT[i].ID = TRIANGLE;
  shapeT[i].pos_x1 = 100 + rand() % 600;
  shapeT[i].pos_y1 = 400;
  shapeT[i].pos_x2 = shapeT[i].pos_x1+20;
  shapeT[i].pos_y2 = 360;
  shapeT[i].pos_x3 = shapeT[i].pos_x1+40;
  shapeT[i].pos_y3 = 400;
  }
}

gnolam
varynoob said:

Have modified, only x1 of the triangle and its way better now, but i get overlapping triangles!!

Therefore, you should..?

You have all the information you need to solve that problem: a list of all the generated triangles and their coordinates.

[EDIT]
I really hope somebody doesn't just give you the solution to this too. You need to start thinking for yourself.

varynoob

[UPDATED]
I have been trying. I have now managed to make things scroll and triangles and squares coming, but i am really in confusion with 2 things :

1. Squares and Triangles OVERLAP each other(as seen in the image).

{"name":"605627","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/f\/efd5069bfe3772701fee009ee6d06eca.jpg","w":806,"h":194,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/f\/efd5069bfe3772701fee009ee6d06eca"}605627

2. How can i make the screen scroll? I mean, for ex mario: you keep on going and things keep coming!!

jmasterx

You scroll by moving the world around the player. The player is always at the center of the screen except at the left and right extents of the level.

It's easier to think of it in terms of a camera. You can look into ALLEGRO_TRANSFORMations for this: http://www.liballeg.org/a5docs/refman/transformations.html

If you were able to get a degree in Engineering, which involved maths far more complex than simple transformations, then the maths required to simulate a camera should be a breeze.

The idea of transformations is that you make the Player's position 0,0 on the screen which will cause your character to be at the center of the screen which consequently scrolls your props too.

If you need an example on transformations in Allegro, there is ex_transform.c that you can have a look at. It comes with the Allegro source code.

In theory, these 3 functions should do it for you:

  ALLEGRO_TRANSFORM transform;
  al_identity_transform(&transform);
  al_translate_transform(&transform, x, y);
  al_use_transform(&transform);

It is up to you to figure out x and y.

Arvidsson

Problem: Triangles overlap
What we want to achieve: Make them not overlap
Solution: Is there a way to see if they overlap and then do something about it?

Neil Walker

So you're trying to remake the impossible game:

{"name":"images","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/7\/07445f55dd03592bdf31dede6f94f276.jpg","w":300,"h":168,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/7\/07445f55dd03592bdf31dede6f94f276"}images

varynoob

Neil Walker : Why impossible ? What i am trying to code, already exists as an smart phone app. The game in the picture isnt the exact model of it.

Arvidsson : As in, you want me to paste the code? I am confused with the statement

"Solution: Is there a way to see if they overlap and then do something about it?"

jmasterx : will try it, have been into the overlapping issue.

As i added, the Ball move functions, for left, right and jump, the JUMP Logic seems to be not working. Cant figure out why?

Here's the updated code :

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_primitives.h> 3#include "objects.h" 4 5const int WIDTH = 1000; 6const int HEIGHT = 400; 7const int NUM_TRIANGLES = 6; 8 9enum KEYS{LEFT, RIGHT, SPACE}; 10 11 12 13//prototypes 14 15void InitBall(Ball &shapeB); 16void DrawBall(Ball &shapeB); 17void MoveLeftBall(Ball &shapeB); 18void MoveRightBall(Ball &shapeB); 19void JumpBall(Ball &shapeB); 20 21 22void InitTriangle(Triangle shapeT[], int size); 23void DrawTriangle(Triangle shapeT[], int size); 24void StartTriangle(Triangle shapeT[], int size); 25void UpdateTriangle(Triangle shapeT[], int size); 26 27int main(void) 28{ 29 bool done = false; 30 bool redraw = true; 31// bool canJump = false; 32 33// float pos_x = 30; 34// float pos_y = 380; 35 float speed =0; 36 37// float dx =1, dy = 1; 38 39 bool keys[3] = {false,false,false}; 40 41 int FPS = 60; 42 43 44 Triangle shapeT[NUM_TRIANGLES]; 45 Ball shapeB; 46 47 ALLEGRO_DISPLAY *display = NULL; 48 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 49 ALLEGRO_TIMER *timer; 50 //Initialization Functions 51 52 53 54 if(!al_init()) //initialize Allegro 55 return -1; 56 57 display = al_create_display(WIDTH, HEIGHT); //create our display object 58 59 if(!display) //test display object 60 return -1; 61 62 al_init_primitives_addon(); 63 al_install_keyboard(); 64 65 66 srand(time(NULL)); 67 InitTriangle(shapeT, NUM_TRIANGLES); 68 InitBall(shapeB); 69 event_queue = al_create_event_queue(); 70 timer = al_create_timer(1.0/FPS); 71 72 73 al_register_event_source(event_queue, al_get_keyboard_event_source()); 74 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 75 76 al_start_timer(timer); 77 78 while(!done) 79 { 80 ALLEGRO_EVENT ev; 81 al_wait_for_event(event_queue, &ev); 82 83 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 84 { 85 switch(ev.keyboard.keycode) 86 { 87 case ALLEGRO_KEY_LEFT: 88 keys[LEFT] = true; 89 break; 90 case ALLEGRO_KEY_RIGHT: 91 keys[RIGHT] = true; 92 break; 93 case ALLEGRO_KEY_SPACE: 94 keys[SPACE] = true; 95 break; 96 } 97 98 } 99 else if(ev.type == ALLEGRO_EVENT_KEY_UP) 100 { 101 switch(ev.keyboard.keycode) 102 { 103 case ALLEGRO_KEY_LEFT: 104 keys[LEFT] = false; 105 break; 106 case ALLEGRO_KEY_RIGHT: 107 keys[RIGHT] = false; 108 break; 109 case ALLEGRO_KEY_ESCAPE: 110 done=true; 111 break; 112 case ALLEGRO_KEY_SPACE: 113 keys[SPACE] = false; 114 break; 115 } 116 } 117 118 119 else if(ev.type == ALLEGRO_EVENT_TIMER) 120 { 121 redraw = true; 122 if(keys[LEFT]) 123 MoveLeftBall(shapeB); 124 if(keys[RIGHT]) 125 MoveRightBall(shapeB); 126 127 128 129 if (shapeB.pos_Y >= 380) 130 { // means the ball is on the ground 131 if(keys[SPACE]) 132 { 133 if (shapeB.canJump) 134 { 135 shapeB.dy= -10; 136 shapeB.canJump = false; 137 } 138 } 139 else 140 shapeB.canJump = true; 141 } 142 143 144 145 if(shapeB.pos_Y < 380) 146 shapeB.dy += 0.5; 147 148 149 //JumpBall(shapeB); 150 if (keys[SPACE] && shapeB.pos_Y <=380 && shapeB.dy > 0) 151 shapeB.dy -= 0.1; // got to be LESS than 0.5 152 153 if(shapeB.dy>5) 154 shapeB.dy = 5; 155 156 speed +=0.01; 157 //shapeB.pos_X +=speed*1/2; 158 shapeB.pos_Y +=shapeB.dy; 159 160 if(shapeB.pos_Y > 380) 161 shapeB.pos_Y = 380; 162 163 164 StartTriangle(shapeT, NUM_TRIANGLES); 165 UpdateTriangle(shapeT, NUM_TRIANGLES); 166 } 167 168 169 if(redraw && al_is_event_queue_empty(event_queue)) 170 { 171 redraw= false; 172 /*al_draw_filled_circle(pos_x,pos_y,20,al_map_rgb(255,0,255));*/ 173 //UpdateTriangle(shapeT,NUM_TRIANGLES); 174 DrawBall(shapeB); 175 DrawTriangle(shapeT,NUM_TRIANGLES); 176 177 //al_draw_rounded_rectangle(180,340,260,400,5,5,al_map_rgb(255,255,255),3); 178 al_flip_display(); 179 al_clear_to_color(al_map_rgb(0,0,0)); 180 181 182 } 183 } 184 185 //al_rest(5.0); 186 187 al_destroy_display(display); //destroy our display object 188 189 return 0; 190 } 191 192 193 194void InitBall(Ball &shapeB) 195{ 196 shapeB.ID=BALL; 197 shapeB.pos_X= 30; 198 shapeB.pos_Y= 380; 199 shapeB.lives = 3; 200 shapeB.speed = 7; 201 shapeB.score = 0; 202 shapeB.boundX = 57; 203 shapeB.boundY = 57; 204 shapeB.dx = 1; 205 shapeB.dy = 1; 206 207} 208void DrawBall(Ball &shapeB) 209{ 210 al_draw_filled_circle(shapeB.pos_X,shapeB.pos_Y,20,al_map_rgb(255,0,255)); 211} 212void MoveLeftBall(Ball &shapeB) 213{ 214 shapeB.pos_X -=shapeB.speed; 215 if(shapeB.pos_X<20) 216 shapeB.pos_X = 20; 217} 218void MoveRightBall(Ball &shapeB) 219{ 220 shapeB.pos_X += shapeB.speed; 221 if(shapeB.pos_X>600) 222 shapeB.pos_X = 600; 223} 224void JumpBall(Ball &shapeB) 225{ 226 if (shapeB.canJump) 227 { 228 shapeB.dy= -10; 229 shapeB.canJump = false; 230 } 231 232 else 233 { 234 shapeB.canJump = true; 235 } 236 237 if(shapeB.pos_Y < 380) 238 shapeB.dy += 0.5; 239 240} 241 242 243 244void InitTriangle(Triangle shapeT[], int size) 245{ 246 for(int i=0; i<size; i++) 247 { 248 shapeT[i].ID = TRIANGLE; 249 shapeT[i].live = false; 250 shapeT[i].speed = 2; 251 shapeT[i].random = 1 + rand() % 10; 252 253 } 254} 255 256void DrawTriangle(Triangle shapeT[], int size) 257{ 258 for(int i=0; i<size; i++) 259 { 260 if(shapeT[i].live) 261 { 262 263 //if(shapeT[i].pos_x3 == shapeT[i+1].pos_x1 || shapeT[i].pos_x3 +100<= shapeT[i+1].pos_x1) 264 //{ 265 /*&& shapeT[i].pos_x3 == shapeT[i].pos_rect_x1 || shapeT[i].pos_x3 + 400 <= shapeT[i].pos_rect_x1 266 || shapeT[i].pos_x1 >= shapeT[i].pos_rect_x2) */ 267 268 if(shapeT[i].random < 5) 269 al_draw_triangle(shapeT[i].pos_x1,shapeT[i].pos_y1,shapeT[i].pos_x2,shapeT[i].pos_y2, 270 shapeT[i].pos_x3,shapeT[i].pos_y3,al_map_rgb(255,0,255),2); 271 else 272 al_draw_rounded_rectangle(shapeT[i].pos_rect_x1,shapeT[i].pos_rect_y1, 273 shapeT[i].pos_rect_x2,shapeT[i].pos_rect_y2,5,5,al_map_rgb(255,255,255),3); 274 //} 275 } 276 } 277} 278 279void StartTriangle(Triangle shapeT[], int size) 280{ 281 for (int i = 0 ; i < size; i++) 282 { 283 if(!shapeT[i].live) 284 { 285 if(rand() % 500 == 0) 286 { 287 shapeT[i].live = true; 288 shapeT[i].pos_x1 = 780 + rand() % 20; 289 shapeT[i].pos_y1 = 400; 290 shapeT[i].pos_x2 = shapeT[i].pos_x1+10; 291 shapeT[i].pos_y2 = 370; 292 shapeT[i].pos_x3 = shapeT[i].pos_x1+20; 293 shapeT[i].pos_y3 = 400; 294 295 shapeT[i].pos_rect_x1 = shapeT[i].pos_x3 + 20; 296 shapeT[i].pos_rect_y1 = 320; 297 shapeT[i].pos_rect_x2 = shapeT[i].pos_rect_x1 + 80; 298 shapeT[i].pos_rect_y2 = 400; 299 300 break; 301 302 } 303 } 304 } 305} 306 307void UpdateTriangle(Triangle shapeT[], int size) 308{ 309 for(int i=0; i<size; i++) 310 { 311 if(shapeT[i].live) 312 { 313 shapeT[i].pos_x1 -= shapeT[i].speed; 314 shapeT[i].pos_x2 -= shapeT[i].speed; 315 shapeT[i].pos_x3 -= shapeT[i].speed; 316 shapeT[i].pos_rect_x1 -= shapeT[i].speed; 317 shapeT[i].pos_rect_x2 -= shapeT[i].speed; 318 319 320 if(shapeT[i].pos_x3 <0 || shapeT[i].pos_rect_x2 <0) 321 shapeT[i].live = false; 322 } 323 } 324}

Trent Gamblin

Trying to make a quick buck piggybacking off people here? :)

Arthur Kalliokoski

I doubt he'd label it "urgent" if he was trying to develop an app, it's homework that he procrastinated on.

Trent Gamblin

That's why I said a "quick" buck. :P

gnolam
varynoob said:

Arvidsson : As in, you want me to paste the code? I am confused with the statement "Solution: Is there a way to see if they overlap and then do something about it?"

What Arvidsson meant is the same as I did: THINK. You can't expect other people to keep solving everything for you. Sooner or later, you're going to have to think for yourself. What he posted was a basic recipe to solving your problem.

I'll restate it in the form of three questions you should ask yourself:

  1. What is the problem?

  2. What are the conditions that cause the problem?

  3. Now that you know what the problem is and how it occurs, how do you fix it?

varynoob

No No No Sir.
Please dont get me wrong, and this isnt any home work, i need to code it by weekend in any case for then, i will miss an opportunity, that's it.
I have been just asking, since this is an allegro forum, and there are people like you who have hell lot of exp, while i am a total newbie.

If this is against, any rules, i am really sorry! ???

[EDIT]

I am trying to sir. But, for a first timer, it gets, little confusing at times.

Trent Gamblin

Ok, I'll take your word. Sounds like something for a job interview. Good luck.

varynoob

Yes exactly, thankyou sir. :)

Its my dream to be a game programmer, and this opportunity means a lot to me, got just 3 days left!
Sadly though, here in, we do not get much resources or motivation for Game Programming, so gets stiff.

Trent Gamblin

Well try a little harder, and you'll get it done and get answers. Ask specific questions relating to your code, which you should post if it has changed.

For example "my triangles overlap, how do I fix it" is a pretty general question. You should try fixing it. You might be able to do it yourself (don't sell yourself short!) If you can't figure it out, show us the code where you tried to figure it out and someone can probably tell you how to fix your code.

People here just don't like giving out a 100% ready made solution, they want you to try and figure it out yourself first.

Johan Halmén

Ok, for the triangles: check the variables defining the positions of the triangles before you draw them.

Anyway, if game programming skills are crucial for the career opening, something says me you should wait for the opening 2 or 3 years and meanwhile improve your skills.

Dizzy Egg

If I put something 10ft wide 7ft away from something else that is 10ft wide do you think they will touch....?

Mark Oates

The London Symphony Orchestra has an opening in the Oboe section! :o I just got an Oboe! Quick, what do the buttons to!? :o

Dizzy Egg

I'm not sure, but I'm thinking they change the pitch of the sound. Try putting the keys in an array called pitch[numNotes] or something, and then do something else blah blah blah yawn. Comon varynoob give us all hope with a custom solution.... :o

varynoob

Guys, look at this, everything seems to be ohkay, except the Ball hangs in the air, when Jump key is pressed. Before i made Ball Struct & functions for Ball Movement, ball was jumping fine. But now, there is this weird error with the same code.
It has something to do with the Draw function of the Ball, but i am not able to figure it out.
Looking to put in collision detection and spritesheets, so need functions for ball movement, such as MoveRightBall/Left/Jump.

This is the code i have changed

#SelectExpand
1 2//HAVE CHANGED THIS PART, THINGS WORKED, WHEN STRUCT WAS NOT CREATED/USED. NOW THE //BALL HANGS IN THE AIR AND DOES NOT COME DOWN 3 4if(keys[LEFT]) 5 MoveLeftBall(shapeB); 6 if(keys[RIGHT]) 7 MoveRightBall(shapeB); 8 9 10 11 if (shapeB.isOnGround) 12 { // means the ball is on the ground 13 if(keys[SPACE]) 14 { 15 if (shapeB.canJump) 16 { 17 shapeB.dy= -10; 18 shapeB.canJump = false; 19 } 20 } 21 else 22 shapeB.canJump = true; 23 } 24 25 26 27 if(!shapeB.isOnGround) 28 shapeB.dy += 0.5; 29 30 if (keys[SPACE] && shapeB.isOnGround && shapeB.dy > 0) 31 shapeB.dy -= 0.1; // got to be LESS than 0.5 in this example 32 33 if(shapeB.dy>5) 34 shapeB.dy = 5; 35 36 speed +=0.01; 37 //pos_x +=speed*1/2; 38 shapeB.pos_Y += shapeB.dy; 39 40 if(shapeB.pos_Y > 380) 41 { 42 shapeB.pos_Y = 380; 43 shapeB.dy = 0; 44 } 45 46 47 48 49 50 51 StartTriangle(shapeT, NUM_TRIANGLES); 52 UpdateTriangle(shapeT, NUM_TRIANGLES); 53 } 54 55 56 if(redraw && al_is_event_queue_empty(event_queue)) 57 { 58 redraw= false; 59 //al_draw_filled_circle(pos_x,pos_y,20,al_map_rgb(255,0,255)); THIS WAS THE WORKING BALL WITHOUT BALL STRUCT AND FUNCTIONS 60 DrawBall(shapeB); 61 DrawTriangle(shapeT,NUM_TRIANGLES); 62 63//HAVE EDITED OUT THE DESTROY PART AND END OF main() 64 65//THE FUNCTION BEGINS 66 67void InitBall(Ball &shapeB) 68{ 69 shapeB.ID=BALL; 70 shapeB.pos_X= 30; 71 shapeB.pos_Y= 380; 72 shapeB.lives = 3; 73 shapeB.speed = 7; 74 shapeB.score = 0; 75 shapeB.boundX = 57; 76 shapeB.boundY = 57; 77 shapeB.dx = 1; 78 shapeB.dy = 1; 79 shapeB.canJump = false; 80 shapeB.isOnGround = true; 81 82} 83void DrawBall(Ball &shapeB) 84{ 85 if(shapeB.pos_Y < 380) 86 shapeB.isOnGround = false; 87 else 88 shapeB.isOnGround = true; 89 al_draw_filled_circle(shapeB.pos_X,shapeB.pos_Y,20,al_map_rgb(255,0,255)); 90} 91void MoveLeftBall(Ball &shapeB) 92{ 93 shapeB.pos_X -=shapeB.speed; 94 if(shapeB.pos_X<20) 95 shapeB.pos_X = 20; 96} 97void MoveRightBall(Ball &shapeB) 98{ 99 shapeB.pos_X += shapeB.speed; 100 if(shapeB.pos_X>600) 101 shapeB.pos_X = 600; 102} 103//void JumpBall(Ball &shapeB) NEED TO FIGURE THIS OUT AS WELL 104//{ 105// if (shapeB.canJump) 106// { 107// shapeB.dy= -10; 108// shapeB.canJump = false; 109// } 110// 111// else 112// { 113// shapeB.canJump = true; 114// } 115// 116// if(shapeB.pos_Y < 380) 117// shapeB.dy += 0.5; 118// 119//}

Neil Walker
varynoob said:

Neil Walker : Why impossible ?

Because that's the name of the game :P

Arvidsson

The ball hangs in the air you say. Then you should ask yourself, what is the condition for the ball to fall. Could it be gravity? What is the condition for gravity to be applied? Is it ever true?

varynoob

Arvidsson : Sir, after trying several times, got the mistake, corrected for the JUMP. Have been working on collisions.

[EDIT]
CIRCLE_TRIANGLE
Is this okay ?

if((shapeB.pos_X + shapeB.r > shapeT[i].pos_x1) && (shapeB.pos_X - shapeB.r < shapeT[i].pos_x3) 
        && (shapeB.pos_Y + shapeB.r > shapeT[i].pos_y2 && shapeB.pos_Y - shapeB.r < shapeT[i].pos_y3))

[edit]

HOW DO I CHECK IN BALL(bounding rectangle)<->RECTANGLE, IF THE BALL HITS LEFT SIDE OF RECTANGLE, THE SCREEN PAUSES, ELSE IF BALL IS ON TOP EDGE OF SQUARE, IT ROLLS DOWN AND SCREEN KEEPS SCROLLING AND GAME CONTINUES!

Suggestions plz. Using this (not working):

#SelectExpand
1if((shapeT[i].pos_x1 - shapeT[i].bound_triangle_x < shapeB.pos_X + shapeB.boundx) 2 && (shapeT[i].pos_x1 + shapeT[i].bound_triangle_x > shapeB.pos_X - shapeB.boundx) 3 &&(shapeT[i].pos_y1 - shapeT[i].bound_triangle_x < shapeB.pos_Y + shapeB.boundy) 4 &&(shapeT[i].pos_y1 + shapeT[i].bound_triangle_x > shapeB.pos_Y - shapeB.boundy)) 5 { 6 //shapeT[i].collidingT = true; 7 shapeB.lives--; 8 //shapeB.pos_Y = shapeT[i].pos_y2 - shapeB.r; 9 //shapeT[i].speed = 0; 10 shapeT[i].live = false; 11 12 StartExplosions(explosion,shapeB.pos_X, shapeB.pos_Y); 13 14 } 15 16 else if((shapeT[i].pos_rect_x1 < shapeB.pos_X + shapeB.boundx) 17 &&(shapeT[i].pos_rect_x2 > shapeB.pos_X - shapeB.boundx) 18 &&(shapeT[i].pos_rect_y1 < shapeB.pos_Y + shapeB.boundy) 19 &&(shapeT[i].pos_rect_y2 > shapeB.pos_Y - shapeB.boundy)) 20 21 22 { 23 //shapeB.pos_X = shapeT[i].pos_rect_x1 - shapeB.r; 24 //shapeB.pos_Y = shapeT[i].pos_rect_y1 - shapeB.r; 25 //shapeT[i].collidingS = true; 26 27 28 //shapeT[i].speed = 0; 29 shapeT[i].live = false; 30 31 }

Mark Oates

Oh God, he's shouting now. :-[

We'll never make the London Symphony. :'(

*sniff... :'( screw it! :'( screw it all!
{"name":"605641","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6de24c7282296dab186ca05f9e5d0e22.jpg","w":268,"h":331,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6de24c7282296dab186ca05f9e5d0e22"}605641

varynoob

What are you talking about? Got no idea!! Spamming ?? :P :-/

Anyone with Circle-Triangle & Circle-Rectangle collision detection simultaneous checking ? ?:-[

jmasterx

With your education, you should have no trouble figuring out a formula for each type of detection; even if it's inefficient, it will do.

Once you come up with some formulas, we will gladly guide you on how to turn that formula into C++ code.

If you can figure out if a point is in a circle, if a point is in a triangle, and if a point is in a rectangle, you should be able to figure out a way to do it.

You might find it easier to treat a circle as a rectangle because if the circle's radius is less than the box's height, you'll have to check if the circle collides with its edge.

Also, he is not spamming, this is the atmosphere at a.cc .

Steve Terry

Mark, that guy in the background may want to see about getting his uni-brow waxed :D

LennyLen

varynoob, without trying to sound demeaning, it's very obvious that you are out of your depth here. If you do manage to get the help you need from people here in order to get the job, then what? It won't take long before your employer realizes that you don't have the necessary experience.

Dizzy Egg

He's absolutely right I'm afraid, that's why I stopped giving you hints. Sorry, but maybe it's time to get realistic. :-[

varynoob

I have learnt from my mistakes sir, as everybody had told here, to try and try, and come up with things, i did the same.

Used Bounding box for circle, and bounding box of triangle to check collisions between the two, while the rectangle itself, has sides, so it is easy for that.

But what i am facing is, the collision comes out to be ok at times and weird at other times. So asked you of the flaw.

Here is the code.

#SelectExpand
1void CollideTriangle(Triangle shapeT[], int csize, Ball &shapeB, Explosion &explosion) //FUNCTION TO CHECK BOTH THE COLLSIONS 2{ 3 for(int i = 0; i < csize; i++) 4 { 5 if(shapeT[i].live) 6 { 7 8 9 if(((shapeT[i].pos_x1 - shapeT[i].bound_triangle_x < shapeB.pos_X + shapeB.boundx) 10 && (shapeT[i].pos_x1 + shapeT[i].bound_triangle_x > shapeB.pos_X - shapeB.boundx) 11 &&(shapeT[i].pos_y1 - shapeT[i].bound_triangle_x < shapeB.pos_Y + shapeB.boundy) 12 &&(shapeT[i].pos_y1 + shapeT[i].bound_triangle_x > shapeB.pos_Y - shapeB.boundy)) || 13 14//UPPER PART CHECKS FOR CIRCLE-TRIANGLE WHILE THE PART BELOW CHECKS FOR CIRCLE=RECTAGLE 15 16 ((shapeT[i].pos_rect_x1 < shapeB.pos_X + shapeB.boundx) 17 &&(shapeT[i].pos_rect_x2 > shapeB.pos_X - shapeB.boundx) 18 &&(shapeT[i].pos_rect_y1 < shapeB.pos_Y + shapeB.boundy) 19 &&(shapeT[i].pos_rect_y2 > shapeB.pos_Y - shapeB.boundy))) 20 21 { 22 //shapeT[i].collidingT = true; 23 //shapeB.lives--; 24 //shapeB.pos_Y = shapeT[i].pos_y2 - shapeB.r; 25 //shapeT[i].speed = 0; 26 shapeT[i].live = false; 27 28 StartExplosions(explosion,shapeB.pos_X, shapeB.pos_Y); 29 30 } 31 32 } 33 } 34}

PS : SO I HAVE BEEN TRYING, AND HAVE COME UP WITH THE COLLISION TECHNIQUES AS WELL.

IT IS ALL ABOUT MORE UP THAN BOTTOM, MORE BOTTOM THAN UP, MORE LEFT THAN RIGHT & MORE RIGHT THAN LEFT.

Dizzy Egg

Why would you add/subtract bound_triangle_x from posy ??

varynoob

Dizzy Egg : Typo sir! It was meant to be 'bound_triangle_y'.

I have been trying out different things, but havnt really landed into any good one, as in i want to achieve if Circle hits Left of square, everything freezes except the ball, which if made to bounce, should make things back normal and scrolling.

What i did is, checked the collision with the sides of square i.e Right of circle more right than square's left & Left of circle more left than Square's right.

If the condition is true, Leftcollision is true.

If Leftcollision is true, All the update functions are skipped, thus screen is freezed.

But this stuff doesnt do well for me. Code below :

#SelectExpand
1for(int i=0; i < ssize ; i++) 2 { 3 if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx) 4 &&(shapeS[i].pos_rect_x1+ 40 > shapeB.pos_X - shapeB.boundx) 5/* &&(shapeS[i].pos_rect_y1 < shapeB.pos_Y + shapeB.boundy) 6 &&(shapeS[i].pos_rect_y1+40 > shapeB.pos_Y - shapeB.boundy)*/) 7 { 8 //StartExplosions(explosion,shapeB.pos_X, shapeB.pos_Y); 9 10 shapeB.LeftCollision = true; 11 } 12 else if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx) 13 &&(shapeS[i].pos_rect_x1+ 40 > shapeB.pos_X - shapeB.boundx) 14 &&(shapeS[i].pos_rect_y1 < shapeB.pos_Y + shapeB.boundy) 15 &&(shapeS[i].pos_rect_y1+40 > shapeB.pos_Y - shapeB.boundy)) 16 { 17 //shapeB.pos_Y = shapeS[i].pos_rect_y1 - shapeB.boundy ; 18 shapeS[i].collidingS = true; 19 shapeB.LeftCollision = false; 20 } 21 22 else 23 shapeB.LeftCollision = false; 24 } 25}

Dizzy Egg

if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx)

...think about it; if shapeS[i].pos_rect_x1 = 20, and shapeB.pos_X = 50, this is ALWAYS going to be true! THINK ABOUT THE LOGIC!!!!!!!! :P

varynoob

if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx)
&&(shapeS[i].pos_rect_x1+ 40 > shapeB.pos_X - shapeB.boundx)

But then, this condition also has an && thus if 1st is always true, the 2nd will only be true, if the left of the ball is less than the right of the square!!

boundx = 23.

So for shapeS[i].pos_rect_x1 = 20, and shapeB.pos_X = 50

it will be : (15<73) && (60 >27> | TRUE

For shapeS[i].pos_rect_x1 = 20, and shapeB.pos_X = 90

it will be : (15<113) && (60 > 67 ) | FALSE

So, it should be correct?? What's wrong? ???

Dizzy Egg

I don't know you tell me! What is wrong! Explain whats wrong when you run the code...

varynoob

Oh yes, sorry, i mean it collides with some squares while it doesnt with others! All random, it is something to do with my Update and Draw functions of square!

How do i check, that only if there is not square already on (x,y) position, next square should be drawn else, neither drawn nor updated(coz sometimes, invisible squares are coming up, i.e which are not drawn, but updated!)

THE SQUARE FUNCTIONS ARE AS :

#SelectExpand
1void InitSquare(Square shapeS[], int size) 2{ 3 for(int i = 0; i < size ; i++) 4 { 5 shapeS[i].ID = SQUARE; 6 shapeS[i].live = false; 7 shapeS[i].pos_rect_x1 = 960; 8 shapeS[i].pos_rect_y1 = 360; 9 shapeS[i].speed = 2; 10 shapeS[i].collidingS = false; 11 } 12} 13void DrawSquare(Square shapeS[], int size) 14{ 15 for(int i = 0; i<size; i++) 16 { 17 if(shapeS[i].live) 18 { 19 //if(random < 10)// && shapeT[i].pos_rect_x1 > shapeT[i-1].pos_rect_x2) 20 al_draw_rounded_rectangle(shapeS[i].pos_rect_x1,shapeS[i].pos_rect_y1, 21 shapeS[i].pos_rect_x1+40,shapeS[i].pos_rect_y1+40,6,6,al_map_rgb(255,255,255),2); 22 } 23 } 24} 25void StartSquare(Square shapeS[], int size) 26{ 27 for (int i = 0 ; i < size; i++) 28 { 29 if(!shapeS[i].live) 30 { 31 if(rand() % 100 == 0) 32 { 33 shapeS[i].live = true; 34 shapeS[i].pos_rect_x1 = 960; 35 shapeS[i].pos_rect_y1 = 360; 36 //shapeT[i].pos_rect_x2 = shapeS[i].pos_rect_x1 + 40; 37 //shapeT[i].pos_rect_y2 = shapeS[i].pos_rect_y1 + 40; 38 39 break; 40 41 } 42 } 43 } 44} 45void UpdateSquare(Square shapeS[], int size, Ball &shapeB) 46{ 47 for(int i=0; i<size; i++) 48 { 49 if((shapeS[i].live)) 50 { 51 shapeS[i].pos_rect_x1 -= shapeS[i].speed; 52 //shapeT[i].pos_rect_x2 -= shapeS[i].speed; 53 54 55 if(shapeS[i].pos_rect_x1+40 <= 0) 56 { 57 shapeS[i].live = false; 58 shapeB.score++; 59 } 60 } 61 } 62} 63 64void CollideSquare(Square shapeS[], int ssize, Ball &shapeB, Explosion &explosion) 65{ 66 for(int i=0; i < ssize ; i++) 67 { 68 if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx) 69 &&(shapeS[i].pos_rect_x1+ 40 > shapeB.pos_X - shapeB.boundx) 70 { 71 shapeB.LeftCollision = true; //CHECKING FOR COLLIOION WITH LEFT SIDE OF SQUARE 72 } 73 else if((shapeS[i].pos_rect_x1 -5 < shapeB.pos_X + shapeB.boundx) 74 &&(shapeS[i].pos_rect_x1+ 40 > shapeB.pos_X - shapeB.boundx) 75 &&(shapeS[i].pos_rect_y1 < shapeB.pos_Y + shapeB.boundy) 76 &&(shapeS[i].pos_rect_y1+40 > shapeB.pos_Y - shapeB.boundy)) 77 { 78 shapeB.pos_Y = shapeS[i].pos_rect_y1 - shapeB.boundy ; //THIS SHOULD MAKE BALL LAND OVER THE SQUARE WHEN ALL CONDITIONS ARE MET, BUT DOESNT 79 shapeS[i].collidingS = true; 80 shapeB.LeftCollision = false; 81 } 82 83 else 84 shapeB.LeftCollision = false; 85 } 86}

23yrold3yrold
LennyLen said:

varynoob, without trying to sound demeaning, it's very obvious that you are out of your depth here. If you do manage to get the help you need from people here in order to get the job, then what? It won't take long before your employer realizes that you don't have the necessary experience.

Gonna have to echo this. You'll finish the game, get the job, and be fired in two weeks. The point of this assignment is to see if you can do the job. If you could, you wouldn't be back in this thread every ten minutes.

I work as a video game programmer. When I applied for the job, they told me to make a Breakout clone, and I was budgeted two days. Difference was I could actually do it. And good thing, because I've had ample opportunity to laugh at some of the things other people send in.

Here, have a video break:

So You Want To Be A Developer Part One
So You Want To Be A Developer Part Two

Mark Oates

Awesome videos, 23. :)

varynoob

Thankyou 23, will try harder! If you see, i have asked many a times, but have only taken from this thread "Jumping mechanism" and lots of advice to KEEP THINKING and TRYING. I have been doing so, and will watch these videos and take your words as motivation. Everyone here has been saying the same, that until you do it yourself, it wont be of any use!

I am almost done with the game, it may not be perfect, but atleast i have tried and got something working! Thanks again everyone.

Steve Terry

I don't believe we normally give this treatment to every user here. We try to be very helpful when someone comes to us with a problem where they already did most of the hard work and have a few bugs with their implementation. The problem is that you started the thread practically expecting us to do everything up front, so it gave a very bad impression. Not to mention that this seems to be something for a job interview or homework which most of us here would rather see you do some research beforehand. We will gladly help you with any of the problems, but you can't sound so desperate and demanding up front.

I did a quick Google search for "circle triangle collision" and "circle square collision" and there are some pretty relevant results returned. You can find most of the information you are needing from sources that practically give you the answer if you look. You may try that and if it fails to work for you, create a new thread and say, hey I found this algorithm for collision detection, this is how I implemented it and it's not quite working when I do this or that, can you help?

You may get a different response from us if that were the case.

Thread #609597. Printed from Allegro.cc