[[1.7.10] Tutorial] Энтити пуля

svk

1,185
3
1 основной класс пули:
http://pastebin.com/cDjNrLqa

В это классе, есть эти строки:
Код:
        this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F *(float)Math.PI) * f);
        this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F *(float)Math.PI) * f);
        this.motionY = (double)(-MathHelper.sin((this.rotationPitch + this.func_70183_g()) / 180.0F * (float)Math.PI) * f);
Видимо они отвечают за корректировку движения и расположения при большой скорости.
Если вы делаете энтити, которое не двигается или же делает это не быстро, то лучше эти строки убрать.

2 промежуточный класс:
Код:
package com.svk.industrialGuns.entity;

import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

public class EntityBullet extends EntityBulletBase
{
    public float speed = 0;
    public float gravity = 0;
    public int damage = 0;
    public double bulletMotionX = 0;
    public double bulletMotionY = 0;
    public double bulletMotionZ = 0;
    public int life = 0;
    
    public EntityBullet(World world)
    {
        super(world);
    }

    public EntityBullet(World p_i1777_1_, EntityLivingBase p_i1777_2_) 
    {
        super(p_i1777_1_, p_i1777_2_);
    }
    
    @Override
    protected void onImpact(MovingObjectPosition p_70184_1_) {}

    @Override
    public void writeSpawnData(ByteBuf buf) 
    {        
        buf.writeFloat(speed);
        buf.writeFloat(gravity);
        buf.writeInt(damage);
        buf.writeDouble(bulletMotionX);
        buf.writeDouble(bulletMotionY);
        buf.writeDouble(bulletMotionZ);
        buf.writeInt(life);
        buf.writeFloat(addSize);
    }

    @Override
    public void readSpawnData(ByteBuf buf) 
    {        
        this.speed = buf.readFloat();
        this.gravity = buf.readFloat();
        this.damage = buf.readInt();
        this.bulletMotionX = buf.readDouble();
        this.bulletMotionY = buf.readDouble();
        this.bulletMotionZ = buf.readDouble();
        this.life = buf.readInt();
        this.addSize = buf.readFloat();
    }
}

Переменные можно поставить свои, но их надо сохранять/загружать в SpawnData

Класс пули:
Код:
package com.svk.industrialGuns.entity;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import com.svk.industrialGuns.client.particle.ColoredParticleCube;
import com.svk.industrialGuns.client.particle.ColoredParticleCubeHeap;
import com.svk.industrialGuns.client.particle.ParticleLava;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.Items;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

public class EntityZardiaShell extends EntityBullet
{
    public EntityZardiaShell(World world)
    {
        super(world);
        super.render = true;
    }
    
    public EntityZardiaShell(World world, EntityLivingBase entity) 
    {
        super(world, entity);
        super.render = true;
    }
    
    @Override
    public void onUpdate()
    {
        super.onUpdate();
        
        life++;
        if(life > 100)
        {
            this.setDead();
        }
        
        this.motionX = bulletMotionX * speed;
        this.motionY = bulletMotionY * speed;
        this.motionZ = bulletMotionZ * speed;
    }

    @Override
    protected void onImpact(MovingObjectPosition mop) 
    {
        if(mop.entityHit != null && !(mop.entityHit instanceof EntityZardiaShell))
        {
            mop.entityHit.hurtResistantTime = 0;//Счётчик неуязвимости энтити
            mop.entityHit.attackEntityFrom(DamageSource.cactus, damage);
            this.setDead();
        }
        if(!(mop.hitInfo instanceof Entity))
        {
            this.setDead();
        }
    }
}

EntityZardiaShell заменить на свой класс.

Спавн пули:
Код:
            if(!world.isRemote)
            {
                        Vec3 movingobjectposition = player.getLookVec();
                        EntityBullet bullet = new EntityZardiaShell(world, player);
                        bullet.setPosition(bullet.posX + movingobjectposition.xCoord * 1.0D, bullet.posY+0.5 + movingobjectposition.yCoord * 1.0D, bullet.posZ + movingobjectposition.zCoord * 1.0D);
                        bullet.bulletMotionX = movingobjectposition.xCoord + Функция_разброса;
                        bullet.bulletMotionY = movingobjectposition.yCoord + Функция_разброса;
                        bullet.bulletMotionZ = movingobjectposition.zCoord + Функция разброса;
                        bullet.damage = bulletDamage;
                        bullet.speed = bulletSpeed;
    
                        world.spawnEntityInWorld(bullet);
            }

И метод регестрации в базовом классе мода:
Код:
    public void registerEntity()
    {
        int entityId = 0;
        EntityRegistry.registerModEntity(EntityZardiaShell.class, "EntityZardiaShell", entityId++, this, 64, 20, true);
    }
64 - дальность апдейта
20 - количество апдейтов в секунду
 
svk написал(а):
Код:
        this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F *(float)Math.PI) * f);
        this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F *(float)Math.PI) * f);
        this.motionY = (double)(-MathHelper.sin((this.rotationPitch + this.func_70183_g()) / 180.0F * (float)Math.PI) * f);

Видимо они отвечают за корректировку движения и расположения при большой скорости.
Наверное они отвечают не за это. Не знаю, с чего ты это взял. Скорее всего это отвечает за изменение траектории движения пули при ее повороте (rotationPitch, rotationYaw). Сначала нужно понять весь код самому, перед тем как писать туториал для других людей. Так же хочу заметить, что такая реализация пули - построение велосипеда и гораздо проще просто наследовать EntityThrowable и дописать туда немного кода в методе onImpact.
 
