Проект игры в понг

Пытался сделать игру в Понг на Яве. Это моя первая игра, которую я когда-либо программировал, и я был бы очень рад, если бы вы нашли время, чтобы посоветовать мне, что я мог бы сделать лучше в следующий раз. Большое спасибо 🙂 .

Вот мой код:

Start.java:

import java.awt.EventQueue;

public class Start {

public static void main(String[] args) {
    Runnable runner = new Runnable() {
        public void run() {
            GameFrame gameFrame = new GameFrame();
            
        }
    };
    
    EventQueue.invokeLater(runner);
}

}

GameFrame.java:

import javax.swing.JFrame;

public class GameFrame extends JFrame{

public GameFrame() {
     
    initFrame();
}

private void initFrame() {
    
    add(new GameBoard());
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("PongGame");
    setResizable(false);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
    
}
}

GameBoard.java:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class GameBoard extends JPanel implements Runnable{

public static final int WIDTH = 900 ; 
public static final int HEIGHT = 2 * WIDTH / 3; 
private final int DELAY = 10;

private int scoreL = 0;
private int scoreR = 0;

private boolean inGame = false;

private Paddle rightPaddle, leftPaddle;
private Ball ball;

private Thread game;


public GameBoard() { 
    
    initGameBoard();
}


private void initGameBoard() {
    
    setBackground(Color.black);
    setPreferredSize(new Dimension(WIDTH, HEIGHT));
    setFocusable(true);
    addKeyListener(new KAdapter());
    
    ball = new Ball();
    
    rightPaddle =  new Paddle("right");
    leftPaddle = new Paddle("left");
    
   }



public void paintComponent(Graphics g) {
    super.paintComponent(g);
    
    Graphics2D g2d = (Graphics2D) g;

    g2d.setStroke(new BasicStroke(5.0f));
    g2d.drawLine(WIDTH/2, 0, WIDTH/2, HEIGHT);
    
    drawBall(g2d);
    drawPaddle(g2d);
    drawScore(g2d);
    
    if(!inGame) {
        drawPressSpace(g2d);
        }
    
    Toolkit.getDefaultToolkit().sync();
}



public void addNotify() {
    super.addNotify();
    
    game = new Thread(this);
    game.start();
}


private void drawPaddle(Graphics2D g2d) {

        g2d.drawImage(rightPaddle.getImage(), rightPaddle.getX(), rightPaddle.getY(), this);
        g2d.drawImage(leftPaddle.getImage(), leftPaddle.getX(), leftPaddle.getY(), this);
    
}


private void drawPressSpace(Graphics2D g2d) {
    
    String press = "Press space to begin";
    Font font = new Font("Verdana", Font.BOLD , 20);
    FontMetrics fm = getFontMetrics(font);
    g2d.setFont(font);
    g2d.setColor(Color.red);
    g2d.drawString(press, (WIDTH - fm.stringWidth(press)) / 2, (HEIGHT - fm.getHeight()) / 2);  

}

private void drawScore(Graphics2D g2d) {

    Font font = new Font("Verdana", Font.PLAIN , 50);
    FontMetrics fm = getFontMetrics(font);
    g2d.setColor(Color.gray);
    g2d.setFont(font);
    g2d.drawString(""+scoreL, 50, fm.stringWidth(""+scoreL) + 40);  
    g2d.drawString(""+scoreR, WIDTH - fm.stringWidth(""+scoreR) - 50, fm.stringWidth(""+scoreR) + 40);
    
}

private void drawBall(Graphics2D g2d) {
    g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(), this);
}


public void run() {
    long beforeT, timeDiff, sleep;
    beforeT = System.currentTimeMillis();
    
    while (true) {
        
        updatePaddles();
        
        if(inGame) {
            updateBall();
        } else {
            rightPaddle.resetPos();
            leftPaddle.resetPos();
            
        }
        repaint();
        
        
        timeDiff = System.currentTimeMillis() - beforeT;
        sleep = DELAY - timeDiff;
        
        if (sleep < 2) {
            sleep = 2;
        }
        
        try {
            Thread.sleep(sleep);
            
        }catch(Exception e) {
            e.getStackTrace();
        }
        
        beforeT = System.currentTimeMillis();
        }
   }


private void updatePaddles() {
    
    rightPaddle.move();
    leftPaddle.move();
}

private void updateBall() {
    
    boolean b = checkCollision();
    
    int i = ball.move(b);
    
    if(i != 0) {
        switch(i) {
        case 1: scoreR++; break;
        case 2: scoreL++; break;
        }
        
        inGame = false;
    }
   }

private boolean checkCollision() {
    Rectangle rb = ball.getBounds();

    Rectangle rp = rightPaddle.getBounds();
        
        if(rb.intersects(rp)) {
            return true;
        }
        
        rp = leftPaddle.getBounds();
        
        if(rb.intersects(rp)) {
            return true;
        }
        
        return false;
    
   }

