Advertisement Jump to content
Sign in to follow this  
Nicholas Kong

Question about my coding approach for game overworld logic

This topic is 1758 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

if(GameState.getState() == "OVERWORLD")
{
                if(!saveMenu.getIsOn())
                {
                    camera.update(link);
                }
                else
                {
                    link.setState(ActionState.IDLE);
                }
                
                link.update();
                link.update(camera);
                
                updateNPCs(camera);
                updateMap(camera, link);
                
                inventory.update();
                drawLevelData.update(link.getLevel());
                
                
                
                
                drawMap(g2D, camera);
                
                drawLink(g2D);
                    
                drawLinkRelativeToCamera(g2D, camera);
                
                levelBar.draw(g2D);
                drawLevelData.draw(g2D);
                
                // collide with npcs
                link.collideWithNPCs(mapsToAdd);
                // collide with monster
                
                link.collide(mapsToAdd);
                
                // collide with loot
                link.collideWithLootDrops(mapsToAdd,inventory);
                
                link.attackMonsters(mapsToAdd);
                
                inventory.draw(g2D);
                
             

}

The Java code works awesome but I did not realize how long it was until I came back to my rpg codebase after a month hiatus. Strange how the realization came so late.

 

Would this look similar to how the game industry would structure a game logic?

Edited by warnexus

Share this post


Link to post
Share on other sites
Advertisement
if(GameState.getState() == "OVERWORLD")

