# Thread: Would someone solve my problem?

1. ## Would someone solve my problem?

I have only been learning C for about 2 months which also explains a very messy structure. The problem here is that it is not plotting a projectile. At the moment, it is only supposed to work for a positive value of angle... but it doesn't even do that. I can't seem to find what's wrong. Can anyone help?

Code:
```#include "graphics_lib.h"
#include "midi_lib.h"
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>

#define X_WINDOW 1000
#define Y_WINDOW 250

#define ARMLENGTH 10
#define BODYSIZE 40
#define ARMPOSITION 15
#define STRIDE 15
#define LEG_LENGTH 40

#define PI 3.141592653589
#define GRAVITY 9.81
#define RETURN 13

#define NUM_HOLES 2
#define PAR1 4

/*	Set offset x and y values for the title text	*/
#define XOFF 100
#define YOFF 30

#define SAND1MIN X_WINDOW/2-100
#define	SAND1MAX X_WINDOW/2
#define	WATER1MIN X_WINDOW/2
#define	WATER1MAX X_WINDOW/2+100
#define HOLE1MIN X_WINDOW - XOFF - 10
#define HOLE1MAX X_WINDOW - XOFF + 10
#define ROUGH1MIN HOLE1MIN-200
#define ROUGH1MAX HOLE1MIN-100
#define OB1MIN X_WINDOW -10
#define OB1MAX X_WINDOW

#define INCREMENT 5
#define POWERMAX 100
#define POWERMIN 5
#define ANGLEMAX 85
#define ANGLEMIN -85
#define BARGAP 10

int draw_ground(int x_ground, int y_head, int COLOUR);
void draw_stick_man(int x_head, int y_head, int COLOUR);
int move_stick_man(int x_head, int y_head, int COLOUR);

void titlescreen(XF,YF)
{
/*	Title Screen ASCII Art	*/
setbkcolor(BLACK);
outtextxy(XF+200,YF,"    _...._           ___     ___    _       _____");
outtextxy(XF+200,YF+10,"  .'.o' o.'.     2D / _ \\   / _ \\  | |     |  ___|");
outtextxy(XF+200,YF+20," /o o .o' o'\\      | / \\_\\ | / \\ | | |     | |___");
outtextxy(XF+200,YF+30,"|'.o 'o. o'.o|     | | __  | | | | | |     |  ___|");
outtextxy(XF+200,YF+40,"|o. o' o 'o .|     | ||_ | | | | | | |     | |");
outtextxy(XF+200,YF+50," \\ o .o.'o'./      | \\_/ | | \\_/ | | |___  | |");
outtextxy(XF+200,YF+60,"  '._o__o_.'        \\___/   \\___/  |_____| |_|");
outtextxy(XF+200,YF+70,"  ^^^^^^^^^^                             By Xi Jin");
outtextxy(XF+200,YF+120,"             Press any key to continue");

getch();

cleardevice();

outtextxy(XF,YF,"Please select a hole");
outtextxy(XF,YF+20,"Hole 1");
outtextxy(XF,YF+30,"Hole 2");
}

void draw_arrow(int x_arrow, int y_arrow, int COLOUR)
{

setcolor(COLOUR);
line(x_arrow,y_arrow,x_arrow+10,y_arrow+5);
line(x_arrow,y_arrow,x_arrow,y_arrow+10);
line(x_arrow,y_arrow+10,x_arrow+10,y_arrow+5);
}

int move_arrow(int x_arrow, int y_arrow, int COLOUR)
{

int key_pressed,new_y_arrow,line;

key_pressed=getch();
key_pressed=getch(); //arrows are extended keys so need two calls

new_y_arrow = y_arrow;
while (key_pressed!=RETURN)
{
draw_arrow(x_arrow, new_y_arrow, BLACK);

/* move arrow if arrow keys pressed */
if (((key_pressed==KEY_DOWN) || (key_pressed==KEY_RIGHT)) && (new_y_arrow <= y_arrow+10*(NUM_HOLES-2)))
{
new_y_arrow=new_y_arrow+10;
}
else if (((key_pressed==KEY_UP) || (key_pressed==KEY_LEFT)) && (new_y_arrow >= y_arrow+10))
{
new_y_arrow=new_y_arrow-10;
}
else new_y_arrow=new_y_arrow;

draw_arrow(x_arrow, new_y_arrow, COLOUR);

/* read keyboard again */
key_pressed=getch();
key_pressed=getch();

} /* end of while loop */

if (key_pressed==RETURN)
{
new_y_arrow=new_y_arrow;
line=new_y_arrow;
}
return line;
}

int plot_projectile(int x_head, int y_ground, int COLOUR, int power, int angle)
{

int x0,y0;
int x,y;
double vx, vy;
double t;

int v = power;
setcolor(COLOUR);
vx=v*cos(2*PI*angle/360);
vy=v*sin(2*PI*angle/360);

y0=y_ground;

x=x0;
moveto(x0,y0);
do
{
/* calculate how long it takes projectile to get from initial x position to new */
t = (x - x0) / vx;

/* calculate where y position of projectile is according to gravity */
y = (int)(y0 - (y * t) + (GRAVITY * t * t)/2);

if ( y <= y_ground) // y position is above ground so keep drawing
{

lineto(x,y); // draw little straight line between old projectile position and new
x = x++; // move projectile ordinate one pixel along
}
else
break;
}
while (x < X_WINDOW); // keep plotting until edge of window encountered

return x;
getch();
}

void draw_cursor1(int x_cursor,int COLOUR)
{
setcolor(COLOUR);

line(XOFF+x_cursor,Y_WINDOW-9,XOFF+x_cursor-5,Y_WINDOW-4);
line(XOFF+x_cursor,Y_WINDOW-9,XOFF+x_cursor+5,Y_WINDOW-4);
line(XOFF+x_cursor+5,Y_WINDOW-4,XOFF+x_cursor-5,Y_WINDOW-4);
}

int move_cursor1(int x_cursor)
{
int XF=XOFF,YF=YOFF;
int key_pressed1,new_x_cursor,angle;

key_pressed1=getch();
key_pressed1=getch(); //arrows are extended keys so need two calls

new_x_cursor = x_cursor;
while (key_pressed1!=RETURN)
{
draw_cursor1(new_x_cursor,BLACK);

/* move arrow if arrow keys pressed */
if ((key_pressed1==KEY_RIGHT) && (new_x_cursor < 360))
{
new_x_cursor=new_x_cursor+10;
}
else if ((key_pressed1==KEY_LEFT) && (0 < new_x_cursor))
{
new_x_cursor=new_x_cursor-10;
}
else new_x_cursor=new_x_cursor;

draw_cursor1(new_x_cursor,RED);

/* read keyboard again */
key_pressed1=getch();
key_pressed1=getch();

} /* end of while loop */

if (key_pressed1==RETURN)
{
angle=new_x_cursor/2 - 90;
}
return angle;
}

void draw_cursor2(int x_cursor2,int COLOUR)
{
setcolor(COLOUR);

line(XOFF+x_cursor2+360+BARGAP,Y_WINDOW-9,XOFF+x_cursor2+360+BARGAP-5,Y_WINDOW-4);
line(XOFF+x_cursor2+360+BARGAP,Y_WINDOW-9,XOFF+x_cursor2+360+BARGAP+5,Y_WINDOW-4);
line(XOFF+x_cursor2+360+BARGAP+5,Y_WINDOW-4,XOFF+x_cursor2+360+BARGAP-5,Y_WINDOW-4);
}

int move_cursor2(int x_cursor2)
{
int XF=XOFF,YF=YOFF;
int key_pressed2,new_x_cursor2,power;

key_pressed2=getch();
key_pressed2=getch(); //arrows are extended keys so need two calls

new_x_cursor2 = x_cursor2;
while (key_pressed2!=RETURN)
{
draw_cursor2(new_x_cursor2,BLACK);

/* move arrow if arrow keys pressed */
if ((key_pressed2==KEY_RIGHT) && (new_x_cursor2 < 400))
{
new_x_cursor2=new_x_cursor2+10;
}
else if ((key_pressed2==KEY_LEFT) && (0 < new_x_cursor2))
{
new_x_cursor2=new_x_cursor2-10;
}
else new_x_cursor2=new_x_cursor2;

draw_cursor2(new_x_cursor2,RED);

/* read keyboard again */
key_pressed2=getch();
key_pressed2=getch();

} /* end of while loop */

if (key_pressed2==RETURN)
{
power=new_x_cursor2/4;
}
return power;
}

void draw_hole1(int x_ground,int y_ground,int y_head)
{
setcolor(WHITE);
outtextxy(10,10,"Hole 1");
//ground
y_ground = draw_ground(x_ground, y_head, GREEN);
//sand
setcolor(YELLOW);
line(SAND1MIN,y_ground,SAND1MAX,y_ground);
//water
setcolor(BLUE);
line(WATER1MIN,y_ground,WATER1MAX,y_ground);
//rough
setcolor(BROWN);
line(ROUGH1MIN,y_ground,ROUGH1MAX,y_ground);
//ob
setcolor(RED);
line(OB1MIN,y_ground,OB1MAX,y_ground);
//hole
setcolor(BLACK);
line(HOLE1MIN,y_ground,HOLE1MAX,y_ground);
setcolor(WHITE);
line(HOLE1MIN+10,y_ground,HOLE1MIN+10,y_ground-100);
}

int angle_meter(int x_angle)
{
int angle;
int x_cursor = 180;
x_angle = XOFF +180;
setcolor(WHITE);
line(XOFF,Y_WINDOW-10,XOFF+360,Y_WINDOW-10);
outtextxy(XOFF,Y_WINDOW-25,"-90                 Angle                  90");
draw_cursor1(x_cursor,RED);
angle = move_cursor1(x_cursor);
return angle;
}

int power_meter(int x_power)
{
int power;
int x_cursor2 = 200;
x_power = XOFF +180;
setcolor(WHITE);
line(XOFF+360+BARGAP,Y_WINDOW-10,XOFF+360+BARGAP+400,Y_WINDOW-10);
outtextxy(XOFF+360+BARGAP,Y_WINDOW-25,"0                    Power                     100");
draw_cursor2(x_cursor2,RED);
power = move_cursor2(x_cursor2);
return power;

}

int draw_ground(int x_ground, int y_head, int COLOUR)
{
int y_ground;

setcolor(COLOUR);
line(x_ground,y_ground,X_WINDOW,y_ground);

return y_ground;
}

void draw_man(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* Draw right arm */

/* draw legs */

/* Draw left arm */

/* draw shaft */

/* draw club head */

}

void man1(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* Draw left arm */

/* Draw right arm */

/* draw legs */

/* draw shaft */

}

void man2(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* draw legs */

/* Draw left arm */

/* Draw right arm */

/* draw shaft */
}

void man3(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* draw legs */

/* Draw left arm */

/* Draw right arm */

/* draw shaft */
}

void man4(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* draw legs */

/* Draw left arm */

/* Draw right arm */

/* draw shaft */
}

void man4b(int x_head, int y_head, int COLOUR)
{
setcolor(COLOUR);

/* draw head */

/* Draw body */

/* draw legs */

/* Draw left arm */

/* Draw right arm */

/* draw shaft */
}

int hole_select(int new_y_arrow, int x_ground, int y_head)
{
int x_arrow=XOFF-15,y_arrow=YOFF+20;
int line_selected;

int shot;
int x_power;
int x_angle;

/* Hole 1 */
if (new_y_arrow == y_arrow)
{
int high1,high2;
int angle,power;
int y_ground;

high1 = 99;
high2 = 99;

for (shot = 0;  shot <= 2*PAR1; shot++)
{
cleardevice();
angle = angle_meter(x_angle);
power = power_meter(x_power);
if (angle < 0 )
{
getch();
}
else
{
getch();
}

cleardevice();
}
if (shot >= 2*PAR1)
{
cleardevice();
setcolor(WHITE);
outtextxy(10,10,"You have failed to achieve double par, your score is automatically double par.");
getch();
if (shot < high1) high1 = shot;
closegraph();
main();
}
else
{
cleardevice();
setcolor(WHITE);
outtextxy(10,10,"Well done");
getch();
if (shot < high1) { high1 = shot; }
closegraph();
main();
}
}

/* Hole 2 */
else if (new_y_arrow == y_arrow+10)
{
setcolor(WHITE);
cleardevice();
outtextxy(10,10,"Hole 2");
line_selected=2;
}

/* Error */
else
{
setcolor(WHITE);
cleardevice();
outtextxy(10,10,"Error");
line_selected=0;
}
return line_selected;
}

int main(void)
{
int x_arrow,y_arrow,line,x_ground,y_ground;

int high1 = 99, high2 = 99;

x_arrow=XOFF-15,y_arrow=YOFF+20;
x_ground = 0;

initwindow(X_WINDOW, Y_WINDOW);

titlescreen(XOFF,YOFF,high1,high2);
draw_arrow(x_arrow,y_arrow,RED);
line = move_arrow(x_arrow,y_arrow,RED);

/*
for (shot = 0;  shot < 2*PAR1; shot++)
{
printf("You are on shot number &#37;d\n",shot+1);
x_ground=0;

getch();
}
*/

return 0;
}```

