I have just started to learn Java, so excuse my messy code. Looking all over the internet, I have not found a solution to this question yet. This is the game pong. I have to padels that I am controlling ith the keys, 'w', 's', up, and down. When I draw the panels in my graphics section, I use the padelY for Y1 and use padelY + padelLength(A constant) for Y2. I cannot seem to understand why when I rut the program the padels change size as I move them up and down. Also, the padel on the right is named panel1, when I draw the padel I use the screen size - the padel spacing for X1 yet the padel appears to be stuck on the side.
I would really appreciate any advice that anyone could give on those issues or how to clean up my code in general!
Thanks!
package Pong;
//Import Libraries
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
#SuppressWarnings("serial")
public class Pong extends JPanel implements KeyListener{
int padel1y = 150;
int padel2y = 150;
static final int padelLength = 100;
int padelWidth = 10;
int padelSpeed = 2;
int padel2Speed = 0;
int padel1Speed = 0;
int ballX = BOX_WIDTH/2;
int ballY= BOX_HEIGHT/2;
int ballXSpeed = 2;
int ballYSpeed = 1;
int ballRadius = 10;
int ballCount = 0;
public final static int ballSpeedIncrease = 500;
public final static int BOX_WIDTH = 600;
public final static int BOX_HEIGHT = 600;
public final static int UPDATE_RATE = 100;
public final static int padelSpace = 10;
public Pong() {
setPreferredSize(new Dimension(BOX_WIDTH,BOX_HEIGHT));
Thread gameThread = new Thread() {
public void run(){
while(true){
ballCount = ballCount + 1;
if(ballCount%ballSpeedIncrease == 0){
if(ballXSpeed < 0){
ballXSpeed = ballXSpeed - 1;
}
if(ballYSpeed < 0){
ballYSpeed = ballYSpeed - 1;
}
if(ballXSpeed > 0){
ballXSpeed++;
}
if(ballYSpeed > 0){
ballYSpeed++;
}
}
if(ballX-ballRadius <= 10+padelWidth){
if(ballY<padel2y || ballY>padel2y+padelLength){
System.exit(0);
}
else{
ballXSpeed = -ballXSpeed;
}
}
else if(ballX+ballRadius >= 590-padelWidth){
if(ballY<padel1y || ballY>padel1y+padelLength){
System.exit(0);
}
else{
ballXSpeed = -ballXSpeed;
}
}
if(ballY-ballRadius <= 0){
ballYSpeed = -ballYSpeed;
}
else if(ballY+ballRadius >= BOX_HEIGHT){
ballYSpeed = -ballYSpeed;
}
padel1y = padel1y +padel1Speed;
padel2y = padel2y +padel2Speed;
ballX = ballX + ballXSpeed;
ballY = ballY+ ballYSpeed;
repaint();
try {
Thread.sleep(1000 / UPDATE_RATE);
}
catch (InterruptedException ex) {}
}
}
};
gameThread.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(0,0,BOX_WIDTH,BOX_HEIGHT);
g.setColor(Color.blue);
g.fillRect(padelSpace,padel2y,padelSpace + padelWidth,padel2y+padelLength);
g.fillRect(BOX_WIDTH-padelSpace,padel1y,BOX_WIDTH-padelSpace-padelWidth,padel1y+padelLength);
g.setColor(Color.green);
g.fillOval(ballX, ballY, ballRadius*2, ballRadius*2);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Create Frame
JFrame frame = new JFrame("PONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONG");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Pong pong = new Pong();
frame.setContentPane(pong);
frame.setSize(BOX_WIDTH,BOX_HEIGHT);
frame.pack();
frame.addKeyListener(pong);
frame.setVisible(true);
}
});
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_UP){
padel1Speed = -padelSpeed;
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
padel1Speed = padelSpeed;
}
else if(e.getKeyCode() == KeyEvent.VK_W){
padel2Speed = -padelSpeed;
}
else if(e.getKeyCode() == KeyEvent.VK_S){
padel2Speed = padelSpeed;
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
padel1Speed = 0;
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
padel1Speed = 0;
}
else if(e.getKeyCode() == KeyEvent.VK_W){
padel2Speed = 0;
}
else if(e.getKeyCode() == KeyEvent.VK_S){
padel2Speed = 0;
}
}
#Override
public void keyTyped(KeyEvent e) {}
}
See this for documentation on how to use the fillRect() method: https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#fillRect(int,%20int,%20int,%20int)
The arguments are: x position, y position, width and height.
You use it like this: g.fillRect(padelSpace,padel2y,padelSpace + padelWidth,padel2y+padelLength);
The second and third arguments are wrong. You should only be passing the width and height. Like this: g.fillRect(padelSpace, padel2y, padelWidth, padelLength);
More generally, when something is going wrong (drawing the paddle) read the documentation on the methods you use to do that.
Related
I have created a game similar to snake in which the user is first prompted with a jpanel asking which difficulty they want, and whatever JButton they pick influences the size of the map as well as the delay between the snake movements. I have the map size working just fine, but the delay variable never seems to change. I suspect it has something to do with the way the timer is being casted, but I have no idea how to fix it. I am also wondering how when the program is first ran it seems some of the variables don't update, but the second time it is ran all of them are updated. Here is my class with the original variables and collision detection:
import java.util.Random;
import javax.swing.JLabel;
public class GameEngine extends JPanel implements ActionListener{
//creates the size of the panel as well as creating the resolution for all objects, including the players and food.
static final int sWidth = 600;
static final int sHeight = 600;
public static int size = 24;
static int objectSize = (sHeight*sWidth) / size;
public static int delay = 100;
final int playerX[] = new int[objectSize];
final int playerY[] = new int[objectSize];
int bodySize = 4;
int score = 0;
int appleX;
int appleY;
char direction = 'D';
boolean started = false;
Random random;
Timer timer;
boolean easy;
JLabel score1;
public static String difficulty;
GameEngine(){
random = new Random();
this.setPreferredSize(new Dimension(sWidth,sHeight));
this.setBackground(Color.black);
this.setFocusable(true);
this.addKeyListener(new UserMovement());
gameStart();
}
public void gameStart() {
newApple();
started = true;
timer = new Timer(delay,this);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
public void drawHead(Graphics g) {
g.setColor(new Color(100,252,0));
g.fillRect(playerX[0], playerY[0], size, size);
}
public void draw(Graphics g) {
if(started) {
//draws the apples
g.setColor(Color.red);
g.fillOval(appleX, appleY, size, size);
for (int i = 0; i < bodySize; i++) {
if(i == 0) {
drawHead(g);
}
else {
g.setColor(new Color(60,180,0));
g.fillRect(playerX[i], playerY[i], size, size);
}
}
g.setColor(Color.white);
g.setFont(new Font("Bold", Font.BOLD, 20));
FontMetrics metrics = getFontMetrics(g.getFont());
g.drawString("Score: " + score,(sWidth - metrics.stringWidth("Score: " + score))/2,g.getFont().getSize());
}
}
public void newApple(){
appleX = random.nextInt((int)(sWidth/size))*size;
appleY = random.nextInt((int)(sHeight/size))*size;
}
//moves the player by using and modifying their coordinates
public void move() {
for (int i = bodySize; i > 0; i--) {
playerX[i] = playerX[i-1];
playerY[i] = playerY[i-1];
}
switch(direction) {
case 'W':
playerY[0] = playerY[0] - size;
break;
case 'S':
playerY[0] = playerY[0] + size;
break;
case 'A':
playerX[0] = playerX[0] - size;
break;
case 'D':
playerX[0] = playerX[0] + size;
break;
}
}
public void checkFood() {
if(playerX[0] == appleX && playerY[0] == appleY)
{
bodySize++;
score++;
newApple();
}
}
public void checkCol() {
//checks for head collision with the body
for(int i = bodySize; i > 0; i--) {
if((playerX[0] == playerX[i]) && (playerY[0] == playerY[i])) {
started = false;
}
}
//checks if head touches any of the walls of the program
if(playerX[0] < 0) {
started = false;
}
if(playerX[0] > sWidth) {
started = false;
}
if(playerY[0] < 0) {
started = false;
}
if(playerY[0] > sHeight) {
started = false;
}
if(started != true) {
timer.stop();
}
}
public void actionPerformed(ActionEvent e){
if(started == true) {
move();
checkFood();
checkCol();
}
repaint();
}
public class UserMovement extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
if(direction != 'D') {
direction = 'A';
}
break;
case KeyEvent.VK_RIGHT:
if(direction != 'A') {
direction = 'D';
}
break;
case KeyEvent.VK_UP:
if(direction != 'S') {
direction = 'W';
}
break;
case KeyEvent.VK_DOWN:
if(direction != 'W') {
direction = 'S';
}
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
}
and here is the code calling and changing the delay and size variables:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StartMenu extends JPanel {
StartMenu()
{
JButton easy = new JButton();
JButton hard = new JButton();
this.setPreferredSize(new Dimension(350,240));
this.setLayout(null);
this.setBackground(Color.black);
this.setFocusable(true);
easy.setBounds(75,40,200,40);
hard.setBounds(75,120,200,40);
this.add(easy);
this.add(hard);
easy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
setVisible(false);
new SnakeStart();
GameEngine.size = 48;
GameEngine.delay = 140;
}
});
hard.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
setVisible(false);
new SnakeStart();
GameEngine.size = 24;
GameEngine.delay = 70;
}
});
}
}
I assume your GameEngine instance is created before the StartMenu action listeners are executed. If that assumption is correct, that means that GameEngine.timer with the default value of delay is created in the GameEngine constructor and is not updated after the delay is changed.
You need to make sure that you explicitly update your timer with the new delay value after StartMenu actions are called.
Brand new to this forum. Tried to learn Java by tutorials for a while, which have worked fine until now when I'm playing around with Swing making a Pong game..
My problem is that when I try to change level in my game my player's keylistener stops working.
I have tried to remove all unnecessary code, hopefully I haven't missed any that causes confusion.
This is what happens in my Main-class, where Data is basically a JPanel working as my background and Player is Another JPanel, I'll get to the Player-class after main.
public class Main {
Data data = new Data(Color.RED);
Player player = new Player(700, 500, 20, 100);
public Main() throws InterruptedException{
run(data, player);
ballRecursive();
}
public void run(Data data) throws InterruptedException {
frame.add(player, BorderLayout.WEST);
frame.add(data, BorderLayout.CENTER);
}
public void ballRecursive() throws InterruptedException {
if(playerScore.returnScore()==1){
Data data = new Data(Color.GREEN);
run(data);
}
This is my Player, tried to remove anything unnecessary here aswell:
public class Player extends JPanel implements ActionListener, KeyListener{
Timer timer = new Timer(5, this);
double yPos = 0, movementY = 0;
int squareSize = 60;
int yBound;
public Player(int w, int h, int width, int height) {
timer.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
yBound = (windowHeight - squareSize);
}
public void actionPerformed(ActionEvent e) {
yPos += movementY;
if (yPos < 0) {
yPos = 0;
} else if (yPos + squareSize > yBound) {
yPos = yBound - squareSize;
}
repaint();
}
public void moveUp()
{
if (yPos == 0)
{
movementY = 0;
}
movementY = -1;
}
public void moveDown()
{
if (yPos == yBound)
{
movementY = 0;
}
movementY = 1;
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP) {
moveUp();
}
if (keyCode == KeyEvent.VK_DOWN) {
moveDown();
}
}
public void keyReleased(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP)
{
movementY = 0;
}
if (keyCode == KeyEvent.VK_DOWN)
{
movementY = 0;
}
I am currently making a Space Shooter in Java. I am able to make bullets shoot and enemies come from the top, but I am not sure how to check if they intersect. I understand that the Rectangle class has a intersects method, but I am not sure how I would place the rectangles around the bullets and the enemies, since I don't know beforehand how many may be on the screen. How can I do this? Here is my code:
Game.java
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener {
//declare values
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Space Shooter";
private boolean running = false;
private Thread thread;
private Player player;
private BufferedImage playerImage;
private BufferedImage bulletImage;
private BufferedImage enemyImage;
int playerx;
int playery;
int round = 1;
public Game() {
//
player = new Player((WIDTH/2)-32, HEIGHT-200);
//allocates all file resources
try {
playerImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/player.png"));
bulletImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/bullet.png"));
enemyImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/enemy.png"));
} catch (IOException e) {
e.printStackTrace();
}
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
//starts thread
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
//stops thread
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
#Override
//game loop
public void run() {
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta > 1) {
tick();
updates++;
delta--;
}
Shoot.updateBullets();
Enemy.updateEnemies();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " TICKS, " + frames + " FPS");
updates = 0;
frames = 0;
}
}
stop();
}
//updates sprite locations
public void tick() {
playerx = player.getX();
playery = player.getY();
}
//renders sprites
public void render() {
//setting up triple-buffering
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
//////////////////////////////////
g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(), getHeight());
g.drawImage(playerImage, playerx, playery, this);
if (Shoot.allBullets.size() != 0) {
for (int i = 0; i < Shoot.allBullets.size(); i++) {
int bulletx = (int) Shoot.allBullets.get(i).x;
int bullety = (int) Shoot.allBullets.get(i).y;
g.drawImage(bulletImage, bulletx + 21, bullety, this);
}
}
if (Enemy.allEnemies.size() != 0) {
for (int i = 0; i < Enemy.allEnemies.size(); i++) {
int enemyx = (int) Enemy.allEnemies.get(i).x;
int enemyy = (int) Enemy.allEnemies.get(i).y;
g.drawImage(enemyImage, enemyx, enemyy, this);
}
} else {
Enemy.createEnemies(round);
round++;
}
//////////////////////////////////
g.dispose();
bs.show();
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
Shoot.addBullet(player.getX(), player.getY());
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
player.setY(playery -= 20);
} else if (key == KeyEvent.VK_DOWN) {
player.setY(playery += 20);
} else if (key == KeyEvent.VK_RIGHT) {
player.setX(playerx += 40);
} else if (key == KeyEvent.VK_LEFT) {
player.setX(playerx -= 40);
}
}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(game);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
game.start();
}
}
Shoot.java
package main;
import java.util.ArrayList;
public class Shoot {
static ArrayList<Point> allBullets = new ArrayList<Point>();
public static void addBullet(int x, int y) {
allBullets.add(new Point(x, y));
}
public static ArrayList<Point> getAllBulletPosistions() {
return allBullets;
}
public static void updateBullets() {
if (allBullets.size() != 0) {
for (int i = 0; i < allBullets.size(); i++) {
allBullets.get(i).y -= 1;
}
}
}
}
Enemy.java
package main;
import java.util.ArrayList;
public class Enemy {
static ArrayList<Point> allEnemies = new ArrayList<Point>();
public static ArrayList<Point> createEnemies(int round) {
for (int i = 0; i < round; i++) {
Point newEnemyLocation = new Point((int) (Math.random()*Game.WIDTH - 64), 0);
if (newEnemyLocation.x < 64) {
newEnemyLocation.x += 70;
}
allEnemies.add(newEnemyLocation);
}
return allEnemies;
}
int validate(int xpos) {
if (xpos > Game.WIDTH - 64) {
xpos -= 64;
}
if (xpos < 64) {
xpos += 64;
}
return xpos;
}
public static ArrayList<Point> updateEnemies() {
if (allEnemies.size() != 0) {
for (int i = 0; i < allEnemies.size(); i++) {
Point enemyLocation = allEnemies.get(i);
if (enemyLocation.y <= Game.HEIGHT) {
allEnemies.get(i).y += 0.1;
} else {
allEnemies.remove(i);
}
}
}
return allEnemies;
}
}
for(int i = 0; i < Shoot.allBullets.size(); i++){
for(int j = 0; j < Enemy.allEnemys.size(); j++){
if(new Rectangle(Shoot.allBullets.get(i).x,Shoot.allBullets.get(i).y, width, height).intersects(new Rectangle(Enemy.allEnemys.get(j).x, Enemy.allEnemys.get(j).y, width, height)){
//on intersect
}
}
}
This would work but you shouldn't create new rectangles like this instead you should create a bullet class and a Enemy class that both contains the position and Rectangle anyways good luck!
Trying to make pong in java but can't move both paddles at once. You can move one or the other but not both at the same time. Do I need to create 2 threads with 2 different pannels?
Here is where I am specifying the key events
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
if(e.getKeyCode() == KeyEvent.VK_A){
y-=10;
}
if(e.getKeyCode() == KeyEvent.VK_S){
y+=10;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
ytwo-=10;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
ytwo+=10;
}
}
}
Here is the full code
import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Pong extends JFrame implements ActionListener{
//implement constants
PongPanel pongPanel = new PongPanel();
//JFrame pong x and y coordinates
static final int jfpX = 150;
static final int jfpY = 20;
// JFrame pong width and height
static final int jfpW = 800;
static final int jfpH = 600;
Thread thrd;
public static void main(String[] args) {
Pong jfp = new Pong();
jfp.setVisible(true);
}
public Pong(){
setBounds(jfpX,jfpY,jfpW,jfpH);
setTitle("Pong");
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground(Color.black);
add(pongPanel);
addKeyListener(pongPanel);
thrd = new Thread (pongPanel);
thrd.start();
}
public void actionPerformed(ActionEvent e) {
}
}
class PongPanel extends JPanel implements Runnable, KeyListener{
Random random = new Random();
static final int jpW = 800;
static final int jpH = 600;
int paddleStart = (jpH/2)-35;
int paddleStarttwo = (jpH/2)-35;
int ballStartX = (jpW/2)-20;
int ballStartY = (jpH/2)-20;
int ytwo,x,y;
int ballD = 30;
int paddleW1 = 20;
int paddleH1 = 100;
int paddleW2 = 20;
int paddleH2 = 100;
int min = -2;
int max = 2;
int randomBallx, randomBally;
// int randomBallx = random.nextInt(max-min+1)+min;
// int randomBally = random.nextInt(max-min+1)+min;
int rand1 = random.nextInt(2-1 + 1)+1; // random for function to determine ballx and bally
int rand2 = random.nextInt(2-1+2)+1;
int dx = 4;
int dy = 4; //direction of y
public void ballNotZero(){// makes sure the ball doesnt go straight up and down
if (randomBallx ==0){
randomBallx = random.nextInt(max-min+1)+min;
}
if(randomBally == 0){
randomBally=random.nextInt(max-min+1)+min;
}
// if(rand1 ==1){
// randomBallx=-1;
// }
// if(rand1 ==2){
// randomBallx=1;
// }
// if(rand2 ==1){
// randomBally =-1;
// }
// if(rand2==2){
// randomBally = 1;
// }
}
public PongPanel(){
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Color ball;
Color paddleOne;
Color paddleTwo;
ball = new Color(255,0,255);
paddleOne = new Color(255,0,0);
paddleTwo = new Color(0,0,255);
g.setColor(ball);
g.fillOval(ballStartX+randomBallx,ballStartY+randomBally,ballD,ballD);
g.setColor(paddleOne);
g.fillRect(20,paddleStart+y,paddleW1,paddleH1);
g.setColor(paddleTwo);
g.fillRect(760,paddleStarttwo+ytwo,paddleW2,paddleH2);
}
public void run() {
while(true){
ballNotZero();
detectPaddle();
randomBall();
ballMove();
repaint();
try {Thread.sleep(75); } catch(Exception e){
};
}
}
public static boolean intervallContains(int low, int high, int n) { //determines if something is in a certain range
return n >= low && n <= high;
}
public void detectPaddle(){ //determines if ball is close enough to paddle for detection
int withinY = (paddleStart+y) -(ballStartY+randomBally);
int withinY1 = (paddleStarttwo+ytwo)-(ballStartY+randomBally);
if (ballStartX+randomBallx <=20 && intervallContains(-50,50,withinY)){
dx = -dx;
}
if(ballStartX+randomBallx >=760 && intervallContains(-50,50,withinY1)){
dx = -dx;
}
}
public void randomBall(){
if(randomBallx >=0 ){
randomBallx+=dx;
}
if(randomBallx<0){
randomBallx-=dx;
}
if(randomBally>=0){
randomBally+=dy;
}
if(randomBally<0){
randomBally-=dy;
}
// randomBallx+=randomBallx;
// randomBally+=randomBally;
}
public void ballMove(){
if(ballStartY+randomBally > jpH-60){
dy= -dy;
}
if(ballStartY+randomBally <0){
dy = -dy;
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
if(e.getKeyCode() == KeyEvent.VK_A){
y-=10;
}
if(e.getKeyCode() == KeyEvent.VK_S){
y+=10;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
ytwo-=10;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
ytwo+=10;
}
}
}
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Don't use while (true) but rather a Swing timer.
Don't use KeyListeners but rather Key Bindings.
Consider turning on a Swing Timer (which can act as your "background thread") that moves one paddle when the bindings detect the correct key has been pressed,
and stopping the timer that moves the paddle when the same key is released.
Same for the other paddle but of course having its actions respond to a bindings of a different pair of keys.
When attempting to get something like this working, try to get it working in a very simple program first, one without all the other junk required for your main program, but one which will allow you to test and prove your concept. Then if you get things working in your small program, great, you add the functionality to your main program. And if your small program code doesn't work and you need our help, you can post the small self-contained program here (an sscce) for us to test and modify.
I am almost done with my first little java game for my final project. It is a sidescroller where you have to shoot/avoid asteroids. My last problem is figuring out how to make my array of asteroids collide with the player's lasers. Here's what I have so far, there's an "AWT-EventQueue-0" java.lang.NullPointerException" on line 137, that I can't deal with. Any help is appreciated.
Edit: I added in my other classes, I realize it would be hard to judge the functionality of my code if I didn't show you where it came from.
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class Board extends JPanel implements ActionListener
{
Enemy[] baddies = new Enemy[10000];
Player p;
Image img;
int y;
Timer time;
boolean lost = false;
static Font font = new Font("SanSerif", Font.BOLD, 24);
public AudioClip theme, bang, laser;
static ArrayList<Enemy> enemies;
public static int score = 0;
public static int lives = 5;
public Board()
{
p = new Player();
addKeyListener(new ActionListener());
setFocusable(true);
ImageIcon i = new ImageIcon("images/background.png");
img = i.getImage();
time = new Timer(5, this);
time.start();
for(int j = 0; j < baddies.length; j++)
{
Random ran = new Random();
y = ran.nextInt(365)+1;
baddies[j]= new Enemy((100*j + 700), y, "images/asteroid.gif");
}
theme = Applet.newAudioClip(getClass().getResource("theme.mid"));
theme.play();
bang = Applet.newAudioClip(getClass().getResource("bang.wav"));
}
public void actionPerformed(ActionEvent e)
{
checkCollisions();
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
if(b.isVisible() == true)
{
b.move();
}
else
{
bullets.remove(i);
}
}
p.move();
for(int i = 0; i < baddies.length; i++)
{
if(p.x > 400)
{
baddies[i].move(p.getdx());
}
}
repaint();
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
if(lost)
{
g2d.drawString("You Lose!", 300, 300);
}
if((p.getX() - 590) % 2400 == 0 || (p.getX() - 590) % 2400 == 1)
{
p.nx = 0;
}
if((p.getX() - 1790) % 2400 == 0 ||(p.getX() - 1790) % 2400 == 1)
{
p.nx2 = 0;
}
g2d.drawImage(img, 685-p.nx2, 0, null);
if(p.getX() >= 590)
{
g2d.drawImage(img, 685-p.nx, 0, null);
}
g2d.drawImage(p.getImage(), p.edge, p.getY(), null);
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
g2d.drawImage(b.getImg(), b.getX(), b.getY(), null);
}
for(int i = 0; i < baddies.length; i++)
{
if(baddies[i].isAlive == true)
{
g2d.drawImage(baddies[i].getImg(), baddies[i].getX(), baddies[i].getY(), null);
}
}
g2d.setColor(Color.white);
g2d.drawString("Score: " + score, 0, 320);
g2d.drawString("Lives: " + lives, 80, 320);
}
public void checkCollisions()
{
Rectangle[] rect = new Rectangle[baddies.length];
for(int i = 0; i < baddies.length; i++)
{
Enemy e = (Enemy)baddies[i];
rect[i] = e.getBounds();
}
ArrayList<?> bullets = Player.getBullets();
for (int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet) bullets.get(i);
Rectangle b1 = b.getBounds();
if (rect[i].intersects(b1) && baddies[i].isAlive())
{
score++;
baddies[i].isAlive = false;
baddies[i].isVisible = false;
bang.play();
}
Rectangle h = p.getBounds();
if (h.intersects(rect[i]))
{
if(baddies[i].isAlive() == true)
{
lives--;
if(lives < 0)
{
lost = true;
theme.stop();
System.exit(1);
}
}
}
}
}
private class ActionListener extends KeyAdapter
{
public void keyReleased(KeyEvent e)
{
p.keyReleased(e);
}
public void keyPressed(KeyEvent e)
{
p.keyPressed(e);
}
}
}
Enemy
package ShooterGame;
import java.awt.*;
import javax.swing.ImageIcon;
public class Enemy
{
int x, y;
Image img;
boolean isAlive = true;
boolean isVisible = true;
public Enemy(int startX, int startY, String location)
{
x = startX;
y = startY;
ImageIcon l = new ImageIcon(location);
img = l.getImage();
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 60, 60);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public boolean isAlive()
{
return isAlive;
}
public boolean isVisible()
{
return isVisible;
}
public Image getImg()
{
return img;
}
public void move(int dx)
{
x = x - dx;
}
}
Bullet
package ShooterGame;
import java.applet.Applet;
import java.awt.*;
import javax.swing.ImageIcon;
import java.applet.AudioClip;
public class Bullet
{
int x, y;
Image img;
boolean visible;
public Bullet(int startX, int startY)
{
x = startX;
y = startY;
ImageIcon newBullet = new ImageIcon("images/bullet.gif");
img = newBullet.getImage();
visible = true;
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 9, 5);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public Image getImg()
{
return img;
}
public boolean isVisible()
{
return visible;
}
public void move()
{
x = x + 2;
if(x > 700)
{
visible = false;
}
}
public void setVisible(boolean isVisible)
{
visible = isVisible;
}
}
Player
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player
{
int x, dx, y, dy, nx2, nx, edge, ceiling;
Image player;
ImageIcon ib = new ImageIcon("images/player1back.gif");
ImageIcon i = new ImageIcon("images/playerstill.gif");
ImageIcon f = new ImageIcon("images/playerforward.gif");
ImageIcon up = new ImageIcon("images/playerup.gif");
ImageIcon down = new ImageIcon("images/playerdown.gif");
public AudioClip laser;
static ArrayList<Bullet> bullets;
public Player()
{laser = Applet.newAudioClip(getClass().getResource("laser.wav"));
player = ib.getImage();
x = 75;
nx = 0;
nx2 = 685;
y = 172;
edge = 150;
ceiling = 0;
bullets = new ArrayList<Bullet>();
}
public static ArrayList<Bullet> getBullets()
{
return bullets;
}
public void fire()
{
Bullet z = new Bullet((edge + 60), (y+17));
bullets.add(z);
}
public Rectangle getBounds()
{
return new Rectangle(edge, y, 43, 39);
}
public void move()
{
y = y + dy;
if(y < ceiling)
{
y = ceiling;
}
if(y > 290)
{
y = 290;
}
if(dx != -1)
{
if(edge + dx <= 151)
{
edge = edge + dx;
}
else
{
x = x + dx;
nx2 = nx2 + dx;
nx = nx + dx;
}
}
else
{
if(edge + dx > 0)
{
edge = edge + dx;
}
}
}
public int getX()
{
return x;
}
public int getdx()
{
return dx;
}
public int getY()
{
return y;
}
public Image getImage()
{
return player;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 2;
player = f.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = -1;
player = up.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 1;
player = down.getImage();
}
if(key == KeyEvent.VK_SPACE)
{
fire();
laser.play();
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 1;
player = ib.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = 0;
player = ib.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 0;
player = ib.getImage();
}
}
}
Frame
package ShooterGame;
import javax.swing.*;
public class Frame
{
public AudioClip theme;
public Frame()
{
JFrame frame = new JFrame();
frame.add(new Board());
frame.setTitle("SideShooter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,365);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args)
{
new Frame();
}
}
Ok, so the problem is the line mentioned in the other answer, but I believe it is that all the enemies may not be initialised before it checks collisions. Because you are making 10000 of them to start with, I think your action performed method may be checking collisions before they have all be created.
One thing to try could be to bring down the amount of enemies you have and see if it still keeps happening, try 100 or 1000, but this still won't fix the issue.
You really want to be change your game to run in it's own loop though, at the moment you are only checking collisions when the player performs an action. so if the player stops moving, no collision detection...
I would suggest that you find a book called 'Killer Game Programming in Java', there are free ebook version, and just read the first 2 chapters about making a game loop. The book is a bit old, but the basics of the loop are very good.
This question here also contains a very simple loop, and some suggestions in the comments about how to make it better.
The error is on the line
rect[i] = e.getBounds();
Are you not initializing the bounds of your Enemy class correctly? Alternatively, the Enemy you pulled out of the array could be null.