• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
P0jahn

Get a points coordinate

15 posts in this topic

Look at these three pictures:

[attachment=12966:example1.png]

[attachment=12967:example2.png]

[attachment=12968:example3.png]

 

So the red object is some sort of watcher. It watches the green object. However, I do not want the coordinates of the green object, but the black circle. Is there any way to calculate this? 

 

Some more info about my game, the top left corner is point 0,0, x increases while moving to the right and y is increasing when moving down, just like any other java coordinate system. The black circle is always going to be at the edge of the map.

0

Share this post


Link to post
Share on other sites

So you want the direction to the green object from the red object?

 

direction = normalize(greenPos - redPos)

 

Then you can multiply the direction by the distance from the red object to the black circle. So if you wanted the black circle to appear 10 units away from the red object you would write:


blackCirclePos = direction * 10

 

 

 

Does that answer your question or have I misunderstood?

1

Share this post


Link to post
Share on other sites

Well, I am afraid he doesn't know the distance to the black circle a priori. The black circle is wherever the ray intersects the edge of the map.

 

Consider a structure called a "ray" that contains the position of the red dot (the ray's "origin") and the direction (as defined in Nyssa's post). You can find a point along the ray as ray.origin + t*ray.direction. I would write a function that finds the intersection of a ray with a line, and returns the value of the parameter t where the intersection happens (use the dot product for this). Then call it four times for the edges of the map and pick the lowest non-negative value of the parameter. That should give you the position of the black dot.

 

I may post some easy-to-read C++ code to solve this later.

Edited by Álvaro
1

Share this post


Link to post
Share on other sites
The black circle is always going to be at the edge of the map.

 

Ah, right, missed that bit. Thanks for clearing that up Alvaro.

0

Share this post


Link to post
Share on other sites
Here's some C++ code to solve the problem. I tried to not use references or static variables, to not confuse matters. But I couldn't get myself to not overload a few operators... Let me know if you have a hard time understanding what it's doing. But the function find_black_dot() is the key to it all, and it should be fairly easy to follow.
 
#include <iostream>
#include <cmath>
struct Vector {
  float x, y;
 
  Vector(float x, float y) : x(x), y(y) {
  }
};

Vector operator*(Vector v, float s) {
  return Vector(v.x*s, v.y*s);
}

float dot_product(Vector v, Vector w) {
  return v.x*w.x + v.y*w.y;
}

Vector normalize(Vector v) {
  return v * (1.0 / std::sqrt(dot_product(v, v)));
}

struct Point {
  float x, y;
 
  Point(float x, float y) : x(x), y(y) {
  }
};

std::ostream &operator<<(std::ostream &os, Point p) {
  return os << '(' << p.x << ',' << p.y << ')';
}

Vector operator-(Point p, Point q) {
  return Vector(p.x-q.x, p.y-q.y);
}

Point operator+(Point p, Vector v) {
  return Point(p.x+v.x, p.y+v.y);
}

struct Ray {
  Point origin;
  Vector direction;
 
  Ray(Point origin, Vector direction) : origin(origin), direction(direction) {
  }
};

// If dot_product(p-origin,normal)==constant, p is in the line
struct Line {
  Vector normal;
  float constant;
  
  Line(Vector normal, float constant) : normal(normal), constant(constant) {
  }
};

float find_intersection_parameter(Ray ray, Line line) {
  return (line.constant - dot_product(ray.origin-Point(0.0f,0.0f), line.normal))
    / dot_product(ray.direction, line.normal);
}