2. Where did you get the ball's flight equation?

I'm wondering if the problem might be that the 'y' of the ball still in flight, is tested against the ground, to see if the 'y' value is less. (In plot projectile function.

It might be less in your window's row coordinates, but in the math, 'y' should be MORE positive than the ground.

You may need to do something like find y for the math, by taking the ground y value, and subtracting the current y value, from it. In other words, using the absolute difference between ground y and the ball's current calculated position.

3. Originally Posted by Adak
Where did you get the ball's flight equation?

I'm wondering if the problem might be that the 'y' of the ball still in flight, is tested against the ground, to see if the 'y' value is less. (In plot projectile function.

It might be less in your window's row coordinates, but in the math, 'y' should be MORE positive than the ground.

You may need to do something like find y for the math, by taking the ground y value, and subtracting the current y value, from it. In other words, using the absolute difference between ground y and the ball's current calculated position.
The equation is just based on uniform acceleration.

If using your approach, where z = y_ground - y
and then test if z >= 0

But that would be the same as testing if y <= y_ground (like I am doing)

I may have misunderstood what you are saying though.

4. Originally Posted by Lonners
The equation is just based on uniform acceleration.

If using your approach, where z = y_ground - y
and then test if z >= 0

But that would be the same as testing if y <= y_ground (like I am doing)

