Java adding 2 objects in a JFrame but only 1 is showing - java

I know this question is asked often in stackoverflow. And i know there is a page on oracle about LayoutManagers but i dont understand how to use it? Can someone help me with my code? Im trying to make a game with 2 squares trying to catch each other. It's not finished yet. I will finish it once i solve the graphical issues. Do i need a JPanel to do it? Thanks in advance!
JFrame class
package catchmev2;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
/**
*
* #author MertKarakas
*/
public class CatchMeV2 implements ActionListener{
public static void main(String[] args) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(true);
frame.setVisible(true);
frame.setSize(width, height);
frame.setTitle("CatchMe.V2");
frame.getContentPane().setLayout(new FlowLayout());
//Adding square 1
RedSquare r = new RedSquare();
frame.getContentPane().add(r);
r.setFocusable(true);
r.requestFocusInWindow();
//Adding square 2
BlueSquare b = new BlueSquare();
frame.getContentPane().add(b);
b.setFocusable(true);
b.requestFocusInWindow();
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
First square class
package catchmev2;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
*
* #author MertKarakas
*/
public class RedSquare extends JPanel implements ActionListener, KeyListener {
int x = 20; int y = 20;
int velX = 0; int velY = 0;
Timer tm = new Timer(5, this);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
public RedSquare(){
addKeyListener(this);
tm.start();
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(x, y, 25, 25);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
x = x + velX;
y = y + velY;
if (x < 0) {
velX = 0;
x = 0;
}
if (x > width - 50) {
velX = 0;
x = width - 50;
}
if (y < 0) {
velY = 0;
y = 0;
}
if (y > height - 40) {
velY = 0;
y = height - 40;
}
repaint();
}
public void keyTyped(KeyEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_LEFT) {
velX = -4;
velY = 0;
System.out.println("sex1");
}
if (code == KeyEvent.VK_UP) {
velX = 0;
velY = -4;
System.out.println("sex2");
}
if (code == KeyEvent.VK_RIGHT) {
velX = 4;
velY = 0;
System.out.println("sex3");
}
if (code == KeyEvent.VK_DOWN) {
velX = 0;
velY = 4;
System.out.println("sex4");
}
}
#Override
public void keyReleased(KeyEvent e) {
velX = 0;
velY = 0;
}
}
Second square class
package catchmev2;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
*
* #author MertKarakas
*/
public class BlueSquare extends JPanel implements ActionListener, KeyListener {
int x = 700;
int y = 600;
int velX = 0;
int velY = 0;
Timer tm = new Timer(5, this);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
public BlueSquare() {
addKeyListener(this);
tm.start();
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(x, y, 25, 25);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
x = x + velX;
y = y + velY;
if (x < 0) {
velX = 0;
x = 0;
}
if (x > width - 50) {
velX = 0;
x = width - 50;
}
if (y < 0) {
velY = 0;
y = 0;
}
if (y > height - 40) {
velY = 0;
y = height - 40;
}
repaint();
}
public void keyTyped(KeyEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_A) {
velX = -4;
velY = 0;
System.out.println("sex1");
}
if (code == KeyEvent.VK_W) {
velX = 0;
velY = -4;
System.out.println("sex2");
}
if (code == KeyEvent.VK_D) {
velX = 4;
velY = 0;
System.out.println("sex3");
}
if (code == KeyEvent.VK_S) {
velX = 0;
velY = 4;
System.out.println("sex4");
}
}
#Override
public void keyReleased(KeyEvent e) {
velX = 0;
velY = 0;
}
}

Related

KeyListener and ActionListener not registering

