Вверх ↑
Этот топик читают: Гость
Ответов: 4557
#1: 2015-01-03 12:03:36 ЛС | профиль | цитата
Работа с Techne
Степени, заборы, калитка и д.р. - всё это модели блоков. Сегодня мы научимся вставлять наши модели из Techne в Minecraft.

Всё, что нам нужно:
JDK Стандартный набор разработчика
Eclipse Для удобной работы с исходниками игры
MCP (любой, но в нашем случае 1.4.6) Поможет декомпилировать исходники
Techne Работа с моделями
Forge src библиотека forge


Я не буду рассказывать, как создать файл мода Это есть на любом сайте.
После установки всего этого мы можем спокойно писать моды на Forge.

Чтобы добавить блоку модель, нужно пройти операций:
Класс блока, BlockHandler, BlockModel, Renderer, TileEntity.

Научимся вставлять нашу модель в игру на примере лестницы.
В классе нашего мода пишем:

public static int renderLadderModelID;//это будет наш RenderType
public static Block ladderModel = new LadderBlock(2024).setCreativeTab(CreativeTabs.tabBlock).setHardness(0.0F).setBlockName("LadderModel");

После
public void load(FMLInitializationEvent event)
{

Пишем:
	GameRegistry.registerBlock(ladderModel);
GameRegistry.registerTileEntity( testmod.TileEntityLadderModel.class, "TileEntityLadderModel" );
LanguageRegistry.addName(ladderModel, "Лестница");
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityLadderModel.class, new RendererLadderModel());//регистрируем рендер, и энтити
//это поможет нам отрендерить модель в руке, то-есть как сундук
renderLadderModelID = RenderingRegistry.getNextAvailableRenderId();
RenderingRegistry.registerBlockHandler(renderLadderModelID, new LadderBlockHandler());

Переходим к созданию блока и добавлении модели.
Создаем класс LadderBlock.java и туда пишем:

package testmod;


import static net.minecraftforge.common.ForgeDirection.EAST;
import static net.minecraftforge.common.ForgeDirection.NORTH;
import static net.minecraftforge.common.ForgeDirection.SOUTH;
import static net.minecraftforge.common.ForgeDirection.WEST;

import java.util.Random;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.*;

public class LadderBlock extends BlockContainer
{
public LadderBlock(int id)
{
super(id, Material.circuits);

}

public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4);
}

@SideOnly(Side.CLIENT)

public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
this.updateLadderBounds(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
}

public void updateLadderBounds(int par1)
{
float var3 = 0.125F;

if (par1 == 2)
{
this.setBlockBounds(0.0F, 0.0F, 1.0F - var3, 1.0F, 1.0F, 1.0F);
}

if (par1 == 3)
{
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var3);
}

if (par1 == 4)
{
this.setBlockBounds(1.0F - var3, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}

if (par1 == 5)
{
this.setBlockBounds(0.0F, 0.0F, 0.0F, var3, 1.0F, 1.0F);
}
}

public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
return par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST ) ||
par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST ) ||
par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) ||
par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH);
}

public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
}

public int getRenderType()
{
return TestModBase.renderLadderModelID;//выбираем наш рендер
}

public boolean isOpaqueCube()
{
return false;
}

public boolean renderAsNormalBlock()
{
return false;
}

public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
{
int var10 = par9;

if ((var10 == 0 || par5 == 2) && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH))
{
var10 = 2;
}

if ((var10 == 0 || par5 == 3) && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH))
{
var10 = 3;
}

if ((var10 == 0 || par5 == 4) && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST))
{
var10 = 4;
}

if ((var10 == 0 || par5 == 5) && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST))
{
var10 = 5;
}

return var10;
}

/**
* Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
* their own) Args: x, y, z, neighbor blockID
*/
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
{
int var6 = par1World.getBlockMetadata(par2, par3, par4);
boolean var7 = false;

if (var6 == 2 && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH))
{
var7 = true;
}

if (var6 == 3 && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH))
{
var7 = true;
}

if (var6 == 4 && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST))
{
var7 = true;
}

if (var6 == 5 && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST))
{
var7 = true;
}

if (!var7)
{
this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
par1World.setBlockWithNotify(par2, par3, par4, 0);
}

super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
}

public void setBlockBoundsForItemRender()

{

this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);

}

public int quantityDropped(Random par1Random)
{
return 1;
}

@Override
public boolean isLadder(World world, int x, int y, int z)
{
return true;
}

@Override
public TileEntity createNewTileEntity(World world)
{
return new TileEntityLadderModel();
}

}

В основном тут идет ссылка на размер рендера, возможность подниматься по лестнице и поворот на стороны света. Здесь сработает только рендер и возможность подниматься.

Готово.
Теперь создаем TileEntityLadderModel, в который вставляем:
package testmod;
import net.minecraft.tileentity.TileEntity;

