In Java using the acm.graphics GPen is there any way to move the entire drawn sequence of lines? I've read the manual thoroughly and I'm beginning to think it's not possible which brings me to my second question. Are there any other graphics objects in Java that work very similar to a pen that can also be moved. The reason I'm asking is because I've been working on a graphing program that allows mouse gestures to be used to pan around and zoom in and out. After building functionality for implicit functions I realized simply clearing the drawing board and redrawing everything is not going to cut it anymore so I really need to work on more efficient ways to handle intermediate changes of the graph without having to recalculate everything. For example with this or similar code:
GPen p = new GPen();
p.setLocation(100,100); //places the pen on the canvas at 100, 100
p.drawLine(-50,0); //draw a line left 50 pixels
p.drawLine(50,-50); //draw a line right and up 50 pixels each
p.drawLine(0,50); //draw a line down 50 pixels
This would result in a simple right triangle who's bottom right most point is at 100, 100 on a particular canvas. What I need to do is be able to move this same drawn sequence of lines relative to one another to another origin. What I hoping for is a class that has separate methods for setLocation() and move() where setLocation() controls pen position and move() would move the entire object around.
Ok so having received almost no attention on here I've came to the conclusion that such a method just needs to be written from scratch and went ahead and did that. I'm not entirely sure how helpful posting my proprietary code would be but in the event that anybody could use it I'll post the basic idea of it. Since Pen utilities are essentially a bunch of lines and lines are a bunch of from and to's I created an object that I called FPen (for FunctionPen) that accepts the instructions for from and to. While defining FPen you pass it where to start and how far to go however many times you need and that's it. Once you've passed these instructions I created another method called returnGPen(Color c) which will on call use the instructions it has on hand and generate the desired GPen object. When you want to move the entire GPen you can then create a method called adjustOrigin(double oX, double oY); which will calculate a change from a previously recorded origin and this new one and go through the list of instructions and adjust them appropriately.
My needs for this Class are strictly for my Graphing program and are not entirely finished either but it does work for most purposes.
import acm.graphics.GPen;
import java.awt.Color;
import java.util.ArrayList;
public class FPen{
private double relativeCenterX;
private double relativeCenterY;
private ArrayList<Double> fromX = new ArrayList<Double>();
private ArrayList<Double> fromY = new ArrayList<Double>();
private ArrayList<Double> distX = new ArrayList<Double>();
private ArrayList<Double> distY = new ArrayList<Double>();
public FPen(double rX, double rY, double z){
relativeCenterX = rX;
relativeCenterY = rY;
}
public void adjustOrigin(double cX, double cY){
double changeX = relativeCenterX-cX;
double changeY = relativeCenterY-cY;
for(int i = 0; i < fromX.size(); i++){
fromX.set(i,fromX.get(i)+changeX*zoom);
fromY.set(i,fromY.get(i)-changeY*zoom);
}
relativeCenterX = cX;
relativeCenterY = cY;
}
public void clear(){
fromX.clear();
fromY.clear();
distX.clear();
distY.clear();
}
public void drawLine(double fX, double fY, double tX, double tY){
fromX.add(fX);
fromY.add(fY);
distX.add(tX);
distY.add(tY);
}
public GPen returnGPen(Color c){
GPen pen = new GPen();
pen.setColor(c);
for(int i = 0; i < fromX.size(); i++){
pen.setLocation(fromX.get(i),fromY.get(i));
pen.drawLine(distX.get(i),distY.get(i));
}
return pen;
}
}
Of course a unexpected nice thing that came out of this was the idea that I can now quickly benchmark different drawing routines by creating different methods for each and calling what I'm interested in.
Related
I have a problem with the correct vector alignment. I want to get a vector pointing in the same direction as the player, but with a constant Y value of 0. The point is, whatever the player's vertical and horizontal rotation, the vector's Y value was 0. The vector is always supposed to point horizontally (value 0), but keeping the direction of the player's rotation.
This picture shows the situation from the side. The red line represents an example of the player's viewing direction (up - down), and the green one the effect I want to achieve. Regardless of the direction in which the player is looking, up or down, the green line remains unchanged:
Here, in turn, I have presented this situation from the top. The red line is the player's viewing direction (left - right) and the green is the effect I want to achieve. As you can see, the player's rotation on this axis sets my vector exactly the same.
I was able to write a piece of code, but it doesn't behave correctly: the Y axis gets higher and higher as the player turns up or down. I don't know why:
Vector playerDirection = player.getLocation().getDirection();
Vector vector = new Vector(playerDirection.getX(), 0, playerDirection.getZ()).normalize().multiply(3);
How to do it correctly?
tl;dr:
Vector vector = new Vector(-1 * Math.sin(Math.toRadians(player.getLocation().getYaw())), 0, Math.cos(Math.toRadians(player.getLocation().getYaw())));
You are missing a fundamental principal of creating a new Vector based on where a player is looking. I don't know the math of it very well, but I can mess around with the math of people who are better than I at Geometry.
As such, let's try to reduce the number of Vector variables you have defined. Taking a quick peek at the source for Location, we can actually create your Vector directly to avoid having multiple defined.
public Vector getDirection() {
Vector vector = new Vector();
double rotX = this.getYaw();
double rotY = this.getPitch();
vector.setY(-Math.sin(Math.toRadians(rotY)));
double xz = Math.cos(Math.toRadians(rotY));
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
}
As you can see, the pitch and yaw of a player are not a 1:1 relationship. No idea why, but let's repurpose their logic.
Here's how we'll do that:
public Vector getVectorForAdixe(Location playerLoc) {
Vector vector = new Vector();
double rotX = playerLoc.getYaw();
double rotY = 0; // this is the important change from above
// Original Code:
// vector.setY(-Math.sin(Math.toRadians(rotY)));
// Always resolves to 0, so just do that
vector.setY(0);
// Original Code:
// double xz = Math.cos(Math.toRadians(rotY));
// Always resolves to 1, so just do that
double xz = 1;
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
Nice! Now, cleaning it up a bit to remove those comments and unnecessary variables:
public Vector getVectorForAdixe(Location playerLoc) {
Vector vector = new Vector();
double rotX = playerLoc.getYaw();
vector.setY(0);
vector.setX(-1 * Math.sin(Math.toRadians(rotX)));
vector.setZ(Math.cos(Math.toRadians(rotX)));
return vector;
Why does this math work like that? No idea! But this should almost certainly work for you. Could even inline it if you really wanted to keep it how you had it originally:
Vector vector = new Vector(-1 * Math.sin(Math.toRadians(player.getLocation().getYaw())), 0, Math.cos(Math.toRadians(player.getLocation().getYaw())));
Closing note, if you want to be able to get the pitch/yaw FROM the vector, that code is here: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Location.java#310
I am currently working on a 2d game in which a player sprite pushes other sprites around on the screen.
My current code (within subclass):
//x and y being the co-ords i want this object to move to (e.g 50 pixels
right of its starting point etc.)
public Boolean move(float x, float y, int delta) {
this.setx(x);
}
How do i make the object move say 50 pixels every 1 second? or alternatively every x frames.
I've tried using delta but that results in smooth motion which is much harder to control for my particular needs.
Any help would be much appreciated
Your approach to accomplish it with the deltas is right. Assuming you have your move method inside your update method and call it in there (or implementing it in a similar way). One way you could achieve these would be the following:
class YourGameStateWithUpdateRenderInit extends BasicGameOrWhatever{
//Global variables for updating movement eacht second.
float myDelta = 0; // your current counter
float deltaMax = 1000; // 1 second, determines how often your object should move
public void update(...){
objectToMove.move(50,50,delta); //The object which contains the move method and you move it by 50 x/y per second.
}
}
Inside your objectToMove class you have your move method:
public Boolean move(float x, float y, float pDelta) {
myDelta += pDelta;
if(myDelta >= deltaMax){
this.setx(x);
myDelta = 0;
}
}
This should work for an update every second. However this implementation is not really good or precise since as you stated you probably have that move method in a sub class or something similar. So you need to adapt it to your needs, but i hope you get the idea behind it. I think it demonstrates the purpose of counting an class attribute up by the delta values until a certain value (e.g. 1000 for 1 second) and after that set it back to zero.
I am currently trying to make a selector box for an RTS game. For this I need to be able to drag the mouse in order to create the selection box, however this can lead to a negative length/width.
In Libgdx is there a way to make rectangle from just using 2 sets of coordinates?
Thanks.
this is a simple idea, if I understand what you want to do:
to create a rectangle you can use this, Rectangle(float x, float y, float width, float height) for more inforamacion you can read it here http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/Rectangle.html
this a psuedo code more or less:
create a listener that captures keystrokes, mouse or them as appropriate,
in touchdown catches x, y, and assign a:
yourVariableTouchDown.x = x;
yourVariableTouchDown.y = y;
then when the touchup captures the x is executed, and the point where it makes up touch and assign a:
yourVariableTouchUp.x = x;
yourVariableTouchUp.y = y;
after create the rectagle:
private Rectangle yourRectangle = new Rectangle();
yourRectangle(yourVariableTouchDown.x, yourVariableTouchDown.y,
(yourVariableTouchDown.x - yourVariableTouchUp.x),
(yourVariableTouchDown.y - yourVariableTouchUp.y));
if you want to see it you can use ShapeRenderer:
look this http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/glutils/ShapeRenderer.html
add for test in variable class
private ShapeRenderer sRDebugRectangel = new ShapeRenderer();
add for test in update or draw
sRDebugRectangel.begin(ShapeType.Filled);
sRDebugRectangel.identity();
sRDebugRectangel.rect(yourRectangle.getX(),
yourRectangle.getY(),
yourRectangle.getWidth(),
yourRectangle.getHeight());
sRDebugRectangel.end();
you can look on that listener use:
https://www.google.es/#q=listener+libgdx
P.S: what you say negative, will be a matter of check when touchup is less than touchdown change where the rectangle is created that was just what I happened to you have test it and adjust the variables to create the rectangle now because you can not be created desirably when negative, now I have time to get with it, in fact eh not tested this why I said it was pseudo code, hope you serve, idea
P.S: You can also look at this https://stackoverflow.com/tour
I got this code that gets x,y positions from a motion sensor tracking a hand. The app draws a circle in the middle of the screen and then detects whether the hand is outside the circle. While the hand is outside the circle, a function checks the distance of the hand from the center of the circle. I'm attempting to store the distance data while the hand is outside of the circle in a linked list.
I need to get both the top 5 largest values and the duration for each time the hand is outside the circle.
Here's my code thus far; I've left out a bunch of the code for setting up the motion sensor just for simplicity, so this is semi-pseudo code. In any case, my main issue is getting the values I need from the list. I have the circle class included as well. I do the outside of the circle calculation and how far outside of calculation inside of my circle class.
Please let me know if this makes sense! The motion sensor is reading in data at 200 fps, so efficiency is factor here. On top of that, I am only expecting the hand, going back and forth, to be outside of the circle for a few seconds at a time.
import java.util.*;
LinkedList<Integer> values;
public void setup()
{
size(800, 300);
values = new LinkedList<Integer>();
HandPosition = new PVector(0, 0); //This is getting x,y values from motion sensor
aCircle = new Circle(); //my class just draws a circle to center of screen
aCircle.draw();
}
public void draw()
{
if (aCircle.isOut(HandPosition)) /* detects if movement is outside of circle. Would it make more sense for this to be a while loop? I also need to start a timer as soon as this happens but that shouldn't be hard */
{
values.add(aCircle.GetDistance(HandPosition)); //gets how far the hand is from center of circle and adds it to linked list. Allegedly at least, I think this will work.
/*So I need to get the 5 largest value from inside of my linked list here.
I also need to start a timer*/
}
}
class Circle {
PVector mCenter;
int mRadius;
Circle()
{
// initialize the center position vector
mCenter = new PVector(0,0);
mRadius = 150;
mCenter.set((width/2),(height/2));
}
boolean isOut(PVector Position) //detects if hand position is outside of circle
{
return mCenter.dist(Position) <= mRadius;
}
float GetDistance(PVector Position) //detects how far the hand is from the center of circle
{
return mCenter.dist(Position);
}
void draw() {
ellipse(mCenter.x, mCenter.y, mRadius, mRadius);
}
}
I'm new to Processing as well so don't hold back if any of this works.
You can use Collections.sort(List); here, then take last five element from the list.
Collection.Sort()
I'm making apong game, in a boolean method in the Paddle class I want to determine if the ball touching any of the two paddles, I'm struggling of finding the proper logic...
here are the variables:
// instance variables
private Screen theScreen;
private MyroRectangle theRectangle;
private int topLeftX;
private int topLeftY;
// constants
private final int HEIGHT = 100; //the paddle's fixed height
private final int WIDTH = 5; //the paddle's fixed width
private final int PIXELS_PER_MOVE = 20; //the number of pixels a paddle can move either up or down in one timestep
here is the method: * this method is just to determine if the ball touch or not it doesn't do anything with bounce the ball back
public boolean isTouching(Ball b)
{
boolean t = false;
if ((theScreen.getWidth()-(b.getX() + b.getRadius())) >= theScreen.getWidth()-theRectangle.getCenterX() )
{
t= true;
}
return t;
also I tried:
if ((b.getX() > theRectangle.getCenterX()/2) && (b.getY() < theRectangle.getCenterY()/2))
==========
** the methods of the ball class that might be needed:
getX()
getY()
getRadius()
==============
** the Rectangle class:
getCenterX()
getCenterY()
===============
** the Screen class:
getWidth()
getHeight()
I just want to determine at least on of the conditions then I can figure out the rest of them.
In my junior year in college I worked on a Collision detection system algorithm for the windows phone. It is hardly perfect but it was EXTREMELY efficient and can be adapted to a majority of games.
The way that it worked was pretty simple. There were two types of objects; Collidable objects (such as enemies or buildings) and Objects that you wish to check for collisions with these collidable objects.
I had this idea when I was going through a data structures class and we spoke about Linked Lists. I thought what if each link was a collidable object that you could stick your game objects that were already created in it. Then as the game objects moved around you would have a lightweight way of checking their locations for collisions. Thus my system was born.
Basically what it comes down to is using
C (or the distance between to points) = SqrRoot(A^2 + B^2) - radius of ball
this formula should look very familiar to you.
You can see the full answer on this question:
Java More Resourceful Collision Detection
This problem can be seen as solving the question if two 2d-areas, the paddle (a rectangle) and the ball (a circle) intersect. You can just google/wiki formulas for that.
If you don't want to go into the math for solving the problem through geometry, package java.awt.geom contains classes that can do the calculations for you, namely java.awt.Area. You would just create Area instances for paddle and ball and then call the intersects() method to know if they collided.