Smooth movement

I’m working on a tile based rpg, and I’m trying to make it look as professional as possible… I already can get smooth movement with scrolling, and I’ve got the character to the point where [on my system at least] if it keeps moving in one direction it will look fairly smooth, more or less thanks to you guys with the bits of code I’ve looked at off of here and some of the suggestions I’ve seen :slight_smile:

Anyhow so the problem is if you want to move in, let’s say a different direction, it looks chopy/does’t happen until the guy gets done moving. If you’re at a complete stop then only try to move in one direction, it looks fine. Currently, the guy makes about 5 intervals during each directional key press, to make it look smooth. I’ve tried making the character just changing direction if there is a key press in between movement shifting, but this looks weird… I’ve tried looking at professional games, but it doesn’t really help me out in seeing how they make the keyboard input/ensuing movement look so smooth.

I’d post code, but it looks a bit icky at the moment.

Ahh, and it seems i’m quite the noob with this .jar business… here is the game I’m working on. Unlike the .jars I’ve seen here that just work instantly, mine seems to work if you extract it, then put the jar in that folder you extracted the stuff to. :-/ What.

www.ki-rush.com/what.jar

Oh, and sorry if I sucked at explaining what’s going on, any feedback would be cool really.

[quote]Ahh, and it seems i’m quite the noob with this .jar business… here is the game I’m working on. Unlike the .jars I’ve seen here that just work instantly, mine seems to work if you extract it, then put the jar in that folder you extracted the stuff to. :-/
[/quote]
There’s really only one thing you need to make your application portable: Stop loading files with “new FileInputStream()” and start loading them with code like this:

InputStream in = getClass().getResourceAsStream("/map1.dat");

That bit of code will cause the classloader to become responsible for loading the file, even if the classes were loaded from an archive, over the network, or from something that hasn’t even been invented yet!

Also, most types of loaders (e.g. javax.imageio, javax.sound.sampled, etc.) take a URL as a parameter. In those cases, it’s usually cleaner to pass the URL instead of creating and managing a stream. e.g.:

Image myimage = ImageIO.getImage(getClass().getResource("/map1.dat"));

One important note to keep in mind is that the paths are relative to the classpath, and you should always use absolute paths! Oh, and the separator is always a forward slash.

Once you have that fixed, it will make it easier for the rest of us to help with the scrolling bug. :slight_smile:

Hmm, I’m not quite sure what to do… I wasn’t loading files with “new FileInputStream()”, I was loading them like this:

BufferedReader in  = new BufferedReader(new FileReader( FileName ));

Hmm, that might be the same thing… dunno :-/

In any case, is there a way to fix the problem you had that would also entail using a way to obtain file input one line at a time, rather than by bytes? I can’t really figure out how to change everything to be loaded from bytes instead of just using .readLine() …

Er… and well currently I’m loading images like this:

Image cloud      =  new ImageIcon("images\\cloud.png").getImage();

and as far as I know, I thought that does load it from the url instead of creating a stream ???

[quote]Hmm, I’m not quite sure what to do… I wasn’t loading files with “new FileInputStream()”, I was loading them like this:

BufferedReader in  = new BufferedReader(new FileReader( FileName ));

Hmm, that might be the same thing… dunno :-/
[/quote]
That’s pretty much the same thing. FileReader is equivalent to:

Reader reader = new InputStreamReader(new FileInputStream("/map1.dat"));

It’s easy to convert it for classloading, however:

Reader reader = new InputStreamReader(getClass.getResourceAsStream("/map1.dat"));

[quote]Er… and well currently I’m loading images like this:

Image cloud      =  new ImageIcon("images\\cloud.png").getImage();

and as far as I know, I thought that does load it from the url instead of creating a stream ???
[/quote]
Erk! Quick, get this guy an IV! He’s going into image loading shock! :wink:

The good news is that the above does load from a URL, but it has several things wrong with it. For one, always use forward slashes for URLs. The use of backslashes may get you in trouble on other OSes. Also, use a forward slash in front of all your paths. This will keep you from running into some nasty bugs. :slight_smile:

The “correct” way to load an image is this:


import java.awt.image.*;
import javax.imageio.*;
...
BufferedImage image = ImageIO.read(getClass().getResource("/myimage.png"));

Be aware that these images may not be accelerated. You need to get an accelerated image from the GraphicsContext and copy your image into it. There’s a mini tut over on the WIKI:

http://wiki.java.net/bin/view/Games/LoadingSpritesWithImageIO

In theory yes. But lets try to make the ImageIO bug common knowledge and encurage the use of the workaround:


import java.awt.image.*;
import javax.imageio.*;
...
BufferedImage image = ImageIO.read(new BufferedInputStream(getClass().getResourceAsStream("/myimage.png")));