public class TileEntityLadderModel extends TileEntity
{
public TileEntityLadderModel()
{

}
}

Теперь непосредственно можно переходить к модели нашей лестницы.

При создании и экспорте модели из Techne в Java, ан выходе получаем код:
package net.minecraft.src;

public class Modelladder extends ModelBase
{
//fields
ModelRenderer Shape1;
ModelRenderer Shape2;
ModelRenderer Shape3;
ModelRenderer Shape4;
ModelRenderer Shape5;
ModelRenderer Shape6;

public Modelladder()
{
textureWidth = 32;
textureHeight = 32;

Shape1 = new ModelRenderer(this, 0, 0);
Shape1.addBox(0F, 0F, 0F, 2, 16, 2);
Shape1.setRotationPoint(-8F, 8F, 5F);
Shape1.setTextureSize(32, 32);
Shape1.mirror = true;
setRotation(Shape1, 0F, 0F, 0F);
Shape2 = new ModelRenderer(this, 0, 0);
Shape2.addBox(0F, 0F, 0F, 2, 16, 2);
Shape2.setRotationPoint(-8F, 8F, -7F);
Shape2.setTextureSize(32, 32);
Shape2.mirror = true;
setRotation(Shape2, 0F, 0F, 0F);
Shape3 = new ModelRenderer(this, 0, 0);
Shape3.addBox(0F, 0F, 0F, 1, 2, 16);
Shape3.setRotationPoint(-8F, 9F, -8F);
Shape3.setTextureSize(32, 32);
Shape3.mirror = true;
setRotation(Shape3, 0F, 0F, 0F);
Shape4 = new ModelRenderer(this, 0, 0);
Shape4.addBox(0F, 0F, 0F, 1, 2, 16);
Shape4.setRotationPoint(-8F, 13F, -8F);
Shape4.setTextureSize(32, 32);
Shape4.mirror = true;
setRotation(Shape4, 0F, 0F, 0F);
Shape5 = new ModelRenderer(this, 0, 0);
Shape5.addBox(0F, 0F, 0F, 1, 2, 16);
Shape5.setRotationPoint(-8F, 17F, -8F);
Shape5.setTextureSize(32, 32);
Shape5.mirror = true;
setRotation(Shape5, 0F, 0F, 0F);
Shape6 = new ModelRenderer(this, 0, 0);
Shape6.addBox(0F, 0F, 0F, 1, 2, 16);
Shape6.setRotationPoint(-8F, 21F, -8F);
Shape6.setTextureSize(32, 32);
Shape6.mirror = true;
setRotation(Shape6, 0F, 0F, 0F);
}

public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
{
super.render(entity, f, f1, f2, f3, f4, f5);
setRotationAngles(f, f1, f2, f3, f4, f5);
Shape1.render(f5);
Shape2.render(f5);
Shape3.render(f5);
Shape4.render(f5);
Shape5.render(f5);
Shape6.render(f5);
}

private void setRotation(ModelRenderer model, float x, float y, float z)
{
model.rotateAngleX = x;
model.rotateAngleY = y;
model.rotateAngleZ = z;
}

public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5)
{
super.setRotationAngles(f, f1, f2, f3, f4, f5);
}

}

Здесь нам надо у super.setRotationAngles(f, f1, f2, f3, f4, f5); убрать super. и в конце файла вставить:
 public void render() 
{
Shape1.render(0.0625F);
Shape2.render(0.0625F);
Shape3.render(0.0625F);
Shape4.render(0.0625F);
Shape5.render(0.0625F);
Shape6.render(0.0625F);

}

Далее создаем класс RendererLadderModel и в него вставляем:

package testmod;

import org.lwjgl.opengl.GL11;
import net.minecraft.client.renderer.tileentity.*;
import net.minecraft.tileentity.TileEntity;

public class RendererLadderModel extends TileEntitySpecialRenderer
{
private static ModelLadder model;//наша модель

public RendererLadderModel()
{
model = new ModelLadder();
}

public void renderTileEntityAt(TileEntity tileEntity, double d1, double d2, double d3, float f)
{
this.renderTileEntity((TileEntityLadderModel)tileEntity, d1, d2, d3, f);
}

public void renderTileEntity(TileEntityLadderModel tileEntity, double d1, double d2, double d3, float f)
{
GL11.glPushMatrix();
GL11.glTranslatef((float)d1 + 0.5F, (float)d2 + 1.5F, (float)d3 + 0.5F);
GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
this.bindTextureByName("/testmod/models/wood.png");//текстура
this.model.render();
GL11.glPopMatrix();
}
}


Здесь мы выбираем модель блока, TileEntity и присваиваем текстуру.

И теперь всё, что нам осталось - добавить класс LadderBlockHandler, в который мы вставляем:
package testmod;

import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;

public class LadderBlockHandler implements ISimpleBlockRenderingHandler
{

@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer)
{
if(block == TestModBase.ladderModel) //Выбираем модель
TileEntityRenderer.instance.renderTileEntityAt(new TileEntityLadderModel(), 0D, 0D, 0D, 0F);
}

