Results 1 to 3 of 3
  1. #1
    java_noob1234 is offline Member
    Join Date
    Mar 2012
    Posts
    1
    Rep Power
    0

    Default Issue with paintComponent() or KeyListener

    Hi guys,

    Over the past month or so I've been learning the foundations of Java / OOP and decided I'd tackle a fairly basic game: Boulder Dash. The general idea is to have a bulldozer run through the level, demolishing dirt and picking up gems (and avoiding the stones). My basic concept is to create a two dimensional array of 'Block' objects to draw my levels. These 'Blocks' are (for anyone who hasn't played boulder dash): stones, gems and dirt.

    I've been able to create and fill an array of my Block() objects with no issues, and then initially draw the level onto the panel without issue. Once this happens, one of the objects (dozer) needs to be able to run around smashing through dirt, collecting gems, etc. Despite my best efforts, my KeyListener doesn't work, or I don't quite understand how to repaint correctly.

    The following is the code for my block object (block.java), although I don't believe there are any gaping issues here causing my problems.

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    // This class will allow us to define features of the different types of blocks in the game
    
    public class Block {
    	
    	int x = 0;	
    	int y = 0;
    	boolean visible = true;
    	
    	String blockType = "";
    	// Initialize the block
    	public Block ()
    	{
    		setPos(0,0);
    		setType("");
    		visible = true;
    	}
    	
    	// Set the position of the block
    	public void setPos (int stone_x, int stone_y)
    	{
    		x = stone_x;
    		y = stone_y;
    		
    	}
    	
    	public Boolean isVisible()
    	{
    		return visible;
    	}
    	
    	public void setVisible(Boolean b)
    	{
    		visible = b;
    	}
    	
    	//Get position of the block
    	public Point getPos()
    	{
    		Point blockPos = new Point();
    		blockPos.x = x;
    		blockPos.y = y;
    		return (blockPos);
    	}
    	
    	
    	// Set type of the block: limited to dirt, stone, gem
    	public void setType (String type)
    	{
    		blockType = type;
    	}
    	
    	// Get type of the block: 
    	public char getType()
    	{
    		char type;
    		type = blockType.charAt(0);
    		return type;
    	}
    	
    	
    	
    
    
    }

    This is my panel (LevelGen.java). What it will do is create an array of my Block() objects, fill them with the correct information based on level input (just basic strings at this point for proof of concept), and then the paintComponent method will pull the relevant information out of the array to draw (and redraw) everything where appropriate. As I said, I think my main issue is with keyListener, which is intended to move around the bulldozer.

    Java Code:
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    import javax.swing.*;
    
    
    
    //----------------------------------------------------------------- 
    //LevelGen.java 
    //
    // This class will extract level information from Level.java, create a two dimensional array to be
    // drawn onto the screen for our level.
    //-----------------------------------------------------------------
    
    public class LevelGen extends JPanel {
    	
    	
    	final int MAP_ROWS = 5;
    	final int MAP_COLUMNS = 5;
    	final int IMG_WIDTH = 64;
    	final int IMG_HEIGHT = 64;
    	
    	String line1 = "dbgbs";
    	String line2 ="bbsgg";
    	String line3 = "gggbg";
    	String line4 = "bbbss";
    	String line5 = "bsbgg";
    	
    	
    	String strMap = line1 + line2 + line3 + line4 + line5;
    	Toolkit toolkit = getToolkit();
    	int numStone =0;
    	int numBomb = 0;
    	int numGem = 0;
    	
    	int dozerX = 64;
    	int dozerY = 64;
    	
    	
    	
    	private Image imgStone = null;
    	private Image imgGem = null;
    	private Image imgBomb = null;
    	private Image imgDirt = null;
    	private ImageIcon imgDozer = new ImageIcon("dozer.png");
    	
    	
    	int x = 0;
    	int y = 0;
    
    	Block[][] map = new Block[MAP_ROWS][MAP_COLUMNS];
    	
    	public LevelGen()
    	{
    
    		fillMap();
    		imgStone = toolkit.createImage("stone.png");
    		imgGem = toolkit.createImage("gem.png");
    		imgBomb = toolkit.createImage("bomb.png");
    		imgDirt = toolkit.createImage("dirt.png");
    		setBackground(Color.black);
    		setFocusable(true);
    		
    		addKeyListener (new DirectionListener());
    
    		
    	}
    	
    	public void paintComponent (Graphics g)
    	{
    
    		super.paintComponent(g);
    
    		Color transparent = new Color(0, 0, 0, 0);
    		
    		
    		for (int i = 0; i < MAP_ROWS ; i++){
    			
    			y = (i*IMG_HEIGHT);
    		
    			for (int j = 0; j < MAP_ROWS ; j++)
    			{	
    				// checks if block is supposed to be visible
    				if (map[i][j].isVisible())
    				{
    									
    					//char type = strMap.charAt(count);
    					char type = map[i][j].getType();
    					
    					x = (j*IMG_WIDTH);
    					switch ((char)type)
    					{
    					case 'S':
    						//draw new stone image
    
    						g.drawImage(imgStone, x, y, transparent, this);
    						break;
    					case 'B':
    						// draw new bomb image
    						g.drawImage(imgBomb, x, y, transparent, this);					
    						break;
    					case 'G':
    						// draw new gem image
    						g.drawImage(imgGem, x, y, transparent, this);
    						break;
    					case 'D':
    						// draw dozer;
    						imgDozer.paintIcon(this, g, dozerX, dozerY);
    					default:break;
    					}
    				}
    				else
    				{
    					g.setColor(Color.black);
    					g.fillRect(x, y, IMG_HEIGHT, IMG_WIDTH);
    				}
    				
    				printArray();
    
    				
    			}
    				
    			}
    				
    				// retrieve value from strMap and convert it into line by line
    				// information about what tile to place in each array field
    				
    				
    
    				
    				//map[i][j] = strMap.charAt(count);
    				
    				
    			}
    							
    		
    
    	
    	
    	public void fillMap ()
    	{
    		
    		int count = 0;
    		
    		for (int i = 0; i < MAP_ROWS ; i++){
    			y = 0;
    			y = y + (i*IMG_HEIGHT);
    		
    			for (int j = 0; j < MAP_ROWS ; j++)
    			{	
    				map[i][j] = new Block();
    				char a = strMap.charAt(count);
    				x = 0;
    				x = x + (j*IMG_WIDTH);
    				map[i][j].setVisible(true);
    				switch ((char)(a))
    				{
    				case 's':
    					//fill array at i & j with stone values
    					map[i][j].setPos(x, y);
    					map[i][j].setType("Stone");
    					break;
    				case 'b':
    					// draw new bomb image
    					map[i][j].setPos(x, y);
    					map[i][j].setType("Bomb");				
    					break;
    				case 'g':
    					// draw new gem image
    					map[i][j].setPos(x, y);
    					map[i][j].setType("Gem");
    					break;
    				case 'd':
    					map[i][j].setPos(x, y);
    					map[i][j].setType("Dozer");
    					dozerX = x;
    					dozerY = y;
    				default:break;
    				}
    				
    				count++;
    				
    			}
    		}
    		
    	}
    	
    /*	public void calcElements ()
    	{
    		int count = 0;
    		char a = strMap.charAt(count);
    		
    		for (int i = 0; i < strMap.length() ; i++)
    		{
    			switch ((char)(a))
    			{
    			
    			case 's':
    				numStone++;
    				break;
    			case 'g':
    				numGem++;
    				break;
    			case 'b':
    				numBomb++;
    				//break;
    			default:break;
    			}
    					
    		}
    		
    		
    	}
    	*/
    	//
    	private class DirectionListener implements KeyListener
    	{
    		
    		
    		public void keyPressed (KeyEvent e)
    		{
    			int i, j;
    			i =0;
    			j =0;
    			
    			switch (e.getKeyCode())
    			{
    			case KeyEvent.VK_UP:
    				if(dozerY >= IMG_HEIGHT)
    				{
    					dozerY = dozerY - IMG_HEIGHT;
    					i = dozerY - IMG_HEIGHT;
    					i = i / IMG_HEIGHT;
    					j = dozerX / IMG_WIDTH;
    					map[i][j].setVisible(false);
    					repaint();
    				}
    				
    				break;
    				
    			case KeyEvent.VK_DOWN:
    				if (dozerY < (HEIGHT - IMG_HEIGHT))
    				{
    					dozerY = dozerY + IMG_HEIGHT;
    					i = dozerY + IMG_HEIGHT;
    					i = i / IMG_HEIGHT;
    					j = j / IMG_WIDTH;
    					map[i][j].setVisible(false);
    					repaint();
    					printArray();
    				}
    				break;
    			case KeyEvent.VK_LEFT:
    				if (dozerX >= IMG_WIDTH){dozerX= dozerX- IMG_WIDTH;}
    				break;
    			case KeyEvent.VK_RIGHT:
    				if(dozerX  < (WIDTH-IMG_WIDTH)){dozerX += IMG_WIDTH;}
    				break;	
    			}
    			
    			
    			
    		
    		}
    		
    		public void keyTyped (KeyEvent e) {}
    		public void keyReleased (KeyEvent e) {}
    		
    	}
    	
    	public void printArray ()
    	{
    		for (int i = 0; i < MAP_ROWS ; i++)
    		{
    			for (int j = 0; j < MAP_COLUMNS ; j++)
    			{
    				System.out.print("" + map[i][j].getType());
    				System.out.println("" + map[i][j].getPos());
    			}
    			
    			System.out.println("");
    				
    		}
    	}
    
    }
    Lastly, this is my GameFrame.java: just a frame wrapper for my panel above. I don't think there are any issues here, either, but I'm posting everything for

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    
    public class GameFrame {
    
    	public static void main (String[] args)
    	{
    		
    		JFrame frame = new JFrame ("Boulder Dash");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(new Dimension(500,500));
    		frame.getContentPane().add(new LevelGen());
    		frame.setVisible(true);
    		
    		
    
    	}
    	
    	
    }
    Any help you could provide in fixing my current problems would be much appreciated. Also, if you've got a cleaner way - conceptually - to do what I'm trying to do then I'm all ears!

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,306
    Rep Power
    25

    Default Re: Issue with paintComponent() or KeyListener

    One problem with keylisteners could be that the component does not have the focus and is not able to receive the focus.
    Make sure the component with the listener is able to get the focus. There are methods to call to enable that.
    If you don't understand my response, don't ignore it, ask a question.

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,184
    Rep Power
    19

    Default Re: Issue with paintComponent() or KeyListener

    Moved from New to Java.

    Swing is designed to work with key bindings, which do not have to depend on the focused state of the component. Go through this tutorial: How to Use Key Bindings (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)

    Also, it's needlessly inefficient to construct a new Color each time through the paintComponent(...) method. Your Color transparent should be a final static field.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

Similar Threads

  1. paintComponent
    By zock70 in forum AWT / Swing
    Replies: 1
    Last Post: 11-16-2011, 03:19 AM
  2. geting value from paintComponent
    By gedas in forum New To Java
    Replies: 3
    Last Post: 03-21-2011, 07:56 PM
  3. Help with paintComponent!
    By joeyea in forum Java 2D
    Replies: 6
    Last Post: 12-27-2010, 01:59 PM
  4. Trouble with paintComponent()
    By ShirlyPunk in forum AWT / Swing
    Replies: 17
    Last Post: 03-13-2010, 04:27 PM
  5. Problem going outside paintComponent
    By Thez in forum Java 2D
    Replies: 9
    Last Post: 12-08-2007, 04:59 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •