Wrong center of screen coordinates - java

I'm coding an Android game and I'm trying to put the character in the middle of the screen (X axis).
In order to get the middle of the screen I get the screen width withe the following command:
int phoneWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
Then I divide phoneWidth by two and hoped that the character would appear in the middle of the screen but it appears slightly to the right.
This is the code that I use:
public void drawCharacter() {
charImg = new Texture("pika.PNG");
charSprite = new Sprite(charImg);
float ahaha = Gdx.graphics.getWidth();
charPosX = (float)phoneWidth/ 2;
}
#Override
public void render() {
ch.stop();
double elapsedSeconds = ch.getSeconds();
checkLevel();
handleObstacles();
scrollTimer = scrollTimer + Gdx.graphics.getDeltaTime() / 2;
if (scrollTimer > 1.0f)
scrollTimer = 0.0f;
sprite.setV(scrollTimer);
sprite.setV2(scrollTimer + 2);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
charSprite.setPosition(charPosX, charPosY);
for (int i = 0; i < obstacles.size(); i++) {
obstacleSprites.get(i).setPosition(obstacles.get(i).getPosX(), obstacles.get(i).getPosY());
}
spriteBatch.begin();
sprite.draw(spriteBatch);
charSprite.draw(spriteBatch);
for (int i = 0; i < obstacleSprites.size(); i++) {
obstacleSprites.get(i).draw(spriteBatch);
}
spriteBatch.end();
moveCharacter();
moveObstacle();
}
Does anyone know where this error come from?

The left-hand edge of your sprite will be in the middle of the screen.
Subtract half the sprite width from half the screen width to draw the sprite centered horizontally.

Related

node's are not intersection while using loops inside of an array?

My problem is wherever i click a node appears and for the second click another node appears with connected edge...so i want that When i click at any location, the node should be generated at the closest grid intersection point. I tried using loops.
and i'm trying to do that without "class"
int n_partition=10;
int length = 101;
PVector[] position = new PVector[length];
int BallNum;
void setup() {
size(600, 360);
background(255);
}
void draw() {
fill(255);
grid();
fill(0);
}
void mousePressed(){
stroke(0);
BallNum++;
position[BallNum]= new PVector(mouseX, mouseY);
circle(position[BallNum].x, position[BallNum].y, 10);
if (BallNum > 1) {
line(position[BallNum].x,position[BallNum].y,position[BallNum-
1].x,position[BallNum-1].y);
line(position[1].x,position[1].y,position[BallNum].x,position[BallNum] .y);
}
for (int i = 0; i < position[BallNum].length; ++ i) {
position[BallNum] = position[BallNum].get(i);
position[BallNum] = position[BallNum].get((i+1) % position[BallNum].length);
line(position[BallNum].x, position[BallNum].y,
position[BallNum].x, position[BallNum].y);
}
}
I EXPECT THE NODE SHOULD GO TO THE CLOSEST INTERSECTION.
You've to calculate the nearest position of the mouse to a point on the grid. For that you've to know the width (tile_width) and the height (tile_height) of cell.
The index of the cell can be calculated by the dividing the mouse position to the size of a tile and round() the result to an integral value (e.g. round(mouseX / (float)tile_width)).
Don't draw anything in int the mousePressed callback. The only thing you've to do there is to add a pint to the list:
void mousePressed(){
int tile_width = width / n_partition; // adapt this for your needs
int tile_height = height / n_partition;
int x = round(mouseX / (float)tile_width) * tile_width;
int y = round(mouseY / (float)tile_height) * tile_height;
position[BallNum]= new PVector(x, y);
BallNum++;
}
All the drawing has to be done in draw(). Draw the lines and points in separate loops:
void draw() {
background(255);
grid();
// draw the lines in a loop
strokeWeight(3);
stroke(0, 0, 255);
for (int i = 0; i < BallNum; ++ i) {
int i2 = (i+1) % BallNum;
line(position[i].x, position[i].y, position[i2].x, position[i2].y);
}
// draw balls in a loop
strokeWeight(1);
stroke(0, 0, 0);
fill (255, 0, 0);
for (int i = 0; i < BallNum; ++i) {
circle(position[i].x, position[i].y, 10);
}
}
Note, the scene is consecutively redrawn in every frame. Before the scene is drawn, the entire window has to be "cleared" by background().
See the result:

