Java Game: Shooting Bullets - java

I am (kind of) new to creating games with Java. I created some simple games before like a bag collecting game but now I want to make a top-down zombie shooting game. I already have a player that can move, but now I want to implement shooting. The problem is that I am not sure how to make a new bullet that shoots from the player to the right / up / down /left to the end of the screen depending on what part of the screen the player is facing.
I have pasted all my of code below (4 classes):
package me.mateo226.main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import me.mateo226.entities.Player;
import me.mateo226.guns.Bullet;
public class GamePanel extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
private static final int PWIDTH = 720;
private static final int PHEIGHT = 480;
private static Thread game;
private static volatile boolean running = false;
public static volatile boolean gameOver = false;
public static volatile boolean paused = false;
public static Graphics g;
public static Image gImage;
public static long lastLoopTime = System.currentTimeMillis();
public static long delta;
public static volatile boolean upPressed = false;
public static volatile boolean downPressed = false;
public static volatile boolean leftPressed = false;
public static volatile boolean rightPressed = false;
public BufferedImage backgroundImage;
public Player player;
Bullet bullet;
public GamePanel() {
setPreferredSize(new Dimension(PWIDTH, PHEIGHT));
setBackground(Color.white);
setFocusable(true);
requestFocus();
waitForTermination();
}
public void addNotify() {
super.addNotify();
startGame();
}
public void waitForTermination() {
addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_ESCAPE) {
GamePanel.stopGame();
}
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
upPressed = true;
}
if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
downPressed = true;
}
if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
leftPressed = true;
}
if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
rightPressed = true;
}
if (keyCode == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
upPressed = false;
}
if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
downPressed = false;
}
if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
leftPressed = false;
}
if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
rightPressed = false;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
});
}
#Override
public void run() {
running = true;
while (running) {
delta = System.currentTimeMillis() - lastLoopTime;
lastLoopTime = System.currentTimeMillis();
gameUpdate();
gameRender();
checkMovement();
paintpauseScreen();
try {
Thread.sleep(5);
} catch (Exception e) {
System.out.println("The thread couldn't sleep! Error info: "
+ e);
}
}
System.exit(0);
}
private void checkMovement() {
if (!paused && !gameOver) {
}
}
private void paintpauseScreen() {
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (gImage != null))
g.drawImage(gImage, 0, 0, null);
g.dispose();
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
private void gameRender() {
if (gImage == null) {
gImage = createImage(PWIDTH, PHEIGHT);
if (gImage == null) {
System.out
.println("image null after creating it??? Please check the code for any errors!");
} else {
g = gImage.getGraphics();
}
}
if (!paused) {
g.setColor(Color.white);
g.fillRect(0, 0, PWIDTH, PHEIGHT);
g.setColor(Color.blue);
}
try {
backgroundImage = ImageIO.read(new File("res\\background.png"));
} catch (IOException e) {
e.printStackTrace();
}
g.drawImage(backgroundImage, 0, 0, Color.white, null);
if (player != null) {
player.drawPlayer(g);
}
if (bullet != null) {
bullet.drawBullet(g);
}
}
private void gameUpdate() {
if (!paused && !gameOver) {
movePlayer();
if (bullet != null){
bullet.shootBullet(g, "right");
}
}
}
public void startGame() {
if (game == null) {
game = new Thread(this);
if (game == null) {
System.out.println("Couldn't create the thread!");
} else {
System.out.println("Thread created!");
game.start();
}
}
if (g == null) {
g = this.getGraphics();
if (g == null) {
System.out.println("The graphics were not created!");
} else {
System.out.println("The graphics are successfully created!");
}
}
player = new Player(32, 32, "res\\player.png");
bullet = new Bullet("res\\grassTile.png", "right", player.x + 32,
player.y);
running = true;
}
public void movePlayer() {
if (upPressed) {
player.y -= player.moveSpeed * delta;
}
if (downPressed) {
player.y += player.moveSpeed * delta;
}
if (leftPressed) {
player.x -= player.moveSpeed * delta;
}
if (rightPressed) {
player.x += player.moveSpeed * delta;
}
}
public static void stopGame() {
running = false;
}
}
This was my GamePanel class.
This is my Main class:
package me.mateo226.main;
import java.awt.Container;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Main extends JFrame implements WindowListener {
private static final long serialVersionUID = 1L;
private static GamePanel panel;
public static boolean DEBUGGING = false;
public Main(){
super("The Gun Reactor");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(this);
Container c = getContentPane();
panel = new GamePanel();
c.add(panel, "Center");
setResizable(false);
pack();
setLocationRelativeTo(null);
if(JOptionPane.showConfirmDialog(null, "Enable debugging?") == 1){
DEBUGGING = true;
} else {
DEBUGGING = false;
}
setVisible(true);
}
#Override
public void windowActivated(WindowEvent arg0) {
}
#Override
public void windowClosed(WindowEvent arg0) {
}
#Override
public void windowClosing(WindowEvent arg0) {
}
#Override
public void windowDeactivated(WindowEvent arg0) {
}
#Override
public void windowDeiconified(WindowEvent arg0) {
}
#Override
public void windowIconified(WindowEvent arg0) {
}
#Override
public void windowOpened(WindowEvent arg0) {
}
public static void main(String args[]){
new Main();
}
}
This is my Player class:
package me.mateo226.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Player {
public int x, y;
public float moveSpeed = 0.1f;
private BufferedImage playerTexture;;
public Player(int x, int y, String texturePath){
this.x = x;
this.y = y;
try {
playerTexture = ImageIO.read(new File(texturePath));
} catch (IOException e){
e.printStackTrace();
}
}
public void drawPlayer(Graphics g){
g.setColor(Color.white);
g.drawImage(playerTexture, x, y, null);
}
}
And finally this is my bullet class which I don't really know how to use or even make it properly:
package me.mateo226.guns;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import me.mateo226.main.GamePanel;
public class Bullet {
private int x, y;
private BufferedImage bulletTexture;
private float bulletSpeed = 0.1f;
public Bullet(String bulletTexturePath, String dir, int x, int y) {
this.x = x;
this.y = y;
try {
bulletTexture = ImageIO.read(new File(bulletTexturePath));
} catch (IOException e) {
e.printStackTrace();
}
}
public void drawBullet(Graphics g) {
g.setColor(Color.white);
g.drawImage(bulletTexture, x, y, null);
}
public void shootBullet(Graphics g, String dir) {
switch (dir) {
case "left":
while (x > -32) {
x -= bulletSpeed * GamePanel.delta;
drawBullet(g);
}
break;
case "right":
while (x < 700) {
x += bulletSpeed * GamePanel.delta;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case "up":
while (y > -32) {
y -= bulletSpeed * GamePanel.delta;
drawBullet(g);
}
break;
case "down":
while (y < 480) {
y += bulletSpeed * GamePanel.delta;
drawBullet(g);
}
break;
}
}
}
Any help would be great! Thank you very much!

EDIT
I just read that you only have four directions. In that case you do not need a direction vector. Just set the direction once.
Ok so the code example.
First the gameloop. Add the firedBullets for update in the gameloop. Every fired bullet gets moved on its direction vector.
private void gameUpdate() {
if (!paused && !gameOver) {
movePlayer();
foreach(Bullet bullet : player.getFiredBullets(){
bullet.moveInDirection();
}
}
}
And your Bullet class:
public class Bullet {
private Direction direction;
private float speed = 1.2f;
private int x;
private int y;
public Bullet(int x, int y){
this.x =x;
this.y=y;
}
public void launchBullet(Direction direction){
this.direction=direction;
}
public void moveInDirection() {
//move the bullet with speed in the set direction. Same as you already have but without the while loop.
}
}
So the player should have a method fire.
This creates the bullet with position of the player. The bullet gets the same direction as where the player is facing. And the bullet get added to the list so it will be updated every gameloop.
public class Player {
private List<Bullet> firedBullets = new ArrayList<Bullet>();
public void fire(){
Bullet bullet = new Bullet(playerX, playerY);
firedbullets.add(bullet);
bullet.launch(direction); //this should be calculated by which direction the player is facing.
}
}
So the direction gets set once when the bullet is fired. Every game update the bullet is moved in this direction by the speed of the bullet. This logic can be used for everything that has to be moved in the game. For example if you want a bullet that changes direction in mid-air you would just change its direction in mid-air.

Related

KeyListener doesn't move "FillRect" on JPanel

I used the KeyListener interface on the KeyBoardInput class as given below :-
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyBoardInput implements KeyListener {
public boolean WPressed, APressed, DPressed, SPressed;
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int pressedKeyNum = e.getKeyCode();
if(pressedKeyNum == KeyEvent.VK_W) {
WPressed = true;
}
if(pressedKeyNum == KeyEvent.VK_A) {
APressed = true;
}
if(pressedKeyNum == KeyEvent.VK_S) {
SPressed = true;
}
if(pressedKeyNum == KeyEvent.VK_D) {
DPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int pressedKeyNum = e.getKeyCode();
if(pressedKeyNum == KeyEvent.VK_W) {
WPressed = false;
}
if(pressedKeyNum == KeyEvent.VK_A) {
APressed = false;
}
if(pressedKeyNum == KeyEvent.VK_S) {
SPressed = false;
}
if(pressedKeyNum == KeyEvent.VK_D) {
DPressed = false;
}
}
}
but when I try to use it in a game loop, that is in the display class it doesn't work(I haven't included the whole display class to make my question shorter)
Here's the game loop :-
Thread t;
int playerX = 100;
int playerSpeed = 4;
int playerY = 100;
public void startThread() {
t = new Thread(this);
t.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.RED);
g2.fillRect(playerX,playerY,tileSide = tileSide*3,tileSide);
g2.dispose();
}
public void update() {
if(kb.WPressed == true) {
playerY -= playerSpeed;
}
else if(kb.APressed == true) {
playerX -= playerSpeed;
}
else if(kb.SPressed == true) {
playerY += playerSpeed;
}
else if(kb.DPressed == true) {
playerX += playerSpeed;
}
}
double drawInterval = 1000000000/FPS;
double nextDrawTime = System.nanoTime() + drawInterval;
public void run() {
while(t != null) {
update();
repaint();
}
}
I can't define the problem really well, all I can say is I don't get a error, it draws the red rectangle, but the rectangle doesn't move.
classes :-
Start.java
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import LCStudios.WhiteSouls.display.DisplayFrame;
public class Start {
public static void main(String [] args) {
final int tileSide, tileArea, scale, finalTileSize, WindowX, WindowY;
JFrame f = new JFrame();
tileSide = 16;
tileArea = tileSide * tileSide;
scale = 3;
finalTileSize = tileSide * 3;
WindowX = finalTileSize * 20;
WindowY = finalTileSize * 12;
System.out.println(WindowX + " :: " + WindowY);
f.setSize(WindowX,WindowY);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setTitle("WhiteSouls :: From LiveCrystal Studios");
f.setLocationRelativeTo(null);
f.setIconImage(new ImageIcon("C:\\Users\\Admin\\Documents\\Code\\LC_lib\\WhiteSouls\\WhiteSouls 64x.png").getImage());
f.add(new DisplayFrame());
f.setResizable(false);
f.setVisible(true);
}
}
DisplayFrame.java
package LCStudios.WhiteSouls.display;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import LCStudios.WhiteSouls.background.KeyBoardInput;
public class DisplayFrame extends JPanel implements Runnable{
int tileSide = 16;
int tileArea = tileSide * tileSide;
int scale = 3;
int finalTileSize = tileSide * scale;
Thread t;
public boolean running;
int playerX = 100;
int playerSpeed = 4;
int playerY = 100;
int FPS = 60;
KeyBoardInput kb = new KeyBoardInput();
public DisplayFrame() {
this.setPreferredSize(new Dimension(960,576));
this.setBackground(Color.BLACK);
this.setDoubleBuffered(true);
this.addKeyListener(kb);
this.setFocusable(true);
}
public void startThread() {
t = new Thread(this);
t.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.RED);
g2.fillRect(playerX,playerY,tileSide = tileSide*3,tileSide);
g2.dispose();
}
public void update() {
if(kb.WPressed == true) {
playerY -= playerSpeed;
}
else if(kb.APressed == true) {
playerX -= playerSpeed;
}
else if(kb.SPressed == true) {
playerY += playerSpeed;
}
else if(kb.DPressed == true) {
playerX += playerSpeed;
}
}
double drawInterval = 1000000000/FPS;
double nextDrawTime = System.nanoTime() + drawInterval;
public void run() {
while(t != null) {
update();
repaint();
}
}
}
KeyBoardInput.java
package LCStudios.WhiteSouls.background;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyBoardInput implements KeyListener {
public volatile boolean WPressed, APressed, DPressed, SPressed;
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int pressedKeyNum = e.getKeyCode();
if(pressedKeyNum == KeyEvent.VK_W) {
WPressed = true;
}
if(pressedKeyNum == KeyEvent.VK_A) {
APressed = true;
}
if(pressedKeyNum == KeyEvent.VK_S) {
SPressed = true;
}
if(pressedKeyNum == KeyEvent.VK_D) {
DPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int pressedKeyNum = e.getKeyCode();
if(pressedKeyNum == KeyEvent.VK_W) {
WPressed = false;
}
if(pressedKeyNum == KeyEvent.VK_A) {
APressed = false;
}
if(pressedKeyNum == KeyEvent.VK_S) {
SPressed = false;
}
if(pressedKeyNum == KeyEvent.VK_D) {
DPressed = false;
}
}
}
I noticed 3 problems in your code.
The boolean variables in KeyBoardInput class is used in 2 different threads.
The run() method in DisplayFrame never gets executed.
The run() method calls update() and repaint() without pausing. This will consume a large portion of your CPU usage.
The boolean variables are being changed at a keypress event. This means that the EDT(Event Dispatching Thread) is modifying the boolean variables in the KeyBoardInput class. However, the boolean variables are being read in Thread t (which is declared in DisplayFrame.) Since one thread is only modifying the variable and the other thread is only reading it, this can simply be resolved by using the volatile keyword.
public volatile boolean WPressed, APressed, DPressed, SPressed;
The constructor of DisplayFrame needs to call startThread() in order for your thread to start running. To do this, simply add this.startThread() in the DisplayFrame constructor.
public DisplayFrame() {
this.setPreferredSize(new Dimension(960,576));
this.setBackground(Color.BLACK);
this.setDoubleBuffered(true);
this.addKeyListener(kb);
this.setFocusable(true);
this.startThread();
}
Finally, the run() method in DisplayFrame should sleep for a bit. Otherwise, the thread will constantly be active, and it will result in heavy CPU usage. To resolve this, simply call Thread.sleep() in the while loop. (This will make the thread sleep for a bit. If you change the argument to a smaller value, the square will move at a faster rate.)
public void run() {
while(t != null) {
update();
try {Thread.sleep(50);}
catch (Exception e) {}
repaint();
}
}
One last thing that I want to point out is the code in DisplayFrame.paintComponent(Graphics g)
g2.fillRect(playerX,playerY,tileSide = tileSide*3,tileSide);
I'm not sure what this code is meant to do, but I think it should be changed to this:
g2.fillRect(playerX,playerY,tileSide*3,tileSide*3);
I applied these changes, and the square moves properly at each keypress.

