applet and player movement help

So im just trying to do an applet, where this @ moves around, but when i press up it jumps. well it incremenets how its supposed to but does it so rapidly. If i slow the thread down, of course that slows the game engine down. I also noticed that if i hit up then down then up then down several times the gap between the two get bigger and bigger. Can anyone suggest anything, thanks :wink:

import java.applet.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Game extends Applet
implements Runnable, KeyListener {
	int x = 0;
	Thread t;
	Image buffer;
	Graphics bufferg;
	int player_y = 100;
	public void init() {
		// Start thread
		t = new Thread(this);
		t.start();
		// Create buffer
		Dimension d = getSize();
		buffer = createImage(d.width, d.height);
		addKeyListener(this);
	}
	public void run() {
		try {
			while(true) {
				//Request a repaint
				repaint();
				// Sleep before update
				Thread.sleep(50);
			}
		}
		catch(Exception e) {
		}
	}
	public void update(Graphics g) {
		paint(g);
	}
	public void paint(Graphics g) {
		//Get graphics object for buffer
		if (bufferg == null)
			bufferg = buffer.getGraphics();
		//Draw to buffer
		Dimension d = getSize();
		bufferg.setColor(Color.white);
		bufferg.fillRect(0, 0, d.width, d.height);
		bufferg.setColor(Color.black);
		bufferg.drawString("@", x, player_y);
		//Update screen
		g.drawImage(buffer, 0, 0, this);
		
		addKeyListener(this);
	}
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==(KeyEvent.VK_UP))
		{
			System.out.println(player_y);
			player_y-= 1;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_DOWN))
		{
			player_y+=1;
		}


	}
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}
}

Output from pressing up once:
100
99
98
97
96
95
94
93
92
91
90
89
88
87
86
85
84
83
82
81
80
79
78
77
76
75

Just a quick peek…

Declare the playerY as a float and try incrementing by .25? or even lower?

Why +=? or -=? why not ++ or --? I just haven’t used that syntax (yet). I did see it’s used alot in for loops for incrementing a variable by a certain amount…

from http://www.freejavaguide.com/increment_decrement_operators.htm


class CountToTwenty  {

  public static void main (String args[]) {
    int i;
    for (i=0; i <=20; i += 2) {  //Note Increment Operator by 2
      System.out.println(i);
    } 
   
 } //main ends here

}

thanks for the peek, i tried the floats, it decreases the ā€œjumpsā€ but after the up and downs the gap still gets bigger. I think my algorithm is just wrong. even used --; and ++; which makes more sense to use. Its really weird that im getting this gap to happen.

Hi,

Remove the

addKeyListener(this);

call from the paint method.

If you want smoother motion, try this:


import java.applet.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Game extends Applet
implements Runnable, KeyListener {
	int x = 0;
	Thread t;
	Image buffer;
	Graphics bufferg;
	boolean upPressed=false;
	boolean downPressed=false;
	int player_y = 100;
	public void init() {
		// Start thread
		t = new Thread(this);
		t.start();
		// Create buffer
		Dimension d = getSize();
		buffer = createImage(d.width, d.height);
		addKeyListener(this);
	}
	public void run() {
		try {
			while(true) {
				//Request a repaint
				repaint();
				// Sleep before update
				Thread.sleep(50);
			}
		}
		catch(Exception e) {
		}
	}
	public void update(Graphics g) {
		paint(g);
	}
	public void paint(Graphics g) {
		//Get graphics object for buffer
		if (bufferg == null)
			bufferg = buffer.getGraphics();
		//Draw to buffer
		Dimension d = getSize();
		bufferg.setColor(Color.white);
		bufferg.fillRect(0, 0, d.width, d.height);
		bufferg.setColor(Color.black);
		bufferg.drawString("@", x, player_y);
		//Update screen
		g.drawImage(buffer, 0, 0, this);
		inputHandler();
	}
	
	private void inputHandler()
	{
		if (upPressed)
		{
			upPressed=false;
			player_y-= 1;
		}
		
		if (downPressed)
		{
			downPressed=false;
			player_y+= 1;
		}
	}
	
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==(KeyEvent.VK_UP))
		{
//			System.out.println(player_y);
//			player_y-= 1;
			upPressed=true;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_DOWN))
		{
//			player_y+=1;
			downPressed=true;
		}


	}
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}
}