I have been working on a Java project that makes a character move with the keys, but the keyListener is not working and registering my actions. I code in eclipse, and I think that problem is my GamePanel, Player, or me KeyChecker class. I am using a guide to help start this, so it is the same code as another project, but it does not work. Here is my code:
class Platformer:
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Platformer {
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.setSize(700,700);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setTitle("Platformer");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class GamePanel:
I have tried changing the layout of the if statements if that was the original problem, but it did not change anything. I also tried changing the statements to just void instead of public void but that did not work either.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements ActionListener{
Player player;
ArrayList<Wall> walls = new ArrayList<>();
Timer gameTimer;
public GamePanel() {
player = new Player(400, 300, this);
makeWalls();
gameTimer = new Timer();
gameTimer.schedule(new TimerTask() {
public void run() {
player.set();
repaint();
}
},0,17);
}
public void makeWalls() {
for (int i = 50; i < 650; i += 50) {
walls.add (new Wall(i, 600, 50, 50));
}
walls.add(new Wall(50, 550, 50, 50));
walls.add(new Wall(50, 500, 50, 50));
walls.add(new Wall(50, 450, 50, 50));
walls.add(new Wall(600, 550, 50, 50));
walls.add(new Wall(600, 500, 50, 50));
walls.add(new Wall(600, 450, 50, 50));
walls.add(new Wall(450, 550, 50, 50));
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D gtd = (Graphics2D) g;
player.draw(gtd);
for (Wall wall: walls) wall.draw(gtd);
}
public void KeyPressed(KeyEvent e) {
if (e.getKeyChar() == 'a')player.keyLeft = true;
if (e.getKeyChar() == 'w') player.keyUp = true;
if (e.getKeyChar() == 's') player.keyDown = true;
if (e.getKeyChar() == 'd') player.keyRight = true;
}
public void KeyReleased(KeyEvent e) {
if (e.getKeyChar() == 'a') player.keyLeft = false;
if (e.getKeyChar() == 'w') player.keyUp = false;
if (e.getKeyChar() == 's') player.keyDown = false;
if (e.getKeyChar() == 'd') player.keyRight = false;
}
public void actionPerformed(ActionEvent e) {
}
}
class Player:
I also tried the same things that I did for the GamePanel, but that did not work either.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Player {
GamePanel panel;
int x;
int y;
int width;
int height;
double xspeed;
double yspeed;
Rectangle hitBox;
boolean keyRight;
boolean keyLeft;
boolean keyUp;
boolean keyDown;
public Player(int x, int y, GamePanel panel) {
this.panel = panel;
this.x = x;
this.y = y;
width = 50;
height = 100;
hitBox = new Rectangle(x,y,width,height);
}
public void set() {
if (keyLeft && keyRight || !keyLeft && !keyRight) xspeed *= 0.8;
else if (keyLeft && !keyRight) xspeed --;
else if (keyRight && !keyLeft) xspeed ++;
if (xspeed > 0 && xspeed < 0.75) xspeed = 0;
if (xspeed < 0 && xspeed > - 0.75) xspeed = 0;
if (xspeed > 7) xspeed = 7;
if (xspeed < -7) xspeed = -7;
if (keyUp) {
hitBox.y++;
for(Wall wall: panel.walls) {
if (wall.hitBox.intersects(hitBox)) yspeed = -6;
}
hitBox.y --;
}
yspeed += .3;
hitBox.x += xspeed;
for(Wall wall: panel.walls) {
if (hitBox.intersects(wall.hitBox)) {
hitBox.x-= xspeed;
while(!wall.hitBox.intersects(hitBox)) hitBox.x += Math.signum(xspeed);
hitBox.x -= Math.signum(xspeed);
xspeed = 0;
x = hitBox.x;
}
}
hitBox.y += xspeed;
for(Wall wall: panel.walls) {
if (hitBox.intersects(wall.hitBox)) {
hitBox.y-= yspeed;
while(!wall.hitBox.intersects(hitBox)) hitBox.y += Math.signum(yspeed);
hitBox.y -= Math.signum(yspeed);
yspeed = 0;
y = hitBox.y;
}
}
x += xspeed;
y += yspeed;
hitBox.x = x;
hitBox.y = y;
}
public void draw(Graphics2D gtd) {
gtd.setColor(Color.BLACK);
gtd.fillRect(x, y, width, height);
}
}
class KeyChecker:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyChecker extends KeyAdapter{
GamePanel panel;
public KeyChecker(GamePanel panel) {
this.panel = panel;
}
public void KeyPressed(KeyEvent e) {
panel.KeyPressed(e);
}
public void KeyReleased(KeyEvent e) {
panel.KeyReleased (e);
}
}
class Wall:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Wall {
int x;
int y;
int width;
int height;
Rectangle hitBox;
public Wall (int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = width;
hitBox = new Rectangle(x, y, width, height);
}
public void draw(Graphics2D gtd) {
gtd.setColor(Color.BLACK);
gtd.drawRect(x, y, width, height);
gtd.setColor(Color.WHITE);
gtd.fillRect(x + 1, y + 1, width - 2, height - 2);
}
}
class MainFrame:
import java.awt.Color;
import javax.swing.JFrame;
public class MainFrame extends JFrame{
public MainFrame() {
GamePanel panel = new GamePanel();
panel.setLocation(0,0);
panel.setSize(this.getSize());
panel.setBackground(Color.LIGHT_GRAY);
panel.setVisible(true);
this.add(panel);
addKeyListener(new KeyChecker(panel));
}
}
Thank you for your help.
The functions in KeyChecker should start with lower case, so public void keyPressed and keyReleased.
In addition, you should add implements KeyListener to the classes KeyChecker and GamePanel (remove ActionListener in GamePanel).
Then, add the unimplemented functions. Eclipse will ask you for it.
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
Remark, it's better to #Override the functions keyPressed and keyReleased, rather than creating new functions.
I tried them, it worked!

two different movable images on Jpanel

I'm creating a two player game and I'm having some difficulties with creating two movable player images. should I just make a player one and player two claas or is this amateuristic? here is my current non working code:
package game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class Speler {
private Image image;
private int x = 0, y = 0, velX=0, velY = 0;
private int eerste;
public Speler(int welke){
welke = eerste;
if( welke < 10){ImageIcon ii = new ImageIcon("C:\\Users\\gil\\Pictures\\blauw vierkant.png" );
image = ii.getImage();
x = 40;
y = 160;}
else{ ImageIcon ii = new ImageIcon("C:\\Users\\gil\\Pictures\\paars vierkant.png" );
image = ii.getImage();
x = 520;
y = 10;}
}
public void move(){
if (x<0)
{
velX = 0;
x=0;
}
if (x>545)
{
velX = 0;
x=545;
}
if (y<0)
{
velY = 0;
y=0;
}
if (y>323)
{
velY = 0;
y=323;
}
x = x + velX;
y = y + velY;
}
public void keyPressed(KeyEvent e){
int c = e.getKeyCode();
if (eerste < 10){
if (c == KeyEvent.VK_Q)
{
velX = -1;
velY = 0;
}
if (c == KeyEvent.VK_Z)
{
velX = 0;
velY = -1;
}
if (c == KeyEvent.VK_D)
{
velX = 1;
velY = 0;
}
if (c == KeyEvent.VK_S)
{
velX = 0;
velY = 1;}
else{
if (c == KeyEvent.VK_LEFT)
{
velX = -1;
velY = 0;
}
if (c == KeyEvent.VK_UP)
{
velX = 0;
velY = -1;
}
if (c == KeyEvent.VK_RIGHT)
{
velX = 1;
velY = 0;
}
if (c == KeyEvent.VK_DOWN)
{
velX = 0;
velY = 1;
}
}
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
velX = 0;
velY = 0;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public void Drawspeler(Graphics g){
Graphics2D g2d1 = (Graphics2D) g;
g2d1.drawImage(image,x,y,null);
}
}
package game;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class Board extends JPanel implements ActionListener{
private Timer tm;
private Speler speler1;
private Speler speler2;
public Board(){
addKeyListener(new Indrukken());
setFocusable(true);
setFocusTraversalKeysEnabled(false);
speler1 = new Speler(1);
speler2 = new Speler(50);
tm = new Timer(10, this);
tm.start();
}
public void paintComponent(Graphics g ) {
super.paintComponent(g);
speler1.Drawspeler(g);
speler2.Drawspeler(g);
}
public void actionPerformed(ActionEvent e){
speler1.move();
speler2.move();
repaint();
}
private class Indrukken extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e){
speler1.keyPressed(e);
speler2.keyPressed(e);
}
#Override
public void keyReleased(KeyEvent e){
speler1.keyReleased(e);
speler2.keyReleased(e);
}
}
}

How could my two classes share the same JFrame or Frame?

Alright, so my first class creates the Frame and also places a red rectangle in it which I can move. Now what i'm doing is, creating another class for a blue rectangle.
Now in my attempt i have created the second class and also extended the first class unto it; which doesn't seem to do the job.
Summery:
What do I need to do so they share the same frame? Is there a method for this?
SOLVED VERSION
My Code(First Class): EDITED
import java.awt.BorderLayout;
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.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MyGame extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
int x = 0, y = 0, velx =0, vely =0, g = 0;
private Color color;
public MyGame() {
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(x, y, 50, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
if (x < 0) //stops us from going backwards past x = 0
{
velx = 0;
x = 0;
}
if (y < 0) //stops us from going to the sky
{
vely = 0;
y = 0;
}
if (y > 330) // stops us from going through the ground
{
vely = 0;
y = 330;
}
x += velx;
y += vely;
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
{
if (code == KeyEvent.VK_DOWN) {
vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time
}
if (code == KeyEvent.VK_UP) {
vely = -1; // same goes for here
}
if (code == KeyEvent.VK_LEFT) {
velx = -1;
}
{
if (code == KeyEvent.VK_RIGHT) {
velx = 1;
}
}
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
velx = 0;
vely = 0;
}
public static void main (String arge[]){
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Incoming());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
(Second Class): EDITED
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 Incoming extends MyGame {
private Color color;
int x = 0, y = 0, velx = 0, vely = 0;
public Incoming() {
color = Color.BLUE;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(x, y, 50, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (x < 0) //stops us from going backwards past x = 0
{
velx = 0;
x = 0;
}
if (y < 0) //stops us from going to the sky
{
vely = 0;
y = 0;
}
if (y > 330) // stops us from going through the ground
{
vely = 0;
y = 330;
}
x += velx;
y += vely;
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
int code = e.getKeyCode();
{
if (code == KeyEvent.VK_S) {
vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time
}
if (code == KeyEvent.VK_NUMPAD8) {
vely = -1; // same goes for here
}
if (code == KeyEvent.VK_NUMPAD4) {
vely = 0;
velx = -1;
}
{
if (code == KeyEvent.VK_NUMPAD6) {
vely = 0;
velx = 1;
}
}
}
}
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
velx = 0;
vely = 0;
}
}
Thank you
You could either take advantage of the color property support of the component or supply your own color property which could set and retrieved through the use of setters and getters
The following example simply uses the components existing foreground property...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GameExample {
public static void main(String[] args) {
new GameExample();
}
public GameExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
MyGame game = new MyGame();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MyGame extends JPanel implements ActionListener {
Timer t = new Timer(5, this);
int x = 0, y = 0, velx = 0, vely = 0, g = 0;
public MyGame() {
t.start();
setFocusTraversalKeysEnabled(false);
setForeground(Color.RED);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-released");
ActionMap am = getActionMap();
am.put("up-pressed", new YDelatAction(-1));
am.put("down-pressed", new YDelatAction(1));
am.put("left-pressed", new XDelatAction(-1));
am.put("right-pressed", new XDelatAction(1));
am.put("up-released", new YDelatAction(0));
am.put("down-released", new YDelatAction(0));
am.put("left-released", new XDelatAction(0));
am.put("right-released", new XDelatAction(0));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getForeground());
g.fillRect(x, y, 50, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
if (x < 0) //stops us from going backwards past x = 0
{
velx = 0;
x = 0;
}
if (y < 0) //stops us from going to the sky
{
vely = 0;
y = 0;
}
if (y > 330) // stops us from going through the ground
{
vely = 0;
y = 330;
}
x += velx;
y += vely;
repaint();
}
public class XDelatAction extends AbstractAction {
private int value;
public XDelatAction(int value) {
this.value = value;
}
#Override
public void actionPerformed(ActionEvent e) {
vely = 0;
velx = value;
}
}
public class YDelatAction extends AbstractAction {
private int value;
public YDelatAction(int value) {
this.value = value;
}
#Override
public void actionPerformed(ActionEvent e) {
vely = value;
}
}
}
}
This would allow you to create a new instance that use a different color by doing...
MyGame game = new MyGame();
game.setForeground(Color.BLUE);
Or you could create a new subclass using something like...
public class MyBlueGame extends MyGame {
public MyBlueGame () {
setForeground(Color.BLUE);
}
}
Generally speaking, you should favour the key bindings API over KeyListener as it provides more control over the level of focus required to generate key events and generally produces more re-usable and configurable code (IMHO)
Updated
So, based on you example code...
Each class is going to need it's own color property, which independent of the other, otherwise the inheritance is going to get in the way (and the parent will want to use the value of the child)
You will also need to change the keyPressed and keyReleased methods for the child class so that the two rectangles can move independently of each other.
This is not my preferred solution. I would have a single game surface which was capable of rendering the state of the overall game (all the entities) and would provide a means by which the gaming elements could be added (and possibly removed) from the surface and some kind of controller that would be able to control the way in which those elements are updated...but that's just me...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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 javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GameTest {
public static void main(String[] args) {
new GameTest();
}
public GameTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Incoming());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MyGame extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
int x = 0, y = 0, velx = 0, vely = 0, g = 0;
private Color color;
public MyGame() {
color = Color.RED;
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(x, y, 50, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
if (x < 0) //stops us from going backwards past x = 0
{
velx = 0;
x = 0;
}
if (y < 0) //stops us from going to the sky
{
vely = 0;
y = 0;
}
if (y > 330) // stops us from going through the ground
{
vely = 0;
y = 330;
}
x += velx;
y += vely;
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
{
if (code == KeyEvent.VK_DOWN) {
vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time
}
if (code == KeyEvent.VK_UP) {
vely = -1; // same goes for here
}
if (code == KeyEvent.VK_LEFT) {
velx = -1;
}
{
if (code == KeyEvent.VK_RIGHT) {
velx = 1;
}
}
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
velx = 0;
vely = 0;
}
}
public class Incoming extends MyGame {
private Color color;
int x = 0, y = 0, velx = 0, vely = 0;
public Incoming() {
color = Color.BLUE;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(x, y, 50, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (x < 0) //stops us from going backwards past x = 0
{
velx = 0;
x = 0;
}
if (y < 0) //stops us from going to the sky
{
vely = 0;
y = 0;
}
if (y > 330) // stops us from going through the ground
{
vely = 0;
y = 330;
}
x += velx;
y += vely;
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
int code = e.getKeyCode();
{
if (code == KeyEvent.VK_NUMPAD2) {
vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time
}
if (code == KeyEvent.VK_NUMPAD8) {
vely = -1; // same goes for here
}
if (code == KeyEvent.VK_NUMPAD4) {
vely = 0;
velx = -1;
}
{
if (code == KeyEvent.VK_NUMPAD6) {
vely = 0;
velx = 1;
}
}
}
}
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
velx = 0;
vely = 0;
}
}
}
i think all what you have to do is to set the colour as a parameter for your class MyGame , to add a field colour to your class.
private Color colour;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Colour);
g.fillRect(x,y,70,40);
}
JFrame f = new JFrame();
MyGame s = new MyGame();
s.setCoulor(Color.RED) // s.setCoulor(Color.BLUE)
f.add(s);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600,400);
f.setVisible(true);