curveVertex() not drawling in Processing?

I'm trying to create a script that drawls a curve through 'n' vertexes equally spaced around the center of an ellipse.
The reason I'm not just drawling an ellipse around the center ellipse is because I eventually want to connect a micro-controller to Processing where the data points acquired from the 'n' amount of sensors will vary the height ('y') of each vertex, creating constantly changing, irregular curves around the center ellipse such as this possible curve:
Essentially, this is supposed to be a data visualizer, but I cannot figure out why this is not working or how to achieve this effect after going through examples and the documentation on https://processing.org/reference/.
Here is my code:
color WHITE = color(255);
color BLACK = color(0);
void setup() {
size(500, 500);
}
void draw() {
background(WHITE);
translate(width/2, height/2); // move origin to center of window
// center ellipse
noStroke();
fill(color(255, 0, 0));
ellipse(0, 0, 10, 10); // center point, red
fill(BLACK);
int n = 10;
int y = 100;
float angle = TWO_PI / n;
beginShape();
for (int i = 0; i < n; i++) {
rotate(angle);
curveVertex(0, y);
}
endShape();
}
The matrix operations like rotate do not transform the single vertices in a shape. The current matrix is applied to the entire shape when it is draw (at endShape). You've to calculate all the vertex coordinates:
Create a ArrayList of PVector, fill it with points and draw it in a loop:
color WHITE = color(255);
color BLACK = color(0);
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
int n = 10;
int radius = 100;
for (int i = 0; i <= n; i++) {
float angle = TWO_PI * (float)i/n;
points.add(new PVector(cos(angle)*radius, sin(angle)*radius));
}
}
void draw() {
background(WHITE);
translate(width/2, height/2);
noFill();
stroke(255, 0, 0);
beginShape();
PVector last = points.get(points.size()-1);
curveVertex(last.x, last.y);
for (int i = 0; i < points.size(); i++) {
PVector p = points.get(i);
curveVertex(p.x, p.y);
}
PVector first = points.get(0);
curveVertex(first.x, first.y);
endShape();
}

Making a moving circle disappear after being clicked on, Processing

I have written a program in which a UFO (in essence, a gray ellipse) appears from the center of the screen and flies to the edge. There is a laser that appears when the mouse is pressed, and disappears when the mouse is released. I want to make it so that the UFO disappears when the mouse clicks on it/the laser touches it.
I've made it as far as to make the UFO class and create variables that determine its movements and speed, and I was able to get the laser to appear directly on the cursor. I thought of making an 'if' statement to check if the cursor is within the radius (or diameter) of the UFO, and placing it inside of the for loop I created for the UFOs. However, I am not sure how to achieve the proper syntax to make it happen.
Note: You may need to wait a few seconds for the first circle to appear after you play the sketch.
UFO[] ufos = new UFO[3];
void setup() {
size(700, 700);
for (int j = 0; j < ufos.length; j++) {
ufos[j] = new UFO();
}
}
//UFO class
//Class setup ends on line 61
class UFO {
float a;
float b;
float c;
float sa;
float sb;
float d;
UFO() {
//declare float a/b/c value
a = random(-width/2, width/2);
b = random(-height/2, width/2);
c = random(width);
}
//UFO movement
void update() {
//float c will serve as a speed determinant of UFOs
c = c - 1;
if (c < 5) {
c = width;
}
}
//UFO setup
void show() {
//moving x/y coordinates of UFO
float sa = map(a / c, 0, 1, 0, width);
float sb = map(b / c, 0, 1, 0, height);
float d = map(c, 0, width, 50, 0);
//UFO drawing shapes
//ellipse is always sa (or sb) / c to allow UFO to appear
//as if it is moving through space
fill(200);
ellipse((sa / c), (sb / c), d + 5, d+5);
//Hides UFO way off the screen
//and replaces it with a black-filled ellipse until
//it forms into a full circle
//When radius d becomes 50, the UFO flies from the
//center of the screen to off of the screen
if (d < 50) {
fill(0);
ellipse(-5, -10, 90, 90);
sa = 10000;
sb = 10000;
}
}
}
void draw() {
//Background
background(0);
//Translated the screen so that the UFOs appear to fly from
//the center of the screen
translate(width/2, height/2);
//UFO draw loop, make UFO visible on screen
for (int j = 0; j < ufos.length; j++) {
ufos[j].update();
ufos[j].show();
//mouse-click laser
if (mousePressed == true) {
fill(200,0,0);
ellipse(mouseX - 352,mouseY - 347,50,50);
}
}
}
Like I said on the Happy Coding forum:
Basically, if your UFO is a series of circles, then you just need to use the dist() function to check whether the distance from the mouse to the center of the circle is less than the radius of the circle. If it is, then the mouse is inside the circle. Here's a small example:
float circleX = 50;
float circleY = 50;
float circleDiameter = 20;
boolean showCircle = true;
void draw(){
background(0);
if(showCircle){
ellipse(circleX, circleY, circleDiameter, circleDiameter);
}
}
void mousePressed(){
if(dist(mouseX, mouseY, circleX, circleY) < circleDiameter/2){
showCircle = false;
}
}
If your UFO is multiple circles, then you need to apply this logic to each circle. Please try something and post a small example like this one (not your whole sketch) if you get stuck. Good luck.