private class KAdapter extends KeyAdapter{
    
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        
        if(!inGame && keyCode == KeyEvent.VK_SPACE) { 
            inGame = true;
            ball.start();
            return;
        } 
        
    if(inGame) {
            
            if(rightPaddle.isKey(keyCode)) {
                rightPaddle.keyPressed(keyCode);

            } else if(leftPaddle.isKey(keyCode)) {
                leftPaddle.keyPressed(keyCode);

            }   
        }
    }
    
    public void keyReleased(KeyEvent e) {
        int keyCode = e.getKeyCode();
        
        if(rightPaddle.isKey(keyCode)) {
            rightPaddle.keyReleased(keyCode);

        } else if(leftPaddle.isKey(keyCode)) {
            leftPaddle.keyReleased(keyCode);

            }
        }
    }
}

Sprite.java:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

public class Sprite {

protected int x; 
protected int y; 
private int width;
private int height;

protected BufferedImage image;

public Sprite(int width, int height) {
    this.width = width;
    this.height = height;
    updateImage();
}

private void updateImage() { 
    
    image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
    Graphics2D g2d = (Graphics2D) image.getGraphics();
    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, width, height);
    
}

public BufferedImage getImage() {
    return this.image;
}

public int getX() {
    return this.x;
}

public int getY() {
    return this.y;
}

public Rectangle getBounds() {
    return new Rectangle(x, y, width, height);
}

}   

Paddle.java:

import java.awt.event.KeyEvent;

public class Paddle extends Sprite{

public final static int WIDTH = 20; 
public final static int HEIGHT = GameBoard.HEIGHT / 5;
private final int SPEED = 8;
private String side;
private int up; 
private int down; 
private int dy; 


public Paddle(String side) {
    super(WIDTH, HEIGHT);
    this.side = side;
    setSide();
    resetPos();     
}

private void setSide() { 
    
    if(side.equals("right")) { 
        
        up = KeyEvent.VK_UP;
        down = KeyEvent.VK_DOWN;
        x = GameBoard.WIDTH - WIDTH;
        
    } else if(side.equals("left")) { 
        
        up = KeyEvent.VK_W;
        down = KeyEvent.VK_S;
        
        x = 0;
        
    } else { 
        System.out.println("tato strana neexistuje!");
    }
    
}

public boolean isKey(int keyCode) { 
    
    return up == keyCode || down == keyCode; 
}

public void move() { 
    if(checkHeightCol()) {
        dy = 0;
    
    }
    
    y+=dy;
        
}

private boolean checkHeightCol() {
    return dy + y < 0 || dy + y > GameBoard.HEIGHT - HEIGHT;
}

public void resetPos() {
    y = (GameBoard.HEIGHT - HEIGHT) / 2;
}

public void keyPressed(int keyCode) { 
    
    if(keyCode == up) {
        dy = -SPEED;
    } 
    if (keyCode == down) {
        dy = SPEED;
    }
    
}

public void keyReleased(int keyCode) { 

    if(keyCode == up) {
        dy = 0;
    }
    if (keyCode == down) {
        dy = 0;
    }
}

}

Ball.java:

import java.util.Random;

public class Ball extends Sprite{

public static final int SIZE = 20;
private int xSpeed;
private int ySpeed;
private final int MIN_SPEED = 8;
private final int MAX_SPEED = 25;

public Ball() {
    
    super(SIZE, SIZE);
    
    restart();
    
}

public void start() {
    
    generateRandomDirection();
    

}

private void generateRandomDirection() {
    
    Random r = new Random();
    double randomY = 0.1 + (0.8 - 0.1) * r.nextDouble();
    ySpeed = (int) Math.round(randomY * MIN_SPEED);
    double randomX = Math.sqrt(MIN_SPEED * MIN_SPEED - ySpeed * ySpeed);
    xSpeed = (int) Math.round(randomX);
    
    ySpeed *= (r.nextInt() % 2 == 0) ? 1 : -1;
    xSpeed *= (r.nextInt() % 2 == 0) ? 1 : -1;
}

public void restart() {
    xSpeed = 0;
    ySpeed = 0;
    x = (GameBoard.WIDTH - SIZE) / 2;
    y = (GameBoard.HEIGHT - SIZE) / 2;
            
}

public int move(boolean paddleCollision) {
    int state = 0;

    if(x + xSpeed < 0) {
        
        restart();
        state = 1;
        
    } else if(x + xSpeed > GameBoard.WIDTH - SIZE ) {
        
        restart();
        state = 2;
        
    }else if(checkHeightCollision()) {
        ySpeed *= -1;
        
    } else if(paddleCollision) {
        xSpeed *= -1;
        
    } 
    
    x+=xSpeed;
    y+=ySpeed;
    
    return state;
}

private boolean checkHeightCollision() {
    return y + ySpeed < 0  || y + ySpeed > GameBoard.HEIGHT - SIZE;
}       
}

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *