It seems several people are getting stuck in this video so I created a FAQ for your reference. Q: The world map is not loading/Only the grass tile is showing. A1: Check if the file paths and the names that you have typed in the getTileImage method are identical to the actual file names and the file paths (check the package name, its placement etc). If they don't match, the program stops there and the rest of the code won't be processed. To check this, type System.out.println("Image loading started"); at the start of the getTileImage method then type System.out.println("Image loading finished"); at the end of the method. Run the program and if the first text showed up on the console and the second text didn't, something went wrong during the loading. If the second text also showed up, your tile images are loaded correctly so the issue is coming from somewhere else. A2: Check if you have correctly switched from maxScreenCol/Row to maxWorldCol/Row. It seems quite a few people somehow forget to update these variables. Check the TileManager(), loadMap() and the draw() methods and make sure all of these variables have been updated correctly. A3: Check if a space has been inserted between the double quotations of the line: line.split(" "). Also check if a space has been inserted between numbers in your map file. The space is the key to split the line and get tile numbers individually so make sure these conditions are matched. A4: Check if you have passed a correct map file to the loadMap method. Here's the line: loadMap("/maps/world01.txt"); If this file name or path is incorrect, the program cannot load the map. Hope this helps!
Im using this now in 2024 and it is working like a charm. "If you want to skip this part but it will make it run better-". Dude, if you can help me more I am up for it always. Thanks for teaching me ❤
Thank you RyiSnow, this whole 2d game tutorial that you make helps me to learn more in java programming/developing, i'm currently learning game developing in java and using your tutorial helps me to create my own game with different mechanics(the game im thinking to make is somekind of 2d shooting arcade where for each wave the horde of enemy is getting harder)
Messing with the text file for the map annoyed me so I ended up spending hours researching and reverse engineering equations to create a method to get the rgb values of a pixel and used that in combination with your text file method of treating it like a 2d array to create a map that is a png and can be changed easily. It honestly was a lot of fun to figure out and I’m really proud of myself for doing it, it took me a couple days but now I understand Java much better, specifically how libraries work, which no one ever really explained to me in school. I wanted to thank you for making this series as it very informative and beginner friendly, unlike most tutorials where they go straight to the final and most efficient and complex version of their code.
working through these videos to get better at java and I really appreciate how clear and simple you made them...thanks for keeping the resource files available as well
Would be nice with like a cheat sheet for this tutorial. I understand if it takes to much of your time. But some parts are really hard to understand. Easy to follow, but really hard to replicate on your own. Maybe put a patreon site or something and expand your channel :).
What do you mean by cheat sheet? Can you be more specific? I don't feel like doing patreon because letting people pay monthly would likely give me an extra pressure. I would feel like "I have to make something because people are paying!" and that's not good for my mental health haha. I'm accepting one time donation via ko-hi though.
I'm having a hard time understanding the things about world and screen coordinates, but i hope i can get it eventually when i practice. Thanks for your dedication! Looking forward for more!
I know, those are pretty confusing at first. World x and world y are the coordinates used for the world map. So in a way, they are abstract coordinates. On the other hand, screen x and screen y are actual coordinates used to draw stuff on the game screen (JPanel in this case). Example: If player is standing on the [0:0] tile, the [0:0] tile is displayed at the center of the screen since player character is always displayed at the center of the screen. If player is standing on the [1:0] tile, the [1:0] tile is displayed at the center and the [0:0] tile is displayed at 1 tile to the left from the center. In other words, tiles' screenX and screenY change depending on the player's current position. On the other hand, tiles' worldX and worldY don't change since tiles position on the map are fixed. Hope this helps. If there's something that you're stuck specifically, feel free to ask!
@@RyiSnow I get that I just completely don’t understand how the code does it. I’ve been looking at this every day trying to figure it out so I can progress but it seems mind boggling to me.
If you guys are running into the tile issue and followed RyiSnow's FAQ then your issue is probably maxWWorldCol and maxWorldRow. For me, I made my own map and then followed his code exactly. Since my map size and the maxWorldCol/Row were different it only showed grass. For example, if your map size in the txt file has a row of 50 tiles horizontally and vertically then you have to set the maxWorldCol/Row to 50. Hopefully, this helps at least 1 person 😅
Love the tutorial! :D Just a suggestion or a tip: When you're changing a variable's name in Eclipse, you can right click the variable, click "refractor" and then click "rename", it will put a box around the variable, whatever you write inside that box will rename the variable everywhere in your code so you don't have to do it manually. :)
Glad you liked it :-) Yes, I know Eclipse has such function. The reason I'm not using those shortcuts is because this is a tutorial. I want everyone to get a clear picture of their code by checking them by themselves. Auto rename/replace is a good function when you have a very good understanding about what you're doing though. But if you don't (which is often the case when you're trying to learn something new), using it is not always a great idea because sometimes it makes you lose track of what has changed and why it has changed.
I was trying to think what a high level analogy for this drawing technique would be. It seems to me that the key is to think of the output window as a camera that has its lens and position totally fixed and immovable. If you think of it as being like an animation camera photographing animation cells, then the player's character would be like a top layer that always has its position fixed to the center of the camera lens. The game map would then be like the background cell that's underneath the player. You can imagine the map being on rollers that can shift it up and down, while the player cell above remains fixed. The map can be much larger than the camera's field of view, so maybe only a portion of it is viewable by the camera at any given position. The movement of the map simulates player movement, but really we are just shifting the map in relation to directional input from the user so that the cell with the player on it appears to move where the player wants it to. The camera itself never moves to different parts of the map. Instead the map is always shifted under the camera.
When we go into the actual code, the player has a world map coordinate position which is changed by user input. The reason the map scrolls is because when the player position changes, we shift the x or y map position in relation to the fixed camera view. The player sprite is always drawn in the center of the camera, and the entire game map is drawn around this position based on the offset calculations in the draw() method and starting from the player's coordinate position on the map. For example: -If you set the player position to (0,0) in the player class and comment out the (x, y) map offset calculations in draw() method, the top left corner of the camera will line up with the top left position (0,0) of the game map, with the player sprite in the center of the screen. However, even though the player map position is (0,0), the sprite is not at position (0,0) on the map because we removed the screen offset. int screenX=worldX - gp.player.worldX ;//+ gp.player.screenX; int screenY=worldY - gp.player.worldY;// + gp.player.screenY; -If we put the (x,y) offset calculations back, the map has now shifted so that both the center of the camera(where the player is drawn) and the player's map coordinates are now at the (0,0) coordinates in the top left corner of the map, with the area outside the map data being filled in with the background color beyond that. int screenX=worldX - gp.player.worldX + gp.player.screenX; int screenY=worldY - gp.player.worldY + gp.player.screenY; -If we're still at (0,0) and the player inputs right direction movement, the player's x position on the map will increase, and the game map's x offset will decrease relative to the camera position (because of the offset calculations in draw() method). As a result the game map shifts to the left while the player sprite remains in the same position in the center of the camera. It seems like the actual code for the camera itself is implemented in the java graphics library we're using. For the analogy above to work though, the camera has to be thought of as its own element that's objective, fixed in place and separate from the game map that shifts up and down under it.
He should use for loops, he over complicated it with all the variables and using the while loops. I wrote everything prev as a for loop, and I got to that part and now I gotta redo the whole thing I think, lol. He's knowledgeable with the keywords and use of classes though!
@@centro.4k Yes, I automatically wrote the last lesson as nested for loops. That was a good thing though because making my code work made me think harder about what's going on this lesson. I'll post my draw() method code below in case it helps someone to look at another way of doing it. public void draw(Graphics2D g2){ int x=0, y=0; //map coordinates offset relative to player position int worldX=0, worldY=0; //objective world map coordinates int i, j; // row and column iterations for the current tile of the world map for (i=0; i < gp.maxWorldRow; ++i){ //outer for loop worldY = i * gp.tileSize; //move down 1 tile length for each outer iteration //only call the inner loop if the current map y coordinate is in the frame of the camera if (worldY + gp.tileSize> gp.player.worldY- gp.player.screenY && worldY -gp.tileSize < gp.player.worldY + gp.player.screenY) { y= worldY -gp.player.worldY + gp.player.screenY; //offset map y coordinate in relation to player for (j = 0; j < gp.maxWorldCol; ++j) { //inner loop worldX = j * gp.tileSize;//move 1 tile over each inner iteration //only draw the tile if the map x coordinate is in the frame of the camera if (worldX + gp.tileSize > gp.player.worldX - gp.player.screenX && worldX - gp.tileSize < gp.player.worldX + gp.player.screenX) { x = worldX - gp.player.worldX + gp.player.screenX; //offset map x coordinate in relation to player int tileNum = mapTileNum[i][j]; //get the tile type g2.drawImage(tile[tileNum].image, x, y, gp.tileSize, gp.tileSize, null); //draw tile } } } } }
Ughhhhh, the camera/coordinate logic is breaking my brain :( Think I'm gunna have to watch this one a couple times. Edit, still confused on how the camera logic works, but I found my bug (of course, it was in the file path, I forgot the .txt for my map.... lol), and now it's working beautifully!! I'm so stoked. I've only been learning Java for a day now, and your videos have been so incredibly helpful and motivating! Thank you so much, can't wait to continue :)
Awesome tutorial!!! I solved my map drawing problem, here was my error: int worldX = worldCol + gp.tileSize; int worldY = worldRow + gp.tileSize; It should have been: int worldX = worldCol * gp.tileSize; int worldY = worldRow * gp.tileSize; Thus, I accidentally used + instead of * , which meant that it got broken, I hope this helps you, reader of this comment!
I Like the way he said "you'll understand it eventually", even i have know fk ing idead whats going, and when the time comes, i will understand it, step by step 🙂
Great video! However please notice that the draw method even after improving the efficiency is still not very effective (time complexity of O(n^2) if the map size is n^2) this could be a real problem for huge\infinite generating maps. Instead of checking every map tile (Is it or is it not in the player camera), I suggest taking the player coordinates, translating them to the array coordinates, and drawing the map only from those coordinates. By doing that even if your map is ridiculously big, your while loop will only use constants (screen coordinates) as the boundaries. Thank you for sharing this tutorial.
@@RyiSnow hi, can you maybe do a video about this? my draw time is so long that i had to go down to 30 fps instead of 60. I don't really understand how to do what deanelie7775 suggested, but i think this might be useful for some people
@@justguni7324 I managed to do it like this, it might be a little late, but could be helpful to someone public void drawV2(Graphics2D g2) { int tileSize = gamePanel.tileSize; int playerX = gamePanel.player.worldX; int playerY = gamePanel.player.worldY; // Translate player coordinates to map tile indices int playerTileX = playerX / tileSize; int playerTileY = playerY / tileSize; // Calculate the range of tiles to draw int startTileX = Math.max(playerTileX - (gamePanel.maxScreenCol / 2) - 1, 0); int endTileX = Math.min(playerTileX + (gamePanel.maxScreenCol / 2) + 1, gamePanel.maxWorldCol - 1); int startTileY = Math.max(playerTileY - (gamePanel.maxScreenRow / 2) - 1, 0); int endTileY = Math.min(playerTileY + (gamePanel.maxScreenRow / 2) + 1, gamePanel.maxWorldRow - 1); for (int worldRow = startTileY; worldRow
After 2 and a half days of trying to solve an illegalArgumentException error I finally fixed it by just changing the tiles that weren't reading. I was about to throw my laptop out of my window. Programming is not for the weak!
Thank you for the awesome tutorials! 0 && screenY + gamePanel.tileSize > 0 && screenX < gamePanel.screenWidth && screenY < gamePanel.screenHeight) { g2.drawImage(tile[tileNum].image, screenX, screenY, gamePanel.tileSize, gamePanel.tileSize, null); } ``` Otherwise your if statement is also correct. It took me a little bit of math transformations to prove it is correct though :)
So basically, player screenX and screenY is where the player is drawn on the screen, it is not a position on the world map. The world map is drawn first and separately, and the player just overlaps the world map drawing. The only thing the player cares about is being at the center of the screen. Now the camera decides the area of the world map that the screen is drawing. So first you create world map, then you add camera that zooms in on certain part of world map, then player is drawn at the center of this camera.
Thank you for such an amazing tutorial so far! I am learning Java and was having a hard time applying my knowledge. This has been such an amazing way to learn! I can't wait to keep going! #wolrd
Don't worry mate, your explanations are very well enough. Who ever wants to develop games should at least understand these offset things.^^ 😉😉😉 The harder things will come when anyone tries to create a 3D game.^^ And especially when shadows and lightnings are joining the game.^^ 🤣🤣🤣🤣🤣🤣
I had only grass drawn and I solved this problem! I downloaded the map from the author, but it may seem that there is 100x50, but in fact he has a space between the numbers! So 50x50, the spaces between the numbers do not need to be deleted. maxWorldCol = 50; maxWorldRow = 50; Everything is correct! Thx 4 video
You can use default key(Alt+Shift+R) in Eclipse to rename a variable to something else which changes all the occurrences of that variable in that file.
Sincerly thanks you a lot your really pedagogue you are actually realizing on of my child wood dream ! i hope i will can create by my own after understanding the "mecanism" of 2D games.
Thanks for the wonderful series! Truly appreciate it :) I have a question: how would you go about implementing a screen scrolling effect when moving around the map like in the original Legend of Zelda?
Love the video, great stuff. I'm having a problem when trying to load my world map. For some reason it loads with no tiles and an all-white background. It also doesn't allow me to close the window. The world map was loading fine until I implemented the camera.
Thanks for the lessons had some problems with the code. Re wrote it works fine. I think that sometimes there are system problems in computers memory not just syntax, logic, or runtime errors.
I am working on remaking an old game called boulder dash. I had this issue were i needed the player's initial position somewhere else than the center of the screen. And perhaps this caused the problem where my character stopped before reaching the wall ends since the camera had reached bounds. I am trying to solve this by using worldX and worldY as coordinates in the player drawing method instead of screenX and screenY. For the case of this causing the black borders of the screen to show i simply adjusted the calculation made in the tile painting function. Even though i must admit i am still quite lost in the camera calculation explaination being new to all this😂. I shared this hoping it might help someone with a similar problem. Happy Coding!
It takes a little more work, but loading only the parts you want can save a lot of processing time. Reloading everything now takes about 4.7ms per refresh!
Great videos. Makes me wonder if this was how they made the old NES final fantasy games and how much code that was written to make them. Amazing how people figure these programming languages out. And ways of using them.
NES games were made in an assembly language that is closer to machine language and in a way, much more primitive than modern computer languages. So I think it was much harder to code back then!
hey ryi , I really wonder if there is any specific reason why you use "weird" while loop instead of nested for loop? is it for optimization purposes or it is just your preference. Thanks . P.S you are god of tutorial bro keep it up .
btw. Great videos! You're very kind to make these. Note, here a little more efficient way to do the draw() method for the TileManager. Instead of ignoring the non visible tiles (like you do with your if/then check), I use the Java Modulo to determine the negative offset of the x & y tile start position. Here's the sample code. Again thank you! (this is in no way a discredit to your work)... public void draw(Graphics2D graphics2D) { // tilePosition should start at the negative modulo of the player position in the world % scaled tile size int tileXPosition = - gamePanel.getPlayer().getXWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize(); int tileYPosition = - gamePanel.getPlayer().getYWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize(); int columnOffset = (gamePanel.getPlayer().getXWorldPosition()/ResourceLoader.getGameSettings().getScaledTileSize()) - (ResourceLoader.getGameSettings().getMaxScreenCol()/2); int rowOffset = (gamePanel.getPlayer().getYWorldPosition()/ResourceLoader.getGameSettings().getScaledTileSize()) - (ResourceLoader.getGameSettings().getMaxScreenRow()/2); for (int rowNum = rowOffset; rowNum= 0 && rowNum < ResourceLoader.getGameSettings().getWorldMapSizeY()) { String mapTile = mapOfLand[columnNum][rowNum]; graphics2D.drawImage((tilesMap.get(mapTile).getImage()), tileXPosition, tileYPosition, ResourceLoader.getGameSettings().getScaledTileSize(), ResourceLoader.getGameSettings().getScaledTileSize(), null); } tileXPosition = tileXPosition + ResourceLoader.getGameSettings().getScaledTileSize(); } tileXPosition = - gamePanel.getPlayer().getXWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize(); tileYPosition = tileYPosition + ResourceLoader.getGameSettings().getScaledTileSize(); } }
8:12 screenX = gp.screenWidth/2 - (gp.tileSize/2); screenY = gp.screenHeight/2 - (gp.tileSize/2); You don't have to use brackets. Basics of mathematics ;)
I need Help. Half of the world won't load. any suggestions? EDIT: forgot to change maxScreenCol to maxWorldCol. ... if(worldCol ==maxWorldCol){ worldCol = 0; worldRow++; }
Hello!! For those experiencing problems with the tiles being drawn, your maxWorldCol and maxWorldRow may be the problem. Count the exact number of rows and columns on your map and set them respectively to the maxWorldCol and maxWorldRow. You see, to have the correct tiles drawn, your while loop has to set the numbers correctly. In other words, to meet the correct criteria (e.g., if you have 32 columns, set your MaxWorldCol to 32). Let’s look at this case scenario: If you set your maxCol to 50 and you only have less than 50 columns, the while loop will not correctly process your map as it does not meet the required criteria. In this video, RyiSnow has a 50x50 map (50 rows and 50 columns), hence why his maxWorldCol and maxWorldRow are set to 50. However, your map may not be 50x50. And if you’ve set those values to 50, it won’t work correctly.
I have a issue, i know it's probably late to say this, but even if i set the boundaries of the map, the player, after going out of the 50x50 map, still walks in the black background, without the map limit. How do i fix this?
My code renders the map properly but whenever I go towards the top or left it starts drawing the black background too. What should I change? Thankyou.(btw Great tutorials!)
I can't believe I missed this simple line of code, I had to of implemented it before but took a break to try to teach myself after guide 40ish. Now watching everything again 😁 awesome teacher right here 👏 making this for Android currently so lots of differences but lots of similarities too. (worldX + game.scaledTileSize > game.player.worldX - game.player.screenX && worldX - game.scaledTileSize < game.player.worldX + game.player.screenX && worldY + (game.scaledTileSize*2) > game.player.worldY - game.player.screenY && worldY - (game.scaledTileSize*2) < game.player.worldY + game.player.screenY)
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
Great tutorials but what if i want to make somehow the 'camera' to move around the map but not actually move a background instead, because i will have other objects that will move in relation to background? Do you have any idea?
Hey! I have a question, I found when I run the game and my character moves down and to the right, the rendering is fine. But when I move up and to the left, a bunch of black lines starts appearing. What do you think the problem would be?
i have the same problem, I've been trying to fix that for months now. Please @RyiSnow, any ideas on how to fix that? I have the assumption that it's a hardware problem. I gave my code as well as sprites and everything else to some friends of mine so that they could try to run the game, and it seems to work fine for them. I guess if the graphics get too heavy for your hardware the program starts having those graphic bugs. Since that would mean that the Java 2D Graphics compontent are too heavy for the PC to handle I began to rewrite the game that I'm making in the LWJGL, which is an external library that has improved rendering options to make stuff like these graphic issues non-existent. I didn't progress far enough to check if the LWGJL is actually the conclusion for this problem yet tho, so I'd love an answer from you Snow - You might be able to help. I really need to fix that
it happened to me when I added a bunch of print lines to do bug fixing, I think it has to do with the loop taking too much time to process. if there is anything that can be axed it might be a good idea to try that.
@@nick8283 For anyone experiencing black or otherwise colored lines when moving up or to the left, try doing this: This method is called Double Buffering, basically what you will do is draw your entire game to a hidden image buffer, and then copy that buffer to the screen. To do this follow these steps: (This is all in your GamePanel class) 1. Create a BufferedImage the same size as your screen: public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB); 2. Get a Graphics2D object for the buffered image by calling `getGraphics()` on the image in your paintComponent() method: Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics(); 3. Draw everything to this buffered image. Then draw this bufferedImage to your screen. All in all, your code should look something like this: public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB); public void paintComponent(Graphics g) //standard method { super.paintComponent(g);
i love your vids. they really helped me out a lot!! i just wanna know if there's any way to use an custom drawn image as a world map as i want to use my custom map that i drawn. everything is helpful so far. Great Work!!!
thanks for tutorial butt I beg you to explain the camera implementation the way you explained it doesn't add up to the mechanism of the tiles rendering :(( are the tiles or screen moving....
The tiles that make up the game map are shifting up or down and left or right and the camera is staying in place. When the user inputs a direction, the screen redraws the tiles using the map data in the text file, offsetting it from the player's new position on the game map. In this code, you can think of the camera as being completely static and outputting directly to the game window, with the game map scrolling underneath it. The player sprite is always drawn in the center of the fixed camera.
In the draw method of the tileManager, wouldn't it be more efficient to do the calculations outside the while loop and calculate the extremities of the drawing that way. Then the calculations are done only onece. I didn't get the black boundary so there was no need to adjust the tiles drawn to counter that. I don't know why it wasn't necessary.
Instead of writing tiles data manually in map.txt file .. Is there any graphical app to design maps for java 2d games that app give output of tile location in the format we are using in our current project
I never thought about implementing zoom in/out function into this game but I think it's possible. You will likely need to reconstruct some code (especially around the tile size and player coordinates) though. Adjusting player coordinates might be a bit tricky but it's actually an intriguing idea so I might try it later.
It's a little bit complicated to explain it in this comment section but basically you need to check something like these: if player is close to the left edge, check if player's worldX is less than player's screenX. If so, set worldX as screenX. If player is close to the right edge, check if the player's offset (screenWidth - screenX) is larger than (worldWidth - worldX). If so, set (screenWidth - (worldWidth - worldX) as screenX. For the top and the bottom edge, you just need to change x to y. And width to height. Do this in both Player and TileManager, then the camera stops moving when player is around the edge of the map. Maybe I'll make a video about this at some point of the series.
Hi ! First, nice vidéo, it was perfectly clear :). I am making a video game with 2 characters, and i was asking myself how the camera can move (the reference point (screenX, screenY) will be the average position between the 2 characters). Only problem : when I move one of them, the background is moving under the second character. Do you have an idea to solve this problem ? How people can move camera when there are more than 1 player on the same screen ?
I've never tried that but I think if you get the halfway point coordinates and set them as screenX and Y, the camera should move as you described. It's an interesting concept. Maybe I'll try it myself when I have time.
In text book, yes. I guess some methods can be set as private or protected but "forbidden" is not a correct word. The main purpose of encapsulation is prevention and is effective when you are working on a big project and working with other members so you can prevent them to access classified information or override the code by mistake.
Is it possible to draw the entire world map with one image? Or to do it in some way so that it's not so many tiles? I want my game to be similar to the Super Nintendo LOTR game, so it would use a lot of uniquely drawn areas, and I am not a big fan of creating 100s of tiles. Also, could tile collision somehow be done based on x and y, and not by the full tile?
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
@@nick8283 Im not sure at all I'm a beginner to this, but my guess would if your seeing the black background underneath maybe the tiles' pixel sizes are not matching up or something creating a small gap. or it's rendering really slowly which your fps counter should be able to show.
For anyone experiencing black or otherwise colored lines when moving up or to the left, try doing this: This method is called Double Buffering, basically what you will do is draw your entire game to a hidden image buffer, and then copy that buffer to the screen. To do this follow these steps: (This is all in your GamePanel class) 1. Create a BufferedImage the same size as your screen: public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB); 2. Get a Graphics2D object for the buffered image by calling `getGraphics()` on the image in your paintComponent() method: Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics(); 3. Draw everything to this buffered image. Then draw this bufferedImage to your screen. All in all, your code should look something like this: public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB); public void paintComponent(Graphics g) //standard method { super.paintComponent(g);
I'm new to this java series and I'm enjoying it! I have a little question though, is there any map generation system that you can implement? I'm having a hard time typing numbers 50 x 50 times😭
It is supposed to happen for sure. Tiles are just background images so unless there is something (such as solid tiles) to stop characters, they can go wherever they want.
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
thank you for uploaded this video. i''m a beginner and i just started in 5days. also i follow your video. but my result is sometihng wrong becasue game displayed only some tiles other tiles are blacked.
It seems several people are getting stuck in this video so I created a FAQ for your reference.
Q: The world map is not loading/Only the grass tile is showing.
A1: Check if the file paths and the names that you have typed in the getTileImage method are identical to the actual file names and the file paths (check the package name, its placement etc). If they don't match, the program stops there and the rest of the code won't be processed. To check this, type System.out.println("Image loading started"); at the start of the getTileImage method then type System.out.println("Image loading finished"); at the end of the method. Run the program and if the first text showed up on the console and the second text didn't, something went wrong during the loading. If the second text also showed up, your tile images are loaded correctly so the issue is coming from somewhere else.
A2: Check if you have correctly switched from maxScreenCol/Row to maxWorldCol/Row. It seems quite a few people somehow forget to update these variables. Check the TileManager(), loadMap() and the draw() methods and make sure all of these variables have been updated correctly.
A3: Check if a space has been inserted between the double quotations of the line: line.split(" "). Also check if a space has been inserted between numbers in your map file. The space is the key to split the line and get tile numbers individually so make sure these conditions are matched.
A4: Check if you have passed a correct map file to the loadMap method. Here's the line: loadMap("/maps/world01.txt"); If this file name or path is incorrect, the program cannot load the map.
Hope this helps!
Thank you 😊
@@trainrobber661 check if the maxworldcol and maxworldrow match your map width and height.
@@trainrobber661 are there any thrown exceptions? are there any errors?
@@trainrobber661 can you be more specific of the error? what isn't working?
@@trainrobber661 lol
Im using this now in 2024 and it is working like a charm. "If you want to skip this part but it will make it run better-". Dude, if you can help me more I am up for it always. Thanks for teaching me ❤
Thank you RyiSnow, this whole 2d game tutorial that you make helps me to learn more in java programming/developing, i'm currently learning game developing in java and using your tutorial helps me to create my own game with different mechanics(the game im thinking to make is somekind of 2d shooting arcade where for each wave the horde of enemy is getting harder)
Messing with the text file for the map annoyed me so I ended up spending hours researching and reverse engineering equations to create a method to get the rgb values of a pixel and used that in combination with your text file method of treating it like a 2d array to create a map that is a png and can be changed easily. It honestly was a lot of fun to figure out and I’m really proud of myself for doing it, it took me a couple days but now I understand Java much better, specifically how libraries work, which no one ever really explained to me in school. I wanted to thank you for making this series as it very informative and beginner friendly, unlike most tutorials where they go straight to the final and most efficient and complex version of their code.
i've been putting off this project for weeks just trying to find a way to generate a world map. i'm definitely going to try your method to do it!
Woah
Progress is looking great! I'm Surprised at how much is getting done each episode
yea he teaches well in less time
working through these videos to get better at java and I really appreciate how clear and simple you made them...thanks for keeping the resource files available as well
So cool! Thank you ryisnow, for your dedication to these tutorials. You are a great teacher and I always have fun following your videos
you can explain complicated things incredible well. Love that tutorial
Really nice work! :D The first game tutorial that actually works without to many errors :D. Waiting for the collision implementation!.
Would be nice with like a cheat sheet for this tutorial. I understand if it takes to much of your time. But some parts are really hard to understand. Easy to follow, but really hard to replicate on your own. Maybe put a patreon site or something and expand your channel :).
What do you mean by cheat sheet? Can you be more specific?
I don't feel like doing patreon because letting people pay monthly would likely give me an extra pressure. I would feel like "I have to make something because people are paying!" and that's not good for my mental health haha. I'm accepting one time donation via ko-hi though.
Thank you so much for these videos, I love how you actually explain everything and it makes me understand so much of it (and i am a beginner)
I'm having a hard time understanding the things about world and screen coordinates, but i hope i can get it eventually when i practice.
Thanks for your dedication! Looking forward for more!
I know, those are pretty confusing at first. World x and world y are the coordinates used for the world map. So in a way, they are abstract coordinates. On the other hand, screen x and screen y are actual coordinates used to draw stuff on the game screen (JPanel in this case).
Example:
If player is standing on the [0:0] tile, the [0:0] tile is displayed at the center of the screen since player character is always displayed at the center of the screen.
If player is standing on the [1:0] tile, the [1:0] tile is displayed at the center and the [0:0] tile is displayed at 1 tile to the left from the center.
In other words, tiles' screenX and screenY change depending on the player's current position. On the other hand, tiles' worldX and worldY don't change since tiles position on the map are fixed.
Hope this helps. If there's something that you're stuck specifically, feel free to ask!
@@RyiSnow I get that I just completely don’t understand how the code does it. I’ve been looking at this every day trying to figure it out so I can progress but it seems mind boggling to me.
If you guys are running into the tile issue and followed RyiSnow's FAQ then your issue is probably maxWWorldCol and maxWorldRow. For me, I made my own map and then followed his code exactly. Since my map size and the maxWorldCol/Row were different it only showed grass.
For example,
if your map size in the txt file has a row of 50 tiles horizontally and vertically then you have to set the maxWorldCol/Row to 50.
Hopefully, this helps at least 1 person 😅
Thanks for you explanation I was stuck for an hour on this problem
thanks man, this will help
When you talk about camera implementation it confuses me down. But you are so good at it, thank you !!
Love the tutorial! :D
Just a suggestion or a tip:
When you're changing a variable's name in Eclipse, you can right click the variable, click "refractor" and then click "rename", it will put a box around the variable, whatever you write inside that box will rename the variable everywhere in your code so you don't have to do it manually. :)
Glad you liked it :-)
Yes, I know Eclipse has such function. The reason I'm not using those shortcuts is because this is a tutorial. I want everyone to get a clear picture of their code by checking them by themselves. Auto rename/replace is a good function when you have a very good understanding about what you're doing though. But if you don't (which is often the case when you're trying to learn something new), using it is not always a great idea because sometimes it makes you lose track of what has changed and why it has changed.
also if you're using vs code you can press f2 (just in case anyone was wondering how to do it there).
I was trying to think what a high level analogy for this drawing technique would be. It seems to me that the key is to think of the output window as a camera that has its lens and position totally fixed and immovable. If you think of it as being like an animation camera photographing animation cells, then the player's character would be like a top layer that always has its position fixed to the center of the camera lens. The game map would then be like the background cell that's underneath the player. You can imagine the map being on rollers that can shift it up and down, while the player cell above remains fixed. The map can be much larger than the camera's field of view, so maybe only a portion of it is viewable by the camera at any given position. The movement of the map simulates player movement, but really we are just shifting the map in relation to directional input from the user so that the cell with the player on it appears to move where the player wants it to. The camera itself never moves to different parts of the map. Instead the map is always shifted under the camera.
When we go into the actual code, the player has a world map coordinate position which is changed by user input. The reason the map scrolls is because when the player position changes, we shift the x or y map position in relation to the fixed camera view. The player sprite is always drawn in the center of the camera, and the entire game map is drawn around this position based on the offset calculations in the draw() method and starting from the player's coordinate position on the map.
For example:
-If you set the player position to (0,0) in the player class and comment out the (x, y) map offset calculations in draw() method, the top left corner of the camera will line up with the top left position (0,0) of the game map, with the player sprite in the center of the screen. However, even though the player map position is (0,0), the sprite is not at position (0,0) on the map because we removed the screen offset.
int screenX=worldX - gp.player.worldX ;//+ gp.player.screenX;
int screenY=worldY - gp.player.worldY;// + gp.player.screenY;
-If we put the (x,y) offset calculations back, the map has now shifted so that both the center of the camera(where the player is drawn) and the player's map coordinates are now at the (0,0) coordinates in the top left corner of the map, with the area outside the map data being filled in with the background color beyond that.
int screenX=worldX - gp.player.worldX + gp.player.screenX;
int screenY=worldY - gp.player.worldY + gp.player.screenY;
-If we're still at (0,0) and the player inputs right direction movement, the player's x position on the map will increase, and the game map's x offset will decrease relative to the camera position (because of the offset calculations in draw() method). As a result the game map shifts to the left while the player sprite remains in the same position in the center of the camera.
It seems like the actual code for the camera itself is implemented in the java graphics library we're using. For the analogy above to work though, the camera has to be thought of as its own element that's objective, fixed in place and separate from the game map that shifts up and down under it.
My brain is still under maintenance trying to understand the camera part
lol
He should use for loops, he over complicated it with all the variables and using the while loops. I wrote everything prev as a for loop, and I got to that part and now I gotta redo the whole thing I think, lol. He's knowledgeable with the keywords and use of classes though!
Lol
@@centro.4k Yes, I automatically wrote the last lesson as nested for loops. That was a good thing though because making my code work made me think harder about what's going on this lesson. I'll post my draw() method code below in case it helps someone to look at another way of doing it.
public void draw(Graphics2D g2){
int x=0, y=0; //map coordinates offset relative to player position
int worldX=0, worldY=0; //objective world map coordinates
int i, j; // row and column iterations for the current tile of the world map
for (i=0; i < gp.maxWorldRow; ++i){ //outer for loop
worldY = i * gp.tileSize; //move down 1 tile length for each outer iteration
//only call the inner loop if the current map y coordinate is in the frame of the camera
if (worldY + gp.tileSize> gp.player.worldY- gp.player.screenY
&& worldY -gp.tileSize < gp.player.worldY + gp.player.screenY) {
y= worldY -gp.player.worldY + gp.player.screenY; //offset map y coordinate in relation to player
for (j = 0; j < gp.maxWorldCol; ++j) { //inner loop
worldX = j * gp.tileSize;//move 1 tile over each inner iteration
//only draw the tile if the map x coordinate is in the frame of the camera
if (worldX + gp.tileSize > gp.player.worldX - gp.player.screenX
&& worldX - gp.tileSize < gp.player.worldX + gp.player.screenX) {
x = worldX - gp.player.worldX + gp.player.screenX; //offset map x coordinate in relation to player
int tileNum = mapTileNum[i][j]; //get the tile type
g2.drawImage(tile[tileNum].image, x, y, gp.tileSize, gp.tileSize, null); //draw tile
}
}
}
}
}
its easy you just take FOO and make BAR! *runs away in confusion*
just want to let you know that your still helping people out, when I become the next Gaben I will not forget you friend
yooo thank you so much for this tutorial series, I wanted to make a game in java to test my skills and your tutorials really help much.
you are an amazing programmer and an amazing person, i dont have any words how much what you are doing means to me, honmani arigato ya!!
My stomach was in my heart when I saw that the map was scrolling! W series
i love how you explain these tutorials ❤️
He is not only noticed but his tutorials are super helpful, Well done!
I was having a bad day, but this video has made things much better! Thank you
Quick tip to renaming variables in Eclipse, highlight the variable and hit Alt + Shift + R on windows
i looking camera system on these days and this video is helped me thank you
That's great to hear! Now I can feel my effort wasn't for nothing. Thank you for the comment.
Ughhhhh, the camera/coordinate logic is breaking my brain :( Think I'm gunna have to watch this one a couple times.
Edit, still confused on how the camera logic works, but I found my bug (of course, it was in the file path, I forgot the .txt for my map.... lol), and now it's working beautifully!! I'm so stoked. I've only been learning Java for a day now, and your videos have been so incredibly helpful and motivating! Thank you so much, can't wait to continue :)
Awesome tutorial!!!
I solved my map drawing problem, here was my error:
int worldX = worldCol + gp.tileSize;
int worldY = worldRow + gp.tileSize;
It should have been:
int worldX = worldCol * gp.tileSize;
int worldY = worldRow * gp.tileSize;
Thus, I accidentally used + instead of * , which meant that it got broken, I hope this helps you, reader of this comment!
camera implementation was explained so well, wow.
I Like the way he said "you'll understand it eventually", even i have know fk ing idead whats going, and when the time comes, i will understand it, step by step 🙂
just completed this tutorial. Really enjoying these tutorials.
Great video! However please notice that the draw method even after improving the efficiency is still not very effective (time complexity of O(n^2) if the map size is n^2) this could be a real problem for huge\infinite generating maps. Instead of checking every map tile (Is it or is it not in the player camera), I suggest taking the player coordinates, translating them to the array coordinates, and drawing the map only from those coordinates. By doing that even if your map is ridiculously big, your while loop will only use constants (screen coordinates) as the boundaries.
Thank you for sharing this tutorial.
Ah interesting. Yeah, that sounds like a better way to do it when you handle gigantic maps. Thank you for the suggestion!
@@RyiSnow hi, can you maybe do a video about this? my draw time is so long that i had to go down to 30 fps instead of 60. I don't really understand how to do what deanelie7775 suggested, but i think this might be useful for some people
@@justguni7324 I managed to do it like this, it might be a little late, but could be helpful to someone
public void drawV2(Graphics2D g2) {
int tileSize = gamePanel.tileSize;
int playerX = gamePanel.player.worldX;
int playerY = gamePanel.player.worldY;
// Translate player coordinates to map tile indices
int playerTileX = playerX / tileSize;
int playerTileY = playerY / tileSize;
// Calculate the range of tiles to draw
int startTileX = Math.max(playerTileX - (gamePanel.maxScreenCol / 2) - 1, 0);
int endTileX = Math.min(playerTileX + (gamePanel.maxScreenCol / 2) + 1, gamePanel.maxWorldCol - 1);
int startTileY = Math.max(playerTileY - (gamePanel.maxScreenRow / 2) - 1, 0);
int endTileY = Math.min(playerTileY + (gamePanel.maxScreenRow / 2) + 1, gamePanel.maxWorldRow - 1);
for (int worldRow = startTileY; worldRow
After 2 and a half days of trying to solve an illegalArgumentException error I finally fixed it by just changing the tiles that weren't reading. I was about to throw my laptop out of my window. Programming is not for the weak!
I'm having the same problem, the map just show one type of tile
I really really loved this! It reminds me of the times when I used to play Ultima V on my old Commodore 64 and then Ultima VI on my 486 dx 4 100 Mhz
17:50 My only reaction throughout all your videos bro :)
Thank you for the awesome tutorials! 0 &&
screenY + gamePanel.tileSize > 0 &&
screenX < gamePanel.screenWidth &&
screenY < gamePanel.screenHeight) {
g2.drawImage(tile[tileNum].image, screenX, screenY, gamePanel.tileSize,
gamePanel.tileSize, null);
}
```
Otherwise your if statement is also correct. It took me a little bit of math transformations to prove it is correct though :)
So basically, player screenX and screenY is where the player is drawn on the screen, it is not a position on the world map.
The world map is drawn first and separately, and the player just overlaps the world map drawing. The only thing the player cares about is being at the center of the screen.
Now the camera decides the area of the world map that the screen is drawing. So first you create world map, then you add camera that zooms in on certain part of world map, then player is drawn at the center of this camera.
Javaを学習中です!
ゲーム作りに興味があります。
有用な動画をあげてくださりありがとうございます!
参考になれたならよかったです。学習頑張ってください!
This strategy worked perfectly on my phone
What youre doing here is absolutely awesome!! Thanks so much!
Thank you for such an amazing tutorial so far! I am learning Java and was having a hard time applying my knowledge. This has been such an amazing way to learn!
I can't wait to keep going! #wolrd
Don't worry mate, your explanations are very well enough. Who ever wants to develop games should at least understand these offset things.^^ 😉😉😉
The harder things will come when anyone tries to create a 3D game.^^ And especially when shadows and lightnings are joining the game.^^ 🤣🤣🤣🤣🤣🤣
Nice. I Googles how other people develop this very part of rendering. And this is very helpful thanks alot😊
I had only grass drawn and I solved this problem! I downloaded the map from the author, but it may seem that there is 100x50, but in fact he has a space between the numbers! So 50x50, the spaces between the numbers do not need to be deleted. maxWorldCol = 50; maxWorldRow = 50; Everything is correct! Thx 4 video
You can use default key(Alt+Shift+R) in Eclipse to rename a variable to something else which changes all the occurrences of that variable in that file.
Sincerly thanks you a lot your really pedagogue you are actually realizing on of my child wood dream !
i hope i will can create by my own after understanding the "mecanism" of 2D games.
excellent, thank you. good teaching speed
Thanks for the wonderful series! Truly appreciate it :)
I have a question: how would you go about implementing a screen scrolling effect when moving around the map like in the original Legend of Zelda?
Love the video, great stuff. I'm having a problem when trying to load my world map. For some reason it loads with no tiles and an all-white background. It also doesn't allow me to close the window. The world map was loading fine until I implemented the camera.
Same here mate did you fix it
Thanks for the lessons had some problems with the code. Re wrote it works fine. I think that sometimes there are system problems in computers memory not just syntax, logic, or runtime errors.
I am working on remaking an old game called boulder dash. I had this issue were i needed the player's initial position somewhere else than the center of the screen. And perhaps this caused the problem where my character stopped before reaching the wall ends since the camera had reached bounds.
I am trying to solve this by using worldX and worldY as coordinates in the player drawing method instead of screenX and screenY. For the case of this causing the black borders of the screen to show i simply adjusted the calculation made in the tile painting function. Even though i must admit i am still quite lost in the camera calculation explaination being new to all this😂.
I shared this hoping it might help someone with a similar problem. Happy Coding!
It takes a little more work, but loading only the parts you want can save a lot of processing time. Reloading everything now takes about 4.7ms per refresh!
Great videos. Makes me wonder if this was how they made the old NES final fantasy games and how much code that was written to make them.
Amazing how people figure these programming languages out. And ways of using them.
NES games were made in an assembly language that is closer to machine language and in a way, much more primitive than modern computer languages. So I think it was much harder to code back then!
very good tutorial and thanks java this code will run for ever! thats why i love java
hey ryi , I really wonder if there is any specific reason why you use "weird" while loop instead of nested for loop? is it for optimization purposes or it is just your preference. Thanks . P.S you are god of tutorial bro keep it up .
btw. Great videos! You're very kind to make these. Note, here a little more efficient way to do the draw() method for the TileManager. Instead of ignoring the non visible tiles (like you do with your if/then check), I use the Java Modulo to determine the negative offset of the x & y tile start position. Here's the sample code. Again thank you! (this is in no way a discredit to your work)...
public void draw(Graphics2D graphics2D)
{
// tilePosition should start at the negative modulo of the player position in the world % scaled tile size
int tileXPosition = - gamePanel.getPlayer().getXWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize();
int tileYPosition = - gamePanel.getPlayer().getYWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize();
int columnOffset = (gamePanel.getPlayer().getXWorldPosition()/ResourceLoader.getGameSettings().getScaledTileSize()) -
(ResourceLoader.getGameSettings().getMaxScreenCol()/2);
int rowOffset = (gamePanel.getPlayer().getYWorldPosition()/ResourceLoader.getGameSettings().getScaledTileSize()) -
(ResourceLoader.getGameSettings().getMaxScreenRow()/2);
for (int rowNum = rowOffset; rowNum= 0 && rowNum < ResourceLoader.getGameSettings().getWorldMapSizeY())
{
String mapTile = mapOfLand[columnNum][rowNum];
graphics2D.drawImage((tilesMap.get(mapTile).getImage()),
tileXPosition,
tileYPosition,
ResourceLoader.getGameSettings().getScaledTileSize(),
ResourceLoader.getGameSettings().getScaledTileSize(), null);
}
tileXPosition = tileXPosition + ResourceLoader.getGameSettings().getScaledTileSize();
}
tileXPosition = - gamePanel.getPlayer().getXWorldPosition() % ResourceLoader.getGameSettings().getScaledTileSize();
tileYPosition = tileYPosition + ResourceLoader.getGameSettings().getScaledTileSize();
}
}
YOUR TUTORIALS ARE SOO COOL, thank you soo much
Thanks you very much for this video!
Amazing work as always!
Бро, ты самый лучший, столько нового узнаю,)
Very great tutorial!!! You earned a sub
8:12
screenX = gp.screenWidth/2 - (gp.tileSize/2);
screenY = gp.screenHeight/2 - (gp.tileSize/2);
You don't have to use brackets. Basics of mathematics ;)
Great job
I need Help. Half of the world won't load. any suggestions?
EDIT: forgot to change maxScreenCol to maxWorldCol.
...
if(worldCol ==maxWorldCol){
worldCol = 0;
worldRow++;
}
thank you bro i was having the same problem
THIS IS WHY WE NEED COMMENTS!!!!!! THANK YU BRO!!
Thank you for your service
Thank you! Totally missed that too!
Hello!!
For those experiencing problems with the tiles being drawn, your maxWorldCol and maxWorldRow may be the problem.
Count the exact number of rows and columns on your map and set them respectively to the maxWorldCol and maxWorldRow.
You see, to have the correct tiles drawn, your while loop has to set the numbers correctly. In other words, to meet the correct criteria (e.g., if you have 32 columns, set your MaxWorldCol to 32).
Let’s look at this case scenario: If you set your maxCol to 50 and you only have less than 50 columns, the while loop will not correctly process your map as it does not meet the required criteria.
In this video, RyiSnow has a 50x50 map (50 rows and 50 columns), hence why his maxWorldCol and maxWorldRow are set to 50.
However, your map may not be 50x50. And if you’ve set those values to 50, it won’t work correctly.
Hi, I ran into this problem where I can't center my player, can you help with that?
i created a own map but why it's showing a black map?
Thanks for the tutorial! I have a question, I want the camera to only follow my character in the Y-axis so how do I do that?
I have a issue, i know it's probably late to say this, but even if i set the boundaries of the map, the player, after going out of the 50x50 map, still walks in the black background, without the map limit. How do i fix this?
trying printing the players location to the console and check if its within the worldWidth & worldHeight
My map was only printing my first texture, spacing out the numbers in the text file did the trick
My code renders the map properly but whenever I go towards the top or left it starts drawing the black background too. What should I change?
Thankyou.(btw Great tutorials!)
I have the exact same problem, do you perhaps know how to solve this?
I can't believe I missed this simple line of code, I had to of implemented it before but took a break to try to teach myself after guide 40ish. Now watching everything again 😁 awesome teacher right here 👏 making this for Android currently so lots of differences but lots of similarities too.
(worldX + game.scaledTileSize > game.player.worldX - game.player.screenX &&
worldX - game.scaledTileSize < game.player.worldX + game.player.screenX &&
worldY + (game.scaledTileSize*2) > game.player.worldY - game.player.screenY &&
worldY - (game.scaledTileSize*2) < game.player.worldY + game.player.screenY)
Very useful tutorial. Thanks a lot!
Awesome! But why is my screen with random black rectangle only when I move up or left?
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
When I move up black stripes will occasionally flash for a short moment. I think its the texture not loading correctly idk
Great tutorials but what if i want to make somehow the 'camera' to move around the map but not actually move a background instead, because i will have other objects that will move in relation to background? Do you have any idea?
Hey! I have a question, I found when I run the game and my character moves down and to the right, the rendering is fine. But when I move up and to the left, a bunch of black lines starts appearing. What do you think the problem would be?
i have the same problem, I've been trying to fix that for months now. Please @RyiSnow, any ideas on how to fix that?
I have the assumption that it's a hardware problem. I gave my code as well as sprites and everything else to some friends of mine so that they could try to run the game, and it seems to work fine for them. I guess if the graphics get too heavy for your hardware the program starts having those graphic bugs.
Since that would mean that the Java 2D Graphics compontent are too heavy for the PC to handle I began to rewrite the game that I'm making in the LWJGL, which is an external library that has improved rendering options to make stuff like these graphic issues non-existent. I didn't progress far enough to check if the LWGJL is actually the conclusion for this problem yet tho, so I'd love an answer from you Snow - You might be able to help. I really need to fix that
make sure you're using primitive integer and not any decimal point datatypes.
it happened to me when I added a bunch of print lines to do bug fixing, I think it has to do with the loop taking too much time to process. if there is anything that can be axed it might be a good idea to try that.
@@nick8283 For anyone experiencing black or otherwise colored lines when moving up or to the left, try doing this:
This method is called Double Buffering, basically what you will do is draw your entire game to a hidden image buffer, and then copy that buffer to the screen. To do this follow these steps:
(This is all in your GamePanel class)
1. Create a BufferedImage the same size as your screen:
public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB);
2. Get a Graphics2D object for the buffered image by calling `getGraphics()` on the image in your paintComponent() method:
Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics();
3. Draw everything to this buffered image. Then draw this bufferedImage to your screen.
All in all, your code should look something like this:
public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB);
public void paintComponent(Graphics g) //standard method
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics();
//render tiles
tileM.draw(g2);
//render player
player.draw(g2);
//save memory
g2.dispose();
g.drawImage(doubleBufferedImage, 0, 0, null);
}
Hopefully this helps!
Hey Julian, you can try this method here in this thread, this is what helped me. I hope that it works for you. Cheers!
Is there a better and easier way of creating .txt maps? Manually putting the numbers itself on the notepad is so confusing and tiring 😢
i love your vids. they really helped me out a lot!!
i just wanna know if there's any way to use an custom drawn image as a world map as i want to use my custom map that i drawn.
everything is helpful so far. Great Work!!!
Yeah there is a way. I think a guy named VanZeban has a tutorial for a 2D RPG in Java and he uses a map image.
@@noahbarger1 thank you so much, mate
@@kogashinto2123 No problem
lifesaver u helped me fix m screen tearing
thanks for tutorial butt I beg you to explain the camera implementation the way you explained it doesn't add up to the mechanism of the tiles rendering :(( are the tiles or screen moving....
The tiles that make up the game map are shifting up or down and left or right and the camera is staying in place. When the user inputs a direction, the screen redraws the tiles using the map data in the text file, offsetting it from the player's new position on the game map. In this code, you can think of the camera as being completely static and outputting directly to the game window, with the game map scrolling underneath it. The player sprite is always drawn in the center of the fixed camera.
Thanks a lot, it is wonderful tutorial.
In the draw method of the tileManager, wouldn't it be more efficient to do the calculations outside the while loop and calculate the extremities of the drawing that way. Then the calculations are done only onece.
I didn't get the black boundary so there was no need to adjust the tiles drawn to counter that. I don't know why it wasn't necessary.
Instead of writing tiles data manually in map.txt file ..
Is there any graphical app to design maps for java 2d games that app give output of tile location in the format we are using in our current project
はじめまして!
この回の日本語字幕は無いんですか?
こんにちは! すみません、日本語字幕は確かPart4までしか作っていないんです(作成に結構時間がかかって途中でストップしてしまいました…) 要望があるようでしたら続きも作ろうと思いますが。
can you make zoom in, zoom out camera ?
I never thought about implementing zoom in/out function into this game but I think it's possible. You will likely need to reconstruct some code (especially around the tile size and player coordinates) though. Adjusting player coordinates might be a bit tricky but it's actually an intriguing idea so I might try it later.
Thank, i will wait your video soon
How can I make the camera stop when it gets to the edge of map so we don't see black space outside game boundaries?
It's a little bit complicated to explain it in this comment section but basically you need to check something like these:
if player is close to the left edge, check if player's worldX is less than player's screenX. If so, set worldX as screenX.
If player is close to the right edge, check if the player's offset (screenWidth - screenX) is larger than (worldWidth - worldX). If so, set (screenWidth - (worldWidth - worldX) as screenX.
For the top and the bottom edge, you just need to change x to y. And width to height. Do this in both Player and TileManager, then the camera stops moving when player is around the edge of the map.
Maybe I'll make a video about this at some point of the series.
@@RyiSnow your approach works really well for the top part and the left edge ,the right edge does not work please help me
24:15 did you do something here? btw i love this tutorial series
Hi ! First, nice vidéo, it was perfectly clear :).
I am making a video game with 2 characters, and i was asking myself how the camera can move (the reference point (screenX, screenY) will be the average position between the 2 characters). Only problem : when I move one of them, the background is moving under the second character. Do you have an idea to solve this problem ? How people can move camera when there are more than 1 player on the same screen ?
I've never tried that but I think if you get the halfway point coordinates and set them as screenX and Y, the camera should move as you described. It's an interesting concept. Maybe I'll try it myself when I have time.
what about the data encapsulation? I heard that setting every var as public is kinda forbidden.
In text book, yes. I guess some methods can be set as private or protected but "forbidden" is not a correct word. The main purpose of encapsulation is prevention and is effective when you are working on a big project and working with other members so you can prevent them to access classified information or override the code by mistake.
Is it possible to draw the entire world map with one image? Or to do it in some way so that it's not so many tiles? I want my game to be similar to the Super Nintendo LOTR game, so it would use a lot of uniquely drawn areas, and I am not a big fan of creating 100s of tiles.
Also, could tile collision somehow be done based on x and y, and not by the full tile?
I am having so much fun but having a problem. When i start the program everything is white. Can someone help me idk what I did wrong
Can someone help? When I run my code, I only get black screen.
Hi! Can you please tell me why when I'm moving the character, my map is flickering (random black lines appear between tiles)?
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
@@nick8283 Im not sure at all I'm a beginner to this, but my guess would if your seeing the black background underneath maybe the tiles' pixel sizes are not matching up or something creating a small gap. or it's rendering really slowly which your fps counter should be able to show.
For anyone experiencing black or otherwise colored lines when moving up or to the left, try doing this:
This method is called Double Buffering, basically what you will do is draw your entire game to a hidden image buffer, and then copy that buffer to the screen. To do this follow these steps:
(This is all in your GamePanel class)
1. Create a BufferedImage the same size as your screen:
public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB);
2. Get a Graphics2D object for the buffered image by calling `getGraphics()` on the image in your paintComponent() method:
Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics();
3. Draw everything to this buffered image. Then draw this bufferedImage to your screen.
All in all, your code should look something like this:
public BufferedImage doubleBufferedImage = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB);
public void paintComponent(Graphics g) //standard method
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) doubleBufferedImage.getGraphics();
//render tiles
tileM.draw(g2);
//render player
player.draw(g2);
//save memory
g2.dispose();
g.drawImage(doubleBufferedImage, 0, 0, null);
}
Hopefully this helps!
damn you're a good teacher
I'm new to this java series and I'm enjoying it! I have a little question though, is there any map generation system that you can implement? I'm having a hard time typing numbers 50 x 50 times😭
draw the map k in piskel and use the concept of height maps, different pixel contain different color and finally relate them to tiles
@@ethannnn5956 That's a cool idea! Imma try it out
when you reach the edge of the map, does the camera stop following the player? mine does :(
Should the player be able to walk outside the map? For me, I can walk over the black background past the tiles. Is that supposed to happen?
It is supposed to happen for sure. Tiles are just background images so unless there is something (such as solid tiles) to stop characters, they can go wherever they want.
@ Alright, I understand. Thank you for your reply. You earned a sub
Is there a software where we can create a world map using tiles and save it as a txt file where the tiles are represented as numbers?
I introduced my tile editor later in this series:
ua-cam.com/video/y06YDM5Kq9Q/v-deo.html
why after that only then walking up or left directions appear little black lines on map between tiles? how to fix it ?
Got the same problem, you could add a reply and a like to the comment of @Julian Jung since he's got similar issues and we might be able to make it more noticeable for RyiSnow
thank you for uploaded this video. i''m a beginner and i just started in 5days.
also i follow your video. but my result is sometihng wrong
becasue game displayed only some tiles other tiles are blacked.