I have this snake game I keep talking about and I added in a menu. now when I run the snake game the first time it works. When I press T to return to the title, it returns. When I click on the colored snake game after that the snake goes twice as fast. I have a feeling that the previous thread starts running again, along with the new thread. How could I fix this error?

The colored snake game

package SnakeTimer;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class CSnakeG extends JPanel implements KeyListener, Runnable{

	private Vector<Point> snake = new Vector<Point> (5,10);
	private Point target;
	private Rectangle targetRect;
	private Rectangle frameRect = new Rectangle (0,0,490,470);
	private Vector<Color> snakeColor = new Vector<Color> (5,10);
	private Color targetColor;
	private Vector<Rectangle> snakeRectangle = new Vector<Rectangle> (5,10);
	private snake snakeClass;
	
	
	
	public void startGraphics (snake s){
		snakeClass = s;
		snake.removeAllElements();
		snakeRectangle.removeAllElements();
		this.addKeyListener(this);
		setup();
	}
	
	private void setup() {
		// TODO Auto-generated method stub
		Thread thread = new Thread (this);
		
		repaint();
		grabFocus();
		snake.add (new Point (250,250));
		genTarget();
		snakeRectangle.add(new Rectangle (250,250,10,10));
		snakeColor.add(Color.black);
		runThread = true;
		thread.start();
	}

	private void addBall() {
		// TODO Auto-generated method stub
		if (previous.equals("right")){
		snake.add (new Point (snake.lastElement().x - 10, snake.lastElement().y));
		}
		if (previous.equals("left")){
			snake.add (new Point (snake.lastElement().x + 10, snake.lastElement().y));
		}
		if (previous.equals("up")){
			snake.add (new Point (snake.lastElement().x, snake.lastElement().y + 10));
		}
		if (previous.equals("down")){
			snake.add (new Point (snake.lastElement().x, snake.lastElement().y - 10));
		}
		snakeRectangle.add(new Rectangle ((int)snake.lastElement().x, (int) snake.lastElement().y, 10,10));
		snakeColor.add(targetColor);
		
		
		
	}

	
	
	public void paintComponent (Graphics g){
		//TODO GRAPHICS AREA
		super.paintComponent (g);
		
		
		for (Point x : snake){
			g.setColor(snakeColor.elementAt(snake.indexOf(x)));
			g.fillOval((int)x.getX(),(int)x.getY(),10, 10);
			
		}
		g.setColor (Color.black);
		if (runThread == false){
			System.out.println ("Lost message entered");
			g.setFont (new Font ("Arail", 30,30));
			g.drawString("You Lose!", 200, 220);
			g.setFont (new Font ("Arial", 10,10));
			g.drawString("Press N for a new Game", 210,230);
			g.setFont(new Font ("Arial", 17,17));
			g.drawString("Your Final Snake Size Was: " + snake.size(), 160, 250);
		}
		else {
			g.setFont(new Font ("Arial", 15,15));
			g.drawString("Snake size: " + snake.size(), 210, 220);
		}
		g.setColor(targetColor);
		g.fillOval((int)(target.getX()), (int)(target.getY()), 10,10);
	}

	
	
	private String previous;
	private boolean wasPressed = false;
	private boolean pressed = false;
	private boolean up,down,left,right;
	
	@Override
	public void keyPressed(KeyEvent e) {
		System.out.println ("KeyListener");
		int key = e.getKeyCode();
		
		up = false;
		down = false;
		left = false;
		right = false;
		System.out.println (pressed);
		if (key == KeyEvent.VK_UP && runThread == true){
			up = true;
			previous = "up";
		}
		else if (key == KeyEvent.VK_DOWN && runThread == true){
			down = true;
			previous = "down";
		}
		else if (key == KeyEvent.VK_LEFT && runThread == true){
			left = true;
			previous = "left";
		}
		else if (key == KeyEvent.VK_RIGHT  && runThread == true){
			right = true;
			previous = "right";
		}
		else if (key == KeyEvent.VK_N && runThread == false){
			resetGame();
		}
		else if (key == KeyEvent.VK_T){
			runThread = false;
			previous = "a";
			returnToMenu = true;
		}
		else {}
		if (previous == null){
			runThread = true;
		}
		
	}

	private boolean returnToMenu = false;
	
	private void resetGame() {
		// TODO Auto-generated method stub
		snake.removeAllElements();
		snakeRectangle.removeAllElements();
		target = null;
		targetRect = null;
		wasPressed = false;
		setup();
	}

	@Override
	public void keyReleased(KeyEvent e) {
		wasPressed = true;
	}

	@Override
	public void keyTyped(KeyEvent e){}

	
	
	private boolean runThread = true;
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println ("Started Thread");
		while (runThread){
			System.out.println ("Up: " + up + "\tDown: " + down + "\tLeft: " + left + "\tRight: " + right);
			
			//moving the snake
			if (up == true){
				System.out.println ("entered if");
				for (int i = snake.size() - 1; i > -1; i--){
					
					if (i == 0){
						snake.firstElement().y -= 10;
						
					}
					else {
						snake.elementAt(i).y = snake.elementAt(i - 1).y;
					}
				}

			}
			else if (down == true){
				for (int i = snake.size() - 1; i > -1; i--){
					
					if (i == 0){
						snake.firstElement().y += 10;
						
					}
					else {
						snake.elementAt(i).y = snake.elementAt(i - 1).y;
					}
				}

			}
			else if (left == true){
				for (int i = snake.size() - 1; i > -1; i--){
					
					if (i == 0){
						snake.firstElement().x -= 10;
						
					}
					else {
						snake.elementAt(i).x = snake.elementAt(i - 1).x;
					}
				}

			}
			else if (right == true){
				for (int i = snake.size() - 1; i > -1; i--){
					
					if (i == 0){
						snake.firstElement().x += 10;
						
					}
					else {
						snake.elementAt(i).x = snake.elementAt(i - 1).x;
					}
					
				}

			}
			System.out.println ("At start of turning");
			//Turning the snake
			if (wasPressed == true){
				if (previous.equals ("up")){
					for (int i = snake.size() - 1; i > 0; i--){
						
						snake.elementAt(i).x = snake.elementAt(i - 1).x;
					}
				}
				else if (previous.equals("down")){
					for (int i = snake.size() - 1; i > 0; i--){
						
						snake.elementAt(i).x = snake.elementAt(i - 1).x;
					}
				}
				else if (previous.equals("left")){
					for (int i = snake.size() - 1; i > 0; i--){
						
						snake.elementAt(i).y = snake.elementAt(i - 1).y;
					}
				}
				else if (previous.equals("right")){
					for (int i = snake.size() - 1; i > 0; i--){
						
						snake.elementAt(i).y = snake.elementAt(i - 1).y;
					}
				}
				else {}
			}
			updateRect();
			collisionDetect();
			
			
			
			
			repaint();
			//System.out.println ("before sleep. runThread: " + runThread);
			try {
				//System.out.println ("before sleep. runThread: " + runThread);
				Thread.sleep(100);
				//System.out.println ("After sleep. runThread: " + runThread);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//System.out.println ("After sleep. runThread: " + runThread);
			
		}
		if (returnToMenu == true){
			returnToMenu = false;
			removeKeyListener (this);
			snakeClass.menu(3);
		}
	}

	private void updateRect() {
		// TODO Auto-generated method stub
		for (int i = 0; i < snake.size(); i++){
			snakeRectangle.get(i).setLocation(snake.elementAt(i));
		}
	}

	private void collisionDetect() {
		// TODO Auto-generated method stub
		for (int i = 0; i < snake.size(); i++){

			//System.out.println("Z: " + z + " I " + i);
			if (i == 0){
				System.out.println("z = i accessed");
			}
			else {
				if (snakeRectangle.firstElement().contains((snakeRectangle.elementAt(i).getX()), (snakeRectangle.elementAt(i).getY()))){
					System.out.println("2 elements are the same");
					lost();
				}
			}

		}
		if (!frameRect.contains(snake.firstElement())){
			lost();
		}
		
		if (snakeRectangle.firstElement().contains(target)){
			addBall();
			genTarget();
		}
		
		
	}
	
	private void lost() {
		// TODO Auto-generated method stub
		runThread = false;
		repaint();
	}

	private void genTarget (){
		target = new Point ((int) (Math.random () * 48)* 10,(int) (Math.random () * 47) * 10);
		System.out.println (target);
		targetRect = new Rectangle (target, new Dimension (10,10));
		int colorGen = (int) (Math.random() * 10);
		
		if (colorGen == 0){
			targetColor = Color.red;
		}
		else if (colorGen == 1){
			targetColor = Color.blue;
		}
		else if (colorGen == 2){
			targetColor = Color.green;
		}
		else if (colorGen == 3){
			targetColor = Color.yellow;
		}
		else if (colorGen == 4){
			targetColor = Color.gray;
		}
		else if (colorGen == 5){
			targetColor = Color.cyan;
		}
		else if (colorGen == 6){
			targetColor = Color.orange;
		}
		else if (colorGen == 7){
			targetColor = Color.magenta;
		}
		else if (colorGen == 8){
			targetColor = Color.pink;
		}
		else if (colorGen == 9){
			targetColor = Color.white;
		}
		repaint();
	}
	
}

