• Advertisement

2D Camera Jitters

Recommended Posts

Hey,

I'm running through some game tutorials and have just implemented my camera. It scrolls, following the player sprite, and culls tiles from the map outside of bounds.

One thing I'm noticing is some minor artifact tearing between some of the tiles that make up the on-screen map. Originally, I assumed it was because I coded my camera X and Y as Integers, and my player coordinates as floats, so there was some classic data loss from downcasting float -> int. I modified that, and removed integer casts that related to passing player coordinates to the camera. This has reduced the tearing, but everything still jitters a small amount.

The player only moves at a speed of 1.0f. If I run it at 3.0f, it is more noticable. Where could I be going wrong?

Thanks,

Stitchs (code below).

package dev.mygame.display;

public class Camera
{
	private float x;
	private float y;
	private int w;
	private int h;
	private int focusX;
	private int focusY;
	
	public Camera(float x, float y, int w, int h)
	{
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
	}
	
	public float getX()
	{
		return x;
	}
	
	public void setX(float x)
	{
		this.x = x;
	}
	
	public float getY()
	{
		return y;
	}
	
	public void setY(float y)
	{
		this.y = y;
	}
	
	public int getFocusX()
	{
		return focusX;
	}
	
	public void setFocus(float focusX, float focusY)
	{
		float lerp = 1.0f;
		x += lerp * (focusX - w/2 - x);
		y += lerp * (focusY - h/2 - y);
	}
	
	public int getFocusY()
	{
		return focusY;
	}
	
	public int getWidth()
	{
		return w;
	}
	
	public int getHeight()
	{
		return h;
	}
	
	public void tick()
	{
		// centre the camera on the focus point
		//focusX -= w/2;
		//focusY -= h/2;
		// set the origin so we can offset everything else
		x = focusX;
		y = focusY;
	}
}
package dev.mygame.entities.creatures;

import java.awt.Graphics;

import dev.mygame.gfx.Assets;
import dev.mygame.Game;

public class Player extends Creature
{
	private Game game;
	
	public Player(Game game, float x, float y)
	{
		super(game, x, y, Creature.DEFAULT_WIDTH, Creature.DEFAULT_HEIGHT);
		this.game = game;
	}
	
	@Override
	public void tick()
	{
		getInput();
		move();
	}
	
	private void getInput()
	{
		xMove = 0;
		yMove = 0;
		
		if(game.getKeyManager().up)
		{
			yMove = -speed;
		}
		if(game.getKeyManager().down)
		{
			yMove = +speed;
		}
		if(game.getKeyManager().left)
		{
			xMove = -speed;
		}
		if(game.getKeyManager().right)
		{
			xMove = +speed;
		}
	}
	
	@Override
	public void render(Graphics g)
	{
		g.drawImage(Assets.playerOne, (int)(x - game.getCamera().getX()), (int)(y - game.getCamera().getY()), width, height, null);
	}
}
package dev.mygame.states;

import java.awt.Graphics;

import dev.mygame.entities.creatures.Player;
import dev.mygame.gfx.Assets;
import dev.mygame.Game;
import dev.mygame.worlds.World;
import dev.mygame.display.Camera;

public class GameState extends State
{
	private Player player;
	private World world;
	
	public GameState(Game game)
	{
		super(game);
		world = new World(game, "/maps/World1.json");
		player = new Player(game, world.getSpawnX(), world.getSpawnY());
	}
	
	@Override
	public void tick()
	{
		player.tick();
		game.getCamera().setFocus(player.getX() + player.getWidth()/2, player.getY() + player.getHeight()/2);
	}
	
	@Override
	public void render(Graphics g)
	{
		world.render(g);
		player.render(g);
	}
}

 

Edited by stitchs_login

Share this post


Link to post
Share on other sites
Advertisement

I would focus on your camera::setFocus function.

The (focusX - w/2) bit gives the offset by itself but (focusX - w/2 - x) seems like it throws it an additional unnecessary amount. I don't see you call camera::tick which is good because then we'd probably be talking half screen jitter. The other mess would be your variable naming between function arguments and the class members. Refactor some naming to make sure you are setting what you think you're setting and double check your camera position logic for one or two render frames by walking the logic by hand.

It's difficult because I don't see your base Creature::move is doing with your user input.

Share this post


Link to post
Share on other sites

Hi @GoliathForge,

The tick() method in Camera is a hangover that I'm removing in this phase. When you say that I should refactor some naming, do you mean that having the parameter names the same as the instance-level members could be confusing? Or am I missing some consistency in the naming pattern?

As for Creature::move()

