I am trying to make a snake game and I am wondering how I could get an element of an vector and then use the number for the y coordinate

like when using ararys

lets say the x element I am using is 3

then I could type in arrayY[3] and it would use the x coordinate for the 4th point. how could I do this for a vector. my current code looks like this

private Vector<Integer> snakeX = new Vector<Integer> (5,2);
	private Vector<Integer> snakeY = new Vector<Integer> (5,2);
	
	public void startGraphics (){
		this.addKeyListener(this);
		repaint();
		snakeX.add(240);
		snakeY.add(240);
		snakeX.add(240);
		snakeY.add(230);
		snakeX.add(240);
		snakeY.add(220);
		
	}
	
	public void paintComponent (Graphics g){
		super.paintComponent (g);
		
		for (int x : snakeX){
			g.fillOval(x, snakeY.elementAt(snakeX.lastIndexOf (x)),10, 10);
			System.out.println ("x: " + x + "\t y: " + snakeY.elementAt(snakeX.lastIndexOf (x)));
		}
		
		
	}

in this I add 3 circles. they should print out on top of each other like a snowman, but when I run the program there is only one circle, and it is at the last location. the indexOf(); doesn't work, because the x coordinates are all the same. How would I fix this?

Thanks for any help.

Recommended Answers

All 14 Replies

The get() method will return an element by index from a Vector.

I'd recommend using ArrayList instead of Vector unless you need a synchronized collection (and I doubt that you do). The get() method is still the same.

You might also consider using Point objects instead of keeping separate lists for the x and y values.

using the getX() and getY() in a point vector method fixed the problem. the code now looks like this

for (Point x : snake){
	g.fillOval((int)x.getX(),(int)x.getY(),10, 10);
	System.out.println ("Point: " + x);
}

Thanks for the help

I now have another problem. I add a key Listener, but it doesn't work.

This is in a class that extends JPanel (for Graphics)

I type

addKeyListener (this);

and my keyListener methods look like this

private boolean pressed = false;
	private boolean up,down,left,right;
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub		
		System.out.println ("KeyListener");
		int key = e.getKeyCode();
		pressed = true;
		up = false;
		down = false;
		left = false;
		right = false;
		if (key == KeyEvent.VK_UP){
			up = true;
		}
		else if (key == KeyEvent.VK_DOWN){
			down = true;
		}
		else if (key == KeyEvent.VK_LEFT){
			left = true;
		}
		else if (key == KeyEvent.VK_RIGHT){
			right = true;
		}
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		pressed = false;
	}

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

but it doesn't seem to be getting a response.

Edit: It has Focus

Glad you got it working. I think you'll find Points a lot more convenient to manage.

> I now have another problem... it has the focus..

Are you certain that it really has the focus? Make sure that you call requestFocusInWindow() on your panel just to be sure because by default the panel itself won't receive focus.

I tried

grabFocus(); // this was there originally
and
requestFocusInWindow();

and still nothing

Post the relevant bits of code where you request focus after constructing the UI.

What is handling your repaints? A separate timer?

This is my starting method and my paintComponent method

public void startGraphics (){
		addKeyListener(this);
		Thread thread = new Thread (this);
		
		repaint();
		grabFocus();
		requestFocusInWindow();
		snake.add (new Point (250,250));
		snake.add(new Point (250,240));
		snake.add(new Point (250,230));
		thread.start();
	}
	
	public void paintComponent (Graphics g){
		super.paintComponent (g);
		
		for (Point x : snake){
			g.fillOval((int)x.getX(),(int)x.getY(),10, 10);
			System.out.println ("Point: " + x);
		}
	}

Here are my KeyListener Methods again

private boolean pressed = false;
	private boolean up,down,left,right;
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub		
		System.out.println ("KeyListener");
		int key = e.getKeyCode();
		pressed = true;
		up = false;
		down = false;
		left = false;
		right = false;
		if (key == KeyEvent.VK_UP){
			up = true;
		}
		else if (key == KeyEvent.VK_DOWN){
			down = true;
		}
		else if (key == KeyEvent.VK_LEFT){
			left = true;
		}
		else if (key == KeyEvent.VK_RIGHT){
			right = true;
		}
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		pressed = false;
	}

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

and I am using a thread that currently looks like this for the movement and the repaint();

@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println ("Started Thread");
		if (up == true){
			System.out.println ("UP");
			for (Point x : snake){
				Point temp = new Point (((int) x.getX()), ((int) x.getY())- 10);
				x = temp;
			}
			
		}
		else if (down == true){
			System.out.println ("Down");
			for (Point x : snake){
				Point temp = new Point (((int) x.getX()), ((int) x.getY())+ 10);
				x = temp;
			}
		}
		else if (left == true){
			System.out.println ("Left");
			for (Point x : snake){
				Point temp = new Point (((int) x.getX() - 10), ((int) x.getY()));
				x = temp;
			}
		}
		else if (right == true){
			System.out.println ("Right");
			for (Point x : snake){
				Point temp = new Point (((int) x.getX() + 10), ((int) x.getY()));
				x = temp;
			}
		}
		
		repaint();
	}

Ok, I would say your thread is the problem. It will repaint just like you want it to - once. There is no loop. You get one repaint and you're done.

You could either add a loop with a sleep() in it or switch to a Swing Timer and put your current run() code into an ActionListener.

commented: that's right +9

You can also replace

Point temp = new Point (((int) x.getX()), ((int) x.getY())- 10);

with

x.y -= 10;

This is my new thread code

@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println ("Started Thread");
		while (true){
			
			if (up == true){
				System.out.println ("UP");
				for (Point x : snake){
					Point temp = new Point (((int) x.getX()), ((int) x.getY())- 10);
					x = temp;
				}

			}
			else if (down == true){
				System.out.println ("Down");
				for (Point x : snake){
					Point temp = new Point (((int) x.getX()), ((int) x.getY())+ 10);
					x = temp;
				}
			}
			else if (left == true){
				System.out.println ("Left");
				for (Point x : snake){
					Point temp = new Point (((int) x.getX() - 10), ((int) x.getY()));
					x = temp;
				}
			}
			else if (right == true){
				System.out.println ("Right");
				for (Point x : snake){
					Point temp = new Point (((int) x.getX() + 10), ((int) x.getY()));
					x = temp;
				}
			}

			repaint();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

but the key listener still doesn't seem to work.

Are you calling startGraphics() after the UI has been completely set up in the frame and set to visible?
Are you getting any of the println messages "KeyListener"?

I was calling it right before the frame was set visible. I guess this took away the focus and made it not work. Thanks for the help

time to use KeyBinding instead of KeyListener

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.