Centering map or camera 2D game

I've tried so many solutions that it's possible that my code is a bit mixed up, but whatever I try, it just won't work.
Basically I made a map with Tiled, where my player can run around and bump into stuff. I want the whole map to be visible for the whole time (it's 20 by 15, 64 pixels a tile). The camera doesn't need to move around or follow the player, it has to stay still at the center of the map.
The problem is that the map only shows in the upper right corner of the screen. When I centered the camera to the map itself it messed up the collission detection, (bumping into trees while they were not visible & walking through visible trees). So what I want to do is center the map to 0,0 where my camera also is (at least I think..).
Another thing I'd like to accomplish is that the size of the map gets resized to match different mobile phones. Tried to accomplish this with the stretchviewport, but haven't been able to test this.
public class PlayScreen implements Screen {
TiledMap map;
OrthogonalTiledMapRenderer mapRenderer;
OrthographicCamera cam;
float unitScale = 1 / 64f;
OrthogonalTiledMapRenderer renderer = new OrthogonalTiledMapRenderer(map, unitScale);
Viewport viewport;
public void show() {
map = new TmxMapLoader().load("maps/map.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map);
cam = new OrthographicCamera(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
cam.setToOrtho(false);
viewport = new StretchViewport(1280, 960, cam);
bounds = new ArrayList<Rectangle>();
for(int i = 0; i < 20; i++){
for(int j = 0; j < 15; j++){
TiledMapTileLayer cur = (TiledMapTileLayer) map.getLayers().get(1);
Cell cell = new Cell();
Vector3 center = new Vector3(cur.getWidth() * cur.getTileWidth() / 2, cur.getHeight() * cur.getTileHeight() / 2, 0);
cam.position.set(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 0);
cam.update();
if(cur.getCell(i,j) != null){ //null = first layer != --> if its not
cell = cur.getCell(i, j);
System.out.println(i + ", " + j + ", " + cell.getTile().getId());
bounds.add(new Rectangle(i * 64, j * 64, 64 , 64));
}
}
}
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mapRenderer.setView(cam);
mapRenderer.render();
cam.position.set(0, 0, 0);
cam.update();
batch.setProjectionMatrix(cam.combined);
batch.begin();
batch.draw(player.getCurrentFrame(), player.getPosition().x , player.getPosition().y);
player.update();
for(int i = 0; i < bounds.size(); i++){
if(bounds.get(i).overlaps(player.getBounds())){
int x = (int)bounds.get(i).x / 64;
int y = (int)bounds.get(i).y / 64;
TiledMapTileLayer cur = (TiledMapTileLayer)map.getLayers().get(1);
Cell cell = cur.getCell(x, y);
if(cell.getTile().getProperties().containsKey("blocked")){
System.out.println("bush");
}
player.reAdjust();
}
}
batch.end();
}
public void resize(int width, int height) {
viewport.update(width, height);
}
Nevermind, I deleted: cam.position.set(0, 0, 0); and everything seems to work just fine. Guess I already made some changes what caused it to work, just didn't see it cause this was still around.

Drawing polygons on right position

this question is continue of GPS coordinates to pixel.
I need to draw a several polygons. I can draw each polygon alone, but cant all polygons on right position.
I load information about polygon from this file:
GPS
I have class Kraj, which represent each polygon.
public class Kraj {
String name;
Point2D.Double points[];
Point2D.Double transPoints[];
Point2D.Double max;
Point2D.Double min;
// polygon
Path2D.Double polygon;
ArrayList<Kraj> kraje;
public Kraj(String name, Point2D.Double body[])
{
this.name = name;
this.body = Arrays.copyOf(body, body.length);
// calculate a bounding box
zjistiLimity();
this.transPoints = new Point2D.Double[points.length];
}
private void transformToWindow(int width, int height)
{
// convert to window
double convertX = width / (max.x - min.x);
double convertY = height / (max.y - min.y);
// calculate polygon to fit in window with right aspect ratio
double convert = convertX > convertY ? convertY : convertX;
// min = 0, convert to interval <0: infinity> and multiply by convert,
for (int j = 0; j < points.length; j++) {
double transX = (points[j].x - min.x) * convert;
double transY = height - (points[j].y - min.y) * convert;
transPoints[j] = new Point2D.Double(transX, transY);
}
this.polygon = new Path2D.Double();
this.polygon.moveTo(transBody[0].x, transBody[0].y);
for (int i = 1; i < body.length; i++)
this.polygon.lineTo(transPoints[i].x, transPoints[i].y);
this.polygon.closePath();
}
private void drawKraj(Graphics2D g2, int width, int height) {
g2.setStroke(new BasicStroke(2));
g2.fill(polygon);
// vykreslime obrys
g2.setColor(Color.black);
g2.draw(polygon);
}
public void draw(Graphics2D g2,
int contextWidth, int contextHeight)
{
// fit to window size
int sirkaSOdsazenim = contextWidth;
int vyskaSOdsazenim = contextHeight;
this.transformujToWindow(sirkaSOdsazenim, vyskaSOdsazenim);
this.drawKraj(g2, sirkaSOdsazenim, vyskaSOdsazenim);
}
/**
* Set min and max
*/
private void zjistiLimity() {
max = new Point2D.Double(-Double.MAX_VALUE, -Double.MAX_VALUE);
min = new Point2D.Double(Double.MAX_VALUE, Double.MAX_VALUE);
for(int j = 0; j < 10; j++)
{
for (int i = 0; i < body.length; i++)
{
if (points[i].getX() < min.getX()) min.x = points[i].getX();
if (points[i].getY() < min.getY()) min.y = points[i].getY();
if (points[i].getX() > max.getX())max.x = points[i].getX();
if (points[i].getY() > max.getY()) max.y = points[i].getY();
}
}
}
With this code I can draw polygon, which fit to window. But I need to draw all polygons to fit to window (calculate coordinates to create this map):
What I need to edit or add? Thanks for all answers.
You can translate the entire polygon by using:
g2.translate(x, y);
g2.draw(polygon);
g2.translate(-x, -y)
Determining the appropriate x/y translation for each polygon is something you will need to do.
I need to draw a several polygons. I can draw each polygon alone, but I can't draw all polygons in the right position.
If you can draw each polygon alone, then your polygons are correct.
You need to add an origin point to your Kraj class. Then your draw method would transform the polygon points from the polygon origin to the map origin. Assuming your polygon origin is (10,10) and a particular polygon needs to be drawn at (20,30), then you would add 10 to the x and add 20 to the y of each point in the polygon before you draw it.
You can do this my making a copy of the polygon in the draw routine before you adjust the X and Y values of each point.
Edited to add: Here's your own code modified to transform the origin. I've not tested these changes.
private void transformToWindow(Point2D windowOrigin, int width, int height)
{
// convert to window
double convertX = width / (max.x - min.x);
double convertY = height / (max.y - min.y);
// calculate polygon to fit in window with right aspect ratio
double convert = convertX > convertY ? convertY : convertX;
// min = 0, convert to interval <0: infinity> and multiply by convert,
for (int j = 0; j < points.length; j++) {
double transX = (points[j].x - min.x) * convert;
double transY = height - (points[j].y - min.y) * convert;
transPoints[j] = new Point2D.Double(transX, transY);
}
this.polygon = new Path2D.Double();
double xShift = windowOrigin.x - transBody[0].x;
double yShift = windowOrigin.y - transBody[0].y;
this.polygon.moveTo(windowOrigin.x, windowOrigin.y);
for (int i = 1; i < body.length; i++)
this.polygon.lineTo(transPoints[i].x + xShift,
transPoints[i].y + yShift);
this.polygon.closePath();
}

Categories