duh im so retarded sometimes, thanks that did it :slight_smile:

Ok i’ve ran into a problem i think its either my buffering or my tile algorithm, if anyone could please take a look and help out that would be awesome.
When i run it off my computer its fine, http://www.scottscreations.com/rpg/index.html run it in a browser off my server it lags like heck.

here is the code

import java.applet.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import java.net.URL;

import javax.imageio.ImageIO;

public class Game extends Applet
implements Runnable, KeyListener {
	int player_x = 0;
	Thread t;
	Image buffer;
	Graphics bufferg;
	boolean upPressed=false;
	boolean downPressed=false;
	boolean leftPressed=false;
	boolean rightPressed=false;
	boolean jumped=false;
	int player_y = 100;
	Image heart;
	Image heart2;
	Image heart3;
	Rectangle playerbound;
	Image ladder;
	Image playerleft;
	Image playerright;
	Image plattile;
	Rectangle ladderbound;
	Rectangle platbound;
	boolean blocked = false;
	
	public void init() {
		// Start thread
		t = new Thread(this);
		t.start();
		// Create buffer
		Dimension d = getSize();
		buffer = createImage(d.width, d.height);
		playerleft = getImage(getURL("player_left.png"));
		playerright = getImage(getURL("player_right.png"));
		ladder = getImage(getURL("ladder.png"));
		
		
		heart = getImage(getURL("heart.png"));
		heart2 = getImage(getURL("heart.png"));
		heart3 = getImage(getURL("heart.png"));
		
		addKeyListener(this);
	}
	public void run() {
		try {
			while(true) {
				//Request a repaint
				repaint();
				// Sleep before update
				Thread.sleep(50);
			}
		}
		catch(Exception e) {
		}
	}
	public void update(Graphics g) {
		paint(g);
	}
	public void paint(Graphics g) {
		//Get graphics object for buffer
		if (bufferg == null)
			bufferg = buffer.getGraphics();
		//Draw to buffer
		Dimension d = getSize();
		
		playerbound = new Rectangle(player_x, player_y, playerright.getHeight(this), playerright.getWidth(this));
		ladderbound = new Rectangle(50, 350, ladder.getWidth(this) - 15, ladder.getHeight(this) -10);
		bufferg.setColor(Color.white);
		bufferg.fillRect(0, 0, d.width, d.height);
		bufferg.setColor(Color.black);
		Platform(-5, 450, 605, 25, bufferg);
		bufferg.drawImage(ladder, 40, 350, this);
		if(leftPressed)
		{
			bufferg.drawImage(playerleft, player_x, player_y, this);
		}
		else
		{
			bufferg.drawImage(playerright, player_x, player_y, this);
		}
		bufferg.drawString("Health: ", 5, 17);
		bufferg.drawImage(heart, 50, 5, this);
		bufferg.drawImage(heart2, 70, 5, this);
		bufferg.drawImage(heart3, 90, 5, this);
		//Update screen
		if(!playerbound.intersects(platbound))
		{
			player_y += 3;
			blocked = false;
		}
		blocked = true;
		g.drawImage(buffer, 0, 0, this);

		inputHandler();
	}
	
	private URL getURL(String string) {
		URL url = null;
		try {
			url = this.getClass().getResource(string);
		}
		catch(Exception e)
		{
			
		}
		return url;
	}
	private void Platform(int x, int y, int w, int h, Graphics g)
	{
		platbound = new Rectangle(x,y,w,h);
		plattile = getImage(getURL("platform.png"));
		int t = 0;
		for(int i = (int) platbound.getMinX(); i <= (int)platbound.getMaxX(); i++)
		{
			g.drawImage(plattile, t, (int) platbound.getMinY(), this);
			t+= 25;
		}
		
	}
	private void inputHandler()
	{
		
		if (leftPressed)
		{
			rightPressed=false;
			player_x-=2;
			player_y-=1;
		}
		if (rightPressed)
		{
			leftPressed=false;
			player_x+=2;
			player_y-=1;
		}
		if (jumped && !blocked)
		{
			int pjumpstart = player_y;
			while(jumped)
			{
				player_y -= 1;
				if(pjumpstart - player_y == 20)
				{
					jumped=false;
				}
			}
		}
		if( upPressed && playerbound.intersects(ladderbound))
		{
			player_y -= 5;
		}
	}
	
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==(KeyEvent.VK_UP))
		{
			upPressed=true;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_DOWN))
		{
			downPressed=true;
		}
		if(e.getKeyCode()==(KeyEvent.VK_LEFT))
		{
			leftPressed=true;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_RIGHT))
		{
			rightPressed=true;
		}
		if(e.getKeyCode()==KeyEvent.VK_SPACE)
		{
			jumped=true;
		}

	}
	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode()==(KeyEvent.VK_UP))
		{
			upPressed=false;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_DOWN))
		{
			downPressed=false;
		}
		if(e.getKeyCode()==(KeyEvent.VK_LEFT))
		{
			leftPressed=false;
		}
		else if(e.getKeyCode()==(KeyEvent.VK_RIGHT))
		{
			rightPressed=false;
		}
		if(e.getKeyCode()==KeyEvent.VK_SPACE)
		{
			jumped=false;
		}

	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}
}