How do I move a graphic across the screen with arrow keys?

I'm trying to create the beginning of a simple game. The first thing I am trying to do is import a graphic into my code and move it across the screen. I was able to draw a ball on the screen and move it around but when I import a graphic from a file I am unable to move it around. What am I missing or doing wrong?
import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velX = 0, velY = 0;
private ImageIcon image;
public Game(){
setBackground(Color.WHITE);
t.start();
addKeyListener(this);
this.setFocusable(true);
setFocusTraversalKeysEnabled(false);
image = new ImageIcon ("ship.gif");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon i = new ImageIcon("C:\\Users\\Bryan\\Pictures\\ship.gif");
i.paintIcon(this, g, 0, 0);
}
public void actionPerformed(ActionEvent e){
repaint();
x += velX;
y += velY;
if(x<0){
velX = 0;
x = 0;
}
if(x>750){
velX = 0;
x = 750;
}
if(y<0);{
velY = 0;
y = 0;
}
if(y>550){
velY = 0;
y = 550;
}
}
public void up(){
velY = -1.5;
velX = 0;
}
public void down(){
velY = 1.5;
velX = 0;
}
public void left(){
velX = -1.5;
velY = 0;
}
public void right(){
velX = 1.5;
velY = 0;
}
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
up();
}
if (code == KeyEvent.VK_DOWN){
down();
}
if (code == KeyEvent.VK_LEFT){
left();
}
if (code == KeyEvent.VK_RIGHT){
right();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
// velX = 0;
// velY = 0;
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
velY = 0;
}
if (code == KeyEvent.VK_DOWN){
velY = 0;
}
if (code == KeyEvent.VK_LEFT){
velX = 0;
}
if (code == KeyEvent.VK_RIGHT){
velX = 0;
}
}
}
My driver is in another class as follows:
import java.awt.Color;
import javax.swing.JFrame;
public class GameDriver {
public static void main(String[] args) {
JFrame f = new JFrame();
Game g = new Game();
f.add(g);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,600);
}
}
Two big problems here:
public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon i = new ImageIcon("C:\\Users\\Bryan\\Pictures\\ship.gif");
i.paintIcon(this, g, 0, 0);
}
You're reading from a file from within paintComponent(...). Never do this as this will slow your drawing unnecessarily. Read the image once, perhaps in a constructor, and then use the stored image variable in drawing. The paintComponent method should be for painting only, and it should be lean, mean and fast.
You're drawing at 0, 0 always. If you want to move something, draw at a variable position, and then change the values held by the variable and repaint.
Also: You should use Key Bindings to accept key strokes in a Swing application as this will help solve focus issues.
For example, please have a look at my code in this answer.

