ID:153819
 
Is it possible to make it so your character faces where your mouse cursor moves? That is, make it face where your cursor is without having to use the Click procedure.


<<>>Kusanagi<<>>
Kusanagi wrote:
Is it possible to make it so your character faces where your mouse cursor moves? That is, make it face where your cursor is without having to use the Click procedure.

It's not all that hard to do, but it isn't that great for turning, as I tried it out once during the development period of Bizlof War. Mainly because the delay in the detection of the movements of the mouse aren't fast enough for my likings. ;)

turf/MouseEntered()
..()
usr.dir = get_dir(usr,src)
In response to Malver
Hmm, thank you very much, :). I prefer having the character face the mouse because it's much easier for shooting games, as is the reason why you wanted to use it for Bizlof of War is my guess. It's alright if it's slow for me though, mine doesn't take place in the future and has to have some combat restrictions.[Edit]Hmm, I noticed that the closer the cursor is to the character when you use mouse turning, the faster the mob turns. The further away the cursor is while trying to turn, the longer it takes them to turn... that is strange.



<<>>Kusanagi<<>>
In response to Kusanagi
That's because get_dir() isn't exactly what you want. The 8 areas for the directions:
<code> NWNW N NENE NWNW N NENE NWNW N NENE WWWW O EEEE SWSW S SESE SWSW S SESE SWSW S SESE </code>
Basically, anything that isn't in the 4 cardinal directions will be a diagnol. You want to probably write your own proc to find a more accurate direction for your purposes.
In response to Garthor
I already have a snippet for this purpose:

//Credit to: Spuzzum
//Contributed by: Spuzzum

//This snippet was created to give better approximations
// than those of the original get_dir proc (provided by
// BYOND). This is because BYOND's get_dir works in
// a special way:
/*
9 9 9 9 9 1 5 5 5 5 5

9 9 9 9 9 1 5 5 5 5 5

9 9 9 9 9 1 5 5 5 5 5

9 9 9 9 9 1 5 5 5 5 5

9 9 9 9 9 1 5 5 5 5 5

8 8 8 8 8 X 4 4 4 4 4

10 10 10 10 10 2 6 6 6 6 6

10 10 10 10 10 2 6 6 6 6 6

10 10 10 10 10 2 6 6 6 6 6

10 10 10 10 10 2 6 6 6 6 6

10 10 10 10 10 2 6 6 6 6 6


Directions:
1 = NORTH, 2 = SOUTH, 4 = EAST, 8 = WEST, 5 = NORTHEAST,
6 = SOUTHEAST, 9 = NORTHWEST, 10 = SOUTHWEST, X = SOUTH (centre)
*/


//Notice how directions immediately to the NORTH, EAST,
// SOUTH, and WEST of the source are reported as such.
// However, even if you're one micrometre off of the
// vertical or horizontal, it will represent it instead
// as a diagonal direction: NORTHEAST, SOUTHEAST, NORTHWEST,
// or SOUTHWEST.

//This snippet returns a different result:
/*
9 9 9 1 1 1 1 1 5 5 5

9 9 9 9 1 1 1 5 5 5 5

9 9 9 9 1 1 1 5 5 5 5

8 9 9 9 9 1 5 5 5 5 4

8 8 8 9 9 1 5 5 4 4 4

8 8 8 8 8 0 4 4 4 4 4

8 8 8 10 10 2 6 6 4 4 4

8 10 10 10 10 2 6 6 6 6 4

10 10 10 10 2 2 2 6 6 6 6

10 10 10 10 2 2 2 6 6 6 6

10 10 10 2 2 2 2 2 6 6 6
*/

//Notice how all of the directions are constrained
// to more realistic angles. This makes
// guessing directions more accurate.
//Note well that get_dir() in its original form has
// many uses -- in fact, this snippet alone depends
// on it. In no case should you ever think that this
// snippet is more useful than the primary form --
// both have their niches to fill.

proc/get_precise_dir(atom/Loc1, atom/Loc2)
var/dir = get_dir(Loc1, Loc2)
switch(dir)
if(NORTH, EAST, SOUTH, WEST)
return dir

if(NORTHEAST, SOUTHWEST)
var/abs_x = abs(Loc2.x - Loc1.x)
var/abs_y = abs(Loc2.y - Loc1.y)

if(abs_y > (2*abs_x))
return turn(dir,45)
else if(abs_x > (2*abs_y))
return turn(dir,-45)
else
return dir

if(NORTHWEST, SOUTHEAST)
var/abs_x = abs(Loc2.x - Loc1.x)
var/abs_y = abs(Loc2.y - Loc1.y)

if(abs_y > (2*abs_x))
return turn(dir,-45)
else if(abs_x > (2*abs_y))
return turn(dir,45)
else
return dir
In response to Spuzzum
I think I can improve on that snippet quite a bit. It has a few optimization prolems, notably the reliance on switch(), 2*n, and turn().

The switch can be taken out because diagonal directions are easy to spot: As long as 2 bits are set in the number, you have a diagonal. My test for this is n&n-1 (which is n&(n-1) since - has a higher precedence); in n-1, the lowest bit of n is switched off and all bits to its right (if any) are switched on, then the binary and will cancel out that lowest bit, leaving any that remain.