Java Draw not moving snake

I am trying to create a snake clone just as a practice. ive drawn the snake and added the movement patterns but the snake eats on it self when I press any key to move. but its not moving. the array retracts the reactacles on the starting point and does nothing.
here is my snake class I have removed my comments as they where more than the code and the posting system was not allowing me to post
Edit
If you need anything from the other classes please let me know. but I think my error is somewhere in here
EDIT 2
Added the entire code, you can just copy paste in inside a new project and you will reproduce my error.
public class Snake {
List<Point> sPoints;
int xDir,yDir;
boolean isMoving,addTail;
final int sSize = 20, startX = 150 , startY = 150;
public Snake(){
sPoints = new ArrayList<Point>();
xDir = 0;
yDir = 0;
isMoving = false;
addTail = false;
sPoints.add(new Point(startX,startY));
for(int i=1; i<sSize; i++) {
sPoints.add(new Point(startX - i * 4,startY));
}
}
public void draw(Graphics g){
g.setColor(Color.white);
for(Point p : sPoints) {
g.fillRect(p.getX(),p.getY(),4,4);
}
}
public void move(){
if (isMoving) {
Point temp = sPoints.get(0);
Point last = sPoints.get(sPoints.size() - 1);
Point newstart = new Point(temp.getX() + xDir * 4, temp.getY() + yDir * 4);
for (int i = sPoints.size() - 1; i >= 1; i--) {
sPoints.set(i, sPoints.get(i - 1));
}
sPoints.set(0, newstart);
}
}
public int getxDir() {
return xDir;
}
public void setxDir(int x) {
this.xDir = xDir;
}
public int getyDir() {
return yDir;
}
public void setyDir(int y) {
this.yDir = yDir;
}
public int getX(){
return sPoints.get(0).getX();
}
public int getY(){
return sPoints.get(0).getY();
}
public boolean isMoving() {
return isMoving;
}
public void setIsMoving(boolean b) {
isMoving = b;
}
}
The following is the point class. just some getters setters for the points ,for those i used the IntelliJ to auto generate them.. (again i removed comments )
public class Point {
private int x,y;
public Point() {
x = 0;
y = 0;
}
public Point(int x, int y) {
this.x =x;
this.y =y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
and finally my main class called game.
in here what I do is create my applet give it background color. create my threat for the runnable. and also add the movement patterns for up/right/down/left...
and use several classes to update my drawing patterns so it can simulate movement by updating each of state of my rect list.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Game extends Applet implements Runnable, KeyListener {
//setting up double buffering.
Graphics graphics;
Image img;
Thread thread;
Snake snake;
public void init() {
//setting the size of our Applet
this.resize(400,400);
//we gonna create the image just the same size as our applet.
img = createImage(400,400);
//this represents our offscreen image that we will draw
graphics = img.getGraphics();
this.addKeyListener(this);
snake = new Snake();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
//Setting the background of our applet to black
graphics.setColor(Color.black);
//Fill rectangle 0 , 0 (starts from) for top left corner and then 400,400 to fill our entire background to black
graphics.fillRect(0,0,400,400);
snake.draw(graphics);
//painting the entire image
g.drawImage(img,0,0,null);
}
//Update will call on Paint(g)
public void update(Graphics g){
paint(g);
}
//Repaint will call on Paint(g)
public void repaint(Graphics g){
paint(g);
}
public void run() {
//infinite loop
for(;;) {
snake.move();
//drawing snake
this.repaint();
//Creating a time delay
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyTyped(KeyEvent keyEvent) {
}
public void keyPressed(KeyEvent keyEvent) {
if(!snake.isMoving()){ //this will allow the snake to start moving, but will disable LEFT for just the 1st move
if(keyEvent.getKeyCode() == KeyEvent.VK_UP || keyEvent.getKeyCode() == KeyEvent.VK_RIGHT ||
keyEvent.getKeyCode() == KeyEvent.VK_DOWN ) {
snake.setIsMoving(true);
}
}
//setting up Key mapping so when the user presses UP,RIGHT,DOWN,LEFT. the Snake will move accordingly
if(keyEvent.getKeyCode() == KeyEvent.VK_UP) {
if (snake.getyDir() != 1) {
snake.setyDir(-1);
snake.setxDir(0);
}
}
if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
if (snake.getxDir() != -1) {
snake.setxDir(1);
snake.setyDir(0);
}
}
if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
if (snake.getyDir() != -1) {
snake.setyDir(1);
snake.setxDir(0);
}
}
if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
if (snake.getxDir() != 1) {
snake.setxDir(-1);
snake.setyDir(0);
}
}
}
public void keyReleased(KeyEvent keyEvent) {
}
}
Here is some opinion I have reading your code.
The reason your snake won't move is because your snake.setyDir() and
snake.setxDir() didn't take the input to overwrite xDir and yDir. They are assigning to itself.
There is a Point2D class ready for you in JDK
When moving the snake, you just need to remove the tail and add one
more block before the head. You can keep the body tight (according
to my common knowledge to snake).
Consider a L shape snake on the left, the bottom end is the head and it is currently heading right. To move the snake, remove the tail (green block) and add one more to the head according to its direction (red block). It final state become the snake on the right. LinkedList suit the needs.
If using two int (xDir and yDir) to control the snake direction
is confusing, you can help your self by creating a enum. Those -1,
0, 1 with x and y may confuse you.
Declare constant instead of magic number. e.g. the width of block 4,
image size 400
Is Snake.addTail unnecessary?
Attribute should has accessibility modifier
End result:
Game.java
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;
public class Game extends Applet implements Runnable, KeyListener {
private final int GAMEBOARD_WIDTH = 400;
// setting up double buffering.
private Graphics graphics;
private Image img;
private Thread thread;
private Snake snake;
public void init() {
// setting the size of our Applet
this.resize(GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
// we gonna create the image just the same size as our applet.
img = createImage(GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
// this represents our offscreen image that we will draw
graphics = img.getGraphics();
this.addKeyListener(this);
snake = new Snake();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
// Setting the background of our applet to black
graphics.setColor(Color.BLACK);
// Fill rectangle 0 , 0 (starts from) for top left corner and then 400,400 to
// fill our entire background to black
graphics.fillRect(0, 0, GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
snake.draw(graphics);
// painting the entire image
g.drawImage(img, 0, 0, null);
}
// Update will call on Paint(g)
public void update(Graphics g) {
paint(g);
}
// Repaint will call on Paint(g)
public void repaint(Graphics g) {
paint(g);
}
public void run() {
// infinite loop
for (;;) {
snake.move();
// drawing snake
this.repaint();
// Creating a time delay
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyTyped(KeyEvent keyEvent) {
}
public void keyPressed(KeyEvent keyEvent) {
int keyCode = keyEvent.getKeyCode();
if (!snake.isMoving()) {
// this will allow the snake to start moving, but will disable LEFT for just the
// 1st move
if (matchKey(keyCode, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN)) {
snake.setIsMoving(true);
}
}
// setting up Key mapping so when the user presses UP,RIGHT,DOWN,LEFT. the Snake
// will move accordingly
if (matchKey(keyCode, KeyEvent.VK_UP)) {
snake.setDirection(Direction.UP);
}
if (matchKey(keyCode, KeyEvent.VK_RIGHT)) {
snake.setDirection(Direction.RIGHT);
}
if (matchKey(keyCode, KeyEvent.VK_DOWN)) {
snake.setDirection(Direction.DOWN);
}
if (matchKey(keyCode, KeyEvent.VK_LEFT)) {
snake.setDirection(Direction.LEFT);
}
}
// return true if targetKey contains the provided keyCode
private boolean matchKey(int keyCode, int... targetKey) {
return Arrays.stream(targetKey).anyMatch(i -> i == keyCode);
}
public void keyReleased(KeyEvent keyEvent) {
}
}
Snake.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.util.LinkedList;
public class Snake {
private final int sSize = 20, startX = 150, startY = 150;
private final int BLOCK_WIDTH = 4;
private LinkedList<Point2D.Float> sPoints;
private boolean isMoving;
private Direction direction;
public Snake() {
sPoints = new LinkedList<Point2D.Float>();
isMoving = false;
sPoints.add(new Point2D.Float(startX, startY));
for (int i = 1; i < sSize; i++) {
sPoints.add(new Point2D.Float(startX - i * BLOCK_WIDTH, startY));
}
}
public void draw(Graphics g) {
g.setColor(Color.white);
for (Point2D p : sPoints) {
g.fillRect((int) p.getX(), (int) p.getY(), BLOCK_WIDTH, BLOCK_WIDTH);
}
}
public void move() {
if (isMoving) {
sPoints.removeLast();
steer(sPoints.getFirst());
}
}
private void steer(Point2D head) {
Point2D.Float newHead = new Point2D.Float();
switch (this.getDirection()) {
case UP:
newHead.setLocation(head.getX(), head.getY() - BLOCK_WIDTH);
break;
case DOWN:
newHead.setLocation(head.getX(), head.getY() + BLOCK_WIDTH);
break;
case LEFT:
newHead.setLocation(head.getX() - BLOCK_WIDTH, head.getY());
break;
case RIGHT:
newHead.setLocation(head.getX() + BLOCK_WIDTH, head.getY());
break;
}
this.sPoints.addFirst(newHead);
}
public int getX() {
return (int) sPoints.get(0).getX();
}
public int getY() {
return (int) sPoints.get(0).getY();
}
public boolean isMoving() {
return isMoving;
}
public void setIsMoving(boolean b) {
isMoving = b;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction d) {
if (this.getDirection() == null) {
this.direction = d;
} else if (!this.getDirection().isOpposite(d)) {
this.direction = d;
}
}
}
Direction.java
public enum Direction {
UP(-1), DOWN(1), LEFT(-2), RIGHT(2);
int vector;
Direction(int i) {
this.vector = i;
}
public boolean isOpposite(Direction d) {
return this.vector + d.vector == 0;
}
}
Snack.java
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Snake extends JFrame {
public Snake() {
initUI();
}
private void initUI() {
add(new Board());
setResizable(false);
pack();
setTitle("Snake");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame ex = new Snake();
ex.setVisible(true);
});
}
}
Board.java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board extends JPanel implements ActionListener {
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int RAND_POS = 29;
private final int DELAY = 140;
private final int x\[\] = new int\[ALL_DOTS\];
private final int y\[\] = new int\[ALL_DOTS\];
private int dots;
private int apple_x;
private int apple_y;
private boolean leftDirection = false;
private boolean rightDirection = true;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;
private Timer timer;
private Image ball;
private Image apple;
private Image head;
public Board() {
initBoard();
}
private void initBoard() {
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
loadImages();
initGame();
}
private void loadImages() {
ImageIcon iid = new ImageIcon("src/resources/dot.png");
ball = iid.getImage();
ImageIcon iia = new ImageIcon("src/resources/apple.png");
apple = iia.getImage();
ImageIcon iih = new ImageIcon("src/resources/head.png");
head = iih.getImage();
}
private void initGame() {
dots = 3;
for (int z = 0; z < dots; z++) {
x\[z\] = 50 - z * 10;
y\[z\] = 50;
}
locateApple();
timer = new Timer(DELAY, this);
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, apple_x, apple_y, this);
for (int z = 0; z < dots; z++) {
if (z == 0) {
g.drawImage(head, x\[z\], y\[z\], this);
} else {
g.drawImage(ball, x\[z\], y\[z\], this);
}
}
Toolkit.getDefaultToolkit().sync();
} else {
gameOver(g);
}
}
private void gameOver(Graphics g) {
String msg = "Game Over";
Font small = new Font("Helvetica", Font.BOLD, 14);
FontMetrics metr = getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);
}
private void checkApple() {
if ((x\[0\] == apple_x) && (y\[0\] == apple_y)) {
dots++;
locateApple();
}
}
private void move() {
for (int z = dots; z > 0; z--) {
x\[z\] = x\[(z - 1)\];
y\[z\] = y\[(z - 1)\];
}
if (leftDirection) {
x\[0\] -= DOT_SIZE;
}
if (rightDirection) {
x\[0\] += DOT_SIZE;
}
if (upDirection) {
y\[0\] -= DOT_SIZE;
}
if (downDirection) {
y\[0\] += DOT_SIZE;
}
}
private void checkCollision() {
for (int z = dots; z > 0; z--) {
if ((z > 4) && (x\[0\] == x\[z\]) && (y\[0\] == y\[z\])) {
inGame = false;
}
}
if (y\[0\] >= B_HEIGHT) {
inGame = false;
}
if (y\[0\] < 0) {
inGame = false;
}
if (x\[0\] >= B_WIDTH) {
inGame = false;
}
if (x\[0\] < 0) {
inGame = false;
}
if (!inGame) {
timer.stop();
}
}
private void locateApple() {
int r = (int) (Math.random() * RAND_POS);
apple_x = ((r * DOT_SIZE));
r = (int) (Math.random() * RAND_POS);
apple_y = ((r * DOT_SIZE));
}
#Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
checkApple();
checkCollision();
move();
}
repaint();
}
private class TAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
}
if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
rightDirection = false;
leftDirection = false;
}
}
}
}

