How do I track the movement of my sprite? - java

I have a program meant to simulate traffic and all process (movement, drawing new cars, responding to traffic lights) except tracking movement are working.
I have used getter methods
float getXposition(){
return x;
}
float getYposition(){
return y;
}
to determine the location of my sprite but my problem is with conditions relating to the position. For example, my do while loop
do {
topcar.setYvelocity((topcar.getYvelocity()/2));
}while(topcar.getYposition() < 275);
is always bypassed.
Update method(s)
public void update() { // update position and velocity every n milliSec
// default - just move at constant velocity
x += dx; // velocity in x direction
y += dy; // velocity in y direction
}
public void actionPerformed(ActionEvent arg0) {
// called by Timer every 50 milliseconds
for (SimpleSprite s : SimpleSprite.sprites)
s.update(); // update positions of all sprites
repaint();
}
What I wanted to do was make it so that when the light turns red the car sprite should slow down to half speed until it reaches y coordinate 275 and then stop, but instead my sprite will abruptly stop as soon as the light turns red

Related

Java - ArrayList Objects not deleted properly

I am working on a 2D platformer game for my, last, HS year project.
The game is basically about a player walking back & forward, collecting points and reaching goals... The player can shoot bullets and when bullets hit a block, it is destroyed. Now, I wanted to add an explosion effect using so called "particle" objects. I have written the manager class for it and it seemed to have worked the first time but after shooting a few times, i noticed that the particles stopped getting deleted, they just continue and travel out of screen. The life-time limit is 500ns.
I have also noticed that if i shoot bullets as soon as the game starts, the effect finishes as it is supposed to. but after waiting for a few more seconds and then shooting bullets, the effect particles do not behave as they should.
Here is what it looks like when i shoot bullets as soon as i start the game (What it's supposed to look like):
and here is what it looks like, after waiting a few seconds before shooting the bullets.
ParticleManager.java
public class ParticleManager {
private ArrayList<Particle> particles;
private ArrayList<Particle> removeParticles;
public ParticleManager() {
particles = new ArrayList<Particle>();
removeParticles = new ArrayList<Particle>();
}
public int getListSize() {
return particles.size();
}
/*
Generate particles
*/
public void genParticle(int x, int y, int amount) {
for(int i = 0; i < amount; i++) {
particles.add(new Particle("explosion" , x,y, i));
}
}
public void update() {
// Iterate trough particle objects
// update them & check for lifeTime
for(Particle p: particles) {
// Updating particle object before
// checking for time lapse
p.update();
// Append outdated particles to removeParticles
// if time limit has passed
if(System.nanoTime() - p.timePassed >= Config.particleLife) {
removeParticles.add(p);
}
}
// finally, delete all "remove-marked" objects
particles.removeAll(removeParticles);
}
public void render(Graphics2D g) {
for(Particle p: particles) {
p.render(g);
}
}
}
Particle.java
class Particle {
private double px, py, x, y;
private int radius, angle;
public long timePassed;
String type;
public Particle(String type, double x, double y, int angle) {
this.x = x;
this.y = y;
this.radius = 0;
this.angle = angle;
this.timePassed = 0;
this.type = type; // explosion, tail
}
public void update() {
px = x + radius * Math.cos(angle);
py = y + radius * Math.sin(angle);
radius += 2;
this.timePassed = System.nanoTime();
}
public void render(Graphics2D g) {
g.setColor(Color.WHITE);
g.fillOval((int)px, (int)py, 5, 5);
}
}
I haven't figured out what I am doing wrong here, I've googled about some stuff and at one point i came across an answer mentioning that some references don't get deleted directly for some reason...
and my question is "How can I make these particles vanish after a certain amount of time has passed? - as shown in the first GIF"
I think the problem is that you are constantly overwriting timePassed.
// Updating particle object before
// checking for time lapse
p.update();
// Append outdated particles to removeParticles
// if time limit has passed
if(System.nanoTime() - p.timePassed >= Config.particleLife) {
removeParticles.add(p);
}
p.update() sets timePassed to now and then the if check checks if time passed is far from now (it will never be since it was just set).
I think you do want to set timePassed in the constructor (maybe it would be better named timeCreated).
Additionally, just a heads up, you never clear removeParticles so that list is going to grow forever until it causes the process to run out of memory.

Animation doesn't work, component just moves along the x axis

I'm trying to make an Agar.io simulation, so I'm using MouseMotionListener's mouseMoved method to find the cursor's location, and calculating the difference between the cursor's coordinates and agar's coordinates to calculate the slope for the animation.
Below is the code for the implemented mouseMoved():
private class CursorTracker implements MouseMotionListener {
public void mouseMoved(MouseEvent e) {
//cursor location
cursor_x = e.getPoint().getX();
cursor_y = e.getPoint().getY();
//agar location
agar_x = agar.getX();
agar_y = agar.getY();
repaint();
}
public void mouseDragged(MouseEvent e) {}
}
Below is actionPerformed() for the panel's timer:
private class Animator implements ActionListener {
public void actionPerformed(ActionEvent e) {
//adding food
if (count == 30) {
addRandomFood();
count = 0;
}
count++;
//agar animation - functions on slope animation: x changes by 1, y by m
double delta_x = cursor_x - agar_x;
double delta_y = cursor_y - agar_y;
//slope
double m = (delta_y)/(delta_x);
//pass parameters
agar.move(1, m);
repaint();
}
}
And here is the code for the Agar.move() method:
public void move(double x_interval, double y_interval) {
if (x >= 0)
x -= x_interval;
if (y >= 0)
y -= y_interval;
}
My intention is to find out the slope (which is ∆y/∆x), change x by 1 and y by the slope (m) value at every timer's repeat, which should theoretically result in the agar object moving towards the cursor location bit by bit. (correct me if I'm wrong)
Also, the cursor detector (mouseMoved) seems to work weirdly; it works only once, agar doesn't change motion direction even the cursor is relocated. And it might even be not properly "listening" to the cursor and just doing it by default because regardless of the cursor's location when the program starts running, the agar always ends up moving along the x-axis towards the origin.

