Minecraft Forge: Particle that does not rotate towards the player - java

I have a problem. I'm working on Forge under 1.19.3. I want to render a particle in such a way that it does not rotate towards the player's camera. By default, all particles rotate towards the camera. I want this particle to be positioned towards a specific position, not the player's position. The problem is that I don't quite understand how to do it. Currently my particle class looks like this:
public class TestParticle extends TextureSheetParticle {
protected TestParticle(SpriteSet spriteSet, ClientLevel level, double x, double y, double z, double xd, double yd, double zd) {
super(level, x, y, z, xd, yd, zd);
setLifetime(20 * 10);
setParticleSpeed(0, 0, 0);
setColor(1 f, 1 f, 1 f);
setSpriteFromAge(spriteSet);
}
#Override
public ParticleRenderType getRenderType() {
return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
}
#Override
public void tick() {
super.tick();
//Some position updates here
}
#OnlyIn(Dist.CLIENT)
public static class Provider implements ParticleProvider<SimpleParticleType> {
private final SpriteSet spriteSet;
public Provider(SpriteSet spriteSet) {
this.spriteSet = spriteSet;
}
#Override
public Particle createParticle(SimpleParticleType simpleParticleType, ClientLevel level, double x, double y, double z, double xd, double yd, double zd) {
return new TestParticle(spriteSet, level, x, y, z, xd, yd, zd);
}
}
}

Related

Java - Superclass Fields Not Properly Being Changed

I have two classes, Entity and Ship where Ship extends Entity. In my entity class I have a private field speed. In my ship class I have a update method that is simply trying to increment speed by saying current speed + acceleration times a delta time.
Here is Entity:
private float height, rotation, speed, width;
private Sprite sprite;
private Vector2 origin, position;
public Entity (float x, float y) { position = new Vector2 (x, y); }
public Entity (float x, float y, Texture texture)
{
this (x, y);
if (texture != null)
{
sprite = new Sprite (texture);
width = sprite.getWidth ();
height = sprite.getHeight ();
origin = new Vector2 (x + width / 2f, y + height / 2f);
}
else
{
sprite = null;
origin = position;
}
}
public Entity (float x, float y, float rotation, Texture texture)
{
this (x, y, texture);
this.rotation = rotation;
}
public Entity (float x, float y, float rotation, float speed, Texture texture)
{
this (x, y, rotation, texture);
this.speed = speed;
}
public float getHeight () { return height; }
public float getRotation () { return rotation; }
public float getSpeed () { return speed; }
public float getWidth () { return width; }
public float getX () { return position.x; }
public float getY () { return position.y; }
public void setPosition (Vector2 vector) { position = vector; }
public void setRotation (float value) { rotation = value; }
public void setSpeed (float value) { speed = value; }
public void setSprite (Sprite sprite) { this.sprite = sprite; }
public void setX (float value) { position.x = value; }
public void setY (float value) { position.y = value; }
public Sprite getSprite () { return sprite; }
public Vector2 getOrigin () { return origin; }
public Vector2 getPosition () { return position; }
And here is the update() method of Ship:
setSpeed (getSpeed () + acceleration * delta);
System.out.println (getSpeed ());
What I expect to happen is that speed is increased by whatever acceleration * delta is. However, what happens is that speed is set equal to that value, not incremented. If I set the fields in Entity to static then my code works, but I feel that I shouldn't do that. I've also tried setting the fields to protected and the Entity class to abstract but I still get the same effect. I'm really at a loss as to what I'm doing wrong, unless setting the fields to static is correct?
EDIT:
The entire update method of Ship.
public void update (float delta)
{
// Updating the origin's position
getOrigin ().set (getX () + getWidth () / 2f, getY () + getHeight () / 2f);
updateTurrets (delta);
updateBullets (delta);
setSprite (updateSprite (delta));
//calculateRotateTo (moveTo);
setRotation (0f);
rotateTo = getRotation ();
if (getRotation () != rotateTo)
{
setRotation (rotateTo);
}
else if (getOrigin () != moveTo)
{
/*float currDistance = Utils.calculateDistance (originalPos, getOrigin ());
float totDistance = Utils.calculateDistance (originalPos, moveTo);
if (currDistance >= totDistance / 2f)
accelerating = false;
else
accelerating = true;
if (accelerating)
setSpeed (getSpeed () + acceleration * delta);
else
{
if (getSpeed () > 0f)
setSpeed (getSpeed () - acceleration * delta);
else
{
setSpeed (0f);
setPosition (moveTo);
}
}*/
setSpeed (getSpeed () + acceleration * delta);
System.out.println (getSpeed ());
}
}
EDIT #2: I did some extra testing and if I put a ship instance in the main render() method that LibGDX gives it works. Anywhere else however, it doesn't.
I believe I fixed it or at least as far as I can tell. Apparently saying static Ship ship = new Ship (); allowed for the fields to properly change without those fields also needing to be static.

Fill Color Custom Shape Java