Java GUI - Moving a circle with no "footprints"

When I run the program and move the circle, it appears as if I'm drawing with a paintbrush in paint. I'm not quite sure what I did to make it to this, or what I can do to make it stop. All help is highly appreciated.
Here is my code:
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.JPanel;
import java.awt.event.KeyListener;
public class MovingCar extends JPanel implements ActionListener, KeyListener {
Timer tm = new Timer(5, this);
int x = 0, y = 0, velX = 0, velY = 0;
public MovingCar()
{
tm.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
protected void paintComponent (Graphics g) {
super.paintComponents(g);
g.drawOval(x, y, 50, 50);
}
public void actionPerformed(ActionEvent e){
x = x + velX;
y = y + velY;
repaint();
}
public void keyPressed(KeyEvent e){
int c = e.getKeyCode();
if (c == KeyEvent.VK_DOWN) {
velX = -1;
velY = 0;
}
if (c == KeyEvent.VK_UP)
{
velX = 1;
velY = 0;
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
if (x < 0)
{
velX = 0;
x = 0;
}
if (x > 600)
{
velX = 0;
x = 0;
}
repaint();
velY = 0;
velX = 0;
}
public static void main(String[] args) {
MovingCar o = new MovingCar();
JFrame jf = new JFrame();
jf.setTitle("Circle Move");
jf.setSize(600,400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(o);
jf.setVisible(true);
}
}
You're calling super.paintComponents(g); instead of super.paintComponent(g);

Categories

Resources