I am writing a game. Its directory tree is basically like this:
ShootGame------>game----------------------->input--------------------------------->InputHandler.class
|-->ShooterGame.class | |-->InputHandler.java
|-->ShooterGame.java |---->player-------------->Player.class
| |-->Player.java
|---->scenario---
|-->Block.class
|-->Block.java
I hope you understand my diagram, but the point is: the "game" folder has 3 folders inside it, "input","player","scenario".
Inside "InputHandler.java", I have declared package game.input.
Inside "Player.java", I have declared package game.player.
And inside "Block.java", I have declared package game.scenario.
So far, so good.
But when, in the Player.java, i do import game.input.InputHandler, it says "package game.input does not exist", even though I have already declared "game.input".
What have I done wrong here? If you need the codes inside the files, please leave a comment. I am not posting them here because I think the main problem I have is the package and import logic.
Thanks.
Edit:
Code
InputHandler.java
package game.input;
import java.awt.Component;
import java.awt.event.*;
public class InputHandler implements KeyListener{
static boolean[] keys = new boolean[256];
public InputHandler(Component c){
c.addKeyListener(this);
}
public boolean isKeyDown(int keyCode){
if (keyCode > 0 && keyCode < 256){
return keys[keyCode];
}
return false;
}
public void keyPressed(KeyEvent e){
if (e.getKeyCode() > 0 && e.getKeyCode() < 256){
keys[e.getKeyCode()] = true;
}
}
public void keyReleased(KeyEvent e){
if (e.getKeyCode() > 0 && e.getKeyCode() < 256){
keys[e.getKeyCode()] = false;
}
}
public void keyTyped(KeyEvent e){}
}
Player.java
package game.player;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.net.URL;
import java.awt.event.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import game.input.InputHandler;
public class Player{
private BufferedImage sprite;
public int x, y, width, height;
private final double speed = 5.0d;
public Player(int x, int y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
try{
URL url = this.getClass().getResource("ship.png");
sprite = ImageIO.read(url);
} catch(IOException e){}
}
public void keyPlayer(double delta, InputHandler i){
if(i.isKeyDown(KeyEvent.VK_D)){
if(this.x>=1240) return;
else this.x+=speed*delta;
}
if(i.isKeyDown(KeyEvent.VK_A)){
if(this.x<=0) return;
else this.x-=speed*delta;
}
}
public void update(InputHandler inputP){
keyPlayer(1.7, inputP);
}
public void Draw(Graphics a){
a.drawImage(sprite,x,y,width,height,null);
}
public Rectangle getBounds(){
return new Rectangle(x,y,width,height);
}
}
Block.java
package game.scenario;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.net.URL;
import java.awt.event.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;
public class Block{
private Timer timer;
private BufferedImage sprite;
private final int t = 1;
public int x, y, width, height;
public Block(int x, int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
try{
URL url = this.getClass().getResource("meteor.png");
sprite = ImageIO.read(url);
} catch(IOException e){}
}
public void Draw(Graphics g){
g.drawImage(sprite,x,y,width,height,null);
}
public boolean destroy(Block b){
if(b.y>=630){
b = null;
timer.cancel();
timer.purge();
return true;
} else { return false; }
}
public void update(int sec){
//if(getBounds().intersects(ShooterGame.ShooterGameClass.player.getBounds())){ System.out.println("Collision detected!"); }
timer = new Timer();
timer.schedule(new Move(), sec*1000);
destroy(this);
}
class Move extends TimerTask{
public void run(){
int keeper = 5;
if(keeper>0){
y+=5;
}
}
}
public Rectangle getBounds(){
return new Rectangle(x,y,width,height);
}
}
The main class(The game start)
ShooterGame.java:
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.*;
import java.net.URL;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.event.MouseEvent;
import game.input.InputHandler;
import game.player.Player;
import game.scenario.Block;
public class ShooterGame extends JFrame{
static int playerX=500;
static int playerY=520;
InputHandler input = new InputHandler(this);
public static Player player = new Player(playerX,playerY,50,50);
Block meteor = new Block(100,100,30,30);
public static void main(String[] args){
ShooterGame game = new ShooterGame();
game.run();
System.exit(0);
}
static int windowWidth = 1300;
static int windowHeight = 600;
static int fps = 30;
static BufferedImage backBuffer = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB);
public void run(){
boolean running = true;
initialize();
while(running){
long time = System.currentTimeMillis();
update();
draw();
time = (1000 / fps) - (System.currentTimeMillis() - time);
if (time > 0) {
try{
Thread.sleep(time);
}
catch(Exception e){};
};
}
}
public void initialize(){
setTitle("--- Shooter Game ---");
setSize(windowWidth, windowHeight);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void update(){
player.update(input);
meteor.update(0);
}
public void draw(){
Graphics g = getGraphics();
Graphics bbg = backBuffer.getGraphics();
bbg.setColor(Color.BLACK);
bbg.fillRect(0, 0, windowWidth, windowHeight);
player.Draw(bbg);
meteor.Draw(bbg);
g.drawImage(backBuffer, 0, 0, this);
}
}
Commands:
compiling Player, Block and InputHandler(javac file.java)
then run the game with _java ShooterGame
You are probably trying to compile from inside the directory that the file is in, which is incorrectly setting the classpath.
cd game/player
javac Player.java
Instead of going into the subpackages, set the classpath explicitly and compile from the top level. I'm assuming that ShooterGame.java is in your game folder:
cd path/to/project/ShootGame
javac -cp . game/player/Player.java
... compile other classes
java -cp . game.ShooterGame
Related
So, I am using ImageIcon and Image to animate a character. So far my code makes it look like the character is running however for a reason that I can't figure out KeyListener is not working. I have been at this for a while and I am wondering what I am doing wrong. This is my code:
*Right now I took out moving up and down because I couldn't get side to side to work. velyY was going to be the change in y.
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Image;
public class Main extends JPanel implements ActionListener,KeyListener{
ImageIcon images[];
int x = 100;
int y = 5;
int velX;
int velY;
int totalImages =3, currentImage = 0, animationDelay = 160;
Timer animationTimer;
public Main() {
images = new ImageIcon[totalImages];
images[0] = new ImageIcon("standing.png");
images[1] = new ImageIcon("ready.png");
images[2] = new ImageIcon("running.png");
startAnimation();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2 = (Graphics) g;
if (images[currentImage].getImageLoadStatus() == MediaTracker.COMPLETE){
Image img = images[currentImage].getImage();
g2.drawImage(img, x, 407, null);
currentImage = (currentImage + 1) % totalImages;
}
}
public void actionPerformed(ActionEvent e) {
repaint();
x+=velX;
}
public void right(){
velX = 8;
}
public void left(){
velX = -8;
}
public void keyPressed(KeyEvent arg0) {
int code = arg0.getKeyCode();
if (code == KeyEvent.VK_A){
left();
}
if(code == KeyEvent.VK_D){
right();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
velX = 0;
velY = 0;
}
public void startAnimation() {
if (animationTimer == null) {
currentImage = 0;
animationTimer = new Timer(animationDelay, this);
animationTimer.start();
} else if (!animationTimer.isRunning())
animationTimer.restart();
}
public void stopAnimation() {
animationTimer.stop();
}
}//end class
You have to register your KeyListener to your panel, if you want it to manage key events.
The second thing is that a JPanel is not focusable by default, so you have to make it focusable to receive key events.
In your Main constructor, just add :
setFocusable(true); // make your panel focusable
addKeyListener(this); // register the key listener
Ok I'm doing a project and the image is supposed to move around randomly and when the user clicks on the image it's supposed to count how many times the click on it. From there on it keeps moving until they x out. However, I made the mistake of making the image move AFTER they click on it, so when the program starts the image isn't already moving. I need it to move from the beginning of the program.
Attached here because for whatever reason, stack overflow keeps saying I formatted wrong.
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
// Zombie class
public class Zombie {
//declare variables
private int x;
private int y;
private int size;
private Image image;
//constructor
public Zombie(int xIn, int yIn, String imagePath) {
x = xIn;
y = yIn;
size = Settings.DEFAULT_SIZE;
setImage(imagePath);
}
//getter for x
public int getX() {
return x;
}
//getter for y
public int getY() {
return y;
}
//setter for x
public void setX(int x) {
this.x = x;
}
//setter for y
public void setY(int y) {
this.y = y;
}
//drawImage method
public void update(Graphics g) {
g.drawImage(image, x, y, size, size, null);
}
//try catch exception, if image isn't found
public void setImage(String imagePath) {
try {
image = ImageIO.read(new File(imagePath));
} catch (IOException ioe) {
System.out.println("Unable to load image file.");
}
}
}
public class Settings {
//adjusts the width and height of the creature
public static final int WIDTH = 500;
public static final int HEIGHT = 300;
public static final int DEFAULT_SIZE = 50;
//image name
public static final String ZOMBIE_IMAGE = "zombie.png";
}
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.util.Random;
class Controller implements MouseListener {
//declares variables
Zombie zombie;
View view;
private int count = 0;
Controller() {
//System.out.println ("Controller()");
}
public void addZombie(Zombie z){
//System.out.println("Controller: adding zombie");
this.zombie = z;
}
public void addView(View v){
//System.out.println("Controller: adding view");
this.view = v;
}
public void mousePressed(MouseEvent e) {
//System.out.println("Controller sees mouse pressed: acting on Model");
int prevX = e.getX();
int prevY = e.getY();
prevX -= zombie.getX();
prevY -= zombie.getY();
if((prevX > 0 && prevX < Settings.DEFAULT_SIZE) &&
(prevY > 0 && prevY < Settings.DEFAULT_SIZE)) {
//System.out.println("Got Zombie.");
Random r = new Random();
zombie.setX(r.nextInt(view.getWidth() - Settings.DEFAULT_SIZE));
zombie.setY(r.nextInt(view.getHeight() - Settings.DEFAULT_SIZE));
++count;
}
}
public int getCount() {
return count;
}
//mouse events
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void update(Graphics g) {
zombie.update(g);
}
}
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.util.Random;
public class View implements ActionListener {
private JFrame frame;
Controller controller;
public static void main(String[] args) {
Zombie zombie = new Zombie(Settings.WIDTH/2, Settings.HEIGHT/2, Settings.ZOMBIE_IMAGE);
View view = new View();
Controller myController = new Controller();
myController.addZombie(zombie);
myController.addView(view);
view.addController(myController);
new Timer(500, view).start();
}
private class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
controller.update(g);
revalidate();
}
}
private MyPanel panel;
View() {
//System.out.println("View()");
frame = new JFrame("Catch The Zombie");
// Create a panel to contain a label, a text box, and a button
panel = new MyPanel();
frame.add(panel);
frame.setSize(Settings.WIDTH, Settings.HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
// TODO Auto-generated method stub
System.out.println("Zombie was caught " + controller.getCount() + "times");
}
});
}
public void revalidate() {
}
public void addController(Controller controller){
//System.out.println("View : adding controller");
this.controller = controller;
frame.getContentPane().addMouseListener((MouseListener) controller);
}
public int getWidth() {
return frame.getWidth();
}
public int getHeight() {
return frame.getHeight();
}
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
I want to make a program to animate a projectile (a ball flying in a projectile in 2D). In main I call a Shoot() function whose argument is a Graphics object, but I don't know how to create the object so that it draws on my JFrame object. Please help me.
import java.lang.Math;
import java.applet.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Projectile extends JPanel{
public static int ScreenH=1500;
public static int ScreenW=3000;
public static int Xcor=0;
public static int Ycor=0;
public static int ballRadius=20;
public static int prevXcor = 0;
public static int prevYcor = 0;
public static int newXcor = 0;
public static int newYcor = 0;
public static int Time = 0;
public static int Angle = 45;
public static int Velocity = 10;
public static double Acceleration = 9.8;
public static void InitGraphics(){
JFrame jframe = new JFrame();
jframe.setTitle("Projectile");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(ScreenW, ScreenH);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.add(new Projectile());
}
public static void drawCenteredCircle(Graphics g, int x, int y) {
int a = x;
int b = 1000 - y;
g.fillOval(a,b, ballRadius, ballRadius);
}
public static void move() throws InterruptedException {
Thread.sleep(20);
Time += 20;
double XVelocity = Math.sin(Velocity);
double YVelocity = Math.cos(Velocity);
int X = (int) (XVelocity*Time);
int Y = (int) ((YVelocity*Time) + (0.5*Acceleration*Time*Time));
newXcor = X;
newYcor = Y;
}
public static void repaint(Graphics g) {
g.setColor(Color.white);
drawCenteredCircle(g, prevXcor, prevYcor);
g.setColor(Color.red);
drawCenteredCircle(g, newXcor, newYcor);
prevXcor = newXcor;
prevYcor = newYcor;
}
public static void Shoot(Graphics g) throws InterruptedException {
while ( (newXcor < (ScreenW - (4*ballRadius))) && (newYcor < (ScreenH - (4*ballRadius)))) {
move();
repaint(g);
}
}
public static void main(String[]args) {
InitGraphics();
Shoot();
}
}
The JFrame is just the window, you need to add a JComponent to it. JComponents contain a protected void paintComponent(Graphics g) method which you need to override like this:
JFrame frame = new JFrame();
JComponent canvas = new JComponent() {
protected void paintComponent(Graphics g) {
//call repaint(g) here instead of this
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
};
};
frame.add(canvas);
You will probably have to clear the background in repaint
I haven't looked at the code for this little game I made a while ago, and now all of the sudden the image won't move up when I click it?
I know the clicks are being called because the counter goes up. But the image won't move up. Any help is appreciated.
Batman class below
package Clicky;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Batman
{
private String batz = "batbomb.png";
private int x;
private int y;
private Image image;
private boolean visible;
public Batman()
{
ImageIcon ii = new ImageIcon(this.getClass().getResource(batz));
image = ii.getImage();
visible = true;
x = 145;
y = 620;
}
public int getX() { return x; }
public int getY() { return y; }
public Image getImage() { return image; }
public boolean isVisible()
{
return visible;
}
public void setVisible(boolean visible)
{
this.visible = visible;
}
public void mouseClicked(MouseEvent e)
{
int button = MouseEvent.BUTTON1;
if (button == MouseEvent.MOUSE_CLICKED)
{
y -= 1;
}
}
}
Where everything is drawn here
package Clicky;
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.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Clicky extends JPanel implements ActionListener
{
private Batman bat;
private Timer timer;
private int clicks = 0;
private boolean visible;
public Clicky() {
addMouseListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
timer = new Timer(5, this);
timer.start();
bat = new Batman();
}
public int getClickCount()
{
return clicks;
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g.setColor(Color.WHITE);
g2d.drawString("Clicks: " + getClickCount(), 10, 50);
g2d.drawRect(150, 70, 200, 600);
g2d.drawImage(bat.getImage(), bat.getX(), bat.getY(), this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
private class TAdapter extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
e.getClickCount();
clicks = clicks + 1;
}
}
}
Your Batman mouseClicked(MouseEvent e) method never gets called (if I'm wrong, please show me where). But even if it did, your MOUSE_CLICKED == BUTTON1 boolean check would always be false, since BUTTON1 and MOUSE_CLICKED are both constants and equal to different things, 1 and 500 respectively, and this will make sure that the if block never worked.
Im having trouble getting the key pressed event to work, it doesn't recognize key input, can someone please help?
I have three classes player, exe, and board
Here is the board class
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.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Board extends JPanel implements ActionListener{
private Timer timer;
private Player player;
//private Floor
public Board() {
addKeyListener( new TAdapter() );
setFocusable(true);
setBackground(Color.WHITE);
setDoubleBuffered(true);
player = new Player();
//floor = new Floor();
timer = new Timer(5, this);
timer.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(player.getImage(), player.getX(), player.getY(), this);
// g2d.drawImage(floor.getImage(), floor.getX(), floor.getY(), this);
//System.out.println(player.getX() + ", " + player.getY());
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
// checkPlayerOnGround();
player.move();
repaint();
}
private class TAdapter extends KeyAdapter implements KeyListener{
public void keyTyped(KeyEvent e) {
player.keyReleased(e);
System.out.println("Released");
}
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
System.out.println("Pressed");
}
}
}
here is the player class
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.Timer;
import java.util.TimerTask;
public class Player{
private String player = "player.jpg";
private int moveX;
private int moveY;
private int x;
private int y;
private Image image;
private boolean canFall = false;
//private Timer jumpTimer = new Timer();
boolean canJump = true;
public Player() {
ImageIcon playeriImage = new ImageIcon(this.getClass().getResource(player));
image = playeriImage.getImage();
x = 40;
y = 60;
}
public void checkFall() {
if(canFall) {
moveY = -4;
}
}
public void move() {
//checkFall();
x = moveX + x;
y = moveY + y;
}
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_A) {
moveX = -4;
}
if (key == KeyEvent.VK_D) {
moveX = 4;
}
if (key == KeyEvent.VK_W) {
if(canJump)
this.jump();
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
moveX = 0;
}
if (key == KeyEvent.VK_D) {
moveX = 0;
}
}
here is the exe class
import javax.swing.JFrame;
public class Exe extends JFrame {
public Exe() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
setTitle("TSA Video Game");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new Exe();
}
}
thanks in advance
KeyListener will only respond to key events IF the component is focusable AND has focus.
It would be better to use the Key Bindings API which will allow you to overcome this limitation (if you want to)
I would also recommend that you override paintComponent instead of paint. You should also not be calling Graphics#dispose, as you did not create the Graphics context, this could actually prevent anything from being painted on some systems
I would also suggest that a delay of 5 milliseconds (on your Timer) might be a little excessive (5 milliseconds = 200fps!).
A value of 16 (60fps) or 40 (25fps) may be more suitable and reduce the overhead on the system...IMHO