How to stop flickering in java.awt.graphics?

So i started to learn Java and tried to create a basic pong game using java.awt.graphics.
After finishing it i saw that it was a lot of flickering to the point when the game was unplayable.
This is my main class named "pong"(What a creative name).
package pong;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class pong extends Applet implements Runnable,KeyListener {
public static void main(String[] args){}
public final int W=700,L=500;
p1 player1;
p1 player2;
ball b;
Thread thread;
public void init() {
resize(W,L);
this.addKeyListener(this);
player2 = new p1(1);
b = new ball();
thread= new Thread(this);
player1 = new p1(2);
thread.start();
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0,0,W,L);
if(!(b.getX()<-10 || b.getX()>690)){
player1.draw(g);
b.draw(g);
player2.draw(g);
}else if(b.getX()<-10){
g.setColor(Color.WHITE);
g.drawString("Right Player Won!",350,250);
}else{
g.setColor(Color.WHITE);
g.drawString("Left Player Won!",350,250);
}
}
#Override
public void update(Graphics g){
paint(g);
}
public void run() {
for(;;){
player1.move();
player2.move();
b.move();
colitionchecker(1);
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_UP)
player1.setUp(true);
else if (e.getKeyCode()==KeyEvent.VK_DOWN)
player1.setDown(true);
else if(e.getKeyCode()==KeyEvent.VK_W)
player2.setUp(true);
else if(e.getKeyCode()==KeyEvent.VK_S)
player2.setDown(true);
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_UP)
player1.setUp(false);
else if (e.getKeyCode()==KeyEvent.VK_DOWN)
player1.setDown(false);
else if(e.getKeyCode()==KeyEvent.VK_W)
player2.setUp(false);
else if(e.getKeyCode()==KeyEvent.VK_S)
player2.setDown(false);
}
public void colitionchecker(int num){
if(num == 1){
if(b.getX()<50 && b.getX()>20 && b.getY()>player2.getY() &&
b.getY()>=player2.getY()-80){
b.xv=-b.xv;
}
else{
if(b.getX()<700 && b.getX()>660 && b.getY()>=player1.getY() && b.getY()<=player1.getY()+80){
b.xv=-b.xv;
}
}
}
}
}
package pong;
import java.awt.*;
public class p1 implements paddle{
final double GRAVITY = 0.94;
double y=210,yv;
boolean up,down;
int player,x;
public p1(int player){
up=false; down=false;
if(player==1)
x=20;
else
x=660;
}
#Override
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(x, (int)y,20,80);
}
public void move() {
if (up){
yv -= 2;
}else if (down){
yv += 2;
}else if (!down && !up){
yv *= GRAVITY;
}
if(yv>=15)
yv=5;
else if(yv<=-5)
yv=-5;
y += yv;
if(y<=0)
y=0;
else if(y>=420)
y=420;
}
public void setUp(boolean up) {
this.up = up;
}
public void setDown(boolean down) {
this.down = down;
}
public int getY() {
return (int)y;
}
}
package pong;
import java.awt.*;
public class ball {
double xv, yv, x, y;
public ball(){
x = 350;
y = 250;
xv = 2;
yv = 1;
}
public int getY() {
return (int)y;
}
public int getX() {
return (int)x;
}
public void move(){
x+=xv;
y+=yv;
if(y<10)
yv=-yv;
if(y>490)
yv=-yv;
}
public void draw(Graphics g){
g.setColor(Color.WHITE);
g.fillOval((int)x-10,(int)y-10,20,20);
}
}
package pong;
import java.awt.*;
public interface paddle {
public void draw(Graphics g);
public int getY();
public void move();
}
I am really lost and any help will be much appreciated.
Thanks.
So i started to learn Java
So your first lesson is, Applets are dead - better to spend your time else where, either using Swing or JavaFX windows based UIs.
Applet is not double buffered, hence the flicker, both Swing and JavaFX, if used correctly are.
I'd also discourage you from using a Thread in this way, as most GUI frameworks are not thread safe
I'd recommend having a look at:
Creating a GUI With JFC/Swing
Getting Started with JavaFX
as a basic starting point
Swing based solution
Because I can do it quickly...
KeyListener is a poor choice which is going to haunt you, better to use the Key Bindings API, which has been designed to overcome its limitations
Things you're going to have to read up on...
2D Graphics
How to Use Key Bindings
How to Use Swing Timers
And as an overall basic example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private DefaultPaddle player1;
private DefaultPaddle player2;
private Ball b;
public TestPane() {
setBackground(Color.BLACK);
player1 = new DefaultPaddle(1);
player2 = new DefaultPaddle(2);
b = new Ball();
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "Player1.up.pressed", new UpAction(player1, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Player1.up.released", new UpAction(player1, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "Player1.down.pressed", new DownAction(player1, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Player1.down.released", new DownAction(player1, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Player2.up.pressed", new UpAction(player2, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Player2.up.released", new UpAction(player2, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Player2.down.pressed", new DownAction(player2, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Player2.down.released", new DownAction(player2, false));
Timer timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
player1.move();
player2.move();
b.move();
// colitionchecker(1);
repaint();
}
});
timer.start();
}
protected void addKeyBinding(KeyStroke ks, String name, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(ks, name);
am.put(name, action);
}
public void colitionchecker(int num) {
if (num == 1) {
if (b.getX() < 50 && b.getX() > 20 && b.getY() > player2.getY()
&& b.getY() >= player2.getY() - 80) {
b.xv = -b.xv;
} else {
if (b.getX() < 700 && b.getX() > 660 && b.getY() >= player1.getY() && b.getY() <= player1.getY() + 80) {
b.xv = -b.xv;
}
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
// if (!(b.getX() < -10 || b.getX() > 690)) {
player1.draw(g);
b.draw(g);
player2.draw(g);
// } else if (b.getX() < -10) {
// g.setColor(Color.WHITE);
// g.drawString("Right Player Won!", 350, 250);
// } else {
// g.setColor(Color.WHITE);
// g.drawString("Left Player Won!", 350, 250);
// }
g2d.dispose();
}
}
public class UpAction extends AbstractAction {
private DefaultPaddle paddle;
private boolean pressed;
public UpAction(DefaultPaddle paddle, boolean pressed) {
this.paddle = paddle;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Up " + pressed);
paddle.setUp(pressed);
}
}
public class DownAction extends AbstractAction {
private DefaultPaddle paddle;
private boolean pressed;
public DownAction(DefaultPaddle paddle, boolean pressed) {
this.paddle = paddle;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
paddle.setDown(pressed);
}
}
public interface Paddle {
public void draw(Graphics g);
public int getY();
public void move();
}
public class DefaultPaddle implements Paddle {
final double GRAVITY = 0.94;
double y = 210, yv;
boolean up, down;
int player, x;
public DefaultPaddle(int player) {
up = false;
down = false;
if (player == 1) {
x = 20;
} else {
x = 660;
}
}
#Override
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(x, (int) y, 20, 80);
}
public void move() {
if (up) {
yv -= 1;
} else if (down) {
yv += 1;
} else if (!down && !up) {
yv *= GRAVITY;
}
if (yv >= 15) {
yv = 5;
} else if (yv <= -5) {
yv = -5;
}
y += yv;
if (y <= 0) {
y = 0;
} else if (y >= 420) {
y = 420;
}
}
public void setUp(boolean up) {
this.up = up;
}
public void setDown(boolean down) {
this.down = down;
}
public int getY() {
return (int) y;
}
}
public class Ball {
double xv, yv, x, y;
public Ball() {
x = 350;
y = 250;
xv = 2;
yv = 1;
}
public int getY() {
return (int) y;
}
public int getX() {
return (int) x;
}
public void move() {
x += xv;
y += yv;
if (y < 10) {
yv = -yv;
}
if (y > 490) {
yv = -yv;
}
}
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval((int) x - 10, (int) y - 10, 20, 20);
}
}
}