Changing direction while moving

I am making a game with a space ship that rotates when the left and right keys are pressed and moves forward when the up key is pressed.
Currently the ship can rotate while its moving forward but it will continue in the same direction that it is going in.
How would i make it so that the ship can change the direction its is moving while the up key is being held down?
This is the update method for the SpaceShip class:
public void update(){
radians += ri;
System.out.println(radians);
if(radians < 0){
radians = 2 * Math.PI;
}if(radians > (2 * Math.PI)){
radians = 0;
}
x += xx;
y += yy;
}
this is the right event:
public void actionPerformed(ActionEvent e) {
if(pressed){
Board.getShip().setRI(0.05);
}else{
Board.getShip().setRI(0);
}
}
and this is the up event:
public void actionPerformed(ActionEvent e) {
if(pressed){
Board.getShip().setXX(Math.cos(Board.getShip().getRadians()) * Board.getShip().getSpeed());
Board.getShip().setYY(Math.sin(Board.getShip().getRadians()) * Board.getShip().getSpeed());
}else{
Board.getShip().setXX(0);
Board.getShip().setYY(0);
}
}
Rockets
A rocket defined as
// pseudo code
rocket = {
mass : 1000,
position : { // world coordinate position
x : 0,
y : 0,
},
deltaPos : { // the change in position per frame
x : 0,
y : 0,
},
direction : 0, // where the front points in radians
thrust: 100, // the force applied by the rockets
velocity : ?, // this is calculated
}
The formula for movement is
deltaVelocity = mass / thrust;
The direction of the thrust is along the direction the ship is pointing. As there are two components to the change in position per frame and that thrust changes the deltas the way to apply thrust is;
// deltaV could be a constant but I like to use mass so when I add stuff
// or upgrade rockets it has a better feel.
float deltaV = this.mass / this.thrust;
this.deltaPos.x += Math.sin(this.direction) * deltaV;
this.deltaPos.y += Math.cos(this.direction) * deltaV;
As the thrust delta is added to the position deltas the result is acceleration in the direction the ship is pointing.
Each frame you then update the position by the delta pos.
this.position.x += this.deltaPos.x;
this.position.y += this.deltaPos.y;
You may want to add some drag to slow the ship over time. You can add a simple drag coefficient
rocket.drag = 0.99; // 1 no drag 0 100% drag as soon as you stop thrust the ship will stop.
To apply the drag
this.deltaPos.x *= this.drag;
this.deltaPos.y *= this.drag;
To get the current velocity, though not needed in the caculations.
this.velocity = Math.sqrt( this.deltaPos.x * this.deltaPos.x + this.deltaPos.y * this.deltaPos.y);
This will produce rocket behaviour that is the same as in the game Asteroids. If you want behaviour that is more like a boat on water, or car (ie the changing direction changes the deltas to match the direction) let me know as it is a simple modification of the above.