@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
{
return false;
}

@Override
public boolean shouldRender3DInInventory() //Надо ли рендерить блок в инвентаре
{
return true;
}

@Override
public int getRenderId()
{
return 0;
}

}

Готово. Наша лестница появилась в игре!

карма: 6
1
Голосовали:OTBETCTBEHHblN
Ответов: 1233
#2: 2015-01-03 20:03:57 ЛС | профиль | цитата
ккал
карма: -71
-1
Голосовали:OTBETCTBEHHblN
Ответов: 1584
#3: 2015-01-03 20:04:39 ЛС | профиль | цитата
Flagnum, сказал человек, сделавший подобный ник. (В чем прикол?)
карма: -14
0
Ответов: 13
#4: 2015-01-03 20:04:59 ЛС | профиль | цитата
Давно хотел запихнуть модельку в игру. Спасибо за статью.
карма: 0
0
Ответов: 1914
Noir Villar
Герцог
#5: 2015-01-03 20:06:06 ЛС | профиль | цитата
Лучше это размещай в специальном сообществе, многим посетившим эту тему будет либо неинтересно это делать, либо лень. И тема так и пропадет в низах форума.
карма: -1
Noir Villar
0
Ответов: 597
OnixCorp
Старожилы
#6: 2015-01-03 20:06:19 ЛС | профиль | цитата
ВООБЩЕ НЕ ЧЕГО НЕ ПОНЯЛ, НО КРУТО.
карма: -39
yshel na pokoy
0
Ответов: 541
#7: 2015-01-03 20:06:37 ЛС | профиль | цитата
-_-KANAPAK-_- писал(а):
ВООБЩЕ НИЧЕГО НЕ ПОНЯЛ, НО КРУТО.

карма: 3
0
Ответов: 13
#8: 2015-01-03 20:07:10 ЛС | профиль | цитата
den10 писал(а):
Лучше это размещай в специальном сообществе, многим посетившим эту тему будет либо неинтересно это делать, либо лень. И тема так и пропадет в низах форума.
На чём основано данное утверждение?
карма: 0
0
Ответов: 4557
#9: 2015-01-03 20:07:55 ЛС | профиль | цитата
Embr0n, кстати, тут речь идет про ModelBase.
Дабы впихнуть сферу, нужно ModelBiped.

Я постараюсь впихнуть сферу в игру и тогда создам туториал по бипеду.

Вот, кстати, ее код


public class Sphere extends ModelBase

{
public Test()
{
Shape1 = new ModelRendererTurbo(this, 64, 32);
Shape1.setRotationPoint(-5F, 12F, -3F);
Shape1.addSphere(0, 0, 0F, 0F, 0F, 8, 25, 25);
Shape1.rotateAngleX = 0F;
Shape1.rotateAngleY = 0F;
Shape1.rotateAngleZ = 0F;
}

public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
{
super.render(entity, f, f1, f2, f3, f4, f5);
setRotationAngles(f, f1, f2, f3, f4, f5);
Shape1.render(f5);
}

public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5)
{
super.setRotationAngles(f, f1, f2, f3, f4, f5);
}

//fields
public ModelRendererTurbo Shape1;
}

карма: 6
0
Ответов: 1584
#10: 2015-01-03 20:08:14 ЛС | профиль | цитата
Embr0n писал(а):
На чём основано данное утверждение?

Личная непривязнь...
карма: -14
0
Ответов: 13
#11: 2015-01-03 20:10:30 ЛС | профиль | цитата
Я в этом может и не разбираюсь, но можно ли как-то увеличить terrain без дополнительных вещей, типа модлоадера и т.д.?
карма: 0
0
Ответов: 1914
Noir Villar
Герцог
#12: 2015-01-03 20:11:19 ЛС | профиль | цитата
Kubastaya, неприязнь*
Embr0n, наверно на том, что большинство лишь комментирует и только
карма: -1
Noir Villar
0
Ответов: 1233
#13: 2015-01-03 20:11:24 ЛС | профиль | цитата
модлоадера ?
карма: -71
0
Ответов: 13
#14: 2015-01-03 20:12:01 ЛС | профиль | цитата
Flagnum, я же говорю, что в этом не разбираюсь. Я мог что-то ошибочное написать.
карма: 0
0
Ответов: 4557
#15: 2015-01-03 20:35:22 ЛС | профиль | цитата
Embr0n, да, но нужно будет переписывать координаты. Но как вариант - создать отдельный терреин и приписать условие: если блок имеет ID, допустим, 200 или выше, то текстура берется из второго терреина. Также и с предметами.
карма: 6
0
Ответов: 51
#16: 2015-04-02 10:22:38 ЛС | профиль | цитата
апну
карма: -15
-1
Голосовали:OTBETCTBEHHblN
16
Сообщение
...