[SOLVED] Using minecraft ideas for code, and It doesn't work :(

:clue:
So… I looked into what minecraft did for blocks, and it was cool sounding to me. In Block.class, he defined a whole bunch of blocks, their traits, and used a seperate class for all the block-specific methods needed. Like this:

EXERPT FROM Minecraft’s Block.java


public static final Block stone = (new BlockStone(1)).setHardness(1.5F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stone").setTextureName("stone");
    public static final BlockGrass grass = (BlockGrass)(new BlockGrass(2)).setHardness(0.6F).setStepSound(soundGrassFootstep).setUnlocalizedName("grass").setTextureName("grass");
    public static final Block dirt = (new BlockDirt(3)).setHardness(0.5F).setStepSound(soundGravelFootstep).setUnlocalizedName("dirt").setTextureName("dirt");
    public static final Block cobblestone = (new Block(4, Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stonebrick").setCreativeTab(CreativeTabs.tabBlock).setTextureName("cobblestone");
    public static final Block planks = (new BlockWood(5)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("wood").setTextureName("planks");
    public static final Block sapling = (new BlockSapling(6)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("sapling").setTextureName("sapling");
    public static final Block bedrock = (new Block(7, Material.rock)).setBlockUnbreakable().setResistance(6000000.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("bedrock").disableStats().setCreativeTab(CreativeTabs.tabBlock).setTextureName("bedrock");
    public static final BlockFluid waterMoving = (BlockFluid)(new BlockFlowing(8, Material.water)).setHardness(100.0F).setLightOpacity(3).setUnlocalizedName("water").disableStats().setTextureName("water_flow");

So every time you wanted to reference a block, you would do (I assume, since all the obfuscation for making the blocks is too hard to decipher):


blocksinworld[0][1][1000] = Block.planks;

So I did that with my blocks:

		Voxel[][] returning = new Voxel[2][2];
		
		returning[0][0] = (Voxel) Voxel.dirt.setPos(4, 0, 4);
		returning[0][1] = (Voxel) Voxel.dirt.setPos(4, 0, 5);
		returning[1][0] = (Voxel) Voxel.dirt.setPos(5, 0, 4);
		returning[1][1] = (Voxel) Voxel.dirt.setPos(5, 0, 5);


		return returning;

And my Voxel.java:

public class Voxel extends Entity {
	Texture texture;
	
	public static final Voxel dirt = new VoxelDirt();
	
	
	public Voxel(String name) {
		super(name);
		try {
			texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/default_vox.png"), GL_NEAREST);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void update() {
		
	}

	public void render() {
		glPushMatrix();
			glTranslatef(x, y, z);
			
		//renders all the vertices using vertex array objects. Don't judge.
		TVAO(24, 3, 2, new float[]{ 
				1,0,0, 1,1,0, 1,1,1, 1,0,1,
				0,1,0, 1,1,0, 1,1,1, 0,1,1,
				0,0,1, 1,0,1, 1,1,1, 0,1,1,
				
				0,1,1, 0,0,1, 0,0,0, 0,1,0,
				1,0,1, 0,0,1, 0,0,0, 1,0,0,
				1,1,0, 0,1,0, 0,0,0, 1,0,0,
				}, new float[] {
				0,0, 1,0, 1,1, 0,1,
				0,0, 1,0, 1,1, 0,1,
				0,0, 1,0, 1,1, 0,1,
				0,0, 1,0, 1,1, 0,1,
				0,0, 1,0, 1,1, 0,1,
				0,0, 1,0, 1,1, 0,1,
		}, texture);
		
		glPopMatrix();
	}
}

But that just produces this:

I don’t really understand… Whats the problem here?

If Voxel.dirt is 1 final object, then you are calling setPos on the same object over and over.

With that code essentially what it (seems) to be doing is creating a stagger of blocks like this:

I may be incorrect but, as I don’t fully understand your problem, I don’t know how I can help. Would you mind explaining what your problem is more in depth?

Hm. Well in that case I suggest you go through and just recheck your loop and how you are using translate. You may just be pulling coordinates that equal zero. Are you setting the blocks x and y when you call the method setPosition? It may be an empty method :P. And if I was you I would create a chunk manager that renders all the blocks in that chunk. That way it is alot easier to render and load blocks that are in range.

I didn’t mean the little purple and black block, I meant the grass looking texture in the background which I am guessing now is a skybox.

He’s obviously setting the x and y. Thats just silly… Anyway. I have never used a final static instance of this code, I’ve always just used static. Basically - public static Tile Grass and then I call that and when I go to render the tile, I loop through the list of tiles and render using the loops x and y values. I don’t believe I even stored the x and y values in the tile class.

You’d be surprised how many times one can forget to set the values :wink:

Unless you initialize them to zero when you create them. I shouldn’t have suggested that, my bad. I suggest you take any of opiops suggestions over mine though, he is more experience in voxels from what I have seen.

I’ve never forgotten to set my values… No offense. And Wesley I’d recommend looking up the cherno project on YouTube and seeing how he does his tile systems. I basically stole his, and it works great. Its also exactly what you’re trying to do here.

Can you seriously not clone Voxel.dirt? Do you not understand OOP? Do learn how to use objects and polymorphism before you do any graphics programming at all.

Just because I’m benevolent, add a “copy()” or a “clone()” method so your 1-line-code stays:


//Voxel.copy()
public Voxel copy() {
    return new Voxel(this);
}


//Add this construct to Voxel
public Voxel(Voxel other) {
    //copy all the variables
}


//magic!
returning[0][0] = (Voxel) Voxel.dirt.copy().setPos(4, 0, 4);
returning[0][1] = (Voxel) Voxel.dirt.copy().setPos(4, 0, 5);
returning[1][0] = (Voxel) Voxel.dirt.copy().setPos(5, 0, 4);
returning[1][1] = (Voxel) Voxel.dirt.copy().setPos(5, 0, 5);

I told you to add it, I just edited my post to supply it because I expected you to say it didn’t exist :cranky:

And either way, clone() does exist, however it exists in the Object class, requires you to implement the Cloneable interface, and is protected, so it cannot be called outside the Voxel class unless you override it and set it to public.

The point of the Minecraft code was to have one instance of the object that could be in many places at once. What you should do when rendering is pass in the block’s coordinates, and render based off that.

The block should not know where it is except when told to do something at a certain location.

You’re using two very different design patterns together, and using bad methods to make them work together.

Yup, the object’s coordinates are already at its array location anyway, no need to create a new object for each location.

Aha, thats what I do too. I alway knew it was a good idea to use that system… I really like it. Its flexible and pretty easy to use. thechernoproject on YouTube has a great tutorial on this system, I’d recommend checking it out wesley.

Right just to run through some stuff , one of the most efficient ways to render stuff like this is to store a new object(dirt) in each area of your matrix that you require it for example (x,y,z) map[3][4][5] = blocks.getnew(“dirt”); But have all the graphics and collision detection in a class such as dirtstatic() so you are not having to store a new value and then just use simple detection methods to find out which block to draw.


public class staticdirt {
	private sprite icon;//setup the sprite object
	private String name = "dirt";//makes checking your objects much easier by comparing names not the actual objects
	private collisionbox col = new collisionbox(2,2,3,3);//if you need one 
	private boolean loaded = false;//stops errors
	public staticdirt(core){//you only need to instantiate this once.
		icon = core.getsprite("location");//load the sprite
		loaded = true;
	
	}
	public sprite getsprite(){//use basic encapsulation
		if(loaded){
			return icon;
		}
	}
	public String getname(){
		return name;
	}
	public collisionbox getcolbox(){
		return col;
	}
}


public class dirt() extends block{
	//vars
	public dirt(){
		super();//constructor
	}
	//method overrides
}

Quick tip: class names always being with a capital letter. Class names, method names, and variable names all use CamelCase.

Yup sorry about that sloppy naming was in a rush with my maths homework!