I think the workaround should be a sticky post on the Java2D section.

Tom, are you sure that happens with URL loading? I’ve seen it happen with InputStream loading, but not with URLs.

Yes I’m sure. Have a look at the source for ImageIO.read(URL). It’s the same as ImageIO.read(InputStream) only it uses URL.openStream() as the InputStream.

So I tried what you said jbanes, does it work now? :-/

www.ki-rush.com/what.jar

why not use the GTGE? :slight_smile:

http://www.goldenstudios.or.id/products/GTGE/

That? It looks like there is a ugly screen required at start up with an unsightly selection thing there as well and… and… and… are you saying I should give up trying to handle this kind of stuff

[quote]So I tried what you said jbanes, does it work now? :-/

www.ki-rush.com/what.jar
[/quote]
Are you sure you uploaded it? I’m still getting the same stack trace:

Exception in thread "main" java.io.FileNotFoundException: map1.dat (The system cannot find the file specified)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileReader.<init>(Unknown Source)
        at Map.MapChange(Map.java:105)
        at Map.<init>(Map.java:90)
        at Game.<init>(Game.java:38)
        at RunGame.main(RunGame.java:10)

[quote]why not use the GTGE? :slight_smile:
[/quote]
You’ll have to pardon my ignorance, but how would that help in this case? The issue includes loading maps as well as images. :-/

[quote]and… and… and… are you saying I should give up trying to handle this kind of stuff


[/quote]
Personally, I would never encourage anyone to quit unless they were in programming for all the wrong reasons (e.g. money, fame, but not the love of creating stuff). I may come across as a jackass sometimes (I don’t mean to, honest!), but my experience has been that it can spur people to find out what they’re truly capable of when they put their mind to something.

Remember, you didn’t learn faster when you were a kid. You just had fewer inhibitions about toying with things! :slight_smile:

BTW, I finally got some time so I extracted your game and got it running. I think the problem you may be having is that your key handling is wrong. If you only move the character on a key event, you’ll end up seeing a pause followed by a constant stream of events. This is called “typematic delay” and is easy to see by opening a text editor and holding down a key. Notice that one character prints, then there’s a pause until the next character prints.

The solution to this problem is to use flags that let you know when a key is down or up. Consider the following code for a moment:


int x;
int y;

boolean left;
boolean right;
boolean up;
boolean down;

public void run()
{
  BufferStrategy strategy.getBufferStrategy();

  while(true)
  {
    //draw stuff

    if(left) x--;
    if(right) x++;
    if(up) y--;
    if(down) y++;
  }
}

public void keyPressed(KeyEvent evt)
{
  if(evt.getKeyCode() == evt.VK_LEFT) left = true;
  if(evt.getKeyCode() == evt.VK_RIGHT) right= true;
  if(evt.getKeyCode() == evt.VK_UP) up = true;
  if(evt.getKeyCode() == evt.VK_DOWN) down = true;
}

public void keyReleased(KeyEvent evt)
{
  if(evt.getKeyCode() == evt.VK_LEFT) left = false;
  if(evt.getKeyCode() == evt.VK_RIGHT) right= false;
  if(evt.getKeyCode() == evt.VK_UP) up = false;
  if(evt.getKeyCode() == evt.VK_DOWN) down = false;
}

Does that help clarify it? Otherwise your scroll code seems to run just fine. :slight_smile:

Wow. My jaw just dropped at how awesome that worked. It took less than 2 minutes to fix it after I read that.

This bug was such a headache I thought I might have to change all of my plans for the game around it. Many thanks. :slight_smile:

Edit: nevermind, I seem to have the jar actually working now. I had the same errors as you it when it wasn’t working… so hopefully it would work now for you… does this .jar load properly? http://www.ki-rush.com/enpitsu.jar

[quote]http://www.goldenstudios.or.id/products/GTGE/

That? It looks like there is a ugly screen required at start up
[/quote]
Oh well an ugly screen lol… ;D
I’m not good at drawing graphics, so forgive my graphics skill :slight_smile:

Well for making tile based RPG, I have made a demo rpg and the source code is available to peek at, just in case you are interested of how I managing the player movement animation and other rpg stuff.
Here is the webstartable :
http://goldenstudios.or.id/products/games/bin/demorpg.jnlp
And the source code :
http://goldenstudios.or.id/products/games/bin/source/demorpg.zip

If you really don’t like the ugly screen I can remove it, I’m the one and only developer you know :wink:
Anyway the ‘ugly screen’ is only exists in the last version, it’s just an exchange of my hard work by giving it freely, not too annoying isn’t it :slight_smile:
At least the ‘ugly screen’ has translucent effect that can impressive player before entering the real game :stuck_out_tongue: