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.
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.
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
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!
Re: Issue with paintComponent() or KeyListener.
What exactly does the program do? You say it doesn't work, but what does it do instead? Do you receive an Exception? Do you see some strange behavior? Does nothing happen? Something else?
Re: Issue with paintComponent() or KeyListener.
No exceptions, no strange behaviour - the dozer just doesn't move around the screen. Someone suggested that it may have been a problem with an object getting focus, so I'll have to see if that's the issue later on today.
Re: Issue with paintComponent() or KeyListener.
Okay, so what you should do is a process of elimination- is your KeyListener ever triggered? Debug the program, or just add some print statements, to figure that out. If so, you've eliminated that as the problem.
If your KeyListener is not triggered, then you can create an SSCCE that demonstrates just that problem without any extra painting or game logic code.
Re: Issue with paintComponent() or KeyListener.
Is this the entire code? Post the entire code for the game please
Re: Issue with paintComponent() or KeyListener.
Quote:
Originally Posted by
D4rk_H34rt
Is this the entire code? Post the entire code for the game please
Let's not resurrect a question that is almost a year old. D4rk, if you have a question, please create a new thread in the forum and ask it there.
Locking.