Reputation: 19
I have been trying to display the graphics for my game, but none of the graphics are being displayed on the panel.
Following is my code. The main class invokes the paint methods of the other two classes.
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 java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Simulator extends JFrame implements KeyListener, Runnable, ActionListener {
private final int WIDTH, HEIGHT;
private Boolean right;
private int xMotion;
public Salt salt;
public Player playR;
Boolean running = false;
private Thread thread;
public static int score, highScore;
private int saltSpeed;
public Simulator(int width, int height) {
JPanel panel = new JPanel();
JFrame frame = new JFrame();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(width, height);
panel.setBackground(Color.BLACK);
frame.add(panel);
playR = new Player();
this.HEIGHT = height;
this.WIDTH = width;
int xCordSalt = (int) (Math.random() * 631);
saltSpeed = 1;
salt = new Salt(saltSpeed);
right = true;
running = true;
}
public static void main(String[] args) {
Simulator game = new Simulator(640, 480);
game.start();
}
public void paintComponent(Graphics g)
{
salt.paint(g);
playR.paint(g);
}
public void start() {
running = true;
thread = new Thread(this);
thread.start();
repaint();
tick();
run();
}
public void stop() {
running = false;
System.exit(0);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_D) {
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_A) {
right = false;
}
}
public void tick() {
salt.tick(this, playR);
playR.tick();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_D)
{
playR.setDirection(true);
}
else if(e.getKeyCode() == KeyEvent.VK_A)
{
playR.setDirection(false);
}
}
@Override
public void run() {
while (running) {
tick();
repaint();
try {
thread.sleep(7);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void incrementScore() {
score++;
}
@Override
public void actionPerformed(ActionEvent e) {
repaint();
tick();
}
}
And here's the code for the method salt:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
public class Salt extends Rectangle{
private final int WIDTH = 10;
private final int HEIGHT = 10;
public int xCordSalt, yCordSalt;
private int speed;
Rectangle boundBox;
public Salt(int speedx)
{
xCordSalt = (int)Math.random()*641;
yCordSalt = 0;
speed = speedx;
boundBox = new Rectangle(xCordSalt, yCordSalt, WIDTH, HEIGHT);
boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);
}
public void tick(Simulator sim, Player playR)
{
boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);
if(yCordSalt >= 480)
{
//sim.stop();
}
else if(checkCollision(playR))
{
sim.incrementScore();
speed++;
yCordSalt = -speed;
}
yCordSalt = yCordSalt + speed;
}
public boolean checkCollision(Player playR)
{
if(this.getBoundBox().intersects(playR.getBoundBox()))
{
return true;
}
return false;
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(xCordSalt, yCordSalt, WIDTH, HEIGHT);
}
public Rectangle getBoundBox()
{
return boundBox;
}
public double getSpeed()
{
return speed;
}
}
And finally the method player, which uses the imageIcon class to display an image:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Player extends JPanel {
private int xCord, yCord;
public Rectangle boundBox;
private static ImageIcon ryan;
boolean isRight;
public Player() {
ryan = new ImageIcon("E:\ryan.png");
xCord = 640/2;
yCord = 460;
boundBox = new Rectangle(xCord, yCord, 20, 20);
}
public static void main(String[] args) {
}
public void tick() {
}
public void setDirection(Boolean right)
{
if(right)
isRight = true;
else
isRight = false;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ryan.getImage(), xCord, yCord, null);
}
public Rectangle getBoundBox()
{
return boundBox;
}
}
Now some of it is incomplete, but I cannot realize why it is displaying no graphics whatsoever. When ran, only a black frame / panel appears. I added some print statements to the tick() methods of each class, the paint() methods of each class and the paintComponent() method, and the start() method. The game will start, run each class's tick method, but paintComponent() or any of the paint() methods are ever called!
Upvotes: 1
Views: 938
Reputation: 347184
Let's start with the obvious...
public class Simulator extends JFrame ... {
//...
public void paintComponent(Graphics g) {
salt.paint(g);
playR.paint(g);
}
JFrame
doesn't have a method called paintComponent
, so your paintComponent
will never be called, so salt
and playR
will never painted.
You can test this by adding @Override
to the paintComponent
which does a compile time sanity check for you
public class Simulator extends JFrame ... {
//...
@Override
public void paintComponent(Graphics g) {
salt.paint(g);
playR.paint(g);
}
This will fail to compile.
Now, you could override paint
instead, but because, because, because, because, because ... I wouldn't recommend it ...
Take a step back for a second. What is the JFrame
really responsible for? Providing a container onto which you can add you gui and have it displayed on the screen. You're not really adding any new functionality to the JFrame
, so I wouldn't use it as your "main" component, instead, I'd just create an instance of it and add what ever components you want to use to it.
Instead, I'd start with a JPanel
and override its paintComponent
method and put all your custom painting into it.
I would then use this component as a starting point for your core logic and controllers.
You might even create several components to act as things like the menu and option views and use a CardLayout
or OverlayoutLayout
to display them.
I'd also recommend having a look at How to Use Key Bindings instead of KeyListener
while you're at it, this will answer your next question.
Upvotes: 2
Reputation: 2682
First you are creating a frame in excess - the class itself is a frame so no need for more:
setSize(width, height);
setVisible(true);
Second you add a panel on to it: that will cover everything;
Third JFrame doesn't have paintComponent - instead use paint().
Fourth, in starting the thread by calling start() the run() method will automatically be called - no need to call run().
Here's my working constructor and paint method:
public Simulator(int width, int height) {
setSize(width, height);
panel.setBackground(Color.BLACK);
setVisible(true);
try {
bim=ImageIO.read(new File(.....));
}
catch (Exception ex) { ex.printStackTrace(); }
this.HEIGHT = height;
this.WIDTH = width;
int xCordSalt = (int) (Math.random() * 631);
saltSpeed = 1;
right = true;
running = true;
}
public void paint(Graphics g)
{
g.setColor(Color.magenta);
g.fillRect(0, 0, 100, 100);
g.drawImage(bim, 100, 0, null);
}
Upvotes: 0