Point find_black_dot(Point red_point, Point green_point) {
  Line lines[4] = {
    Line(Vector(1.0f,0.0f), 0.0f),
    Line(Vector(1.0f,0.0f), 30.0f),
    Line(Vector(0.0f,1.0f), 0.0f),
    Line(Vector(0.0f,1.0f), 20.0f)
  };
 
  Ray ray(red_point, normalize(green_point-red_point));
  double min_non_negative_intersection_parameter = 1.0e20f;
  for (int i=0; i<4; ++i) {
    float intersection_parameter = find_intersection_parameter(ray, lines[i]);
    if (intersection_parameter >= 0.0f
        && intersection_parameter < min_non_negative_intersection_parameter)
      min_non_negative_intersection_parameter = intersection_parameter;
  }
 
  return ray.origin + ray.direction * min_non_negative_intersection_parameter;
}

int main() {
  Point red(16.5,10.5);
  Point green(11.5,15.5);
 
  std::cout << find_black_dot(red, green) << '\n';
}
Edited by Álvaro
0

Share this post


Link to post
Share on other sites

I would use the Pythagorean theorem and slope, however I'm just now getting into linear algebra tongue.png.

0

Share this post


Link to post
Share on other sites
You don't really need the Pythagorean theorem for this, and the method I proposed is also kind of overkill.

This is much simpler code that does the same thing. I should probably posted this solution before:
#include <iostream>

struct Point {
  float x, y;

  Point(float x, float y) : x(x), y(y) {
  }
};

Point find_black_dot(Point red_point, Point green_point) {
  float vertical_intersection_time = 1.0e20f;
  if (green_point.x > red_point.x)
    vertical_intersection_time = (30.0f-red_point.x)/(green_point.x-red_point.x);
  else if (green_point.x < red_point.x)
    vertical_intersection_time = (0.0f-red_point.x)/(green_point.x-red_point.x);

  float horizontal_intersection_time = 1.0e20f;
  if (green_point.y > red_point.y)
    horizontal_intersection_time = (20.0f-red_point.y)/(green_point.y-red_point.y);
  else if (green_point.y < red_point.y)
    horizontal_intersection_time = (0.0f-red_point.y)/(green_point.y-red_point.y);

  float time = std::min(horizontal_intersection_time,vertical_intersection_time);
  return Point(red_point.x + time * (green_point.x-red_point.x), red_point.y + time * (green_point.y-red_point.y));
}

int main() {
  Point red(16.5,10.5);
  Point green(11.5,15.5);

  Point black = find_black_dot(red, green);
  std::cout << '(' << black.x << ',' << black.y << ")\n";
}
1

Share this post


Link to post
Share on other sites
Thanks Alvaro. May I ask what type of data the returned point actually contains? If it is the black circle as you described, how can it find it without knowing the dimension of the map?
Also, can you suggest some sort of professional name for this method? :) Edited by P0jahn
0

Share this post


Link to post
Share on other sites

I didn't understand what you did the second time there (I need to copy it into SciTE and look at it more closely), but this is what I came up with (just because I like messing with this kind of problem).

 

struct Vector2 {
  int x;
  int y;
};

Vector2 findTargetAlignedBoundaryIntersection(Vector2 obsever, Vector2 target) {
  Vector2 targetDelta = { //vector to the target from the obserer
    target.x - observer.x,
    target.y - observer.y
  };
  
  //position of the relevant boundaries (will also be abused as a retval later)
  //start by assuming max bounds (lower right)...
  Vector2 boundary = {
    X_MAXIMUM_BOUND,
    Y_MAXIMUM_BOUND
  };
  //and then correct by axis when wrong
  if(targetDelta.x < 0) {boundary.x = X_MINIMUM_BOUND;}
  if(targetDelta.y < 0) {boundary.y = Y_MINIMUM_BOUND;}
  
  //vector from observer to relevant map corner
  Vector2 boundaryDelta = {
    boundary.x - observer.x,
    boundary.y - observer.y
  };
  
  //find ratio of boundary vs target deltas per-axis
  //(Edit - corrected against div-by-zero)
  //(Note - behavior is undefined if observer and target are equal)
  float xRatio = std::numeric_limits<float>::max();
  if(targetDelta.x) {xRatio = (float)(boundaryDelta.x) / targetDelta.x;}
  float yRatio = std::numeric_limits<float>::max();
  if(targetDelta.y) {yRatio = (float)(boundaryDelta.y) / targetDelta.y;}
  
  if(xRatio > yRatio) { //slope collides with y bound first
    boundary.x = observer.x + (targetDelta.x * yRatio);
  }
  else { //slope collides with x bound first
    boundary.y = observer.y + (targetDelta.y * xRatio);
  }
  
  return boundary;
}

 