2*n is almost certainly less efficient than n+n or n<<1, even in floating point.

The turn() is unnecessary because all you need to know is if the north/south component of the diagonal should be dropped, or if the east/west should be dropped, or neither. This again would be accomplished via bit masking.
proc/get_precise_dir(atom/ref,atom/target)
var/d=get_dir(ref,target)
if(d&d-1) // diagonal
var/ax=abs(ref.x-target.x)
var/ay=abs(ref.y-target.y)
if(ax>=(ay<<1)) return d&12 // keep east/west (4 and 8)
else if(ay>=(ax<<1)) return d&3 // keep north/south (1 and 2)
return d
This snippet is now so tight that it could probably be fit into a 4K project with relative ease.

[EDIT 6/26/03: You need to put parentheses around ay<<1 and ax<<1 for those parts to work right.]

Lummox JR
In response to Lummox JR
Heh... Lummox, I wish I could optimize code like you. :-)
In response to Crispy
Crispy wrote:
Heh... Lummox, I wish I could optimize code like you. :-)

Well, if you ever need a hand, you know where to send the dimes (by hundreds). ;)

Lummox JR
In response to Spuzzum
get_precise_dir()? Wouldnt the precise direction be what the original get_dir()? Wouldnt this be a get_rough_dir()?
Anyway, just wondering.
-DogMan
In response to Dog Man
Dog Man wrote:
get_precise_dir()? Wouldnt the precise direction be what the original get_dir()? Wouldnt this be a get_rough_dir()?
Anyway, just wondering.

I was thinking the same thing. But it's not my place to go renaming his procs like that--just to show him up with better code. :)

Lummox JR
In response to Lummox JR
Lummox JR wrote:
This snippet is now so tight that it could probably be fit into a 4K project with relative ease.

Talking about 4K projects, I can see a use for this in Stickster. :-)
In response to Crispy
Crispy wrote:
Lummox JR wrote:
This snippet is now so tight that it could probably be fit into a 4K project with relative ease.

Talking about 4K projects, I can see a use for this in Stickster. :-)

It'd be less useful than you might think. If it was put in for targeting the Stickster it'd miss most of the time because if the Stickster isn't exactly in one of the 8 directions he's gonna come in along a diagonal until he's directly in line. And it couldn't be used for the Stickster's movement because this routine can't be used with get_step_to().

Lummox JR
In response to Lummox JR
I meant in the statpanel where it says "Stickster is 20 spaces NE of you", or whatever. Now that I think about it, though, it would be less useful because it's always good to know if you're on a direct line with it. Maybe you could have "north" and "due north" as different directions? (Due north would be, of course, directly north, while north would be either NE or NW but close to due north.)
In response to Crispy
Crispy wrote:
I meant in the statpanel where it says "Stickster is 20 spaces NE of you", or whatever. Now that I think about it, though, it would be less useful because it's always good to know if you're on a direct line with it. Maybe you could have "north" and "due north" as different directions? (Due north would be, of course, directly north, while north would be either NE or NW but close to due north.)

Ah, now I see what you mean. It's been so long since I was working on that particular aspect of the game that I forgot.

Yeah, I actually did want a better way of gauging direction. Ultimately it would've taken around 100 bytes any way I did it; I'm wondering now if I could squinch that down to 80 or 90, but it could go no further.

Lummox JR
In response to Lummox JR
Just release Scream of the "Stickster 2: Return of the Stickster". Fill it up with all sorts of fun features, like traps, multiple Sticksters, improved compass, more weapons, ect.
Although Id wait until after SOTS gets a little boring before I went and did that, no use in making a fun game obsolete.
-DogMan
In response to Dog Man
Would you consider a skewing of 1 to the east and 100 to the north to be considered precise if it is represented as NORTHEAST? =P
In response to Lummox JR
Well, seeing as how I'm not a mathematical/logical prodigy, my method works fine as far as human beings go. =P
In response to Spuzzum
Spuzzum wrote:
Well, seeing as how I'm not a mathematical/logical prodigy, my method works fine as far as human beings go. =P

Except that human beings aren't designed to use the metric system... oh, wait, that doesn't matter here. But what the heck. The method has to have something wrong with it. :)

(For newbies who don't have any context: Spuzz is a very clever guy. I just like to give him a hard time.)
In response to Gughunter
Gughunter wrote:
Except that human beings aren't designed to use the metric system...

Human beings are. I don't know about the average US citizen though. *ducks for cover*
In response to Lummox JR
Lummox JR wrote:
The switch can be taken out because diagonal directions are easy to spot: As long as 2 bits are set in the number, you have a diagonal. My test for this is n&n-1 (which is n&(n-1) since - has a higher precedence); in n-1, the lowest bit of n is switched off and all bits to its right (if any) are switched on, then the binary and will cancel out that lowest bit, leaving any that remain.

if(d&d-1) // diagonal

Beautiful! I used a messy "if(dir in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))" to detect a diagonal, cursing myself and knowing there had to be a better way. If you'll excuse me, I have a few libraries to update. :)
Page: 1 2