package testapplication;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class TestApplication extends JFrame implements Runnable {
int sizex = 800;
int sizey = 650;
int x, y, xDirection, yDirection;
private Image dbImage;
private Graphics dbg;
Image character;
#Override
public void run(){
try{
while(true){
move();
Thread.sleep(5);
}
}
catch(Exception e){
System.out.println("ERROR!!!");
}
}
public void move(){
x += xDirection;
y += yDirection;
if(x <= 0)
x = 0;
if(x >= 778)
x = 778;
if(y <= 22)
y = 22;
if(y >= 628)
y = 628;
}
public void setXDirection(int xdir){
xDirection = xdir;
}
public void setYDirection(int ydir){
yDirection = ydir;
}
Font font = new Font("Arial", Font.BOLD, 30);
public class AL extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
//Key press inputs "WASD"
if(keyCode == KeyEvent.VK_W) {
setYDirection(-1);
}
if(keyCode == KeyEvent.VK_A) {
setXDirection(-1);
}
if(keyCode == KeyEvent.VK_S) {
setYDirection(+1);
}
if(keyCode == KeyEvent.VK_D) {
setXDirection(+1);
}
//end Key press inputs "WASD"
}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
//Key release inputs "WASD"
if(keyCode == KeyEvent.VK_W) {
setYDirection(0);
}
if(keyCode == KeyEvent.VK_A) {
setXDirection(0);
}
if(keyCode == KeyEvent.VK_S) {
setYDirection(0);
}
if(keyCode == KeyEvent.VK_D) {
setXDirection(0);
}
//end Key release inputs "WASD"
}
}
public TestApplication() {
//Load images
ImageIcon i = new ImageIcon("C:/Users/Min/Documents/NetBeansProjects/TestApplication/src/testapplication/Untitled-1.png") {};
character = i.getImage();
//Game properties
addKeyListener(new AL());
setTitle("TestApplication");
setSize(sizex, sizey);
setResizable(false);
setVisible(true);
setBackground(Color.LIGHT_GRAY);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x = 30;
y = 628;
}
#Override
public void paint(Graphics g) {
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g) {
g.setFont(font);
g.setColor(Color.RED);
g.drawString("Welcome to TESTTEST", 300,125);
g.setColor(Color.RED);
g.drawImage(character, x, y, this);
repaint();
}
public static void main(String[] args) {
TestApplication ta = new TestApplication();
//Threads
Thread t1 = new Thread();
t1.start();
}
}
In my Java code, there is supposed to be an image that moves using the WASD keys. The image shows, yet it will not move. What's wrong?
This is a simple Java code that is supposed to make an image roam around the window with WASD keys. I am not sure what I did wrong in the code, I've double checked and everything looked fine...
First of all, if you need to change the image location while the user presses one of the wsda keys then you need to add 1 and -1 to the current value of x and y ( image location). You just set 1 and -1 which will move the image just one pixel even if, for example, you press the d button multiple times over and over.
You need to change method setXDirection to this (I have added a plus before the equal sign to add xDir value to whatever xDirection is.)
public void setXDirection(int xDir)
{
xDirection += xDir
}
Make the same correction with yDirection (yDirection += yDir)
Second, you don't call your paint method. You have to call it each time your user presses a key (one of wasd ofcourse), so do it at the final line of your keyReleased method.
I hope these two correct your code but I think you need to recheck the code again with much care.
Good luck,
Iman
You forgot to add the Runnable instance to the Thread constructor.
Your main method should be:
public static void main(String[] args) {
TestApplication ta = new TestApplication();
//Threads
Thread t1 = new Thread(ta);
t1.start();
}
Related
hi im trying to make a rectangle move up and down on key press in jframe.
but the rectangle only goes down when i press the up or down arrow key and it does not stop. and i cant see where i have made a mistake.
i don't think the mistake is in file one but as said, i cant find it so it maybe is.
file 1
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class test{
public static void main (String[] arg) {
JFrame window = new JFrame();
test2 t2 = new test2();
window.add(t2);
window.setSize(1000,1000);
window.setTitle("TEST");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
}
file 2
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class test2 extends JPanel implements ActionListener, KeyListener{
Timer t = new Timer(5, this);
double x = 0, y = 0, velx = 0, vely = 0;
public test2() {
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Rectangle((int)x, (int)y, 20, 40));
}
public void actionPerformed(ActionEvent e) {
repaint();
x += velx;
y += vely;
}
public void up() {
vely = -1.5;
velx = 0;
}
public void down() {
vely = 1.5;
velx = 0;
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP); {
up();
}
if (code == KeyEvent.VK_DOWN); {
down();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){}
}
Your logic is not very optimal. You should have your code more like this:
/** DELETE THIS METHOD!
public void actionPerformed(ActionEvent e) {
repaint();
x += velx;
y += vely;
}**/
private static final double MOVEMENT = 1.5;
public void up() {
x += -MOVEMENT; // Mind the - in front of MOVEMENT to negate the value.
// No need to change y if it does not change at all
repaint() // Repaint _after_ you changed the coordinates
}
public void down() {
x += MOVEMENT; // Mind that there is no - infront of this MOVEMENT.
// No need to change y if it does not change at all
repaint() // Repaint _after_ you changed the coordinates
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP); {
up();
}
if (code == KeyEvent.VK_DOWN); {
down();
}
}
You miss calling repaint() onYour JPanel after changing the position of x,y;
Also note that your events will only trigger twice (OnKeyDown and OnKeyUp).
Hey so I'm fairly new to java, but based on doing a lot of research and analyzing various code, I came up with some code to move a basic circle on a screen by using arrow keys.
However, for some reason, the code does not run the whole key event. If I press any key on the keyboard, even different arrow keys, it will cause the circle to only move one direction.
Based on my code, I feel like everything should work, but it just won't run the KeyEvent function properly. Any ways to fix it?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class second extends JPanel implements ActionListener, KeyListener
{
Timer t = new Timer(5, this);
int x = 0, y = 0, velx = 0, vely = 0;
public second()
{
t.start();
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void actionPerformed(ActionEvent e)
{
x += velx;
y += vely;
repaint();
}
public void up()
{
velx = 0;
vely = 2;
}
public void down()
{
velx = 0;
vely = -2;
}
public void left()
{
velx = -2;
vely = 0;
}
public void right()
{
velx = 2;
vely = 0;
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP);
{
up();
}
if (keyCode == KeyEvent.VK_DOWN);
{
down();
}
if (keyCode == KeyEvent.VK_LEFT);
{
left();
}
if (keyCode == KeyEvent.VK_RIGHT);
{
right();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
velx = 0;
vely = 0;
}
public static void main(String args[])
{
second s = new second();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
}
}
First of all, ActionListener is not required in this case. KeyListener is sufficient. Also there is a semicolon beside if statements, this is causing all the functions up, down, left and right to be invoked negating the effect.
Also for up, y should be reduced and for down, y should be increased.
Please find the below code which works fine. You can limit the right and down movement with MAX_LIMIT based on the window size. I limited it for 0,0 for left and up movement.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class Second extends JPanel implements KeyListener
{
int x = 0, y = 0;
public Second()
{
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void up()
{
if(y >= 5) {
y -= 5;
repaint();
}
}
public void down()
{
y += 5;
repaint();
}
public void left()
{
if(x >= 5) {
x -= 5;
repaint();
}
}
public void right()
{
x += 5;
repaint();
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP)
{
up();
}
if (keyCode == KeyEvent.VK_DOWN)
{
down();
}
if (keyCode == KeyEvent.VK_LEFT)
{
left();
}
if (keyCode == KeyEvent.VK_RIGHT)
{
right();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public static void main(String args[])
{
Second s = new Second();
JFrame f = new JFrame();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
}
}
First, you have a semi-colon following your first if statement in keyPressed(), which impeaches considering following instructions. cf :
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP)
up();
if (keyCode == KeyEvent.VK_DOWN)
down();
if (keyCode == KeyEvent.VK_LEFT)
left();
if (keyCode == KeyEvent.VK_RIGHT)
right();
}
You also have a negative value for vely in down() where it should be positive (and vice-versa). And since you already reset velx and vely to 0 on keyReleased(), it is unnecessary to do it in your directions functions.
public void up() {
vely = -2;
}
public void down() {
vely = 2;
}
Class names should be CamelCase (not lowercase as presented).
Have fun.
I am making a game and the game window will only open to the size of the title. Please let me know what changes I need to make the "b.setSize(900,885)" work. I will change or add any amount of code if needed.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class Background extends JFrame implements KeyListener, ActionListener{
int platform1X = 300, platform1Y = 555, platform2X, platform2Y;
Image image;
public boolean isJumping = false;
int playerx = 100, playery = 585, velX = 0, velY = 0;
public boolean[] keyDown = new boolean[4];
private int fallingSpeed = 0;
private int gravity = 5;
private int jumpPower = -30;
public Background(){
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
keyDown[0] = false;
keyDown[1] = false;
keyDown[2] = false;
keyDown[3] = false;
}
public void paint(Graphics g){
if(!isOnGround()){
fall();
}
ImageIcon i = new ImageIcon("/Users/kairotieremorton/Documents/java code/Kairo and Enoch Game/src/images/Backgroundsquareman.png");
image = i.getImage();
g.drawImage(image, 0, 0, 900, 700, null);
g.setColor(Color.BLUE);
g.fillRect(platform1X, platform1Y, 120, 20);
g.setColor(Color.RED);
g.fillRect(playerx, playery, 30, 30);
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
playery = playery + velY;
playerx = playerx + velX;
}
public static void main(String[] args){
Background b = new Background();
b.setTitle("Game");
b.setSize(900,885);
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.setVisible(true);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(isOnGround() && key == KeyEvent.VK_SPACE){
keyDown[0] = true;
jump();
}
//if(key == KeyEvent.VK_DOWN){ setvelY(5); keyDown[1] = true;}
if(key == KeyEvent.VK_LEFT) { setvelX(-5); keyDown[2] = true;}
if(key == KeyEvent.VK_RIGHT) { setvelX(5); keyDown[3] = true;}
System.out.println(key);
System.out.println(playerx);
System.out.println(playery);
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_SPACE){ keyDown[0] = false;} //tempObject.setVelY(0);
//if(key == KeyEvent.VK_DOWN) keyDown[1] = false;//tempObject.setVelY(0);
if(key == KeyEvent.VK_LEFT) keyDown[2] = false;//tempObject.setVelX(0);
if(key == KeyEvent.VK_RIGHT) keyDown[3] = false; //tempObject.setVelX(0);
//vertical movement
if(!keyDown[0]) setvelY(0); System.out.println(isOnGround());
//horizontal movement
if(!keyDown[2] && !keyDown[3]) setvelX(0);
}
public void keyTyped(KeyEvent e) {}
public void actionPerformed(ActionEvent e) {
//playery = playery + velY;
//playerx = playerx + velX;
//repaint();
}
public boolean isOnGround(){
if(playery + (30 /2) >= 585) {
return true;
}
return false;
}
public void fall(){
playery = playery + fallingSpeed;
fallingSpeed = fallingSpeed + gravity;
}
public void jump(){
fallingSpeed = jumpPower;
fall();
}
public void setvelX(int velX) {
this.velX = velX;
}
public void setvelY(int velY) {
this.velY = velY;
}
public float getvelX(){
return velX;
}
public float getvelY(){
return velY;
}
public int getplayerx(){
return playerx;
}
public int getplayery(){
return playery;
}
public void setplayerx(int playerx) {
this.playerx = playerx;
}
public void setplayery(int playery) {
this.playery = playery;
}
public Rectangle getBounds(){
return new Rectangle(getplatform1X(), platform1Y(), 120, 20);
}
public int getplatform1X(){
return platform1X;
}
public int platform1Y(){
return platform1Y;
}
public Rectangle getBoundsTop(){
return new Rectangle(getplayerx() + 10, getplayery(), 30 - 20, 5);
}
public Rectangle getBoundsBottom(){
return new Rectangle(getplayerx() + 10, getplayery() + 30 - 5, 30 - 20, 5);
}
public Rectangle getBoundsLeft(){
return new Rectangle(getplayerx(), getplayery()+10, 5, 30 -20);
}
public Rectangle getBoundsRigth(){
return new Rectangle(getplayerx() + 30 - 5, getplayery()+10, 5, 30 - 20);
}
}
Okay, that took a lot of looking, but...
public Rectangle getBounds() {
return new Rectangle(getplatform1X(), platform1Y(), 120, 20);
}
is your problem. JFrame#getBounds is a method used by JFrame to return the position and the size of the component and since you've overridden it, it will now ignore any values you pass to setSize (directly or indirectly)
Have a read of the following for reasons why you shouldn't override paint of top level containers like JFrame
How can I set in the midst?
Graphics rendering in title bar
Java JFrame .setSize(x, y) not working?
How to get the EXACT middle of a screen, even when re-sized
As a general rule of thumb, you should avoid extending from JFrame, as you're not really adding any new functionality to the class, it locks you into a single use case and, based on your experience, can cause other problems.
You should start with something like JPanel and override its paintComponent method instead (and make sure you call super.paintComponent before you do any custom painting)
Take a look at Painting in AWT and Swing and Performing Custom Painting
You paint methods should run as fast as possible, so you should avoid loading resources like loading images, within the paint method
Swing is single threaded, so calling Thread.sleep in the paint method will cause the entire program to stop, including it's ability to respond to new events from the user.
I'd also discourage you from using KeyListener, using the key bindings API will be more reliable. Take a look at How to Use Key Bindings for more details
Edit:
A better way to achieve the same result is to call b.setPreferredSize(dimension); and then pack() your frame.
See this answer for more information about JFrame.pack() :
https://stackoverflow.com/a/22982334/5224040
Try this in your main method:
public static void main(String[] args) {
Background b = new Background();
Dimension d = new Dimension(900, 885); //Create a new Dimension
b.setTitle("Game");
b.setPreferredSize(d); //Set the PreferredSize;
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.pack(); //Pack the frame
b.setVisible(true); //Setting Visible
}
You can also use the following methods to reposition your frame as necessary:
b.setLocationRelativeTo(null); //center the location on the screen.
b.setLocation(0, 0); //Set location explicitly
Call either of these methods below b.pack(); to reposition your frame.
I created an oval which shoots a bullet(rectangle) that if it hits the red rectangle, the collision would detect the bullet hitting the rectangle. However, when I run my program, the collision has already been done and I haven't even pressed the space bar yet to shoot. What I wanted to happen is that, when I shoot and if the bullet hits the rectangle, that's when it detects the collision. I tried to analyze it and do something but I just couldn't get it. here is my source code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JavaGame2 extends JPanel implements KeyListener,Runnable{
//variables
JFrame frame;
int x, y, xDir, yDir,bx,by;
Rectangle bullet;
boolean readyTofire, shot = false;
//constructor for game
public JavaGame2(){
frame = new JFrame("Java Game");
int x=150;
int y=150;
}
//drawings
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.WHITE);
Rectangle rec = new Rectangle(50, 20, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(x, y, 55, 55);
g.fillRect(x+23, y-15, 10, 20);
g.setColor(Color.RED);
g.fillRect(rec.x, rec.y, rec.width, rec.height);
bullet = new Rectangle(bx, by, 5, 3);
if(shot){
g.setColor(Color.BLACK);
g.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
}
if(bullet.intersects(rec));
g.drawString("collision!", 50, 20);
repaint();
}
public void setxDir(int xdir){
xDir = xdir;
}
public void setyDir(int ydir){
yDir = ydir;
}
//key event listener keypressed
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_UP){
setyDir(-1);
}
if(code == KeyEvent.VK_DOWN){
setyDir(+1);
}
if(code == KeyEvent.VK_LEFT){
setxDir(-1);
}
if(code == KeyEvent.VK_RIGHT){
setxDir(+1);
}
if(code == KeyEvent.VK_SPACE){
if(bullet == null ){
readyTofire = true;
if(readyTofire){
bx = x+26;
by = y-15;
bullet = new Rectangle(bx, by, 5, 3);
shot = true;
}
}
}
}
//key event listener for key released
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_UP){
setyDir(0);
}
if(code == KeyEvent.VK_DOWN){
setyDir(0);
}
if(code == KeyEvent.VK_LEFT){
setxDir(0);
}
if(code == KeyEvent.VK_RIGHT){
setxDir(0);
}
if(code == KeyEvent.VK_SPACE){
readyTofire = false;
if(bullet.y <= -5){
bullet = new Rectangle(0, 0, 0, 0);
shot = false;
readyTofire = true;
}
}
}
public void keyTyped(KeyEvent e) {
}
//shot of bullet
public void shoot(){
if(shot){
bullet.y--;
}
}
//movement of the oval
public void move(){
x += xDir;
y += yDir;
if(x <= 0){
x = 0;
}
else if(x >= 500){
x = 500;
}
else if(y <= 0){
y = 0;
}
else if(y >= 500){
y = 500;
}
}
//thread
public void run() {
try{
while(true){
shoot();
move();
Thread.sleep(5);
}
}
catch(Exception e){
System.out.println("error!");
}
}
}
Take a moment to have a look at you collision detection statement...
if (bullet.intersects(rec));
g.drawString("collision!", 50, 20);
The problem is, you've ended your if statement with a ;
if (bullet.intersects(rec));
^---
This means that the statement is effectively ignored, it would be the same as...
if (bullet.intersects(rec)) {
}
g.drawString("collision!", 50, 20);
Which would have alerted you to the problem in the first place
Instead, try using
if (bullet.intersects(rec)) {
g.drawString("collision!", 50, 20);
}
Now, don't call repaint or any method that might call repaint (like setBackground) from any paint method. This will set up a cycle of repeated paint events that will eventually consume your CPU.
I don't think you really need 200fps and Thread.sleep of roughly 40 would give you 25fps and would typically be more then adequate for your purposes.
You should also consider using key bindings, which will allow you to over come the focus related issues of KeyListener.
I'd also encourage you to explore the use of a Swing Timer which will reduce the possibility of un-synchorised updates between the model and the view, which could cause random and difficult to solve artificates or other issues...
Shooting Problems
There's a bunch of logic issues and mis-use of variables...
To start with...
Remove bx and by, you don't need them. You actually don't really need x and y either, but that might be come a little more apparent as we go...
Don't create bullet in paintComponent, this is causing some confusion...
You may not need the keyReleased check of VK_SPACE but if you did, you should set shot to false and bullet to null...
Setting readyToFire to true right before you check to see if it's true seems weird...however, when you detect a VK_SPACE in keyPressed check to see if bullet is null or not, if it's not, then a bullet already exist, don't know if this is an issue, but if you were to use a List, you could have multiple bullets firing at the same time...any way, create a new Rectangle and assign to to bullet
if (code == KeyEvent.VK_SPACE) {
readyTofire = true;
if (readyTofire) {
int bx = x + 26;
int by = y - 15;
bullet = new Rectangle(bx, by, 5, 3);
shot = true;
}
}
In you shoot method, do forget to do a bounds check...
public void shoot() {
if (shot) {
bullet.y--;
// Have we past the edge of the screen
if (bullet.y < 0) {
shot = false;
bullet = null;
}
}
}
And finally, paint it all...Here you should be taking advantage of the 2D Graphics API
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Rectangle rec = new Rectangle(50, 20, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(x, y, 55, 55);
g.fillRect(x + 23, y - 15, 10, 20);
g.setColor(Color.RED);
g.fillRect(rec.x, rec.y, rec.width, rec.height);
if (shot && bullet != null) {
g2d.setColor(Color.BLACK);
g2d.fill(bullet);
if (bullet.intersects(rec)) {
g2d.drawString("collision!", 50, 20);
}
}
g2d.dispose();
}
And in case I missed anything, here's you the code I tested with...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JavaGame2 extends JPanel implements KeyListener, Runnable {
//variables
int x, y, xDir, yDir;
Rectangle bullet;
boolean readyTofire, shot = false;
public static void main(String[] args) {
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.add(new JavaGame2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
//constructor for game
public JavaGame2() {
int x = 150;
int y = 150;
this.setBackground(Color.WHITE);
setFocusable(true);
addKeyListener(this);
requestFocusInWindow();
Thread t = new Thread(this);
t.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
//drawings
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Rectangle rec = new Rectangle(50, 20, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(x, y, 55, 55);
g.fillRect(x + 23, y - 15, 10, 20);
g.setColor(Color.RED);
g.fillRect(rec.x, rec.y, rec.width, rec.height);
if (shot && bullet != null) {
g2d.setColor(Color.BLACK);
g2d.fill(bullet);
if (bullet.intersects(rec)) {
g2d.drawString("collision!", 50, 20);
}
}
g2d.dispose();
}
public void setxDir(int xdir) {
xDir = xdir;
}
public void setyDir(int ydir) {
yDir = ydir;
}
//key event listener keypressed
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
setyDir(-1);
}
if (code == KeyEvent.VK_DOWN) {
setyDir(+1);
}
if (code == KeyEvent.VK_LEFT) {
setxDir(-1);
}
if (code == KeyEvent.VK_RIGHT) {
setxDir(+1);
}
if (code == KeyEvent.VK_SPACE) {
readyTofire = true;
if (readyTofire) {
int bx = x + 26;
int by = y - 15;
bullet = new Rectangle(bx, by, 5, 3);
shot = true;
}
}
}
//key event listener for key released
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
setyDir(0);
}
if (code == KeyEvent.VK_DOWN) {
setyDir(0);
}
if (code == KeyEvent.VK_LEFT) {
setxDir(0);
}
if (code == KeyEvent.VK_RIGHT) {
setxDir(0);
}
// if (code == KeyEvent.VK_SPACE) {
// readyTofire = false;
// if (bullet.y <= -5) {
// bullet = new Rectangle(0, 0, 0, 0);
// shot = false;
// readyTofire = true;
//
// }
// }
}
public void keyTyped(KeyEvent e) {
}
//shot of bullet
public void shoot() {
if (shot) {
bullet.y--;
if (bullet.y < 0) {
shot = false;
bullet = null;
}
}
}
//movement of the oval
public void move() {
x += xDir;
y += yDir;
if (x <= 0) {
x = 0;
} else if (x >= 500) {
x = 500;
} else if (y <= 0) {
y = 0;
} else if (y >= 500) {
y = 500;
}
}
//thread
public void run() {
try {
while (true) {
shoot();
move();
repaint();
Thread.sleep(40);
}
} catch (Exception e) {
System.out.println("error!");
}
}
}
No offense, but you approach is a little primitive. Instead of containing the entire game model within the same class that is trying to display it, you should separate your game "logic" into a model and update the model state and then simply have your view paint the model...IMHO
so i using netbeans, and i'm starting to get into coding games... and i've done this so far with no errors, however when i run it just a grey box with my title "zachs game appears and thats it.... please help if you know the problem 1 -thank you
package swing9;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class JavaApplication2 extends JFrame implements Runnable {
int x, y, xDirection, yDirection;
Font font = new Font("Arial", Font.BOLD | Font.ITALIC, 30);
public void run() {
try {
while (true) {
move();
Thread.sleep(5);
}
} catch (Exception e) {
System.out.println("Error");
}
}
public void move() {
x += xDirection;
y += yDirection;
if (x <= 0)
x = 0;
if (x >= 300)
x = 300;
if (y <= 50)
y = 50;
if (y <= 300)
y = 300;
}
public void seyXDir(int xdir) {
xDirection = xdir;
}
public void setYDirection(int ydir) {
yDirection = ydir;
}
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
int setXDirection = -1;
}
if (keyCode == e.VK_RIGHT) {
int setXDirection = +1;
}
if (keyCode == e.VK_UP) {
int setYDirection = -1;
}
if (keyCode == e.VK_DOWN) {
int setYDirection = +1;
}
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
int setXDirection = 0;
}
if (keyCode == e.VK_RIGHT) {
int setXDirecetion = 0;
}
if (keyCode == e.VK_UP) {
int setYDirectiom = 0;
}
if (keyCode == e.VK_DOWN) {
int setYDirecction = 0;
}
}
public JavaApplication2() {
addKeyListener((KeyListener) new JavaApplication2.AL());
setTitle("Zachs Game");
setSize(300, 300);
setResizable(false);
setVisible(true);
setBackground(Color.blue);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x = 150;
y = 150;
}
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.drawString("Play", 40, 40);
g.setFont(font);
g.setColor(Color.red);
g.fillOval(x, y, 15, 15);
repaint();
}
public static void main(String[] args) {
new JavaApplication2();
// threads
Thread t1 = new Thread();
t1.start();
}
}
JFrame or any of its super classes do not implement the paintComponent method so is never invoked. Check this yourself by adding the #Override annotation.
Move this method to a new class that extends JComponent and invoke super.paintComponent(g) as the first statement.
Don't call repaint from within paintComponent, this create an infinite loop and degrades performance. Swing Timers were designed to interact more easily with swing components. Use these over than raw Threads for periodic updates.
Aside: JFrame is not focusable by default so KeyEvents which require focus will not be triggered without making the window focusable. Use Key Bindings instead.