Jump to content

How Would I Get A Thrown Entity to Circle Around Another One?


Recommended Posts

Posted

I have a thrown entity I can summon in for lengths of time, It acts as though it has no gravity.

 

What I would like to do is from that entity have another entity that circulates around it on the horizontal plane.

 

Is there some simple looking code or an example of this anywhere anyone knows of?

 

The purpose of this is to imitate flowing of ocean waves with multiple circulating objects.

Posted

The initial description sounds more like a sun and planets, but whatever...

 

For one object to orbit another, you need to give the orbiter an initial velocity tangential to the hub, then periodically impart a radial impulse toward the hub. Calculating the vector directions will be easy, but calibrating magnitude will take testing.

 

Your orbiter can tick 20 times per second, and you can initialize radius and tangential speed, which tells you how many ticks you have to complete an orbit. Start doing physics calculations for circular motion.

 

And then decide what should happen if anything gets in the way.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

Here is an example of what I'm talking about (its definitely not planets):

 

(I can just imagine some awesome floors and stuff, and it would be super easy to set up with some repeaters.)

 

I've been looking at some things, I don't know how I will loop it exactly right now.

But I could summon the entity in, then have it add motion to itself. Then do that at intervals of time.

My question was more related to if there was some kind of multiplication example or something to make the adding motion part easier. Or if I would have to have more intervals of motion being added. Instead of some algorithm drawing the line for me.

 

(I guess I'd just like to know if there is such an algorithm, but then again drawing a circular line around an object by summoning things from the center of it to complete a circle then have something spawn to travel that circle may just be a tad too bit complex/unnecessary)

 

But I find myself in the same predicament with adding motion several times then looping it somehow.

 

It would be simpler to have some kind of algorithm that as it existed an amount of motion would be added in that would allow it to travel around in a circle. But I'm not really technically advanced here... I have something to learn here for certain.

 

And then decide what should happen if anything gets in the way.

ftw:

 

if (!this.worldObj.isRemote)
        {
            this.doBlockCollisions();
        }

Posted

Hi

 

Like the previous answers said, programming a circular motion is easy if you use a bit of trigonometry; look up the "unit circle" for more information.  Your object needs to store the angle, the radius, then convert these to x and z using trig.  Every tick, you just increase the angle.

 

There is a way to make an object circle around a point without using trig, it's based on the fact that the derivative of sine and cosine are also cosine and sine; so if the object is circling around a point at a constant height (constant y) then you can calculate

 

x_velocity_object = A.(z_position_object - z_position_point)

z_velocity_object = A.(x_position_object - x_position_point).

 

Just choose a suitable value for the constant A (the speed), initialise the x_position_object and the z_position_object at the desired starting location (radius from the centre point), and then every tick update the velocity using those calculations.

 

It will perform a circular paths for quite a few rotations, although it may drift eventually due to roundoff errors.

 

-TGG

 

 

 

 

Posted

The picture you showed was a large number of particles moving in circles, and none of them were circling around any of the others. Instead, each circled about a fixed point, and the apparent wave motion there depends on coordinating the phases of the various particles.

 

To simulate this in detail, you would need a field of tile entities (computationally expensive), with each responding both to its neighbors (propagation) and specific external stimuli (stimulation).

 

What is it that you are ultimately trying to achieve?

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

By the way, if you're uncomfortable with trigonometry (it is even more of a pain in computing if you aren't comfortable with with concept of radians) you can actually do repetitive motion without any actual math.

 

Instead of math you can take some graph paper and find the points on the path you want and then put those into a List data structure and then cycle through that. I use this a lot in animating entities where calculating the trigonometry is complex or where the motion does not follow a simple equation. This is the same technique that "stop motion" animation uses -- you just put the object in each position and then run them together to make the illusion of motion.

 

Since Minecraft uses 20 ticks per second, if you wanted the circular motion to take 1 second then you need 20 points from a circle in your list.

 

And since you want the motion to be around another entity, you would just add the values from the List to the position you want to orbit around.

 

In most cases of animation, using this method (a List of positions) will give better results and take very little time than trying to calculate the positions.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

The picture you showed was a large number of particles moving in circles, and none of them were circling around any of the others. Instead, each circled about a fixed point, and the apparent wave motion there depends on coordinating the phases of the various particles.

 

To simulate this in detail, you would need a field of tile entities (computationally expensive), with each responding both to its neighbors (propagation) and specific external stimuli (stimulation).

 

What is it that you are ultimately trying to achieve?

 

I'm a big fan of making particles do weird things. If I had a field of these things to execute particles at I'd have a bunch of fun with it. Ocean waves of particles.

 

I'd just like to do as many cool things with particles and moving pieces as I possibly can.

Posted

a thing I did once to make an entity circle another entity, was spawn the first, immobile entity, that would rotate its view around every tick.

 

rotationYawHead += 2f;

 

then you can get the vector frow its view

 

Vec3d vec = getVectorForRotation(0, rotationYawHead);

 

and from that vector, you can get the x and z coordinates, + the position of the immobile entity to set the position of the rotating entity.

 

myentity.setPosition(imobileEntity.x+vec.xcoord, [...] );

feel free to devide the vec.xcoord by 5 or any other number to adjust distance to the entity

Posted

Which of course, is the same thing as working out the trig yourself, except it requires an additional entity.

 

Like seriously.  Sine and Cosine are amazing.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.