I want to fill a color inside of my custom shape
here is my code for trapezium shape
Trapezium Class
public class Trapezium implements Shape {
private GeneralPath trapezium = new GeneralPath();
public Trapezium (Point2D A, double height, double width)
{
double Ax = A.getX();
double Ay = A.getY();
double Bx = Ax + (width/6);
double By = Ay;
double Cx = Bx + (width/3);
double Cy = By + height;
double Dx = Cx - width;
double Dy = Cy;
double Ex = Dx + (width/3);
double Ey = Dy - height;
trapezium.moveTo(Ax, Ay);
trapezium.lineTo(Bx, By);
trapezium.lineTo(Cx, Cy);
trapezium.lineTo(Dx, Dy);
trapezium.lineTo(Ex, Ey);
trapezium.closePath();
}
#Override
public java.awt.Rectangle getBounds() {
return trapezium.getBounds();
}
#Override
public Rectangle2D getBounds2D() {
return trapezium.getBounds2D();
}
#Override
public boolean contains(double x, double y) {
return trapezium.contains(x, y);
}
#Override
public boolean contains(Point2D p) {
return trapezium.contains(p);
}
#Override
public boolean intersects(double x, double y, double w, double h) {
return trapezium.intersects(x, y, w, h);
}
#Override
public boolean intersects(Rectangle2D r) {
return trapezium.intersects(r);
}
#Override
public boolean contains(double x, double y, double w, double h) {
return trapezium.contains(x, y,w ,h);
}
#Override
public boolean contains(Rectangle2D r) {
return trapezium.contains(r);
}
#Override
public PathIterator getPathIterator(AffineTransform at) {
return trapezium.getPathIterator(at);
}
#Override
public PathIterator getPathIterator(AffineTransform at, double flatness) {
return trapezium.getPathIterator(at, flatness);
}
}
Here's my code when i call the trapezium class
DrawPanel Class
else if(type.get(a).equals("Trapezium"))
{
int[]coordinates=allShapes.get(a);
Point2D b= new Point2D.Double(coordinates[0], coordinates[1]);
Trapezium trapezium = new Trapezium(b,coordinates[3], coordinates[2]);
g2.setStroke(new BasicStroke(coordinates[4]));
g2.setPaint(dragColor);
g2.draw(trapezium);
}
the setPaint only colors the stroke of my shape , how do i color the inside of the shape ?
Image of my current code when executed
EDIT
I have 2 JColorChooser, 1 is for the stroke of the shape , and 2 is for the color inside the shape
if i use the
g2.setPaint(color2)
g2.fill(trapezium)
how do i get the color1 to change the color of my stroke ?
you have to simply fill the shape ^_^
Trapezium trapezium = new Trapezium(b,coordinates[3], coordinates[2]);
g2.setStroke(new BasicStroke(coordinates[4]));
g2.setPaint(dragColor);
g2.fill(trapezium); //HERE!!!!

change volume up and down using touchDragged (libGDX)

In this image How can I use touchDragged to drag this in x axis only ??
This is my code to make this action:
iBtnDrag = new Image(tBtnDrag);
iBtnDrag.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
iBtnDrag.setPosition(x, 448, Align.center);
}
});
you should create DragListener
...
float startX;
DragListener listener = new DragListener()
{
public void dragStart(InputEvent event, float x, float y, int pointer)
{
startX = x;
}
public void drag(InputEvent event, float x, float y, int pointer)
{
//x, y are delta from starting point so
iBtnDrag.setPosition(startX + x, 448, Align.center);
}
public void dragStop(InputEvent event, float x, float y, int pointer)
{
//when stopping drag
}
};
buuuut a way better would be to just create the Slider. To achieve it the best would be use skin mechanism
your skin file should be like for example:
com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle:
{
default-horizontal: { background: greenBackground, disabledBackground: sliderDisabled, knob: woodenKnob, disabledKnob: transparent },
},
and then you are creating slider like
music= new Slider(minValue, maxValue, stepSize, isVertical, skin);
music.setWidth( musicSiderWidth );
Slider allows you to get its value by calling
music.getValue();
which is actually very convenient

Moving circle towards touched point

