I need help with SCROLLING

Im having an annoying problem, im making a side scrolling game, and i tried to do scrolling today, and it ALMOST works except for one thing,

…my character doesn’t “stop” moving during scrolling so he goes to the edge

basically when im trying to scroll, my level elements and main character suppose to be scrolling the other direction, so far my elements scroll but my character person just sort of slows down but doesn’t stop…

import java.awt.*;
import java.applet.*;

public class Main extends Applet implements Runnable
{
	int startPosX;
	int startPosY;	
	
	Thread gameThread;
	Quixote quix;
	
	Image donFacingRight;
	Image donFacingLeft;
	Image donWalkingLeft;
	Image donWalkingRight;
	Image donWalkingLeft2;
	Image donWalkingRight2;
	
	private Image dbImage;
	private Graphics dbg;
	
	MediaTracker tracker;
	
	Level level;

	public void init()
	{
		setBackground(Color.blue);
		startPosX = 0;
		startPosY = 400-DQConstants.donNormalHeight;
		
		
		quix = new Quixote(startPosX,startPosY,this);
		level = new Level(DQConstants.testlevel,this,this);
		
		createImages();
		
	
		quix.setImages(donFacingLeft,donFacingRight,donWalkingLeft,
						donWalkingRight, donWalkingRight2, donWalkingLeft2);
						
		quix.setGroundList(level.getGroundList());
						
		
	}
	
	public void createImages()
	{
		tracker = new MediaTracker(this);
		
		donFacingRight = getImage(getCodeBase(),"donFaceRight.gif");
		tracker.addImage(donFacingRight, 1);
		donFacingLeft = getImage(getCodeBase(),"donFaceLeft.gif");
		tracker.addImage(donFacingLeft, 2);
		donWalkingRight = getImage(getCodeBase(),"donWalkRight.gif");
		tracker.addImage(donWalkingRight, 3);
		donWalkingLeft = getImage(getCodeBase(),"donWalkLeft.gif");
		tracker.addImage(donWalkingLeft, 4);
		donWalkingRight2 = getImage(getCodeBase(),"donWalkRight2.gif");
		tracker.addImage(donWalkingRight2, 5);
		donWalkingLeft2 = getImage(getCodeBase(),"donWalkLeft2.gif");
		tracker.addImage(donWalkingLeft2, 6);
	
		try
		{
			tracker.waitForAll();
		}
		catch (Exception exception)
		{

		}
	}
	
	public void run()
	{
		while(true)
		{
			quix.updateQuixote();
			
			if( level.inScrollLeft( quix.getXposLeft() ) )
			{
				if( level.insideLeftBound())
				{
					level.scrollLevel(2);
					quix.scroll(2);
					setBackground(Color.green);
				}
			}
			else if( level.inScrollRight( quix.getXposRight() )	)
			{
				if( level.insideRightBound())
				{
					level.scrollLevel(-2);
					quix.scroll(-2);
					setBackground(Color.black);
				}
			}
		
			repaint();
		
			try
			{
				gameThread.sleep(14);
			}
			catch(InterruptedException E)
			{
				
			}
		}
	}
	public void start()
	{
		gameThread = new Thread(this);
		gameThread.start();
	}
	public void stop()
	{
		gameThread.stop();
	}
	
	public boolean keyDown (Event e, int key)
	{
		if(key == Event.LEFT)
		{
			quix.isWalkingLeft(true);
		}
		else if (key == Event.RIGHT)
		{
			quix.isWalkingRight(true);
		}
		else if (key == Event.UP)
		{
			if(!quix.getJumpLock())
				quix.isJumping(true);
			
		}

		return true;
	}

	// event handling for keys up
	public boolean keyUp(Event e, int key)
	{
		if(key == Event.LEFT)
		{
			quix.isWalkingLeft(false);
			quix.isFaceLeft(true);
		
			
		}
		else if(key == Event.RIGHT)
		{
			quix.isWalkingRight(false);
			quix.isFaceLeft(false);
		
		}
		
			
		return true;
	}