The menu to launch it

package SnakeTimer;
import javax.swing.*;


public class snake {

	private SnakeG sg = new SnakeG ();
	private SnakeMenu sm = new SnakeMenu ();
	private JFrame frame;
	private CSnakeG csg = new CSnakeG ();
	private OSnakeG osg = new OSnakeG ();
	
	public snake (){
		frame = new JFrame ("Snake - v2.0");
		frame.setSize (500,500);
		frame.setResizable (false);
		
		frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		frame.add (sm);
		
		
		frame.setVisible (true);
		sm.startMenu(this);
		
	}
	
	public void campaign (){
		frame.remove (sm);
		frame.add(sg);
		frame.validate();
		sg.startGraphics(this);
	}
	
	public void freeRunNorm(){
		frame.remove(sm);
		frame.add (osg);
		frame.validate();
		osg.startGraphics(this);
	}
	public void freeRunRainbow (){
		frame.remove(sm);
		frame.add(csg);
		frame.validate();
		csg.startGraphics(this);
	}
	public void highScore (){
		
	}
	public void menu (int option){
		if (option == 1)
			frame.remove(sg);
		else if (option == 2)
			frame.remove(osg);
		else if (option == 3)
			frame.remove(csg);
		
		frame.add (sm);
		frame.validate ();
		sm.startMenu(this);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		snake s = new snake ();
	}

}