i'm trying to move a circle to the point i touch in my running app. I want to see the circle moving along a path towards this point i touch.
I have three classes:
public class Drawing extends View{
Context ctx;
static Circle c1;
private float circleCenterX = 100;
private float circleCenterY = 100;
private float lerpX;
private float lerpY;
private float time = 25;
private float frames = 100;
public Drawing(Context context) {
super(context);
this.ctx = context;
c1 = new Circle (165, 350, 33);
}
public void update(float x, float y) {
this.circleCenterX = x;
this.circleCenterY = y;
}
protected void onDraw (android.graphics.Canvas canvas){
Paint p = new Paint();
p.setColor(Color.GREEN);
lerpX = (circleCenterX - c1.getX()) * (time / frames) + c1.getX();
lerpY = (circleCenterY - c1.getY()) * (time / frames) + c1.getY();
canvas.drawCircle(lerpX, lerpY, c1.getR(), p);
c1.setX(lerpX);
c1.setY(lerpY);
}
public class Circle {
private float x;
private float y;
private float r;
public Circle(float x, float y, float r) {
super();
this.x = x;
this.y = y;
this.r = r;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getR() {
return r;
}
public void setR(float r) {
this.r = r;
}`
public class Game extends Activity implements OnTouchListener {
Drawing d;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
d=new Drawing(this);
setContentView(d);
d.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent me) {
d.update(me.getX(), me.getY());
d.invalidate();
return true;
}
I think i will need something like a while or for loop to increment the x and y coords and or maybe need a speed value?!
Maybe im totally wrong and its a lot of more math to get it.
Thanks for your help
Cheers
Every time onDraw is called you need to move the circle a bit. The easiest way is just to move a certain number of pixels each time it's called.
To be able to do this you need to keep track of:
Where the animation started
Where you want the animation to end
Use linear interpolation to calculate the position of the circle in each onDraw call

Java: When I Instantiate a Subclass of an Abstract Class It Doesn't Recognize the Constructor of its Superclass

I do not have very much Java experience but I see codes where there is an abstract class with a certain constructor and then a subclass of that abstract class without a constructor. Then when the subclass is instantiated it is constructed with its superclass constructor. Is that right?
I have this abstract class:
public abstract class Tile{
public int x;
public int y;
public int z;
protected Color color;
protected float friction;
protected float bounce;
protected boolean liquid;
public void Tile(int x, int y, int z){
this.x = x;
this.y = y;
this.z = z;
init();
}
abstract protected void init();
And this subclass:
public class TestTile extends Tile{
protected void init(){
color = Color.RED;
friction = 0.1f;
bounce = 0.2f;
liquid = false;
}
}
But when I instantiate a TestTile with this:
Tile tile = new TestTile(0, 0, 0);
the init() method never runs. All of the values defined inside it are null. I tried making what I though might be a redundant constructor in the subclass which just called super with the exact same parameters, but when I did that, even with super(x, y, z) the only statement inside it, it said this:
TestTile.java:27: call to super must be first statement in constructor
I want to make a bunch of subclasses of Tile which implement the properties of a Tile. If this is not the correct way to do that, what is a better way?
I am using 32-bit Ubuntu Linux 11.04 if it has to do with anything.
Thanks.
Your constructor is not in propert constructor format, it's void, make it:
public Tile(int x, int y, int z){
this.x = x;
this.y = y;
this.z = z;
init();
}
I don't see a constructor for TestTime that takes three arguments. I don't see any ctor at all, which means that all you have is the default that the compiler gives you. Did I go too fast and miss it?
I'd recommend paying careful attention to this. I'd rethink this design:
What's wrong with overridable method calls in constructors?
Try this - it includes the fix for your constructor and avoids the issue that the other thread points out:
public abstract class Tile{
public int x;
public int y;
public int z;
protected Color color;
protected float friction;
protected float bounce;
protected boolean liquid;
public Tile(int x, int y, int z){
this.x = x;
this.y = y;
this.z = z;
}
}
public class TestTile extends Tile{
// You're missing this.
public TestTile(int x, int y, int z)
{
super(x, y, z);
this.init();
}
protected void init(){
color = Color.RED;
friction = 0.1f;
bounce = 0.2f;
liquid = false;
}
}
First of all, Tile has only one constructor with the x, y, z parameters, no default constructor, so you have to call super(x, y, z) in the TestTile constructor. As slandau said, the "constructor" has a wrong void return type.
The TestTile needs to declare the parameters or pass default values:
public TestTile(int x, int y, int z) {
super(x, y, z);
}
public TestTile() {
super(0, 0, 0);
}
In Java, there are many riscs to call an abstract method in a constructor, see also here, the instance is not initialized properly. You can only call static methods safe (which will not work here).
public TestTile(int x, int y, int z) {
super(x, y, z);
color = Color.RED;
friction = 0.1f;
bounce = 0.2f;
liquid = false;
}
or you need to call a private method in the derived class (remove the abstract init() from Tile):
public TestTile(int x, int y, int z) {
super(x, y, z);
init();
}
private void init() {
color = Color.RED;
friction = 0.1f;
bounce = 0.2f;
liquid = false;
}
Are you sure members are the right implementation here? Maybe abstract methods (getters) may be better here to declare a behavior and implement it in the subclass?
public abstract class Tile {
public int x;
public int y;
public int z;
public Tile(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public abstract Color getColor();
public abstract float getFriction();
public abstract float getBounce();
public abstract boolean isLiquid();
}
public class TestTile extends Tile {
public TestTile(int x, int y, int z) {
super(x, y, z);
}
public Color getColor() {
return Color.RED;
}
public float getFriction() {
return 0.1f;
}
public float getBounce() {
return 0.2f;
}
public boolean isLiquid() {
return false;
}
}
Constructors are not inherited, so the three-parameter constructor of Tile is not invoked when you create your TestTile object. You need to explicitly call the three-parameter Tile constructor from a TestTile constructor, like you said you did try, but that call to super(x,x,x) must be the first statement of the TestTile constructor.
And like Matt Ball said, your Tile "constructor" isn't really a constructor until you remove the void return type.

Categories

Resources