Implementing extended class or not - java

Another question about inheritance in java: I was wondering about two things:
1) how can I set my program to switch between using an inherited class or not?
2) I'm not sure why my extended class glidingObject.java is not responding to my key presses
Here's my Game.java (which runs the game; I should be passing in some parameter that allows the user to choose which class to use right - either flying object or gliding object? I've also included my two classes for flying object and gliding object)
public class Game extends JPanel {
private static final long serialVersionUID = 1L;
public static int WIDTH = 800, HEIGHT = 750;
public static ArrayList<Rectangle> columns;
public static Random rand;
public static double score;
public static boolean gameOver, started; //two modes, started and gameover
public static String username;
public static String currTime;
public static Timer timer;
public static flyingObject obj;
private PropertyChangeSupport mPcs = new PropertyChangeSupport(this);
public Game(flyingObject object){
obj = object;
timer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
tick();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
columns = new ArrayList<Rectangle>();
rand = new Random();
Background bk = new Background();
addColumn(true);
addColumn(true);
addColumn(true);
addColumn(true);
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
started = true;
}
});
PropertyChangeListener listener = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
try {
scoreBoard.record();
} catch (IOException e) {
e.printStackTrace();
}
}
};
this.addPropertyChangeListener(listener);
getDate(); //get the date of the game played
mPcs.firePropertyChange("gameOver",false, true); //alert record() method when the game is over
timer.start();
}
//adding the column
public static void addColumn(boolean start) {
int space = 300;
int width = 100;
int height = 50 + rand.nextInt(300);
if (start) {
//add top and bottom
columns.add(new Rectangle(WIDTH + width + columns.size() * 300, HEIGHT - height - 120, width, height + 100));
columns.add(new Rectangle(WIDTH + width + (columns.size() - 1) * 300, 0, width, HEIGHT - height - space));
}
else
{
columns.add(new Rectangle(columns.get(columns.size() - 1).x + 600, HEIGHT - height - 120, width, height + 100));
columns.add(new Rectangle(columns.get(columns.size() - 1).x, 0, width, HEIGHT - height - space));
}
}
//paint the columns
public void paintColumn(Graphics g, Rectangle column) {
g.setColor(Color.white);
g.fillRect(column.x, column.y, column.width, column.height);
}
public static void reset() {
obj = new glidingObject(WIDTH / 2 - 10, HEIGHT / 2 - 10);
columns.clear();
score = 0.0;
addColumn(true);
addColumn(true);
addColumn(true);
addColumn(true);
gameOver = false;
}
public void tick() throws IOException {
if (started) {
int speed = 10;
glidingObject.move();
for (int i = 0; i < columns.size(); i ++) {
Rectangle column = columns.get(i);
column.x -= speed;
if (column.x + column.width < 0) {
columns.remove(column);
if (column.y == 0) {
addColumn(false);
}
}
}
for (Rectangle column: columns) {
if (column.x == glidingObject.X) {
score += 0.5;
}
if (column.intersects(glidingObject.getBounds())) {
gameOver = true;
//when the object crashes, it does not go through the column
if (glidingObject.X <= column.x) {
glidingObject.X = column.x - glidingObject.DIAMETER;
}
else if (glidingObject.Y < column.height) {
glidingObject.Y = column.height;
}
Main.gameOver();
}
}
if (glidingObject.Y > HEIGHT || glidingObject.Y < 0) {
gameOver = true;
//timer.stop();
Main.gameOver();
}
if (glidingObject.Y + glidingObject.YMotion >= HEIGHT) {
gameOver = true;
//timer.stop();
Main.gameOver();
}
}
//update the display
repaint();
}
public void getDate() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
currTime = dateFormat.format(date);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Background.paint(g);
glidingObject.paint(g);
for (Rectangle column: columns) {
paintColumn(g, column);
}
g.setColor(Color.white);
g.setFont(new Font("Manaspace", 1, 60));
if (!started) {
g.drawString("Click to start!", 75, HEIGHT / 2 - 50);
}
if (gameOver) {
g.drawString("Game Over!", 200, HEIGHT / 2 - 50);
}
if (!gameOver && started) {
g.drawString(String.valueOf(score), WIDTH / 2 - 25, 100);
}
}
}
class flyingobject.java
public class flyingObject implements ActionListener, MouseListener, KeyListener {
static int DIAMETER = 25;
static int Y; // Y position of the unicorn
static int X; // X position of the unicorn
static int YMotion; // Y movement of the unicorn
//parameters are the initial positions
public flyingObject(int xpos, int ypos) {
X = xpos;
Y = ypos; // this changes
}
//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;
}
//the bounds of the object (rectangle)
public static Rectangle getBounds() {
return new Rectangle(X, Y, DIAMETER, DIAMETER);
}
//the visible component of the object - this can get overriden by subclasses
public static void paint(Graphics g){
g.setColor(Color.white);
g.fillRect(X, Y, DIAMETER, DIAMETER);
}
//the movement component of the object
public static void jump() {
if (Game.gameOver) {
Game.reset();
Game.gameOver = false;
}
if (!Game.started) {
Game.started = true;
}
else if (!Game.gameOver) {
if (YMotion > 0) {
YMotion = 0;
}
YMotion -= 14;
}
}
public static void move() {
if ((Y > 0) && (Y < Game.HEIGHT)) {
YMotion += 1.5; // gravity
Y += YMotion;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
jump();
}
}
#Override
public void mouseClicked(MouseEvent e) {
jump();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Class glidingobject.java (the game.java should allow the user to choose between just using flying object, or the extended class gliding object)
public class glidingObject extends flyingObject{
//velocity of the object
private static int vx;
private static int vy;
private static int lives;
public glidingObject(int xpos, int ypos) {
super(xpos, ypos);
vx = 0;
vy = 0;
lives = 3;
}
//getter methods
public int getVx() {
return vx;
}
public int getVy() {
return vy;
}
//setter methods
public void setVx(int newVx) {
vx = newVx;
}
public void setVy(int newVy) {
vy = newVy;
}
//moves the object
public static void jump() {
X += vx;
Y += vy;
}
public static void paint(Graphics g) {
g.setColor(Color.CYAN);
g.fillOval(X, Y, DIAMETER, DIAMETER);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
vx = 10;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
vx = -10;
}
if (e.getKeyCode() == KeyEvent.VK_UP){
vy = 10;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN){
vy = -10;
}
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}

I should be passing in some parameter that allows the user to choose which class to use right - either flying object or gliding object?
This is where interfaces become so powerful. Both the "flying" and "gliding" objects are going to share some common properties/functionality, these should be described by the interface. You Game should then only accept instances of this interface, it shouldn't care what the implementation, only that they adhere to the agreed interface.
This is principle of "code to interface, not implementation"
How complicated this gets is up to you, for example, you could have abstract implementations which describe "air" based entities and "ground" based entities, from which you could have "powered" and "unpowered" implementations of the abstract "air" class, all of which would be tied back to the "game entity" interface
I'm not sure why my extended class glidingObject.java is not responding to my key presses
This is because you're using KeyListener, this well known for it's focus related issues. See How to Use Key Bindings for the recommended solution

Related

can't make geometric shapes to move in Java

I'm all new to this site and to Java, so please be lenient.
I'm writing a program that allows to draw different type of shapes with a button click and after hitting another button move/stop/reset them.
I've made already the most part I think (the shapes are correctly creating and storing in an arraylist, the same with the reset, which clear the screen), but I can't figure out how to make them move.I got a function for movement but can't find a way to make the shapes form the arraylist to move. Can anyone give me a little advise.
Thanks
P.S. If there is something wrong/bad coding and needs to be fixed I'll be grateful if you will point at them.
Here is my code:
MyShape class is for creating different shapes.
import java.awt.*;
import java.util.Random;
public abstract class MyShape extends Component {
protected Color color;
private int x, y, dimX, dimY;
public Random random = new Random();
public MyShape(int x, int y, int dimX, int dimY){
this.x = x;
this.y = y;
this.dimX = dimX;
this.dimY = dimY;
color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
public abstract void draw(Graphics g);
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDimX() {
return dimX;
}
public void setDimX(int dimX) {
this.dimX = dimX;
}
public int getDimY() {
return dimY;
}
public void setDimY(int dimY) {
this.dimY = dimY;
}
}
CircleShape - creating circles.
import java.awt.*;
public class CircleShape extends MyShape {
public CircleShape(int x, int y, int dimX, int dimY) {
super(x, y, dimX, dimY);
}
#Override
public void draw(Graphics g) {
g.setColor(color);
g.fillOval(getX(), getY(), getDimX(), getDimY());
}
}
RectangleShape - rectangles
import java.awt.*;
public class RectangleShape extends MyShape {
public RectangleShape(int x, int y, int dimX, int dimY) {
super(x, y, dimX, dimY);
}
#Override
public void draw(Graphics g) {
g.setColor(color);
g.fillRect(getX(), getY(), getDimX(), getDimY());
}
}
and the DrawShape class which handles pretty much everything
public class DrawShapes extends JPanel {
private JButton addButton, resumeAllButton, stopAllButton, resetButton;
private final int FRAME_WIDTH = 800;
private final int FRAME_HEIGHT = 530;
private int x, y, dimX, dimY;
private Random random = new Random();
public List<MyShape> myShapeList = new CopyOnWriteArrayList<MyShape>();
private Timer timer = null;
public boolean move = false;
public DrawShapes() {
this.setLayout(null);
addButton = new JButton("Add Shape");
resumeAllButton = new JButton("Resume Shapes");
stopAllButton = new JButton("Stop All Shapes");
resetButton = new JButton("Reset");
addButton.setBounds(40, 20, 150, 30);
resumeAllButton.setBounds(230, 20, 150, 30);
stopAllButton.setBounds(420, 20, 150, 30);
resetButton.setBounds(610, 20, 150, 30);
this.add(addButton);
this.add(resumeAllButton);
this.add(stopAllButton);
this.add(resetButton);
stopAllButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
move = false;
}
});
resumeAllButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
move = true;
}
});
addButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Thread thread = new Thread() {
public void run() {
init();
}
};
thread.start();
}
});
resetButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < myShapeList.size(); i++) {
myShapeList.clear();
repaint();
}
}
});
}
public void moveIt() {
boolean directionUp = random.nextBoolean();
boolean directionLeft = random.nextBoolean();
boolean directionDown = !directionUp;
boolean directionRight = !directionLeft;
while (move) {
if (x <= 0) {
directionRight = true;
directionLeft = false;
}
if (x >= FRAME_WIDTH - dimX) {
directionRight = false;
directionLeft = true;
}
if (y <= 70) {
directionUp = false;
directionDown = true;
}
if (y >= FRAME_HEIGHT + 50 - dimY) {
directionUp = true;
directionDown = false;
}
if (directionUp)
y--;
if (directionDown)
y++;
if (directionLeft)
x--;
if (directionRight)
x++;
}
}
public void init() {
x = 0;
y = 0;
dimX = (random.nextInt(FRAME_WIDTH) + 100) / 2;
dimY = (random.nextInt(FRAME_HEIGHT) + 100) / 2;
while (x <= 0)
x = (random.nextInt(FRAME_WIDTH) - dimX);
while (y <= 70)
y = (random.nextInt(FRAME_HEIGHT) - dimY);
int choice = 0;
choice = random.nextInt(2) + 1;
switch (choice) {
case 1:
RectangleShape rectangleShape = new RectangleShape(x, y, dimX, dimY);
myShapeList.add(rectangleShape);
timer.start();
repaint();
break;
case 2:
CircleShape circleShape = new CircleShape(x, y, dimX, dimY);
myShapeList.add(circleShape);
repaint();
break;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 70, 800, 530);
for (MyShape aMyShapeList : myShapeList) {
aMyShapeList.draw(g);
}
}
public static void main(String args[]) {
JFrame jFrame = new JFrame();
jFrame.add(new DrawShapes());
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jFrame.setSize(800, 600);
jFrame.setResizable(false);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
jFrame.setLocation(dim.width / 2 - jFrame.getSize().width / 2, dim.height / 2 - jFrame.getSize().height / 2);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);
}
}
From the code you posted I can see that you are not calling your moveIt() method anywhere.
You have the right idea of how to move things around. The basic algorithm is:
Calculate new positions
Repaint the view
I can recommend you do the following:
You are currently calling your init method in a thread. I am not sure this is needed. Remove the thread logic and just call the method on the main thread.
Introduce another button tho start the actual animation. When clicking, create a thread that will call your moveIt() method.

