首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >首次尝试打乒乓球

首次尝试打乒乓球
EN

Code Review用户
提问于 2017-01-10 02:27:15
回答 1查看 182关注 0票数 4

这是我的主要类,它处理游戏的循环和设置:

代码语言:javascript
复制
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

public class Game extends Canvas implements Runnable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Thread thread;
    private Boolean running;

    public int width;
    public int height;

    protected static Boolean p1won, p2won;

    public static boolean gameover = false;

    private Player1 p1;
    private Player2 p2;
    private Ball ball;
    private Window window;

    public static boolean playing = false;

    public Game(){
        new Window(this, width, height, running);
        width = this.getToolkit().getScreenSize().width;
        height = this.getToolkit().getScreenSize().height;

        p1 = new Player1();
        p2 = new Player2();
        ball = new Ball(width, height, p1,p2, null, window);

        start();
    }

    private synchronized void start() {
        thread = new Thread(this);
        thread.start();
        running = true;
    }

    private synchronized void stop(){
        try {
            thread.join();
            running = false;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void run() {
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 100000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while(running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while(delta >= 1){
                update();
                delta--;
            }
            if(running)
                render();
            frames++;

            if(System.currentTimeMillis() - timer > 1000){
                timer += 1000;
                System.out.println("FPS : "+frames);
                frames = 0;
            }
        }
        stop();
    }

    private void update() {

        if(p1.score == 7){
            gameover = true;
            playing = false;
            p1.score = 0;
            p2.score = 0;
            p1won = true;
        } else if(p2.score == 7){
            gameover = true;
            playing = false;
            p1.score = 0;
            p2.score = 0;
            p2won  =true;
        }

        if(playing){
        p2.update(height);
        p1.update(height);

        ball.update(width, height);
        }
    }

    private void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null){//when a bufferedStrategy is gottn its default value is null
            this.createBufferStrategy(3);//gives the buffered strategy a value of three
            return;//returns the value so we don't create more buffered strategy's
        }
        Graphics g = bs.getDrawGraphics();

        Font f1 = new Font("Arial", 0, 150);
        Font f2 = new Font("Arial", 0, 50);

        g.setColor(Color.black);
        g.fillRect(0, 0, getToolkit().getScreenSize().width, getToolkit().getScreenSize().height);

        if(!playing && gameover == false){

        g.setColor(Color.white);

        g.setFont(f1);
        g.drawString("PONG", width/2-250, height/5);

        g.setFont(f2);
        g.drawString("(Press Enter To Start)", width/2 - 250, height/2);
        g.drawString("Press ESCAPE to exit", width/2-250, height-400);
        }else if(playing && gameover == false){
            p2.render(g,width);
            ball.render(g);  
            p1.render(g,width);
            g.fillRect(width/2, 0, 25, 150);
            g.fillRect(width/2, height/100*20-150, 25, 150);
            g.fillRect(width/2, height/100*40-150, 25, 150);
            g.fillRect(width/2, height/100*60-150, 25, 150);
            g.fillRect(width/2, height/100*80, 25, 150);

        }
        else if(gameover == true && playing == false){
            g.setFont(f2);
            g.setColor(Color.white);
            if(p1won) g.drawString("Gameover Player 1 WON!", width/2-300, height/2);
            else if(p2won) g.drawString("Gameover Player 2 WON!", width/2-300, height/2);
        }

        bs.show();

    }

    public Window getWindow(){
        return window;
    }


    public static void main(String[] args) {
        new Game();

    }

}

这将处理Ball移动和碰撞检测:

代码语言:javascript
复制
     import java.awt.Color;

    import java.awt.Graphics;
    import java.awt.Rectangle;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class Ball {

    private Game game;
    private Player1 p1;
    private Player2 p2;

    private Random rand;


    int x;
    int y;

    int xa ;
    int ya ;

    public Ball(int width, int height, Player1 p1, Player2 p2, Game game, Window window){
        this.game = game;
        x = width/2;
        y = height/2;

        rand= new Random();

        xa = rand.nextInt(3)+1;
        ya = rand.nextInt(3)+1;

    }

    public void update(int width, int height){

        if(y<=0 || y>= height - 25)ya = ya *-1;
        if((x + 25 >= width - 150 && x <= width - 125 ) && (y >= p2.y && y <= p2.y +150 || y + 25 >= p2.y && y + 25 <= p2.y + 150))xa =rand.nextInt(2) - 4;
        if((x >= 150 && x <= 175) && (y >= p1.y && y <= p1.y + 150 || y + 25 >= p1.y && y + 25 <= p1.y + 150 )){
            xa =rand.nextInt(4);
            ya = rand.nextInt(4);
        }

        x += xa;
        y += ya;

        checkScoreCollision(width, height);
    }

    private void checkScoreCollision(int width, int height) {
        if(x <= 5){
            p2.score++;
            ballReset(width, height);
        }
        else if(x+26 >= width-5){
            p1.score++;
            ballReset(width, height);
        }
    }

    private void ballReset(int width, int height) {

        x = width/2;
        y = height/2;

        xa = rand.nextInt(4)-2;
        ya = rand.nextInt(4)-2;

        if(xa == 0 || ya == 0)ballReset(width, height);

    }


    public void render(Graphics g){
        g.setColor(Color.white);
        g.fillRect(x, y, 25, 25);
    }

}