For this, I recommend using either an enum or inheritance with polymorphism. You should also try to split your update logic and render. Here's how I'd write this (though without knowing more about your code, I don't know where to put things like the instances of link and camera, so I put them in the game class and use getter methods)

// All the different states of the game inherit this and implement the abstract methods
public abstract class GameState {
	public Game game;



	public GameState(Game game) {
		this.game = game;
	}


	// Returns the next game state (most of the time would be this)
	public abstract GameState update();

	public abstract void render(Graphics2d graphics);
}



public final class Overworld extends GameState {
	public Overworld(Game game) {
		super(game);
		// Other stuff in here
	}


	public GameState update() {
		// Because the game state doesn't have own these
		Camera camera = game.getCamera();
		Link link = game.getLink();

		if (!saveMenu.isOn()) {
			camera.update(link);
		} else {
			link.setState(ActionState.IDLE);
		}

		link.update();
		link.update(camera); // This is confusing

		updateNpcs(camera);
		updateMap(camera, link);

		game.getInventory().update();

		// Maybe all these could be moved into link.update(mapsToAdd, inventory);
		link.collideWithNpcs(mapsToAdd);
		link.collide(mapsToAdd);

		link.collideWithLootDrops(mapsToAdd, inventory);
		link.attackMonsters(mapsToAdd);

		return this;
	}



	public void render(Graphics2d graphics) {
		drawLevelData.update(game.getLink().getLevel());

		drawMap(graphics, game.getCamera());

		drawLink(graphics);
		drawLinkRelativeToCamera(graphics, camera);

		levelBar.draw(graphics);

		drawLevelData.draw(graphics);

		inventory.draw(graphics);
	}
}



public final class Game {
	private GameState gameState;
	private final Camera camera;
	private final Link link;



	public Game() {
		gameState = new Overworld(this);
	}



	public void update() {
		gameState = gameState.update();
	}



	public void render() {
		gameState.render();
	}



	public Camera getCamera() {
		return camera;
	}


	public Link getLink() {
		return link;
	}
}

Edit: I also think you should change "state" to something else, like "world". "State" to me implies loading, main menu, play screen, game over screen, pause screen etc.

Edited by dr01d3k4

Share this post


Link to post
Share on other sites

I'd also try to get things to be more abstract, so that you could do something like:

 

foreach(UIElement uiElement in uiElements)

{

   uiElement.Draw(g2D, camera)

}

 

instead of having things be as hardcoded as they are, same thing with your 3d game objects, and you have something called link, which I think is because you're making a zelda type game?  Usually they don't name things that specific.  (Though you'd be surprised!  Third party Unreal developers got a bit of a shock when they saw some stuff in there that was hardcoded for Gears of War)

Share this post


Link to post
Share on other sites

if(GameState.getState() == "OVERWORLD")

You can't tell me this is working. Logicaly it doesn't make sense and as far as I know even Java doesn't support this kind of action.

 

Besides code formatting and clarity (formatting, empty lines, comments) it could be something a professionel developer studio could have made.

Since this is clearly a direct programming of a simple zelda-clone without the roundabout rout developing an engine first everything seems to be completly fine for me as much as I can see.

However you will maybe have problems later with your hardcoded solution when you should realize that you want to change/add some bigger design decisions or when you notice that you have forgotten something. Then such code get completly messed up, pretty fast.

Share this post


Link to post
Share on other sites
if(GameState.getState() == "OVERWORLD")

I'm not a Java guy, but isn't that just a string compare?  It's inefficient but should still work.  Or are you thinking it's checking if it's equal to the exact address?

Share this post


Link to post
Share on other sites

 

if(GameState.getState() == "OVERWORLD")

I'm not a Java guy, but isn't that just a string compare?  It's inefficient but should still work.  Or are you thinking it's checking if it's equal to the exact address?

 

 

Well everytime this code is running, the program is creating a new String object (with a char-array containing "OVERWORLD") and is comparing the object with the other String object given by getState().

However, only because both String objects contain a char-array with the same data, those objects are own instances and this comparison should return false because they are not the same but "equal" and should also be compared so

getState().equals( "OVERWORLD" );

In Java Strings are saved in a global String pool. When creating a new String that contains the same data like a previous created String, chances are high that Java returns the same String object and the comparison would be correct again which makes the original code temporarily working (besides that enums would have been a better choice).

While chances that this happens are high, it is not a Java law that this will actually happen and developers shouldn't count on this.

Edited by IceCave

Share this post


Link to post
Share on other sites
if(GameState.getState() == "OVERWORLD")

You can't tell me this is working. Logicaly it doesn't make sense and as far as I know even Java doesn't support this kind of action.

 

Besides code formatting and clarity (formatting, empty lines, comments) it could be something a professionel developer studio could have made.

Since this is clearly a direct programming of a simple zelda-clone without the roundabout rout developing an engine first everything seems to be completly fine for me as much as I can see.

However you will maybe have problems later with your hardcoded solution when you should realize that you want to change/add some bigger design decisions or when you notice that you have forgotten something. Then such code get completly messed up, pretty fast.

 

Sure it will work. Here is the code. It is just a string comparison. Of course in order for it to work, I need to set the state to "OVERWORLD" first before the comparison.

package com.nicholaskong.Game;

public class GameState {

    public static String state = "";
    
    public static void setState(String state)
    {
        GameState.state = state;
    }
    
    public static String getState()
    {
        return GameState.state;
    }
    

}
 
Edited by warnexus

Share this post


Link to post
Share on other sites

The problem is, in Java == is not a string comparison. It compares the addresses of the two string objects being compared. IceCave explained why == SOMETIMES results in temporary working code, but it is not correct. The equals function will compare two strings. See the following link for more information.
 
http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java
 
As was stated, an enumeration is likely the best representation of your state.
 
 
The code above isn't exactly industry standard, but it's not too bad, and you're not really building an industry level game so at this stage it's not the most important.
 
Some additional feedback:
-You change the character's state when your save menu is open. This is fairly strange. If you have a blocking save system (meaning you don't play while it's saving) then you would usually pause the simulation, or put the game in a tight loop (I don't recommend this) until saving is complete. The game would simply resume where you left off when it is "unpaused". An examples of this is(even this is too simple as there are likely other things that can pause your simulation):
 

Pausing Simulation:

[source]if(gameState == OVERWORLD){
    if(saveMenu.IsActive()){
        //Save menu update (probably at least need to update save state machine).
    }
    else{
        //Game update

    }

    //Render logic (You still might need to render during a save to pass certification if saving takes long enough. You can separate rendering from your game update and do it outside of your simulation block).
}[/source]

 

 

-The rest of your game loop isn't too bad. It's fairly specific. Game industry code would be much more generic, with less coupling between systems.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!