Game in Java is not displaying

Hello everyone I am trying to make a game where the user plays as some kind of character, and trys to collect coins while avoiding monsters that spawn. My program compiles with no error, but nothing is showing up when I run the applet. This could be because of the order of extension I have everything in but I am not sure. Any help would be greatly appreciated (this is for a final school project for my intro to Java class). Here is the code, I know it is long but it all pertains to the question at hand:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class Sprite extends JApplet
{
Image image;
int x, y;
boolean isVisible;
public Sprite()
{
isVisible = false;
image = null;
}
public Sprite(Image i)
{
isVisible = true;
image = i;
x = 10;
y = 10;
}
public void setImage(Image img)
{
image = img;
isVisible = true;
}
public void setLocation(int _x, int _y)
{
x = _x;
y = _y;
}
public Rectangle getDimensions()
{
return new Rectangle(x, y, image.getWidth(null), image.getHeight(null));
}
public boolean intersects(Sprite s)
{
return getDimensions().intersects(s.getDimensions());
}
public void setVisible(boolean vis)
{
isVisible = vis;
}
public void paintComponent(Graphics g)
{
if(isVisible)
{
g.drawImage(image, x, y, null);
}
}
}
class Coins extends Sprite
{
int amount;
public Coins(int amt)
{
amount = amt;
}
public int getAmount()
{
return amount;
}
public void setAmount(int amt)
{
amount = amt;
}
}
class AnimateSprite extends Sprite
{
int speed = 5;
int directionX = 1, directionY = 1;
int healthPoints = 100;
final boolean DEAD = false;
final boolean ALIVE = true;
public void moveUp()
{
y -= speed;
}
public void moveDown()
{
y += speed;
}
public void moveLeft()
{
x -= speed;
}
public void moveRight()
{
x += speed;
}
public int getHealthPoints()
{
return healthPoints;
}
public void setHealthPoints(int hp)
{
healthPoints = hp;
}
public boolean hit(int amt)
{
healthPoints -= amt;
if(healthPoints < 0)
return DEAD;
else
return ALIVE;
}
}
class Game extends AnimateSprite implements Runnable, KeyListener
{
AnimateSprite user;
AnimateSprite monster, troll;
Coins ten, twenty;
Thread thread;
Random r;
public void init()
{
r = new Random();
user = new AnimateSprite();
user.setImage(getImage(getCodeBase(), "player.gif"));
monster = new AnimateSprite();
monster.setImage(getImage(getCodeBase(), "monster.gif"));
troll = new AnimateSprite();
troll.setImage(getImage(getCodeBase(), "monster.gif"));
troll.setLocation(350, 350);
setupCoins();
setFocusable(true);
addKeyListener(this);
thread = new Thread(this);
thread.start();
}
public void setupCoins()
{
ten = new Coins(10);
twenty = new Coins(20);
ten.setLocation(400, 350);
twenty.setLocation(450, 50);
ten.setImage(getImage(getCodeBase(), "coins.gif"));
twenty.setImage(getImage(getCodeBase(), "coins.gif"));
}
public void keyPressed(KeyEvent ke) //Event handling
{
int key = ke.getKeyCode();
if(key == KeyEvent.VK_UP)
user.moveUp();
else if(key == KeyEvent.VK_DOWN)
user.moveDown();
else if(key == KeyEvent.VK_LEFT)
user.moveLeft();
else if(key == KeyEvent.VK_RIGHT)
user.moveRight();
}
public void keyReleased(KeyEvent ke) {}
public void keyTyped(KeyEvent ke) {}
public void update(Graphics g) {paint(g);}
public void paint(Graphics g)
{
g.clearRect(0, 0, this.getWidth(), this.getHeight());
ten.paintComponent(g);
twenty.paintComponent(g);
monster.setLocation(r.nextInt(10) - 5 + monster.x, r.nextInt(10 - 5 + monster.y));
monster.paintComponent(g);
user.paintComponent(g);
if(user.intersects(monster))
{
g.setFont(new Font("Serif", Font.BOLD, 26));
g.drawString("YOU HAVE DIED, YOU LOSE!", 20, 100); //Prints this when you lose
thread.interrupt(); //Stopping the thread if you die
}
}
public void run()
{
try //Try catch
{
while(true) //Only does this while when the boolean is true
{
repaint();
Thread.sleep(10); //Thread sleeps
}
} catch(Exception e) {} //Exception handling
}
}
Your order of inheritance seems odd, but its not whats causing the problem. Take a look at this website: http://www.dreamincode.net/forums/topic/28410-application-to-japplet-and-reverse/
Java Applets need to have init(), start(), stop(), and destroy(). You will need to put these methods in your Sprite class for the Applet to function.