	public void update(Graphics g)
	{
		if (dbImage == null)
		{
			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();
		}

		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

		dbg.setColor (getForeground());

		paint(dbg);

		g.drawImage (dbImage, 0, 0, this);
	}
	public void paint(Graphics g)
	{
		quix.paintQuixote(g);
		level.paintLevel(g);
		level.paintGround(g);
		
	}

}

import java.applet.*;
import java.awt.*;
import java.util.*;

public class Quixote
{
	
	int x_posRight;
	int x_posLeft;
	int x_posCenter;
	int y_posUp;
	int y_posDown;
	
	int col;
	
	int walkspeed = 2;
	int fallspeed = 4;
	int jumpspeed = -6;
	int jumpspeed2 = -4;
	 
	int currentJumpSpeed=0;
	
	int jumpCounter = 0;
	int walkCounter = 0;
	
	boolean faceLeft = false;
	boolean jumping = false;
	boolean falling = false;
	boolean walkingLeft = false;
	boolean walkingRight = false;
	boolean jumpLock = false;

	Component applet;
	
	Image donFacingRight;
	Image donFacingLeft;
	Image donWalkingLeft;
	Image donWalkingRight;
	Image donWalkingLeft2;
	Image donWalkingRight2;
	Image groundImage;
	
	Element[] gList;
	
	
	
	public Quixote(int xpos, int ypos, Component applet)
	{
		x_posLeft = xpos;
		x_posRight = xpos + DQConstants.donNormalWidth;
		y_posUp = ypos;
		y_posDown = ypos + DQConstants .donNormalHeight;
		x_posCenter = xpos + DQConstants.donNormalWidth/2;
		
		col = (x_posCenter+6)/ 100;
		
		this.applet = applet;
		
	}
	
	public void setImages(Image faceLeft, Image faceRight, Image walkLeft, 
						   Image walkRight, Image walkRight2, Image walkLeft2)
	{
		donFacingRight = faceRight;
		donFacingLeft = faceLeft;
		donWalkingRight = walkRight;
		donWalkingLeft =  walkLeft;
		donWalkingLeft2 = walkLeft2;
		donWalkingRight2 = walkRight2;
		
	}
	
	public void setGroundList(Element[] groundList)
	{
		gList = groundList;
	}
	
	public int getXposLeft()
	{
		return x_posLeft;
	}
	public int getXposRight()
	{
		return x_posRight;
	}
	public int getYposUp()
	{
		return y_posUp;
	}
	public int getYposDown()
	{
		return y_posDown;
	}
	public int getXposCenter()
	{
		return x_posCenter;
	}
	public boolean getJumpLock()
	{
		return jumpLock;
	}
	public void isJumping(boolean b)
	{
		jumping = b;
	}
	public void isFaceLeft(boolean b)
	{
		faceLeft = b;
	}
	public void isWalkingLeft(boolean b)
	{
		walkingLeft = b;
		faceLeft = b;
	}
	public void isWalkingRight(boolean b)
	{
		walkingRight = b;
		faceLeft = !b;
	}
	