package dev.mygame.entities.creatures;

import dev.mygame.entities.Entity;
import dev.mygame.Handler;

public abstract class Creature extends Entity
{
	public static final int DEFAULT_HEALTH = 10;
	public static final float DEFAULT_SPEED = 1.0f;
	public static final int DEFAULT_WIDTH = 64;
	public static final int DEFAULT_HEIGHT = 64;
	
	protected int health;
	protected float speed;
	protected float xMove;
	protected float yMove;
	
	public Creature(Handler handler, float x, float y, int width, int height)
	{
		super(handler, x, y, width, height);
		health = DEFAULT_HEALTH;
		speed = DEFAULT_SPEED;
		xMove = 0f;
		yMove = 0f;
	}
	
	public void move()
	{
		x += xMove;
		y += yMove;
	}
	....
}

I admit, I haven't yet printed the values to the setFocus method, so I will do that in my next round of implementation. Thinking about my original wording, if anything, it's not camera jitter I'm experiencing. It's more akin to a tear in some graphic rendering between tiles when I move my player vertically.

@the incredible smoker

On 10/6/2017 at 4:34 PM, the incredible smoker said:

Floats are not accurate.

Could you elaborate in relation to the screen-tearing that I'm experiencing? Right now, I don't *need* the precision provided by doubles. It would be something I'd consider in the future when I begin to implement physics calculations that may require it. Currently, I'm following a tutorial series that doesn't suggest using them. If this is a possible solution to my issues, I would love to hear some more context to your answer.

Thanks,

Stitchs.

Share this post


Link to post
Share on other sites
3 hours ago, stitchs_login said:

When you say that I should refactor some naming, do you mean that having the parameter names the same as the instance-level members could be confusing?

right...it's just a little thing, but every bit helps.

3 hours ago, stitchs_login said:

Thinking about my original wording, if anything, it's not camera jitter I'm experiencing. It's more akin to a tear in some graphic rendering between tiles when I move my player vertically.