Java key event not working

Hello i am trying to make the game pong. Now i am trying to move the paddle with my keyboard but it is not responding at all. Can anyone tell me what i am missing here? I can't figure it out what it is i am doing wrong.
The paddle is moving when i set the condition in the check to false so there is not a problem in moving it. Just getting the keyEvent to work.
What am i missing in the keyEvent?
Thanks in advance!
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Paneel extends JPanel
{
private int height, width;
private boolean moveLeft, moveRight, moveUp, moveDown, playerMoveLeft,
playerMoveRight, computerMoveLeft, computerMoveRight = false;
private Timer timer;
private Ball ball;
private Paddle player, computer;
public Paneel()
{
ball = new Ball(994, 772);
player = new Paddle(1, 994, 722);
computer = new Paddle(2, 944, 722);
TimerHandler timerHandler = new TimerHandler();
timer = new Timer(20, timerHandler);
timer.start();
}
public void paintComponent(Graphics pen)
{
super.paintComponent(pen);
ball.drawBall(pen);
player.drawPaddle(pen);
computer.drawPaddle(pen);
pen.drawString("" + getHeight() + " " + getWidth(), 50, 50);
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_LEFT) playerMoveLeft = true;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT) playerMoveRight =
true;
}
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_LEFT) playerMoveLeft = false;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT) playerMoveRight =
false;
}
public void movePlayer()
{
if (playerMoveRight == true) player.moveDown();
else if (playerMoveLeft == true) player.moveUp();
}
public void moveComputer()
{
}
public void resetBall()
{
}
public void resetPlayer()
{
}
public void resetComputer()
{
}
class TimerHandler implements ActionListener
{
public void actionPerformed(ActionEvent e) {
movePlayer();
repaint();
}
}
}

