simple game problem using JLabels

R

rob bell

Hello im having a problem drawing over existing JLables. is there anyway to
do it, its hard to explain what im trying to do, but basically my problem is
that i cant get my program to draw a certain tile in a certain place, or
atleast it does but it doesnt show up, maybe its drawing behind the old
tile. here is my code:

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

public class MyGame implements KeyListener{


JFrame gameFrame;
JPanel gamePanel;

int playerX, playerY, newPlayerX, newPlayerY;

int[][] mapArray = { {1,1,1,1,1,1,1,1,2,3},
{1,1,1,1,1,1,1,2,2,2},
{1,1,1,1,1,1,1,1,1,1},
{2,2,2,2,2,1,1,1,1,1} };

JLabel labelArray[][] = new JLabel[4][10];


public MyGame() {


gameFrame = new JFrame("Quest");
gamePanel = new JPanel();

gameFrame.addKeyListener(this);

fillMap();

gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

gameFrame.setDefaultLookAndFeelDecorated(true);

gameFrame.getContentPane().add(gamePanel, BorderLayout.CENTER);

gameFrame.pack();
gameFrame.setSize(600,450);
gameFrame.setResizable(false);

gameFrame.setVisible(true);

placeMap();

runGame();



}//MyGame Constructor


private void fillMap(){

ImageIcon grassIcon = new ImageIcon("img/grass.gif");

ImageIcon playerIcon = new ImageIcon("img/playerDown.gif");

ImageIcon waterIcon = new ImageIcon("img/water.gif");

for(int row = 0; row < 4; row++){

for(int col = 0; col < 10; col++){

if(mapArray[row][col] == 1){

labelArray[row][col] = new JLabel(grassIcon);
gamePanel.add(labelArray[row][col], new Integer(1));

}

if(mapArray[row][col] == 2){

labelArray[row][col] = new JLabel(waterIcon);
gamePanel.add(labelArray[row][col], new Integer(1));

}

if(mapArray[row][col] == 3){

labelArray[row][col] = new JLabel(playerIcon);
gamePanel.add(labelArray[row][col], new Integer(1));
playerX = col;
playerY = row;

}

}

}

}//fillMap


private void placeMap(){

for(int row = 0; row < 4; row++){

for(int col = 0; col < 10; col++){

labelArray[row][col].setLocation((col*20),(row*20));
}

}

}//placeMap

private void runGame(){

while(true){


placeMap();


}

}//runGame

public void keyTyped(KeyEvent e){



}

public void keyPressed(KeyEvent e){

if((e.getKeyCode()) == 37){//left

mapArray[playerY][playerX] = 1;//sets old player pos to grass

playerX--;

mapArray[playerY][playerX] = 3;//sets new player pos


fillMap(); // attempts to redraw the map

}

if((e.getKeyCode()) == 38){

System.out.println("go up");

}

if((e.getKeyCode()) == 39){

System.out.println("go right");

}

if((e.getKeyCode()) == 40){

System.out.println("go down");

}

}

public void keyReleased(KeyEvent e){



}

public static void main (String[] args){


MyGame newGame = new MyGame();


}//main

}//MyGame

Is there maybe a better way to do what im trying to do, ive tryed using
drawImage but found it confusing, could you point me to any good tutorials
on drawing images, or on games programming. I believe the above is working
but its drawing it behind the old tile, because if u press left ten times
you get a null out of bounds exception, where it goes off the screen.

thanks in advance

rob
 
C

Chris Smith

rob said:
Hello im having a problem drawing over existing JLables. is there anyway to
do it, its hard to explain what im trying to do, but basically my problem is
that i cant get my program to draw a certain tile in a certain place, or
atleast it does but it doesnt show up, maybe its drawing behind the old
tile.

You need to take a step back. There are a lot of problems with the code
you've written. Here are a few:
public MyGame() {


gameFrame = new JFrame("Quest");
gamePanel = new JPanel();

gameFrame.addKeyListener(this);

fillMap();

gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

gameFrame.setDefaultLookAndFeelDecorated(true);

The setDefaultLookAndFeelDecorated method is static. You are treating
it like an instance method. While this is legal (an unfortunately bit
of short-sightedness in language design), it is a really bad idea and
can be misleading. This should look like:

JFrame.setDefaultLookAndFeelDecorated(true);

and it should probably be done before any JFrame instances are created.
private void fillMap(){

You are adding components to the GUI hierarchy here. That's fine the
first time, but after that, you continue to add more and more components
each time the method is called, and it's called every time a certain key
is pressed! You probably want to change the contents of the existing
components -- or at the very least remove them first before you add new
ones. (I would avoid the latter option; changing the GUI hierarchy
after a window is visible is generally a bad idea.)
ImageIcon grassIcon = new ImageIcon("img/grass.gif");
ImageIcon playerIcon = new ImageIcon("img/playerDown.gif");
ImageIcon waterIcon = new ImageIcon("img/water.gif");

for(int row = 0; row < 4; row++){

for(int col = 0; col < 10; col++){

if(mapArray[row][col] == 1){

labelArray[row][col] = new JLabel(grassIcon);
gamePanel.add(labelArray[row][col], new Integer(1));

new Integer(1) ??? What do you expect that to do? Since the layout is
FlowLayout, any component constraints specified will be ignored. In any
case, an Integer object is an unusual component constraint for any
layout manager. Whatever you were trying to do, all you've succeeded in
doing is confuse the reader.

Speaking of layout, though, do you expect this to show up as a grid?
FlowLayout draws only enough components to fit on a row, then moves to
the next row. If you want a grid, you should use GridLayout instead.
(Perhaps that's why you chose a non-resizable window and specific pixel
count, because you were tweaking FlowLayout to coincidentally place
enough components in one row? If so, that's a bad solution; use a
layout manager that does what you want it to do, instead.)
private void placeMap(){

for(int row = 0; row < 4; row++){

for(int col = 0; col < 10; col++){

labelArray[row][col].setLocation((col*20),(row*20));
}

}

}//placeMap

This method does nothing at all. Since your components are controlled
by a layout manager, there is no point in trying to set their location.
They will be moved again by the layout manager anyway. Justr delete
this method and any calls to it.
private void runGame(){

while(true){


placeMap();


}

}//runGame

Since placeMap does nothing, this similarly does nothing, except of
course generate unneeded heat and speed up battery loss in laptop
computers by running a CPU-bound infinite loop. Get rid of it and let
the main thread terminate.

Oh wait: this does do one more thing. The other thing this does is
ensure that your application is broken from a multithreading standpoint.
The placeMap method deals with values (in labelArray) that are not
properly synchronized for access by multithreads. These same variables
are modified in fillMap from the event handling thread, again without
proper synchronization. By getting rid of this method and allowing the
main thread to terminate, you eliminate that problem by only keeping one
active thread in the first place.
Is there maybe a better way to do what im trying to do, ive tryed using
drawImage but found it confusing, could you point me to any good tutorials
on drawing images, or on games programming.

You don't need to use drawImage for this application, but you would be
well advised to look into the setIcon method on JLabel. It's far better
than trying to create a whole new label and re-add it to the GUI
hierarchy.

Eventually, though, if you want to write games in Java, you WILL need to
understand the painting infrastructure. What do you mean by "I found it
confusing"? What reference book or tutorial web site are you using to
learn how to do this?
I believe the above is working
but its drawing it behind the old tile, because if u press left ten times
you get a null out of bounds exception, where it goes off the screen.

There's no such thing as a "null out of bounds exception". There is an
IndexOutOfBoundsException and a NullPointerException. In any case, fix
the big problems first, and then the rest can be addressed.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top