Paint method is not working

I'm trying to make a 2D game that should draw a character to the screen. But when I run it, I just get a black screen.
The important bits:
public class StartingClass extends Applet implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
private Walrus walrus;
private Image image, character;
private Graphics second;
private URL base;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Applet");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
// Image Setups
character = getImage(base, "src/data/walrus_right.png");
}
#Override
public void start() {
walrus = new Walrus();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
walrus.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(character, walrus.getCenterX() - 61, walrus.getCenterY() - 63, this);
}
}
Also, here's my other class:
public class Walrus {
private int centerX = 100;
private int centerY = 382;
private boolean jumped = false;
private int speedX = 0;
private int speedY = 1;
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 150) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Handles Jumping
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= 382) {
centerY = 382;
speedY = 0;
jumped = false;
}
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if (jumped == false) {
speedY = -15;
jumped = true;
}
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public boolean isJumped() {
return jumped;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
I haven't gotten any errors at this point, but it's not working right.
The problem is that your image is not loaded. The line
getImage(base, "src/data/walrus_right.png");
tries to read the image for a deployed applet and will fail quietly (not throw errors), which is what caused the confusion. Try to replace it with
ImageIO.read(new File(getClass().getResource("relative/path.png").getPath()));
where you should replace the path as specified under getResource API.
Edit:
Break the call into several calls:
Class<? extends StartingClass> clas = getClass();
URL url = clas.getResource("relative/path.png");
String path = url.getPath();
File file = new File(path);
try {
Image image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
and move with the debugger step by step to see which line throws the error. My guess is that the file is not located in the right place, which causes getResource to return null, which causes new File(path) to throw NullPointerException.

Creating multiple instances of an object. (Game)

I've been asked to make a game for my CS (high school) class as my end of semester assignment. We haven't been taught properly all of the coding required to make a game so my knowledge in this area is very poor. Anyways, the game I am trying to make is something like "Flappy Fall" (an Apple appstore game) where objects fall from the top of the screen and descend to the bottom of the screen. The objective is to catch these objects before they reach the bottom. I am able to get one object to fall and have also created the "catcher", but I am not sure how to create multiple falling objects, nor do I know how to remove the object once it has been caught by the catcher. So far I have classes "JavaGame", "Catcher", and "Ball". Any help would be greatly appreciated.
int x, y;
int t = 1;
private Image dbImage;
private Graphics dbGraphics;
Image player;
Image bkg;
static Catcher p = new Catcher(150, 450);
public JavaGame() {
//Game Images
ImageIcon b = new ImageIcon("bkg.png");
bkg = b.getImage();
//Game properties
setTitle("Game");
setSize(350, 600);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
addKeyListener(new Keys());
addMouseMotionListener(new Mouse());
}
public void paint(Graphics g) {
//
dbImage = createImage(getWidth(), getHeight());
dbGraphics = dbImage.getGraphics();
draw(dbGraphics);
g.drawImage(dbImage, 0, 0, this);
}
public void draw(Graphics g) {
g.drawImage(bkg, 0, 0, this); //Creates background
p.draw(g);
//while (t < 100) {
p.b.draw(g);
//t++;
//}
g.setColor(Color.WHITE);
g.drawString(""+p.score, 175, 50);
repaint();
}
public static void main(String[] args) {
JavaGame jg = new JavaGame();
//Threads
Thread p1 = new Thread(p);
p1.start();
Thread ball = new Thread(p.b);
ball.start();
}
public class Keys extends KeyAdapter {
public void keyPressed(KeyEvent e) {
p.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
p.keyReleased(e);
}
}
public class Mouse implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
p.mouseDragged(e);
}
public void mouseMoved(MouseEvent e) {
p.mouseMoved(e);
}
}
}
int x, y, ranX, xDirection;
int score;
Rectangle catch1;
Ball b = new Ball(170, 1);
public Catcher (int x, int y) {
score = 0;
this.x = x;
this.y = y;
catch1 = new Rectangle(this.x, this.y, 50, 15);
}
public void run() {
try {
while(true) {
move();
Thread.sleep(5);
}
}
catch(Exception e) {
System.out.println("Error");
}
}
public void collision() {
if (b.ball.intersects(catch1)) {
b.ball(Color.blue);
score++;
System.out.println(score);
}
}
public void move() {
collision();
catch1.x += xDirection;
if (catch1.x <= 0)
catch1.x = 0;
if (catch1.x >= 300)
catch1.x = 300;
}
public void setXDirection(int xDir) {
xDirection = xDir;
}
public void keyPressed(KeyEvent m) {
int keyCode = m.getKeyCode();
if (keyCode == m.VK_LEFT) {
setXDirection(-1);
}
if (keyCode == m.VK_RIGHT) {
setXDirection(+1);
}
m.consume();
}
public void keyReleased(KeyEvent m) {
int keyCode = m.getKeyCode();
if (keyCode == m.VK_LEFT) {
setXDirection(0);
}
if (keyCode == m.VK_RIGHT) {
setXDirection(0);
}
m.consume();
}
public void mouseDragged(MouseEvent e) {
catch1.x = e.getX()-25;
e.consume();
}
public void mouseMoved(MouseEvent e) {
catch1.x = e.getX()-25;
e.consume();
}
public void draw(Graphics g) {
g.fillRect(catch1.x, catch1.y, catch1.width, catch1.height);
}
}
int x, y, yDirection;
Rectangle ball;
public Ball (int x, int y) {
this.x = x;
this.y = y;
ball = new Rectangle(this.x, this.y, 10, 10);
}
public void run() {
try{
while(true) {
move();
Thread.sleep(5);
}
}
catch(Exception e) {
System.out.println("Error");
}
}
public void move() {
if (ball.y >= 600) {
ball.y = 600;
}
if (ball.y > 0) {
ball.y++;
}
}
public void setYDirection(int yDir) {
yDirection = yDir;
}
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(ball.x, ball.y, ball.width, ball.height);
System.out.println(ball.x+ " "+ ball.y+ " " + ball.width + " " + ball.height);
}
}
I'd re-organize the code a little. In the main game, you can have a collection of 'Ball' types. I'll leave the collection option up to you. But you'll want to add 'new' Balls to the collection and then remove them once they are caught.
Since I do not want to do your assignment, I am just giving a short answer:
By calling new Ball() multiple times.
Of course you might want to add them to a collection, like
List list = new ArrayList();
list.add(ball);
And remove them from that collection once they are finished.