Thanks for any help.

Recommended Answers

All 9 Replies

There is no definition for the SnakeMenu class.

sorry. I'll post it now.

package SnakeTimer;

import java.awt.*;
import java.awt.event.*;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class SnakeMenu extends JPanel implements MouseListener, MouseMotionListener{

	private int mx, my;
	private Rectangle campaign = new Rectangle (50,50,160,50);
	private Rectangle freePlayN = new Rectangle (50,125,160,50);
	private Rectangle freePlayC = new Rectangle (50,200,160,50);
	private Rectangle highScore = new Rectangle (50,275,160,50);
	private snake snake;
	private Color campSel = Color.black; 
	private Color fPSel = Color.black;
	private Color fPCSel = Color.black;
	private Color hSSel = Color.black;
	
	
	public void startMenu (snake s){
		snake = s;
		addMouseListener (this);
		addMouseMotionListener (this);
		repaint ();
	}
	
	public void paintComponent (Graphics g){
		super.paintComponent (g);
		
		g.setColor(Color.orange);
		g.fillRect (50,50,160,50);
		g.setColor(Color.LIGHT_GRAY);
		g.fillRect (50,125,160,50);
		g.setColor(Color.magenta);
		g.fillRect (50,200,160,50);
		g.setColor (Color.red);
		g.fillRect (50,275,160,50);
		g.setColor (Color.black);
		g.setFont (new Font ("Arial", 20,20));
		g.setColor(campSel);
		g.drawString("Campaign", 80, 80);
		g.setColor(fPSel);
		g.drawString("Free Play", 80, 155);
		g.setColor(fPCSel);
		g.drawString("Free Play - Color", 55, 230);
		g.setColor(hSSel);
		g.drawString("High Scores", 75, 305);
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		mx = e.getX();
		my = e.getY();
		
		campSel = Color.black;
		fPSel = Color.black;
		fPCSel = Color.black;
		hSSel = Color.black;
		if (campaign.contains (mx,my)){
			campSel = Color.white;
		}
		else if (freePlayN.contains(mx,my)){
			fPSel = Color.white;
		}
		else if (freePlayC.contains(mx,my)){
			fPCSel = Color.white;
		}
		else if (highScore.contains(mx,my)){
			hSSel = Color.white;
		}
		repaint();
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if (campaign.contains(mx,my)){
			snake.campaign();
		}
		else if (freePlayN.contains(mx,my)){
			snake.freeRunNorm();
		}
		else if (freePlayC.contains(mx,my)){
			snake.freeRunRainbow();
		}
		else if (highScore.contains(mx,my)){
			JOptionPane.showMessageDialog(null, "This Option has not been implemented yet!");
		}
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		
		
	}

}

Now missing definition for OSnakeG

and SnakeG

Those are different versions of the same game. Just comment them out.

What is supposed to happen?
What do you do to observe the problems?
I see a black circle and a yellow circle. The black circle moves with the arrow keys.

When I press T to return to the title, it returns.

What is the T you mention?

when you are in game the "T" button on your keyboard returns you to the title screen or the snakeMenu code. After when you go into the same snake game option (Free Play - Color) the snake moves twice as fast. then if you repeat again then the snake moves even faster. I am wondering why this is happening and how I can fix the problem.

Do some more debugging by adding more printlns.
What makes the black dot move faster? Changing its position and doing repaint more frequently. Look at those.
printout a message when the run method exits - that is the end of a thread.

I added a println right before the if statement that goes back to the menu and every single time I go to the menu it prints out more and more thread ended. Which means that every time I start playing again multiple threads are running.

*EDIT: I fixed it by removing the while statement in the thread and adding a timer in to control the thread.

Thanks for the help

Add this statement in the mousePressed method and look at what it prints out.

System.out.println(" >>>>>>>>>>>>>>>>>>>> mousePressed at " + System.currentTimeMillis());

Look especially at the times when it is called. That will tell you about your mouse listener.

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.