moving my character to where the user left-clicks...
red-dragon

hey guys,
thanks for ALL the help. after I figure out what was wrong, I say to myself 'Oh that was it, eh?' Figuring out little things is really fun, but uh, heh, I need some help again.

Now, I will attach the code here so you can see the functions. I appologize because it is not commented or clean yet, but it's simple enough that I think most of you will have no problem figuring out what's going on.

So, as it stands, what I have in main loop towards end of the program: keyboard input works, character walks up, down, left, right, and northeast (I haven't programmed in se, sw, nw yet). However, the left-click doesn't work. I mean, I don't see the sprite move at all when user left-clicks. I call all the functions that I would if the user was using the keyboard.

When user left-clicks on screen northeast of character, the character should walk upto where the click took place. That is the goal. Can you guys tell me where my logic is wrong? I think I've just stared at the code too long tonight and hopefully the mistake is fairly obvious. I'll put in while loop here:

1while(!key[KEY_ESC])
2 {
3 if(mouse_b & 1)
4 {
5 flag = 1;
6 textout(screen, font, "Left mouse button was pressed", 60, 60, WHITE);
7 int mx, my;
8 mx = mouse_x;
9 my = mouse_y;
10 calculate_position(mx, my);
11 int x1, y1;
12 mario->dir = xdir;
13 for(x1 = 0; x1<xnew; x1++)
14 {
15 erasesprite(screen, mario);
16 updatesprite(mario);
17 move_character();
18 acquire_screen();
19 draw_character_mario();
20 release_screen();
21 }
22 mario->dir = ydir;
23 for(y1 = 0; y1<ynew; y1++)
24 {
25 erasesprite(screen, mario);
26 updatesprite(mario);
27 move_character();
28 acquire_screen();
29 draw_character_mario(); //fix this;
30 release_screen();
31 }
32
33
34
35 }
36
37
38 //check for keypresses
39 else if (keypressed())
40 { getinput();
41
42 //erase the sprite
43 erasesprite(screen, mario);
44 updatesprite(mario);
45
46 //move mario character
47 move_character();
48 mario->dir = 0;
49 
50 acquire_screen();
51 draw_character_mario(); //fix this;
52 
53 release_screen();
54 }


calculate_position will simply see if x is positive/negative and same for y. Below, if x is positive and y is negative, then the character should walk north, then east. So if you go back to while loop, my intent is for character to walk right on x scale, then go up on y scale.

This is what calculate position looks like:

void calculate_position(int x, int y)
{
     if((x==abs(x)) && (y!=abs(y)))
     {
          xdir = 3;
          ydir = 2;
          
          xnew = x - mario->x;
          ynew = y - mario->y;
     }      
}

here is
main.c

TIA.

p.s. I realize I refer to link as mario in the code, I'll be changing that soon 'nuff ;)

EDIT: c'mon guys, I desperately need help to get started with this part. If you need to ask ?s, do so... I know you guys have worked with mouse input ;)

razor
in function said:

xdir = 3;

main source said:

xdir = 3

First off do you have a lot of global variables or something?
Now...

function said:

if((x==abs(x)) && (y!=abs(y)))

What are you trying to do here? you are passing mouse_x as x and mouse_y as y... those will never be negative as far as I know (mouse positions represent the pixel position of the mouse on the screen).

brigham toskin

First, I have to say, this is kinda an inefficient way of handling your update loop. Every time you get input and update mario's position, you drop everything and draw it to the screen. Not only can this lead to choppy logic or animation, but if you ever change the way that you render to the screen, now you've got 3 places you have to rewrite all that code. It would be better to get your input and update mario's position, and then at the end draw to the screen whatever his revised position is. Better still would be putting logic on a timer to ensure consisten speed, but for this simple example that's probably not important yet.

Second, saying (x == abs(x)) is the same as saying (!(X < 0)). abs() will always return a positive version of the value fed in, so basically you're just asking to make sure it's not negative in the first place. Seems a little more straghtforward that way. Same goes for the other test, just in reverse.

And third, from what I can see here, you're only updating mario's position once when it is clicked? At most he would move one step in the direction of the coords clicked. What you would have to do is move the declarations for mx and my outside of the if(mouse_B) statement so you can store them for later reference. After the code inside the if collects the mouse coords, you have a function or code block that moves mario one step toward that point at your desired speed every iteration through the loop. THEN, at the very end of the loop, you redraw the screen with Mario in his new updated position.

EDIT:
Also, Razor is right. Your calc position function will NEVER actually execute in response to a mouse click because the Y coord of the mouse can't ever be negative. I think maybe what you're meaning to do is pass in (my - mario->y) or some such thing to get the position of the mouseclick relative to mario's current position?

red-dragon

razor, brigham, you both bring up good points. you're right, the mouse coord will never be negative. It was late at night, and I was thinking of a regular x, y coordinate system ::) Let me make a few changes and get back to your other comments.

p.s. I'm changing that abs line crap to:
else if((x > mario->x) && (y < mario->y)), where x and y are mouse x, y coordinates.

EDIT:
Okay guys, thanks for your help. As I stated, this is what calculate_position function looks like:

 void calculate_position(int x, int y)
{
....
..
.
else if((x > mario->x) && (y < mario->y))//(x==abs(x)) && (y!=abs(y)))
     {
          flag = 1;
          xdir = 3;
          ydir = 2;
          
          xnew = x - mario->x;
          ynew = mario->y - y;
     }

While loop still looks the same as I originally posted. I've put in a flag and have tried to print out xnew and ynew in main.. It seems that within calculate_position, the statement ((x > mario->x) && (y < mario->y)) never hits true.

The idea behind the statement is this: x and y are the mouse-clicked x, y values. So, if x > mario->x, then x has to move to the right. And if y < mario->y, then we have to go up. Am I wrong here again...?

In main, xnew and ynew have no values... I try to print them after the for loops have executed. They are global variables, so after calculated_position gets executed, these values shouldn't change, right?

SO, why isn't that else if statement turning out to be true? I'm trying to figure it out , but ANY help is always apprecited. TIA. ;)

brigham toskin

I can't say for sure without seeing what all is going on, but keep in mind that an else if will NEVER EVEN BE EVALUATED if an if before it is true.

Try setting a breakpoint at the start of calculate_position() and see where it goes and why, when you click to the northeast.

Johan Halmén

I prefer to put a return inside the braces instead of an else if after the closing brace. It looks nicer.

You said:

They are global variables, so after calculated_position gets executed, these values shouldn't change, right?

What do you mean by that? They do change incalculated_position and will have the changed values after that in the main() scope or in any scope.

You said:

In main, xnew and ynew have no values...

???

Shouldn't ydir be set to -2 and not 2?

red-dragon

Johan,
I still have to clean up the code. As for ydir being -2 or 2, I guess I should've used something more intuitive for directions like you've just stated. Here's what it does in my code:
left = 1;
up = 2;
right = 3;
down = 4;
northeast = 5;
southeast = 6;
southwest = 7;
northwest = 8;

Sorry for the confusion.

Thread #588059. Printed from Allegro.cc