Ты сам его сначала пойми, и проведи несколько тестов, прежде чем меня править.И не для слепых, там addSize и несколько правок стоит.
 
Супер гайд. Всё ясно и понятно.
Даже не знаю, почему конь до сих пор не перенес его в соответствующий раздел.
 
Честно - хз, кому там что ясно и понятно.
Я следил за соседней темой, где глуми всё по пальцам пояснял svk, и, имхо, здесь кода от глуми больше.
Объяснений я толком не вижу, только не очень внятное "наверное этот код отвечает за корректировку". Если уж рассматривать геометрию - рассматривайте с пояснением и картинками, где хотя бы на двумерном примере пояснен принцип движения\корректировки\etc.
По большей части тут только готовый код.
Тут не объяснено, почему надо сделать именно так, а в основном гайд отвечает на вопрос "как".
 
И что? Откуда мне было знать, что энтити регестрировать надо, я был полностью уверен, что и без этого можно спавнить. Или к примеру про интерфейс IEntityAdditionalSpawnData.

Это всервно что тебя послать, когда ты написал гайд, мотивируя "ты же где-то это прочитал, а не сам разобрался"

Насчёт этих трёх строчек кода - они меняют движение пули, в зависимости от взгляда игрока, что-бы корректировать движение, когда игрок будет двигать экраном.
[merge_posts_bbcode]Добавлено: 20.06.2015 17:39:38[/merge_posts_bbcode]

Ну могу расписать, что и как делается, если вы дадите гарантию, что переместите в учебник (Мне же не зря писать всё это)
 
Интересно, а каким боком ВЗГЛЯД игрока может влиять на положение пули в пространстве? А если игроков несколько?
Да и я как-то не вижу в коде обращения к переменным, отвечающим за ВЗГЛЯД игрока. rotationPitch/Yaw в данном случае берутся локальные, т.е. от пули.
 
Oldestkon написал(а):
Честно - хз, кому там что ясно и понятно.
54d0a6cdc1ec2b211782191901b383c087d9dc9384c20f01944b014f1e33a8b4.jpg

же.

Попробую сегодня родить что-то внятное по этой теме.
 
Oldestkon написал(а):
Интересно, а каким боком ВЗГЛЯД игрока может влиять на положение пули в пространстве? А если игроков несколько?
Да и я как-то не вижу в коде обращения к переменным, отвечающим за ВЗГЛЯД игрока. rotationPitch/Yaw в данном случае берутся локальные, т.е. от пули.
Слушай, я не знаю каким это раком происходит, но я уверен в этом на 100%
У меня был баг, я его на этот форум даже писал, что положение энтити связанно с взглядом игрока, и пофиксил я удалением именно этих строк.
[merge_posts_bbcode]Добавлено: 20.06.2015 18:09:53[/merge_posts_bbcode]

Кстати так я и не понял - что тут не понятного?)
 
svk написал(а):
я не знаю каким это раком происходит
> Писать туториал
svk написал(а):
что тут не понятного?)
Действительно.

Если в результате твоих колдований с кодом позиция пули ПОСЛЕ ВЫСТРЕЛА имеет зависимость от взгляда игрока, спешу тебя огорчить - косяк тут только твой.
 
Если в результате твоих колдований с кодом позиция пули ПОСЛЕ ВЫСТРЕЛА имеет зависимость от взгляда игрока, спешу тебя огорчить - косяк тут только твой.


Блин, ты тупой? Я же сказал - это из-за этих строк. Каким образом, вообще, вы споритите, самим не проверив, а?
 
krok написал(а):
ИМХО, гайд, отвечающий на вопрос [font=Verdana, Helvetica, Arial, sans-serif]как[/font], но не отвечающий на вопрос почему - это не гайд, а кака.(С)TaoGunner
В смысле? Мне закомментировать, что, как, и где происходит?
 
krok написал(а):
>>>Если вы делаете энтити, которое не двигается или же делает это не быстро, то лучше эти строки убрать.
Это костыли называется
В смысле? Не понял...
[merge_posts_bbcode]Добавлено: 20.06.2015 18:23:33[/merge_posts_bbcode]

Да дайте дельный совет, я просто не понимаю чего вы хотите от туториала :D
 
Ну могу расписать, что и как делается, если вы дадите гарантию, что переместите в учебник (Мне же не зря писать всё это)
 
Ты не понимаешь как оно работает, но почему-то этот код тебя спасает. Логично будет предположить, что ты даже его не сам писал. Ага?
Писать туториал по какой-то теме, в которой ты не шаришь (что следует из того, что ты не понимаешь, почему костыль выше тебя спасает) не стоит. Стоит пояснять почему, или сам догадаешься?

Я стараюсь следовать чисто логически. Направление, скорость и прочее для пули (которая игнорирует сопротивление воздуха и гравитацию) задаются лишь ЕДИНОЖДЫ непосредственно при выстреле. У тебя пуля же не летит по параболе и не учитывает сопротивление воздуха? Значит она НИКАК не может менять траекторию во время полёта. А если у тебя она меняет и ты НАСИЛЬНО (здесь будет более уместно слово forced, мне даже не хватает моих знаний русского, чтобы нормально выражать свои мысли) задаешь скорость пуле во время полёта - это называется КОСТЫЛЬ.
Что делают эти три строки ты так и не пояснил, а они всего лишь задают вектор скорости пули согласно ВЕКТОРУ её направления домноженному на СКОРОСТЬ (численную её величину). Ты это не мог объяснить? Так зачем же тогда гайд?
 
Назад
Сверху