Java code shows no errors, but JFrame won't show

I have a project due in a couple days, and my code in Eclipse shows no errors, and no warnings, how ever the game(JFrame) wont show up. I believe the error has to do with the way I've done the movement
this.addKeyListener(movement);
Any ideas are welcome!
Main.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class Main extends JFrame implements Runnable {
private Movement movement = new Movement();
public int width = 800;
public int height = 600;
public int fps = 1000;
public int score;
public int charX;
public int charY;
public int charUp;
public int charDown;
public int charLeft;
public int charRight;
public int movementSpeed = 5;
public int movementFrame = 0;
public int movementDiagonal = 10;
public boolean bCharUp = false;
public boolean bCharDown = false;
public boolean bCharLeft = false;
public boolean bCharRight = false;
public Color cytoplasm = new Color(50,130,255);
public Image character;
public Thread game;
//Double Buffer
private Image dbImage;
private Graphics dbg;
public Main() {
//Images
ImageIcon characterImage = new ImageIcon("F:/workplace/com.thecellsells.lysosome/src/com/thecellsells/lysosome/Lysosome.gif");
character = (characterImage.getImage());
//Game Properties
setSize(width, height);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(cytoplasm);
this.addKeyListener(movement);
//Threads
game = new Thread(this);
game.start();
//Other
charY = height/2 - 10;
charX = width/2 - 16;
}
public void paint(Graphics g) {
//Double Buffer
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g) {
g.drawImage(character, charX, charY, this);
repaint();
}
public static void main(String[] args) {
#SuppressWarnings("unused")
Main Main = new Main();
}
#Override
public void run() {
while (true) {
fpsSetter();
}
}
//FPS -- set's how fast game runs
#SuppressWarnings("static-access")
public void fpsSetter() {
try {
game.sleep(fps/fps);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Movement.java
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
#SuppressWarnings("serial")
public class Movement extends Main implements KeyListener {
public int charUp;
public int charDown;
public int charLeft;
public int charRight;
public int movementSpeed = 5;
public int movementFrame = 0;
public int movementDiagonal = 10;
public boolean bCharUp = false;
public boolean bCharDown = false;
public boolean bCharLeft = false;
public boolean bCharRight = false;
public void keyPressed (KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W ) {
bCharUp = true;
if (bCharUp) {
charY -= 1;
}
}
if (e.getKeyCode() == KeyEvent.VK_A) {
bCharLeft = true;
if (bCharLeft) {
charX -=1;
}
}
if (e.getKeyCode() == KeyEvent.VK_W ) {
bCharDown = true;
if (bCharDown) {
charY -=1;
}
}
if (e.getKeyCode() == KeyEvent.VK_D) {
bCharRight = true;
if (bCharRight) {
charX +=1;
}
}
}
#Override
public void keyReleased (KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W ) {
bCharUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_A) {
bCharLeft = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
bCharDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
bCharRight = false;
}
}
#Override
public void keyTyped(KeyEvent e) { }
}
Thomas
Try using setPreferredSize(width, height);.
EDIT:
The problem lies in that you extended the Main class in the Movement class. So when you start the program, the movement class calls the Main class and that initializes the Movement class again, making a race condition. Just dont extend the Main class and make variables charX and charY static. Thus you can access the variables anywhere using Main..
In your main() method, you are creating the Main object (which extends from JFrame) but you haven't set it visible.

Categories

Resources