Edit - Ah, I see. Same solution. Cool.

 

@P0jahn - He's just using 30.0f and 20.0f as map bounds there. You'd have to fill in the actual bounds where he uses the constants.

Edited by Khatharr
0

Share this post


Link to post
Share on other sites

I guess 30.0f is the width and 20.0f is the height? So what is vertical_intersection_time and horizontal_intersection_time?

And as I am not a C++er, I guess std::min is Math.min in java?

0

Share this post


Link to post
Share on other sites

Yes, 30.0 is the width and 20.0 is the height (as in the examples in the first post). I think of the ray as being a particle starting at the red point, moving at constant velocity so that at time 1 it is at the green point. I use vertical_intersection_time and horizontal_intersection_time to see when that particle would hit the edges of the map. Whichever one happens first is where the black dot will be.

 

std::min does what you expect: Return the minimum of two values. I don't know how you say that in Java.

0

Share this post


Link to post
Share on other sites

Hmmmm. I did not get it to work for some reason.

Watch the result:

[attachment=12972:error.png]

 

The position is wrong as well.

 

The code:

public static Point findEdgePoint(GameObject observer, GameObject target) //TODO:
{
 float vertical_intersection_time = 1.0e20f;


 if (target.posX > observer.posX) vertical_intersection_time = (observer.stage.width-observer.posX)/(target.posX-observer.posX);
 else if (target.posX < observer.posX) vertical_intersection_time = (0.0f-observer.posX)/(target.posX-observer.posX);


 float horizontal_intersection_time = 1.0e20f;


 if (target.posY > observer.posY) horizontal_intersection_time = (observer.stage.height-observer.posY)/(target.posY-observer.posY);
 else if (target.posY < observer.posY) horizontal_intersection_time = (0.0f-observer.posY)/(target.posY-observer.posY);


 float time = Math.min(horizontal_intersection_time, vertical_intersection_time);


 return new Point((int)(observer.posY + time * (target.posY-observer.posY)), (int)(observer.posY + time * (target.posY-observer.posY)));
}

Where did it go wrong?

0

Share this post


Link to post
Share on other sites

Whoa, I just realized we've got some div-by-zero time-bombs hangin' out in here. Better factor those out.

 

Meanwhile, look closely at the args you've passed to 'new Point()'.

Edited by Khatharr
0

Share this post


Link to post
Share on other sites

Ops, my bad. Fixed it. Works perfect now, almost...

There seems to be some inconsistency  when the black circle is at the bottom. The circle is not at the bottom-most position, instead, it is about 40 pixels above it.

The problem is probably because the provided method use float as coordinates while my game only use ints as coordinates.

Is there a way around this?

0

Share this post


Link to post
Share on other sites
Ops, my bad. Fixed it. Works perfect now, almost...
There seems to be some inconsistency  when the black circle is at the bottom. The circle is not at the bottom-most position, instead, it is about 40 pixels above it.
The problem is probably because the provided method use float as coordinates while my game only use ints as coordinates.
Is there a way around this?

That doesn't sound like a int-vs-float problem at all. Pick a particular example where the code does the wrong thing and follow it step by step, using a debugger. You should be able to see at what point the computation departs from what you expect.
0

Share this post


Link to post
Share on other sites

I fixed it somehow. I think that it... Actually I have no idea how I fixed it. But the problem is solved, big thanks to all the help.

I am going to test this ingame, as see how it works. I will report back if there is anything that do not work well.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0