Minecraft 2d Remake: Building and Destroying Blocks Issue - java

I am well into creating my 2d remake of minecraft in java. I know it can be done well, orange451 on youtube inspired me to try and make this. I have all blocks on the map loading from text files, and when the game loads, it adds all of the blocks from the text files to an ArrayList. I created an algorithm for calculating the index of the block your cursor is on in the game, and added a MouseListener so that when i clicked it would replace the block with an air block (basically destroying the block). To replace the block in the ArrayList, I used the ArrayList set(index, obj) method. In theory, it should be working correctly, and it in a way does. The only problem is that it also creates a black space in the map a few blocks away. This is extremly frustrating, especially since I have come so far. ADDITIONAL INFO: I need a method that will replace the object in the ArrayList, or a better way to do it because my collision detection method also uses the ArrayList to detect a blocks position. PLEASE HELP ME! I cant post images but its setting the block to the air texture but creating a black square (a gap in the arraylist mabey?) near it. Because theres too much code to post, heres the source code for the whole project: Blockworld 2D Source

You're struggling with this because an ArrayList of objects that know their coordinate is an insane way to represent this 2d structure. It's unordered - you could reverse or shuffle your ArrayList and it would paint the same. It has O(N) update, as you have to search the ArrayList for an object of the appropriate coordinate before you can replace it. It can have more than one object with the same coordinate. It can be in a state where visible coordinates do not have corresponding objects at all -- which is what you've encountered, here.
PLEASE HELP ME
OK. Start with a two dimensional array (array, not ArrayList) of byte. Which allows you 256 kinds of block, and which allows your players to dig without constantly allocating memory with your new AirBlock(0, 0) madness. To draw the world, iterate over visible coordinates and map bytes to Bitmap or like.
Also: a 2d Minecraft already exists. It's called Terraria.

Related

Implementing a 2-Dimensional Position for Java

I want to know what I should use for 2-dimensional positions for a Sprite.
I see Dimension objects referring to size, mainly around GUI components.
I was thinking about doing int[2], but it could easily be sabotaged by inserting in an empty array or one with the incorrect number of elements.
I only see Point objects around Mouse positions, so I don't know if it has the same purpose as what I'm looking for.
I have no idea what to choose for my purpose.

Filling enclosed space / air inside voxel models - any fast algorithms?

I've created a Voxelizer for .obj models which is working pretty well so far. However, it only turns the surface of the model into voxels and doesn't fill it up. And filling it up afterwards is very important for further exporting and optimization.
I was thinking about options to fill up the space but just couldn't put my finger on an efficient algorithm that does it.
This is what the inside of a "cat" looks like, exported as .obj again.
Is there any fast algorithms for detecting enclosed space within a voxel shape?
My voxels are being stored using either a
List<Voxel> //Voxel contains 4 integers for x,y,z,rgb OR
Map<int[], java.awt.Color>.
I would need an algorithm that works really efficiently with one of these.
here's the best approach I've come up with so far:
1) It starts from the assumption that you only have one volume: no separate polygon meshes. That's easy to check. If it doesn't hold true, extra steps would be required, but the process would still be the same.
2) Take any voxel in the grid which is not part of the shell voxels. ray trace it to the closest point on the mesh to figure out whether this is part of an inside or outside volume.
3) Recursively flood to all the neighbours which are not in the shell either, until there's no where to grow. When that happens you have recognized either the outside or inside of your mesh (depending on where you started).
4) finding the opposite volume is a simple subtraction operation: vol_2 = all_voxels - shell - vol_1. if vol_2 is empty, your shell is open and the flood operation permeated through the gaps.

Rendering very big 2D Map