Ah, very good. I'm not a java user but it's my understanding that you can't enable vsync programmatically and has to be done with the graphics card's settings interface. Try that. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By EddieK
      Hi I am having this problem where I am drawing 4000 squares on screen, using VBO's and IBO's but the framerate on my Huawei P9 is only 24 FPS. Considering it has 8-core CPU and a pretty powerful GPU, I don't think it is not capable of drawing 4000 textured squares at 60FPS.
      I checked the DMMS and found out that most of the time spent was by the put() method of the FloatBuffer, but the strange thing is that if I'm drawing these squares outside of the view frustum, the FPS increases. And I'm not using frustum culling. 
      If you have any ideas what could be causing this, please share them with me. Thank you in advance.
    • By menyo
      I am trying to figure out a good component design for my item classes since otherwise it probably ends up in a hierarchy disaster. I will just be just using this to define my items in a data driven way. My items do not have a position or interact with the map, they are either on a character or on a tile in the map and that is where they are stored. So I created a blank interface and a couple implementations, nothing is set in stone but I think my concept is pretty solid and I'm looking for feedback from people with more experience on the topic since it would not be the first time I burry myself into something I cannot climb out of :).
      public interface ItemComponent { } public class WeaponComponent implements ItemComponent{ int damage; int range; float attackSpeed; String damageType; } public class ArmorComponent implements ItemComponent { int defense; String armorType; String bodyPart; } Easy enough, like most component systems they only add data the system in my case are the characters using the items, I could add functionality but that will probably complicate things once more components are added. When the character uses any item with the corresponding component I have access to the data, and that is all I currently need. A shield that could also be used as a weapon should be easy to model in. To know and find a specific type of item I implemented a Map that maps a String to a ItemComponent.
      public class Item { private String name; private int weight; private Map<String, ItemComponent> itemComponents = new HashMap<>(); public Item() { } public void addComponent(ItemComponent component) { itemComponents.put(component.getClass().toString(), component); } } A basic item that is used for crafting only would not have any components. For easy lookup I added a couple methods.
      public boolean hasComponent(Class c) { return itemComponents.containsKey(c.toString()); } public boolean isWeapon() { return hasComponent(WeaponComponent.class); } public boolean isArmor() { return hasComponent(ArmorComponent.class); } To instantiate items I will import all JSON data in a Factory pattern and clone the items. Since crafting is a thing I will add another Map to this that maps the items name to the recipe.
      public Item clone() { return new Item(name, weight, itemComponents); } public class ItemPrototype { private Item item; private Recipe recipe; public Item cloneItem(){ return item.clone(); } public Item createItem(List<Item> ingredients) { // Todo: Check ingredients. // Todo: Remove ingredients. return cloneItem(); } } public class ItemFactory { private static Map<String, ItemPrototype> itemPrototypes = new HashMap<>(); static { // Todo: Import items from JSON } public static Item createItem(String name, List<Item> ingredients) { // TODO: Error handling return itemPrototypes.get(name).createItem(ingredients); } public static Item createItem(String name) { // TODO: Error handling return itemPrototypes.get(name).cloneItem(); } } Here is how an item would look inside a JSON file. A simple rock would truncate everything except for it's name and weight unless it I decide it can be used as a weapon too.
      "Rifle" : { "item" : { "name" : "Rifle", "weight" : 3500, "itemComponents" : { "WeaponComponent" : { "damage" : 18, "range" : 20, "attackSpeed" : 10.0, "damageType" : "Piercing" } } }, "recipe" : { "ingredients" : { "Wood" : 1, "lense" : 1, "Steel Plate" : 4 } } } I love to hear what more experienced people have to say about this. There are not much examples to look at on internet except for a couple that go all the way down to engine level where basically everything is a entity. If I have success with this structure I definitely write a article about it.
    • By Honneamise
      Hello,
      im looking for some feedback about my latest experiment .
      You can find it here :
      http://www.honny.net/hexnet
      But please before to do that take some minutes to read what follow.
       
      In all my previous projects i have always used C language ( C not C++ ), yes i am a very old person.
      Some time ago I felt the need to “evolve” in some way, I cant say why exactly.
      To be honest in C i have always been able to find a way to solve a problem by myself or a library for a specific task.
      Of consequence all this stuff about OOP and Classes was really new to me.
      To test this experience i have used Processing.
      From what i have understood this was the fastest ( and easiest ) way to setup this kind of project.
      Well, if you are reading this you have already understood that this is not really a "complete game",
      just a minimalist minesweeper-like similar to the "mini hack" sub-games that you can find in major titles.
      Keep in mind that the main goal was to make some experience with basic stuff like :
      setup a project
      learning OOP and Classes
      basic drawing and images loading
      handling user input
      etc...
       
      UPDATE 11/02/2018 : updated new game version and added some screenshots !!!
      UPDATE 03/02/2018 : now it exist AT LEAST a path to complete the game :-)
       
    • By Ruzicar
      Hi folks,
      During a recent leave of absence for family reasons, I needed something to take my mind off my troubles.  So I decided to learn Android development and create a game I've always wanted to play.  "Borbudo" is available on the Google Play Store at:
      https://play.google.com/store/apps/details?id=com.borbudo.free
      Very briefly, Borbudo is inspired by the old 80s games Time Bandits and Gauntlet, and in the future I hope to include lots of puzzles and quests in the spirit of Dungeon Master.  Right now I confess that the game needs some re-work to create a unifying theme, but I think the alpha version available now is pretty solid.  My game also features the music of Eric Matyas.
      I'd very much appreciate any comments (or even Patreon pledges).
      With many thanks,
      Rob Lehrbass
    • By Time4Tea
      This is linked to another question that I asked here a couple of days ago:
      I'm looking at making a client-server game with a game server programmed in Java. The game will be a 2D turn-based game (like a board game), with a maximum of around 50-100 games going on at any one time. So, the performance requirements are not very high. The reason I would like to use Java for the server are because I already have some familiarity with it and I would like the server to not be tied to one particular platform. I would also like to design it so that the client interface to the server is as generic as possible, so that the same server could be used with multiple different clients. For example, there might be a web-based client, or someone else might design a stand-alone 3D client application later on, using the same server.
      So, I am looking for some advice on where to start with this, as I have very little experience with coding servers.
      I was planning to use web sockets for the client-server connection, which apparently uses Java EE (Enterprise Edition), which seems to require the use of the GlassFish server. However, I have been advised that a fully-fledged application server, like GlassFish, may be overkill for a game server. So, here are my questions:
      Should I use something like GlassFish? Does it makes sense for the type of game server I am describing? If not, then what sort of networking protocol/library would experienced Java game designers recommend? Are there any existing, general-purpose Java game servers that exist, which I might be able to use as a starting point? (Or even free software/open-source client-server games?) Or, should I look at coding my own game server from scratch? In which case, again, what sort of connection type/library would be recommended? Does anyone know of any suitable introductory tutorials that deal with how to make this sort of game server in Java? I guess my priority is probably minimizing the learning curve and the amount of time/effort involved, over performance. How much effort is this sort of undertaking going to require?
      Thanks in advance! :-)
  • Advertisement