	public void scroll(int speed)
	{
		x_posLeft += speed;
		x_posRight +=  speed;
		x_posCenter +=  speed;
	}
	public void updateXpos(boolean x)
	{
		boolean left = x;
		
		if(left)
		{
			x_posLeft -= walkspeed;
			x_posRight -= walkspeed;
			x_posCenter -= walkspeed;
		}
		else
		{
			x_posLeft += walkspeed;
			x_posRight += walkspeed;
			x_posCenter += walkspeed;
		}
		
		col = (x_posCenter+6)/ 100;
		
		walkCounter++;
		if(walkCounter==46)
			walkCounter=1;
	}
	public void updateYpos(int y)
	{
		int ySpeed = y;
		
		y_posUp+=ySpeed;
		y_posDown+=ySpeed;
		
	}
	public void updateQuixote()
	{
		if(walkingLeft)
		{
			updateXpos(true);
			faceLeft = true;
		}
		else if(walkingRight)
		{
			updateXpos(false);
			faceLeft = false;
		}
		
		if(jumping)
		{
			jumpLock = true;
			
			if(jumpCounter<30)
			{
				updateYpos(jumpspeed);
				jumpCounter++;
			}
				
		
			else if(jumpCounter<45)
			{
				updateYpos(jumpspeed2);
				jumpCounter++;
			}
			
			else
			{
				jumping = false;
				jumpCounter = 0;
				falling = true;
				
			}
			
			
			
			
		}
			
		
		if(falling)
		{
			
			updateYpos(fallspeed);
			
			if(y_posDown==DQConstants.GROUNDPOSITION)
			{
				falling=false;
				jumpLock = false;
			}		
			
		}
	
		if(y_posDown==200)
		{
			
			if(gList[col]==null)
			{
				if(!jumping)
				{
					falling = true;
					jumpLock = true;
				}
			}
			else if(gList[col].getCol()==col)
			{
				falling = false;
				jumpLock = false;
					
			}	
			
		}
		
		if(y_posUp==221)
		{
			if(gList[col]==null)
			{
				

			}	
			else if(gList[col].getCol()==col)
			{
				jumping = false;
				falling = true;
				jumpCounter = 0;
			}
				
		}
					
				
				
				
		
		
		
		
		
			
	}
	
	
	public void paintQuixote(Graphics g)
	{
		g.setColor(Color.red);
		g.drawString(x_posLeft + " " + x_posRight,100,100);
		g.drawString(y_posDown + " " + y_posUp,100,80);
		g.drawString(""+col,100,120);
		if(jumping)
			if(faceLeft)
				g.drawImage(donFacingLeft,x_posLeft,y_posUp,applet);
			else
				g.drawImage(donFacingRight,x_posLeft,y_posUp,applet);

		else
		
			if(walkCounter>30)
				if(faceLeft)
					g.drawImage(donWalkingLeft2,x_posLeft,y_posUp,applet);
				else
					g.drawImage(donWalkingRight2,x_posLeft,y_posUp,applet);
			else if(walkCounter>15)
				if(faceLeft)
					g.drawImage(donWalkingLeft,x_posLeft,y_posUp,applet);
				else
					g.drawImage(donWalkingRight,x_posLeft,y_posUp,applet);
			else
				if(faceLeft)
					g.drawImage(donFacingLeft,x_posLeft,y_posUp,applet);
				else
					g.drawImage(donFacingRight,x_posLeft,y_posUp,applet);
		
	
			
		g.drawString(Integer.toString(x_posCenter),x_posCenter,y_posUp-20);
	}
}	



  1. That’s WAY too much code. Next time try to trim it to the important calculations.

  2. Your problem is caused by having two coordinate systems. You have the virtual coordinates of the world (which we’ll assume is 2-3x the width of the screen) and the real coordinates of the screen. Both your character and your world need to be in the same world coordinates, then translated into screen coordinates for rendering. Instead, you’ve got the character in the screen coordinates and the background in the world coordinates.

Fixing this issues is quite easy. For the character position:

int characterx;
int charactery;
Image characterImage;

//This is how far the screen has scrolled
int scrollx;
...

if(right_key_pressed) characterx++;
if(left_key_pressed) characterx--;

...

//The subtraction is translating the characters virtual position to his real position on the screen
g.drawImage(characterImage, characterx-scrollx, charactery);

If you want to lock the character at the center of the screen and scroll the background around him, you need to add the following line after the key presses are handled:

//Adjusts the scroll point to place the character at precisely the center of the screen.
scrollx = characterx+(characterWidth/2)-(screenWidth/2)

woohoo! thank you