How do I detect if the user touched my Sprites/screen?

Basically, the sprite is spawned at a random time every (1,2 or 3 sec) and infinitely. I want the sprite to disappear once it's touched on the screen. (android touch event)
public void newEnemy(){
Sprite newEnemy=Pools.obtain(Sprite.class);
newEnemy.set(enemy);
newEnemy.setPosition(200, 700);
enemies.add(newEnemy);
}
public void update(){
deltaTime=Gdx.graphics.getDeltaTime();
timer+=1*deltaTime;
timer2+=1*deltaTime;
timer3+=1*deltaTime;
if(timer>=random){
newEnemy(); //spawn a new enemy
timer-=random;
random=rTime.nextInt(3)*1f+1;//create random time if timer>= initial random time;
}
You will need to set up a touch listener. Information on that here
You will then need to check if the touch location is within your sprite bounds.
A common way to do this would be to create a rectangle and check if the touch location is inside of the rectangle like this
Rectangle2D bounds = new Rectangle2D.Float(x, y, width, height);
`if(bounds.contains(`the touch x value`,` the touch y value`){`
//your code to remove the sprite
}
Alternately you could write your own method in sprite, this would be a better decision if all you needed was the contains method. That way, you don't have to import another library. (Note that it doesn't make much of a difference but it's good practice)
public boolean contains(int x, int y) {
return (x > this.x && y > this.y && x < this.x + this.width && y < this.y + this.height);
}

Setting arc position in Java using Mouse

I am writing a 2D program. On my paintComponent I created an arc.
public class Board extends Panel{
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D graphics2d = (Graphics2D)g;
int x = MouseInfo.getPointerInfo().getLocation().x;//set mouses current position
int y = MouseInfo.getPointerInfo().getLocation().y;
graphics2d.setStroke(wideStroke);
graphics2d.draw(new Arc2D.Double(200, 200, 100, 100, ?, 180, Arc2D.OPEN));
}
}
In my main I am using a Thread to update the graph. The position of the ? is the starting angle. Every time I change this the arc will move in a circle like half a car wheel. Is it possible to get the arc movement to follow the mouse? e.g. ? = 270
How will I do this? (Sorry for my bad paint skills!)
So based on the information from Java 2d rotation in direction mouse point
We need two things. We need the anchor point (which would be the centre point of the arc) and the target point, which would be the mouse point.
Using a MouseMotionListener, its possible to monitor the mouse movements within the component
// Reference to the last known position of the mouse...
private Point mousePoint;
//....
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});
Next we need to calculate the angle between these two points...
if (mousePoint != null) {
// This represents the anchor point, in this case,
// the centre of the component...
int x = width / 2;
int y = height / 2;
// This is the difference between the anchor point
// and the mouse. Its important that this is done
// within the local coordinate space of the component,
// this means either the MouseMotionListener needs to
// be registered to the component itself (preferably)
// or the mouse coordinates need to be converted into
// local coordinate space
int deltaX = mousePoint.x - x;
int deltaY = mousePoint.y - y;
// Calculate the angle...
// This is our "0" or start angle..
rotation = -Math.atan2(deltaX, deltaY);
rotation = Math.toDegrees(rotation) + 180;
}
From here, you would need to subtract 90 degrees, which would give your arcs start angle and then use an extent of 180 degrees.

Categories

Resources