I want to create a 2D Game with Java and LWJGL. It is a retro styled RPG game. So there is a really big map(about 1000x1000 or bigger). I want to do it with tiles but I don't know how to save it/how to render it.
I thought at something like a 2D-Array with numbers in it and the render just sets the right tile at the right place.
But i think the bigger the map gets the more it will slow down.
I hope you can help me. :)
My second suggestion was to make a big image and just pick a part of it(the part where the player is) but than its hard to know where I have to do a collision detection, so this ist just an absurd idea.
Thank you for your suggestions!
As one of the comments mentioned, this subject is far too large to be easily covered with a single answer. But I will give you some advice from personal experience.
As far as saving the map in a 2D array, as long as the map is fairly simple in nature there is no problem. I have created similar style maps (tiled) using 2D integer arrays to represent the map. Then have a drawing method to render the map to an image which I can display. I use multiple layers so I just render each layer of the map separately. Mind you most of my maps are 100x100 or smaller.
I would recommend for such large maps to use some sort of buffer. For example, render only the playable screen plus a slight offset area outside of the map. E.g. if your screen if effectively 30x20 tiles, render 35x25, and just change what is rendered based on current location. One way that you could do this would be to load the map in "chunks". Basically have your map automatically break the map into 50x50 chunks, and only render a chunk if you get close enough that it might be used.
I also recommend having the drawing methods run in their own thread outside of the main game methods. This way you constantly draw the map, without having random blinking or delays.
I'm maintaining my 400*400 tiles map in the Tiled map editor and render it with the Slick2D framework. It provides support for rendering only visible subsections of the map. (TiledMap class).
I've tried both approaches - Image based and tiled based map creation and ended up with the latter. With tiles you can not only create the view of your map but also invisible meta data layers, like collision, spawn spots, item locations etc.

Trying to make a game viewer without changing the location of every object when camera changes

I've build a simple click and drag background for a program I've written which is all good and working. It adds on the distance moved by the mouse while held down. However thinking ahead I'd have to do this for all objects every time I moved the image as I was going to give the objects positions relative to the image and this might cause a few issues with processing power.
What I would like to do is have the background in a set position within the program and move the users view over the image without having to change the position of every object every tick, the problem I'm having is where to start and how to build something like this.
Thanks in advance
Well you need to tell your program where the objects are supposed to be drawn somehow.
It sounds like you are currently thinking to draw your frame by looping through your objects and drawing them at their location, and when you move the background, updating the object location.
If that method isn't sitting well with you, you could create a sort of 'map' (2-d array of pixels/locations) that you fill sections in on when you create new objects. Then when you go to draw your frame, you could scan through some range of positions in your 'map' and draw the objects that you find. When the background is moved, you could then keep the offset in a single location and use that when determining what range of map values to scan through.
i'm not positive how the processing implications of these two methods compare, i'm sure it depends on the size of your frame, level of detail, and number of objects that you have offscreen at any time.

creating a grid of rectangles dynamically

I wanted to create Conway's Game of Life. I read the Java 2d API, but the Graphics class only provides methods to drawRect() and fillRect() on the paintComponent of a JPanel. I mean that the rectangles cannot be handled individually as objects i.e. so that i can check which one is on in relation to the ones in the vicinity.
So I wanted to ask how are squares to be made so that they can be handled individually and the grid be created dynamically?
Create a Sqaure class with all properties required.
Create a list of Square objects representing the board.
In the draw method for the JPanel, iterate over your list of Square objects, drawing each one out, based on its properties.
Keep your display code separate from your logic as much as possible - it's nearly always a good idea.
I'd like to propose a completely different solution. Normally have to treat the generated graphics as output-only, meaning, you don't want to read state from the graphics because that'd be too slow.
You'll have to keep the state of the cells elsewhere, like in a two-dimensional array.
boolean[][] or int[][] for example.
Then you'll need a "render" method of sorts, that takes the values of your cells, and draws it out.
But I'd like to propose an even cooler way of doing this. Instead of keeping a two dimensional array, use the (one dimensional) array that a BufferedImage is made up of.
Normally, each "pixel" is an element in that array. Then you use drawImage to draw that image, and scale that image up. This could perform really well. You might be able to have an entire screen draw in real time pretty much.
There are various methods on BufferedImage, it gets a little confusing at first. In the end you'll find a DataBuffer somewhere. You'll want access to the int[].
Then, to set a cell: data[y * width + x] = -1; (white cell)
to clear a cell: data[y * width + x] = 0; (black cell)
(for example - or vice versa - or any other color).
You can get really fancy with this. You could use various offset variables instead of having to calculate the y*width+x all the time, and optimize it really well.
In fact, I go as far as being able to make it so efficient, that you could actually outperform another guy making the exact same program in C++.

Categories

Resources