Window类设置游戏的框架:

代码语言:javascript
复制
import java.awt.Canvas;
import java.awt.Component;

import javax.swing.JFrame;

public class Window extends Canvas{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Player1 p1;

    public Window(Game game, int Height, int Width, Boolean playing){
        JFrame frame = new JFrame("Pong");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT);
        frame.setResizable(false);
        frame.setUndecorated(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLocationRelativeTo(null);
        frame.add(game);

        frame.addKeyListener(new KeyInput(playing));//add this shit to the frame you twat (spent 3-4 hours trying to figure thius out)
        frame.setFocusable(true);

        frame.setVisible(true);
    }

    public Player1 getPlayer1(){
        return p1;
    }

}

KeyInput类处理所有输入:

代码语言:javascript
复制
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyInput implements KeyListener{

    private Game game;
    private Player1 p1;
    private Player2 p2;

    public KeyInput(Boolean playing){
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if(key == KeyEvent.VK_ESCAPE){
            System.exit(0);
        }
        if(key == KeyEvent.VK_R && Game.gameover == true){
            Game.playing = true;
            System.out.println(Game.playing);
            Game.gameover = false;
            Game.p1won = false;
            Game.p2won = false;  
        }
        if(key == KeyEvent.VK_SPACE && Game.playing == false && Game.gameover == false) Game.playing = true;
        else if(key == KeyEvent.VK_SPACE && Game.playing == true) Game.playing = false;


        //player ones movement
        if(key == KeyEvent.VK_W)p1.up = true;
        else if(key == KeyEvent.VK_S) p1.down = true;

        //player two's movement
                if(key == KeyEvent.VK_UP)p2.up = true;
                else if(key == KeyEvent.VK_DOWN) p2.down = true;
    }     

    public void keyReleased(KeyEvent e) {
        Player1.down = false;
        Player1.up = false; 
        Player2.down = false;
        Player2.up = false; 
    }

    public void keyTyped(KeyEvent e) {

    }

}

玩家1:

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Player1 {

    public static int x = 150;
    public static int y = 500;
    public static int score = 6;
    public String scorestr;

    static Boolean up = false;
    static Boolean down = false;


    public void update(int height){
        if(y<=height  - 150)if(down)y += 2;
        if(y>= 0)if(up)y -= 2;
    }
    public void render(Graphics g, int width){
        //scoreStr = score;
        Font f1 = new Font("Arial", 0, 150);
        g.fillRect(150, y, 25, 150);
        scorestr = Integer.toString(score);
        g.setFont(f1);
        g.drawString(scorestr, width /2 -150, 150);
    }

}

玩家2:

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

public class Player2 {

    public static int y = 500;

    public static int score;
    public String scorestr;

    static Boolean up = false;
    static Boolean down = false;

    public void update(int height){
        if(y<=height  - 150)if(down)y += 3;
        if(y>= 0)if(up)y -= 3;
    }
    public void render(Graphics g, int width){
        scorestr= Integer.toString(score);
        Font f1 = new Font("Arial", 0, 150);
        g.setFont(f1);
        g.setColor(Color.white);
        g.fillRect(width- 150, y, 25, 150);
        g.drawString(scorestr, width /2 + 150, 150);
    }

}

我想从这件事中学到尽可能多的东西,所以我要残忍地诚实,并试图突出一些积极的方面。

EN

回答 1

Code Review用户

回答已采纳

发布于 2017-01-10 06:50:59

Player

为什么你有一个Player1Player2的类。将其重构为Player类。

碰撞检测

你的碰撞检测不是一个好方法。你让Ball检测碰撞。我会将这个逻辑移到Game或其他类中,后者的目的是检测冲突。

见这个答案

通常的碰撞检测方法是不让A或B单独检测碰撞。

然而,你有Ball做自己的工作。

相反,首先移动所有对象,然后让一个单独的碰撞系统查找所有对对象之间的冲突,告诉每个对象与其发生冲突的事情,然后最后呈现所有对象。

Ball可以有一个类似于collided(who)的方法,但关键是,Game确定何时调用该方法,而Game则告诉ball who。球不应该把这一切弄清楚。

重申:ball不应该决定它是否碰撞,相反,游戏应该告诉Ball:“嘿,伙计,你撞了”,Ball应该对此做出反应。

票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/152205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档