I may have misunderstood what you are saying though.
Here's what I meant:

Your window has y coordinates from top (1) to bottom(vertical rows of window). In your calculations though, you need to have y become greater, as it moves upward. Just the opposite of your window y (rows).

e.g.:

The ball is in flight, at yground + 10.
That should be equal to window y max - window y of ground, - 10.

I haven't run the program yet (I will later tonight), but I didn't see that conversion in your code. I might just have missed it?

I looked for it in this function:

Code:
```int plot_projectile(int x_head, int y_ground, int COLOUR, int power, int angle)
{

int x0,y0;
int x,y;
double vx, vy;
double t;

int v = power;
setcolor(COLOUR);
vx=v*cos(2*PI*angle/360);
vy=v*sin(2*PI*angle/360);

y0=y_ground;

x=x0;
moveto(x0,y0);
do
{
/* calculate how long it takes projectile to get from initial x position to new */
t = (x - x0) / vx;

/* calculate where y position of projectile is according to gravity */
y = (int)(y0 - (y * t) + (GRAVITY * t * t)/2);

if ( y <= y_ground) // y position is above ground so keep drawing
{

lineto(x,y); // draw little straight line between old projectile position and new
x = x++; // move projectile ordinate one pixel along
}
else
break;
}
while (x < X_WINDOW); // keep plotting until edge of window encountered

return x;
getch();
}```