pretty basic, it has to render the tile though each update and that i think is what is causing it, its cool cause if i want to say make this platform here and make it this long it does it. But maybe i’m way off on the idea and there is a better way.

Thanks :slight_smile:


playerbound = new Rectangle(player_x, player_y, playerright.getHeight(this), playerright.getWidth(this));
ladderbound = new Rectangle(50, 350, ladder.getWidth(this) - 15, ladder.getHeight(this) -10);

Creating new objects each time the render code is executed makes the garbage collector work overtime.

Another way is to do this in your init() method:

playerbound = new Rectangle();
ladderbound = new Rectangle();

Then in the paint() method:


playerbound.setBounds(player_x, player_y, playerright.getHeight(this), playerright.getWidth(this));
ladderbound.setBounds(50, 350, ladder.getWidth(this) - 15, ladder.getHeight(this) -10);

Also, the same thing goes for your Platform method:

In init():

platbound = new Rectangle();

Then in Platform():

platbound.setBounds(x,y,w,h);

Hope that helps.

thanks ill give it a shot, sometimes you stare at code so long you miss things :wink:

Another thing you can try is to preload all images before your loop starts. Specifically, remove the

plattile = getImage(getURL("platform.png"));

from Platform() and see if that makes any difference.

ya, i just updated it, then found that tile was being ā€œreloadedā€ over and over again and fixed that also, its now cleaned up and lag free, thankyou again.

It’s good that your movement is working out nicely, but there’s another issue.
The while loop you’re using for updating graphics? Be rid of it.
What you want to do is use a Timer ( javax.swing.Timer ) and have your updates contained within an ActionLIstener class.
Like so :


class UpdateListener implements ActionListener 
			{ 
				public void actionPerformed(ActionEvent event) 
				{
				repaint();
				}
			}
UpdateListener Update = new UpdateListener();
Timer t = new Timer(50, Update);
t.start();

Why you should do this : Timers can have multiple ActionListeners added to them and removed from them. This is especially important when you have multiple things to refresh that will act in different ways, such as NPCs moving around according to their surroundings or the player’s position. You can also stop and start Timers, which is useful if you want to pause the game or only have some things being refreshed under certain conditions.
Other points include that you can remove ActionListeners from a timer (IE - removing the ActionListener from the timer when a component is removed from the screen).

I tried timer before and I wouldn’t recommend it. Sure the a Timer with a calling to repaint() is the easiest way to get started for a begginer but I found out it had some issue. For example, the Timer was always like 2 milliseconds off the speed I want him to be… (Sometime like 10 millisec for fast timer).

However, you can still add multiple ActionListeners to a timer. This is especially important when you have multiple objects in multiple classes all checking and reacting to certain conditions (Such as a ball changing direction when it touches a wall, or a turtle turning around when it approaches a cliff).