I'm working on a fairly basic game for myself. New to Java Swing but not to Cpp. Onto the problem at hand.
As I start to run the GUI app, I'm shot with a Null Pointer Exception and given four links where they happen(I use Eclipse as my IDE). But when I look at them I see no problem with the lines or anything around them.
So I came to see if any of you can spot what I can't find.
This class grabs the picture from the source folder and sets up the keys for giving movement.
import java.awt.event.KeyEvent;
import java.awt.Image;
import javax.swing.ImageIcon;
public class SPRITES
{
private int x_sped;
private int y_sped;
private int x;
private int y;
private Image sprite;
public SPRITES()
{
ImageIcon pine = new ImageIcon(this.getClass().getResource("Untitled.png")); //exception here, line 17
sprite = pine.getImage();
x = 0;
y = 0;
}
public void move()
{
x += x_sped;
y += y_sped;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public Image getImage()
{
return sprite;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_A)
{
x_sped = -1;
}
if(key == KeyEvent.VK_D)
{
x_sped = 1;
}
if(key == KeyEvent.VK_W)
{
y_sped = -1;
}
if(key == KeyEvent.VK_S)
{
y_sped = 1;
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_A)
{
x_sped = 0;
}
if(key == KeyEvent.VK_D)
{
x_sped = 0;
}
if(key == KeyEvent.VK_W)
{
y_sped = 0;
}
if(key == KeyEvent.VK_S)
{
y_sped = 0;
}
}
}
The second one is for getting the frame setting up with completely making the frame and finishing up the making of the movement.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Stage extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private Timer start_stop;
private SPRITES player;
public Stage()
{
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.black);
setDoubleBuffered(true);
player = new SPRITES();
start_stop = new Timer(5, this);
start_stop.start();
}
public void paint(Graphics character)
{
super.paint(character);
Graphics2D G2D = (Graphics2D) character;
G2D.drawImage(player.getImage(), player.getX(), player.getY(), this);
Toolkit.getDefaultToolkit().sync();
character.dispose();
}
public void actionPerformed(ActionEvent arg0)
{
player.move();
repaint();
}
private class TAdapter extends KeyAdapter
{
public void keyReleased(KeyEvent e)
{
player.keyReleased(e);
}
public void keyPressed(KeyEvent e)
{
player.keyPressed(e);
}
}
}
This last one should tie it all together...granted I knew how to fix the exception.
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class Framing extends JFrame
{
public Framing()
{
add(new Stage());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setLocationRelativeTo(null);
setTitle("FLY");
setResizable(false);
setVisible(true);
}
public static void main(String[] args)
{
new Framing();
}
}
What is causing these exceptions to happen? How can I fix the problem and what should I work on to avoid this happening again?
I think you are misreading the stacktrace from eclipse. All the links except for the first(The one at the top) is the call stack, which show the calls made to the place where you got a nullpointer exception.
Which fit because the code:
new Framing()
Calls
add(new Stage())
which calls
player = new SPRITES();
Which calls
ImageIcon pine = new ImageIcon(this.getClass().getResource("Untitled.png"));
And this is where your nullpointer exception is. My guess is that getResources("Untitled.png"); returns null which then causes the ImageIcon constructor to throw a nullpointer exception.
Related
Hi I'm using the Timer class and the repaint method for the JPanel, but whenever I hit DOWN and the space ship moves halfway down the screen, it shrinks and stays in place. It never reaches the bottom of the window. It is the same when I move it to the RIGHT.
Also when I try to place it in a differnt y position, the background isn't black anymore. Can someone help me with this please? Here is a sample of my code:
package javapaint;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SpaceShipFlight
{
private JFrame windowFrame;
private BufferedImage shipSprite;
private BufferedImage spaceBackground;
/** MAIN METHOD **/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
SpaceShipFlight window = new SpaceShipFlight();
window.windowFrame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/** CONSTRUCTOR **/
public SpaceShipFlight() throws IOException
{
/*************************************************************************
SPACE SHIP FLIGHT JFRAME
*************************************************************************/
windowFrame = new JFrame("Space Ship Flight");
windowFrame.setBounds(0, 0, 950, 700);
windowFrame.setBackground(Color.BLACK);
/*************************************************************************
SPACE SHIP FLIGHT SPRITES (FOR DRAWING)
*************************************************************************/
spaceBackground = ImageIO.read(new File("Space (Medium).png"));
// 450 x 374
shipSprite = ImageIO.read(new File("Ship Sprite.png"));
// 64 x 64 png of space ship
/*************************************************************************
SPACE SHIP FLIGHT JPANEL (FOR DRAWING)
*************************************************************************/
SpacePanel spacePanel = new SpacePanel();
windowFrame.add(spacePanel);
/*************************************************************************
SPACE SHIP FLIGHT TIMER
*************************************************************************/
Timer timer = new Timer(10, new AnimationListener(spacePanel));
timer.start();
/*************************************************************************
EVENT HANDLER TO MOVE SPACE SHIP
*************************************************************************/
/*
EventHandler <KeyEvent> moveShip = new EventHandler<KeyEvent> ()
{
#Override
public void handle(KeyEvent event)
{
if (event.getCharacter().equalsIgnoreCase("X"))
{
spacePanel.setX( spacePanel.getX() + 1 );
}
}
};
*/
KeyListener moveShip = new KeyListener()
{
#Override
public void keyTyped(KeyEvent e)
{
}
#Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_RIGHT && spacePanel.getX() < 375)
{
spacePanel.setX( spacePanel.getX() + 5 );
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT && spacePanel.getX() > 0)
{
spacePanel.setX( spacePanel.getX() - 5);
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_UP && spacePanel.getY() > 0)
{
spacePanel.setY( spacePanel.getY() - 5);
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_DOWN && spacePanel.getY() < 700)
{
spacePanel.setY( spacePanel.getY() + 5 );
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_X)
{
System.out.printf("X: %d, Y: %d\n", spacePanel.getX(),
spacePanel.getY());
}
}
#Override
public void keyReleased(KeyEvent e)
{
}
};
windowFrame.addKeyListener(moveShip);
}
/** ANIMATION LISTENER CLASS **/
public static class AnimationListener implements ActionListener
{
private SpacePanel panel;
private Graphics graphics;
public AnimationListener(SpacePanel panel)
{
this.panel = panel;
this.graphics = panel.getGraphics();
}
#Override
public void actionPerformed(ActionEvent e)
{
panel.repaint();
}
}
/** SPACE PANEL SUBCLASS **/
public class SpacePanel extends JPanel
{
// Variables for the space ship's position temporarily placed here
private int x;
private int y;
// Constructor
public SpacePanel()
{
super();
x = 0;
y = 0;
}
// Getters
public int getX()
{
return x;
}
public int getY()
{
return y;
}
// Setters
public void setX(int newX)
{
x = newX;
}
public void setY(int newY)
{
y = newY;
}
#Override
public void paint(Graphics g)
{
g.drawImage(spaceBackground, 0, 0, this);
g.drawImage(shipSprite, x, y, this);
}
}
}
i have been trying this code and editing it but it doesnt work.
it is suppose to get a keyboard input store it in the variable "c" and then compare that
to keys on the keyboard. Then it is suppose to move a little square depending the key pressed.
The keyboard doesnt seem to be recognised. Can someone please help me?
Please be aware i am 14 so please dont say how simple and easy it is, i am still learning and could you also write it in a way i am likely to understand. Thank you in advance
'package package1;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Class1 extends JPanel implements KeyListener, ActionListener{
Timer timer = new Timer(5, this);
//variables
int cox = 0;
int spx = 0; //cox = coordinates x, spx = speedx
int coy = 0;
int spy = 0; //coy = coordinates y, spy = speedy
public void paintComponent(Graphics g)
{
timer.start();
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(cox, coy, 50, 50);
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void actionPerformed(ActionEvent e)
{
cox = cox + spx;
coy = coy + spy;
repaint();
}
public void keyPressed(KeyEvent e)
{
int c = e.getKeyCode();
if(c == KeyEvent.VK_LEFT)
{
spx = -1;
spy = 0;
}
if(c == KeyEvent.VK_UP)
{
spx = 0;
spy = -1;
}
if(c == KeyEvent.VK_RIGHT)
{
spx = 1;
spy = 0;
}
if(c == KeyEvent.VK_DOWN)
{
spx = 0;
spy = 1;
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
spx = 0;
spy = 0;
}
public static void main(String args[])
{
Class1 t = new Class1();
JFrame frame = new JFrame("window");
frame.setSize(500,500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(t);
}
}
Problems with your code:
KeyListeners are very low-level constructs, and in general should be avoided in favor of key bindings in most Swing applications. Doing this will also make it much easier to solve focus issues that plague KeyListeners, and which is causing your current KeyListener to do nothing whatsoever. If you read most questions on this site tagged with Swing and KeyListeners, you'll see this advice time and again -- because it's true, and it works.
Please understand that the paintComponent(Graphics g) method is for painting only. It is frequently called, often out of your control, since the OS can induce it to be called.
The paintComponent method has a significant influence on the perceived responsiveness of your GUI, since it is in control of drawing your GUI and any animations that your GUI might contain. If it is slowed for any reason, your GUI will seem slow.
For this reason, this method should be used for drawing and only drawing and nothing but drawing. Specifically,
Don't start your Swing Timer from within this method,
Don't add KeyListeners from within this method (unless you want to add a KeyListener 20 times to the GUI which will result in wildly unpredictable behavior),
Don't change the state of any of your objects from within this method.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class Class1B extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private static final int ANIMATION_DELAY = 15;
private static final int RECT_WIDTH = 15;
private static final Color RECT_COLOR = Color.red;
private EnumMap<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
private Map<Integer, Direction> keyToDir = new HashMap<>();
private Timer animationTimer;
public int rectX;
public int rectY;
public Class1B() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.FALSE);
}
keyToDir.put(KeyEvent.VK_UP, Direction.UP);
keyToDir.put(KeyEvent.VK_DOWN, Direction.DOWN);
keyToDir.put(KeyEvent.VK_LEFT, Direction.LEFT);
keyToDir.put(KeyEvent.VK_RIGHT, Direction.RIGHT);
setKeyBindings();
animationTimer = new Timer(ANIMATION_DELAY, new AnimationListener());
animationTimer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(RECT_COLOR);
g.fillRect(rectX, rectY, RECT_WIDTH, RECT_WIDTH);
}
private void setKeyBindings() {
int condition = WHEN_IN_FOCUSED_WINDOW;
final InputMap inputMap = getInputMap(condition);
final ActionMap actionMap = getActionMap();
boolean[] keyPressed = { true, false };
for (Integer keyCode : keyToDir.keySet()) {
Direction dir = keyToDir.get(keyCode);
for (boolean onKeyPress : keyPressed) {
boolean onKeyRelease = !onKeyPress;
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, 0,
onKeyRelease);
Object key = keyStroke.toString();
inputMap.put(keyStroke, key);
actionMap.put(key, new KeyBindingsAction(dir, onKeyPress));
}
}
}
private class KeyBindingsAction extends AbstractAction {
private Direction dir;
boolean pressed;
public KeyBindingsAction(Direction dir, boolean pressed) {
this.dir = dir;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent evt) {
dirMap.put(dir, pressed);
}
}
private class AnimationListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent evt) {
boolean repaint = false;
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
rectX += dir.getIncrX();
rectY += dir.getIncrY();
repaint = true;
}
}
if (repaint) {
repaint();
}
}
}
private static void createAndShowGui() {
Class1B mainPanel = new Class1B();
JFrame frame = new JFrame("Class1B");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum Direction {
UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0);
private int incrX;
private int incrY;
private Direction(int incrX, int incrY) {
this.incrX = incrX;
this.incrY = incrY;
}
public int getIncrX() {
return incrX;
}
public int getIncrY() {
return incrY;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm getting an error when I call my refresh() method from another class.
public void refresh() {
repaint();
}
It's a JFrame that the refresh() is in and I'm calling it from a normal class. The error is a Null Pointer, and it is on my level.refresh(), as well as as public void refresh().
What I am trying to do is working completely fine, but I'm getting this error
Player class`package entity.player;
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import level.Level;
public class Player {
public static Image playerImgLeft = new ImageIcon(
"resources/Player/left/player_anim1_left.png").getImage();
public static Image playerImgRight = new ImageIcon(
"resources/Player/right/player_anim1_right.png").getImage();
public static Level levelp;
public int x = 0;
public int y = 0;
public int dy = 0;
public int dx = 0;
// Direction = right
public int direction = 0;
public Player() {
x = 10;
y = 10;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImageLeft() {
return playerImgLeft;
}
public Image getImageRight() {
return playerImgRight;
}
public void move() {
x = x + dx;
y = y + dy;
}
public void keyPressed(KeyEvent key) {
if (key.getKeyCode() == KeyEvent.VK_A) {
dx = -1;
direction = 1;
System.out.println("left");
levelp.refresh();
}
if (key.getKeyCode() == KeyEvent.VK_D)
dx = 1;
direction = 0;
if (key.getKeyCode() == KeyEvent.VK_W)
dy = -1;
if (key.getKeyCode() == KeyEvent.VK_S)
dy = 1;
}
public void keyReleased(KeyEvent key) {
if (key.getKeyCode() == KeyEvent.VK_A)
dx = 0;
if (key.getKeyCode() == KeyEvent.VK_D)
dx = 0;
if (key.getKeyCode() == KeyEvent.VK_W)
dy = 0;
if (key.getKeyCode() == KeyEvent.VK_S)
dy = 0;
}
}
Level class:
package level;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
import entity.player.Player;
public class Level extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
public static int level = 0;
Player player;
public Timer time;
public Image img;
public Level() {
this.setVisible(true);
setFocusable(true);
player = new Player();
this.addKeyListener(new LevelKeyListener());
ImageIcon i = new ImageIcon("");
img = i.getImage();
time = new Timer(5, this);
time.start();
}
public void actionPerformed(ActionEvent e) {
player.move();
repaint();
revalidate();
}
public void refresh () {
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawImage(img, 0, 0, null);
if(player.direction == 0) {
g2d.drawImage(player.getImageRight(), player.getX(), player.getY(), null);
} else if(player.direction == 1) {
g2d.drawImage(player.getImageLeft(), player.getX(), player.getY(), null);
}
}
private class LevelKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
}
}
`
As was suspected, your levelp variable points to nothing (is null).
When you look at this line you'll see that you're trying to call the refresh() method on a variable that isn't actually referencing anything:
levelp.refresh();
which is just declared as
public static Level levelp;
without any code that actually creates a Level object (ergo: you are trying to call a method on a reference that points to null).
Try creating an immediate object like this:
public static Level levelp = new Level();
I also encourage you to read through this post so you understand how and when NullPointerExceptions occur!
I am trying to make a program that has a moving ball and a platform that it will sit on. I am new too java and I cant figure out how to detect when 2 swing objects are overlapping. My code it below and I am wondering what the best way is to detect overlapping objects.
KeyDemo.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class KeyDemo
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
LayoutManager overlay = new OverlayLayout(panel);
panel.setLayout(overlay);
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Move the Ball");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final WallComponent wc1 = new WallComponent(400, 400);
final BallComponent bc = new BallComponent(400, 300);
panel.add(wc1);
panel.add(bc);
frame.add(panel);
KeyboardController kc = new KeyboardController(bc);
frame.addKeyListener(kc);
frame.setVisible(true);
class AnimationListener implements ActionListener{
public void actionPerformed(ActionEvent event){
bc.tick();
//wc1.checkOverlap(bc);
}
}
ActionListener aListener = new AnimationListener();
final Timer timer = new Timer(1, aListener);
timer.start();
}
}
KeyboardController.java:
import java.awt.*;
import java.awt.event.*;
public class KeyboardController implements KeyListener
{
BallComponent bComp;
public KeyboardController(BallComponent t)
{
bComp = t;
}
/** Handle the key pressed event from the text field. */
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == 38)
{
System.out.println("Pressed Up!");
bComp.moveUp();
}
if(keyCode == 37)
{
System.out.println("Pressed Left!");
bComp.moveLeft();
}
if(keyCode == 39)
{
System.out.println("Pressed Right!");
bComp.moveRight();
}
if(keyCode == 40)
{
System.out.println("Pressed Down!");
bComp.moveDown();
}
}
/** Handle the key released event from the text field. */
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == 38)
{
System.out.println("Released Up!");
bComp.stopY();
}
if(keyCode == 37)
{
System.out.println("Released Left!");
bComp.stopX();
}
if(keyCode == 39)
{
System.out.println("Released Right!");
bComp.stopX();
}
if(keyCode == 40)
{
System.out.println("Pressed Down!");
bComp.stopY();
}
}
public void keyTyped(KeyEvent e) {
}
}
BallComponent.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class BallComponent extends JComponent
{
int xSpeed;
int ySpeed;
int x;
int y;
public BallComponent(int x, int y)
{
super();
this.x = x;
this.y = y;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
Ellipse2D.Double ball = new Ellipse2D.Double(x-10,y-10,10,10);
g2.setColor(Color.RED);
g2.fill(ball);
g2.draw(ball);
}
public void moveLeft()
{
xSpeed=-1;
}
public void moveRight()
{
xSpeed=1;
}
public void moveUp()
{
ySpeed=-1;
}
public void moveDown()
{
ySpeed=1;
}
public void tick()
{
x=x+xSpeed;
y=y+ySpeed;
repaint();
}
public void stopY()
{
ySpeed=0;
}
public void stopX()
{
xSpeed=0;
}
}
WallComponent.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class WallComponent extends JComponent
{
int x;
int y;
public WallComponent(int x, int y)
{
super();
this.x = x;
this.y = y;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
Rectangle wall = new Rectangle(x-40,y-40,40,40);
g2.setColor(Color.YELLOW);
g2.fill(wall);
g2.draw(wall);
}
public void checkOverlap(BallComponent bc){
if (this.contains(bc.getLocation())){
bc.stopY();
bc.stopX();
}
}
}
All Swing components have a concept of "bounds". This is a rectangular area within which they are "drawn".
If you are controlling the size and position correctly, you should be able to use the contains method of the Rectangle which is returned from calling Component#getBounds
So you checkOverlap method could look like...
public void checkOverlap(BallComponent bc){
if (getBounds().intersects(bc.getBounds())){
bc.stopY();
bc.stopX();
}
}
You will also want to make sure that you are calling super.paintComponent before performing any custom painting, espeically when using components that extend from JComponent. This will ensure that the Graphics context is prepared for painting correctly...
Updated
There's a cascade of issues. Basically, instead of positing the components within the parent container yourself (which is how I thought you had done it), you've laid each component out to fill the parent container and only "painted" the objects...This makes life more difficult
Instead, if you are going to use components, I would use a null layout (or even possibly use a JLayeredPane as the parent container).
I would then change the physical position of the components, for example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGame {
public static void main(String[] args) {
new TestGame();
}
public TestGame() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(null);
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Move the Ball");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final WallComponent wc1 = new WallComponent(400, 400);
final BallComponent bc = new BallComponent(400, 300);
panel.add(wc1);
panel.add(bc);
frame.add(panel);
KeyboardController kc = new KeyboardController(bc);
frame.addKeyListener(kc);
frame.setVisible(true);
class AnimationListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
bc.tick();
wc1.checkOverlap(bc);
}
}
ActionListener aListener = new AnimationListener();
final Timer timer = new Timer(1, aListener);
timer.start();
}
});
}
public class KeyboardController implements KeyListener {
BallComponent bComp;
public KeyboardController(BallComponent t) {
bComp = t;
}
/**
* Handle the key pressed event from the text field.
*/
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == 38) {
System.out.println("Pressed Up!");
bComp.moveUp();
}
if (keyCode == 37) {
System.out.println("Pressed Left!");
bComp.moveLeft();
}
if (keyCode == 39) {
System.out.println("Pressed Right!");
bComp.moveRight();
}
if (keyCode == 40) {
System.out.println("Pressed Down!");
bComp.moveDown();
}
}
/**
* Handle the key released event from the text field.
*/
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == 38) {
System.out.println("Released Up!");
bComp.stopY();
}
if (keyCode == 37) {
System.out.println("Released Left!");
bComp.stopX();
}
if (keyCode == 39) {
System.out.println("Released Right!");
bComp.stopX();
}
if (keyCode == 40) {
System.out.println("Pressed Down!");
bComp.stopY();
}
}
public void keyTyped(KeyEvent e) {
}
}
public class BallComponent extends JComponent {
int xSpeed;
int ySpeed;
public BallComponent(int x, int y) {
super();
setBounds(x, y, 10, 10);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double ball = new Ellipse2D.Double(0, 0, 9, 9);
g2.setColor(Color.RED);
g2.fill(ball);
g2.draw(ball);
}
public void moveLeft() {
xSpeed = -1;
}
public void moveRight() {
xSpeed = 1;
}
public void moveUp() {
ySpeed = -1;
}
public void moveDown() {
ySpeed = 1;
}
public void tick() {
int x = getX() + xSpeed;
int y = getY() + ySpeed;
setLocation(x, y);
repaint();
}
public void stopY() {
ySpeed = 0;
}
public void stopX() {
xSpeed = 0;
}
}
public class WallComponent extends JComponent {
public WallComponent(int x, int y) {
super();
setBounds(x, y, 40, 40);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle wall = new Rectangle(0, 0, 40, 40);
g2.setColor(Color.YELLOW);
g2.fill(wall);
g2.draw(wall);
}
public void checkOverlap(BallComponent bc) {
System.out.println(" me: " + getBounds());
System.out.println("you: " + bc.getBounds());
if (getBounds().intersects(bc.getBounds())) {
bc.stopY();
bc.stopX();
}
}
}
}
Now, you could use "painted" objects, but in that case I would have a virtual concept of a Ball and Wall which you could paint within a single component. These objects would need to provide information about there position and size, which you could, again, check using Rectangle#intersects...
Generally, just try to make a "bounding box" for your objects. This will be the invisible rectangle that goes with the object. Then just do
if(rectangle1.intersects(rectangle2)) ...
The intersects method only works with rectangles, and that's why you need a bounding box.
I'm kind of a beginner when it comes to java programming, and I have a project in school where I'm going to create a game much like Icy Tower. And my question is, how am I going to write to make the character stand on the ground and be able to jump up on objects?
Here's my code so far:
Part one
package Sprites;
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class jumper {
private String jump = "oka.png";
private int dx;
private int dy;
private int x;
private int y;
private Image image;
public jumper() {
ImageIcon ii = new ImageIcon(this.getClass().getResource(jump));
image = ii.getImage();
x = 50;
y = 100;
}
public void move() {
x += dx;
y += dy;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -5;
ImageIcon ii = new ImageIcon(this.getClass().getResource("oki.png"));
image = ii.getImage();
}
if (key == KeyEvent.VK_RIGHT){
dx = 5;
ImageIcon ii = new ImageIcon(this.getClass().getResource("oka.png"));
image = ii.getImage();
}
if (key == KeyEvent.VK_SPACE) {
dy = -5;
}
if (key == KeyEvent.VK_DOWN) {
dy = 5;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_RIGHT){
dx = 0;
}
if (key == KeyEvent.VK_SPACE) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}
Part two
package Sprites;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class board extends JPanel implements ActionListener {
private Timer klocka;
private jumper jumper;
public board() {
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.WHITE);
setDoubleBuffered(true);
jumper = new jumper();
klocka = new Timer(5, this);
klocka.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(jumper.getImage(), jumper.getX(), jumper.getY(), this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
jumper.move();
repaint();
}
private class TAdapter extends KeyAdapter {
public void keyReleased(KeyEvent e) {
jumper.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
jumper.keyPressed(e);
}
}
}
Part three
package Sprites;
import javax.swing.JFrame;
public class RType extends JFrame {
public RType() {
add(new board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
setTitle("R - type");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new RType();
}
}
I really appreciate all the help I can get!
This might help. It's a set of tutorials aimed at helping people make tile-based games. Including side-on platform games. See http://www.tonypa.pri.ee/tbw/tut07.html. By the way, you're doing quite intensive image-loading stuff in the character movement methods. Don't do that. Cache the images first. Also, you can double-buffer your Canvas to make it smooth. See the code here for details.