5. Originally Posted by Adak
Here's what I meant:

Your window has y coordinates from top (1) to bottom(vertical rows of window). In your calculations though, you need to have y become greater, as it moves upward. Just the opposite of your window y (rows).

e.g.:

The ball is in flight, at yground + 10.
That should be equal to window y max - window y of ground, - 10.

I haven't run the program yet (I will later tonight), but I didn't see that conversion in your code. I might just have missed it?

I looked for it in this function:
In my program, the y of the projectile must be less than y_ground when in flight. Also, I think my y_ground is based on the distance from the top of the window. It isn't based on a relative position from the bottom of the window.

In future, I would suggest you adopt an approach which sees you compile and test as you go.

Writing several hundred lines of code, then dumping it all on a message board with "it doesn't work" is not a long term development strategy which is going to work.

I would suggest you begin with a systematic run through each function to find out whether each one works or not, and if not then set about fixing that function. If you're still stuck, you can post a single function (and a simple main() to test it), along with a more targeted question.

7. I don't have the "midi.h" file in my version of Turbo C, so I can't compile your golf program.

Can you upload that header file to Swoopshare or any other free file sharing websites? I'll need the url you get from Swoopshare , so I can d/l it.

Turn on your warnings, also. Many variables are never used.

8. As I said in the first post, the problem is when it is plotting a projectile. All the other functions work because I have tested them before using the plot_projectile function. What I suspect is that I may not be using the correct values of variables angle and power. I have included the other functions for this reason.

I have also tested the plot_projectile function in a separate program which uses scanf to input power and angle. This works fine.

The other variables that aren't used may be used when I adapt the program further.

Some of the other files that are used are here:
http://www.elec.york.ac.uk/intsys/us...aphics_lib.cpp
http://www.elec.york.ac.uk/intsys/us...graphics_lib.h
http://www.elec.york.ac.uk/intsys/users/jfm7/midi_lib.c
http://www.elec.york.ac.uk/intsys/users/jfm7/midi_lib.h

I don't think I used anything from the midi files.

9. OK, I got the program to run. (Although the display is goofed, but that's probably due to the laptop, since it goofs up a lot of programs graphic output).

In plot_projectile(), y_ground is 24,780, at the start of the function, which is clearly whacked.

x0 is then set to the value of y_ground, and used to calculate one or more parameters of the golf balls flight.

I would look into that variable first. The power was 50, or close to it. What is a good power range for the game?

10. Originally Posted by Adak
OK, I got the program to run. (Although the display is goofed, but that's probably due to the laptop, since it goofs up a lot of programs graphic output).

In plot_projectile(), y_ground is 24,780, at the start of the function, which is clearly whacked.

x0 is then set to the value of y_ground, and used to calculate one or more parameters of the golf balls flight.

I would look into that variable first. The power was 50, or close to it. What is a good power range for the game?
Hmm thanks for pointing that out. I'll have to look into that.

The power is supposed to range from 0 to 100 for now. Depending on whether these values are too large or too small, I will multiply it by a factor. I may also change the minimum to 5 instead of 0.

Popular pages Recent additions