Why does the height of the rectangles jump vary?

Why does the height of the rectangle's jump vary? It seems to go in a cycle. First it jumps low then it doesn't jump at all then it jumps high then it doesn't jump at all. i can't figure out why as the same code is used and it is triggered by the same event.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
class Game extends JPanel{
Square square = new Square(this);
Ground ground = new Ground (this);
public Game() {
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
square.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
square.keyPressed(e);
}
});
setFocusable(true);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("My Mario");
Game game = new Game();
frame.add(game);
frame.setSize(600, 700);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
game.move();
game.repaint();
Thread.sleep(30);
}
}
private void move() {
square.move();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
square.paint(g2d);
ground.paint(g2d);
}
}
public class Square {
Square square;
int x,xa;
static int y;
int ya;
private Game game;
public static int fistX,fistY;
static int d = 60;
int wide;
boolean onGround;
public Square(Game game) {
this.game = game;
x = 100;
y = 631;
xa = 0;
ya = 0;
onGround = false;
wide = game.getWidth();
}
public void move() {
if (x + xa > 0 && x + xa < game.getWidth()-30)
x = x + xa;
if (y + ya > 0 && y + ya < game.getHeight()-60){
for(int i=12; i< 0; i--);
ya+=10;
y = y + ya;
}
if ( collision() ) {
y-=10;
onGround = true;
}
Square.y+=10;
}
public void paint(Graphics2D g) {
g.setColor(Color.RED);
g.fillRoundRect(x, y-d, 30, d, 10, 10);
}
private boolean collision() {
return game.ground.getBounds().intersects(getBounds());
}
public Rectangle getBounds() {
return new Rectangle(x, y, 30, 60);
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa=0;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa=0;
if(e.getKeyCode() == KeyEvent.VK_DOWN)
d = 60;
if(e.getKeyCode() == KeyEvent.VK_UP);
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = xa -3;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = xa + 3;
if(e.getKeyCode() == KeyEvent.VK_DOWN)
d = 30;
if(e.getKeyCode() == KeyEvent.VK_UP)
ya -= 60;
}
}
class Ground {
int y,x,h,w;
public Ground(Game game){
x = 0;
y = game.getHeight()-30;
w = game.getWidth();
h = 30;
}
public void paint(Graphics2D g){
g.setColor(Color.BLACK);
g.fillRect(0, 700, 99999999, 30);
}
public Rectangle getBounds() {
return new Rectangle(0, 700, 99999999, 30);
}
}
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeated tasks like animation. See Concurrency in Swing for more details.
frame.setSize(600, 700); I recommend instead setting a preferred size for the content and packing the frame around it. This suggests a constant size for the game on different PLAFs or OS'.
For Swing components other than top-level containers (e.g JFrame or JWindow), override paintComponent(Graphics) rather than paint(Graphics).
Look into key bindings instead of key listeners for Swing.
The first 3 are implemented, the last one (and other one commented in the code) is TODO - BNI.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SuperMarioGame extends JPanel {
private static final long serialVersionUID = 1L;
Square square = new Square(this);
Ground ground = new Ground (this);
public SuperMarioGame() {
// TODO Update to Key Bindings
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
square.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
square.keyPressed(e);
}
});
setFocusable(true);
// Use a listener/timer combo.
ActionListener gameAnimation = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
move();
repaint();
}
};
Timer timer = new Timer(30,gameAnimation);
timer.start();
// Set a preferred size for the panel.
Dimension preferred = new Dimension(600,700);
this.setPreferredSize(preferred);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("My Mario");
SuperMarioGame game = new SuperMarioGame();
frame.add(game);
// Pack the frame to the preferred size.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void move() {
square.move();
}
#Override
// for Swing components, generally override
// paintComponent rather than paint
//public void paint(Graphics g) {
public void paintComponent(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
square.paint(g2d);
ground.paint(g2d);
}
}
class Square {
Square square;
int x,xa;
static int y;
int ya;
private SuperMarioGame game;
public static int fistX,fistY;
static int d = 60;
int wide;
boolean onGround;
public Square(SuperMarioGame game) {
this.game = game;
x = 100;
y = 631;
xa = 0;
ya = 0;
onGround = false;
wide = game.getWidth();
}
public void move() {
if (x + xa > 0 && x + xa < game.getWidth()-30)
x = x + xa;
if (y + ya > 0 && y + ya < game.getHeight()-60){
for(int i=12; i< 0; i--);
ya+=10;
y = y + ya;
}
if ( collision() ) {
y-=10;
onGround = true;
}
Square.y+=10;
}
public void paint(Graphics2D g) {
g.setColor(Color.RED);
g.fillRoundRect(x, y-d, 30, d, 10, 10);
}
private boolean collision() {
return game.ground.getBounds().intersects(getBounds());
}
public Rectangle getBounds() {
return new Rectangle(x, y, 30, 60);
}
public void keyReleased(KeyEvent e) {
// TODO Else-if would be better here..
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa=0;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa=0;
if(e.getKeyCode() == KeyEvent.VK_DOWN)
d = 60;
if(e.getKeyCode() == KeyEvent.VK_UP);
}
public void keyPressed(KeyEvent e) {
// TODO Else-if would be better here..
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = xa -3;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = xa + 3;
if(e.getKeyCode() == KeyEvent.VK_DOWN)
d = 30;
if(e.getKeyCode() == KeyEvent.VK_UP)
ya -= 60;
}
}
class Ground {
int y,x,h,w;
public Ground(SuperMarioGame game){
x = 0;
y = game.getHeight()-30;
w = game.getWidth();
h = 30;
}
public void paint(Graphics2D g){
g.setColor(Color.BLACK);
g.fillRect(0, 700, 99999999, 30);
}
public Rectangle getBounds() {
return new Rectangle(0, 700, 99999999, 30);
}
}
Don't block the Event Dispatching Thread any way, it will prevent the EDT from processing repaint requests (and other events) which will make it look like your program has crashed. Have a read of Concurrency in Swing for more information.
Only modify the UI from the EDT, NEVER from any other thread, this includes creating UI elements
Favor key bindings over KeyListeners, they are more capable of resolving focus issues amongst other things. Have a read of How to Use Key Bindings for more details
Favor overriding paintComponent rather then paint. Paint does a lot of important work which you should avoid messing with if you can. Apart from any thing else paintComponent is going to be included in the double buffering of the component where as paint isn't (as super.paint sets it up)
Avoid using static state variables where possible
I don't know if this was deliberate or not, but, for (int i = 12; i < 0; i--); isn't going to achive anything, as the semi colen at the end means, do nothing for a count of 1
Personally, try not to use absolute values for things like width and height, which is actually reliant on parent container. You should also, where possible, provide sizing hints to allow the parent container to make better decisions on how much space it actually needs
UPDATED
Fixed bug in my movement code :P
I had a look at your collision detection code (in move) and, frankly, couldn't make heads or tails of it. I corrected it as well as changed in the way the paint method works so that x,y is always the top, left corner
public class TestGame {
public static void main(String[] args) throws InterruptedException {
new TestGame();
}
public TestGame() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
Game game = new Game();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GameThread extends Thread {
private Game game;
public GameThread(Game game) {
setDaemon(false);
this.game = game;
}
#Override
public void run() {
while (true) {
game.move();
try {
long startedAt = System.currentTimeMillis();
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
game.repaint();
}
});
long completedAt = System.currentTimeMillis();
long sleepFor = 30 - (completedAt - startedAt);
if (sleepFor < 0) {
sleepFor = 30;
}
Thread.sleep(sleepFor);
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
}
public class Game extends JPanel {
Square square = new Square(this);
Ground ground = new Ground(this);
public Game() {
// addKeyListener(new KeyListener() {
// #Override
// public void keyTyped(KeyEvent e) {
// }
//
// #Override
// public void keyReleased(KeyEvent e) {
// square.keyReleased(e);
// }
//
// #Override
// public void keyPressed(KeyEvent e) {
// square.keyPressed(e);
// }
// });
setFocusable(true);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "press-left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "press-right");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "press-down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "press-up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "release-left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "release-right");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "release-down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "release-up");
am.put("press-left", new PressLeftAction(square));
am.put("press-right", new PressRightAction(square));
am.put("press-down", new PressDownAction(square));
am.put("press-up", new PressUpAction(square));
am.put("release-left", new ReleaseLeftAction(square));
am.put("release-right", new ReleaseRightAction(square));
am.put("release-down", new ReleaseDownAction(square));
am.put("release-up", new ReleaseUpAction(square));
new GameThread(this).start();
// public void keyReleased(KeyEvent e) {
//
//
//
// if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// xa = 0;
// }
//
// if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// xa = 0;
// }
// if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// d = 60;
// }
//
// if (e.getKeyCode() == KeyEvent.VK_UP);
// }
//
// public void keyPressed(KeyEvent e) {
//// TODO Auto-generated method stub
// if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// xa = xa - 3;
// }
//
// if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// xa = xa + 3;
// }
//
// if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// d = 30;
// }
//
// if (e.getKeyCode() == KeyEvent.VK_UP) {
// ya -= 60;
// }
//
//
//
//
//
// }
}
public void move() {
square.move();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
// Don't override paint, use paintComponent instead
// #Override
// public void paint(Graphics g) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
square.paint(g2d);
ground.paint(g2d);
g2d.dispose();
}
}
public class Square {
Square square;
private int x, xa;
// static int y;
private int y;
private int ya;
private Game game;
// public static int fistX, fistY;
private int fistX, fistY;
// static int d = 60;
private int d = 60;
private int wide;
private boolean onGround;
public Square(Game game) {
this.game = game;
x = 100;
y = 100;
xa = 0;
ya = 0;
onGround = false;
wide = game.getWidth();
}
public void move() {
y += ya;
x += xa;
if (x < 0) {
x = 0;
} else if (x + 30 > game.getWidth()) {
x = game.getWidth() - 30;
}
if (y < 0) {
y = 0;
} else if (collision()) {
onGround = true;
y = game.ground.getBounds().y - d;
}
// if (x + xa > 0 && x + xa < game.getWidth() - 30) {
// x = x + xa;
// }
//
// if (y + ya > 0 && y + ya < game.getHeight() - 60) {
// // This was never going to do anything, look at the
// // end of the line...the `;` is going to prevent the
// // statemt ya += 10 from begin called within the loop
//// for (int i = 12; i < 0; i--);
// for (int i = 12; i < 0; i--) {
// ya += 10;
// }
// y = y + ya;
// }
// if (collision()) {
// y -= 10;
// onGround = true;
//
// }
//
// y += 10;
}
public void paint(Graphics2D g) {
g.setColor(Color.RED);
System.out.println(x + "x" + (y - d));
g.fillRoundRect(x, y, 30, d, 10, 10);
}
private boolean collision() {
return game.ground.getBounds().intersects(getBounds());
}
public Rectangle getBounds() {
return new Rectangle(x, y, 30, 60);
}
}
public class Ground {
private Game game;
public Ground(Game game) {
this.game = game;
}
public void paint(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, game.getHeight() - 30, game.getWidth(), 30);
}
public Rectangle getBounds() {
return new Rectangle(0, game.getHeight() - 30, game.getWidth(), 30);
}
}
public abstract class AbstractSquareAction extends AbstractAction {
private Square square;
public AbstractSquareAction(Square square) {
this.square = square;
}
public Square getSquare() {
return square;
}
}
public class PressLeftAction extends AbstractSquareAction {
public PressLeftAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().xa = -3;
System.out.println("pressLeft");
}
}
public class PressRightAction extends AbstractSquareAction {
public PressRightAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().xa = 3;
}
}
public class PressDownAction extends AbstractSquareAction {
public PressDownAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().ya = 30;
}
}
public class PressUpAction extends AbstractSquareAction {
public PressUpAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().ya -= 30;
}
}
public class ReleaseLeftAction extends AbstractSquareAction {
public ReleaseLeftAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().xa = 0;
}
}
public class ReleaseRightAction extends AbstractSquareAction {
public ReleaseRightAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().xa = 0;
}
}
public class ReleaseDownAction extends AbstractSquareAction {
public ReleaseDownAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().ya = 0;
}
}
public class ReleaseUpAction extends AbstractSquareAction {
public ReleaseUpAction(Square square) {
super(square);
}
#Override
public void actionPerformed(ActionEvent e) {
getSquare().ya = 0;
}
}
}

Categories

Resources