在Java Ping Pong游戏中,如何使桨的一侧成为机器人?

时间:2019-06-06 05:23:40

标签: java processing

我正在制作一个Java乒乓游戏,并且我想使桨的一侧成为机器人,以便玩家可以与机器人竞争。我已经输入了机器人程序,但是我想对其进行改进。我试图创建一个线程来每隔x秒暂停bot,但是失败了。请帮忙找出解决方案。

我已经对桨和球进行了预编程,包括检查碰撞这类东西。游戏可以认为是完整的。我只想添加一个机器人,所以它将是PVE

这是桨码

import processing.core.PApplet;
import processing.core.PFont;

public class Paddle {
private char upKey, downKey;
private boolean upDown, downDown;
private float x,y,width,height,speed;
private int r,g,b; //colors
private int score;
private PFont scoreFont;

public Paddle(float x, float y, float w, float h, float s, char up, 
        char down, int r, int g, int b, int score, PFont f) {
    scoreFont = f;
    this.x = x;
    this.y = y;
    upKey = up;
    downKey = down;
    width = w;
    height = h;
    speed = s;
    this.r = r;
    this.g = g;
    this.b = b;
    score = 0;
}

public void draw(PApplet p) {
    p.rectMode(PApplet.CENTER);
    p.noStroke();
    p.fill(r, g, b);
    p.rect(x, y, width, height);

    p.textFont(scoreFont, 46);
    p.fill(255);
    p.text(score, PongMain.SCR_W-x-15, 50);
}

public void handlePress(char key) {
    if(key == upKey)
        upDown = true;
    else if (key == downKey) 
        downDown = true;
}

public void handleRelease(char key) {
    if(key == upKey) {
        upDown = false;
        speed = 15;
    }
    else if (key == downKey) {
        downDown = false;
        speed = 15;
    }
}

public void update() {
    if(upDown) {
        y = (float) (y - speed * 1.1);
    }else if(downDown) {
        y = (float) (y + speed * 1.1);
    }
    if(this.y >= PongMain.SCR_H - this.height/2) {
        this.y = PongMain.SCR_H - this.height/2;
    }
    if(this.y <= 0 + this.height/2) {
        this.y = 0 + this.height/2;
    }
}

public void bot(Ball theBall){
    if( theBall.getY() < y){
        y = y - speed;
    }else{
        y = y + speed;
    }
}

public float getX() {
     return x;
}

public float getY() {
     return y;
}

这是球代码:

package ball;
import processing.core.PApplet;

public class Ball {
float x, y, diameter, speed;
float direction;
int color[] = new int [3];

public Ball(float x,float y,float diameter,float speed,float direction, int red, int green, int blue) {
    this.x = x;
    this.y = y;
    this.diameter = diameter;
    this.speed = speed;
    this.direction = direction;
    color[0] = red;
    color[1] = green;
    color[2] = blue;
    }

    public void draw(PApplet p) {
    p.noStroke();
    p.fill(color[0],color[1],color[2]);
    p.ellipse(x, y, diameter, diameter);
    }

    public void update() {
    x+= speed * PApplet.cos(direction);
    y+= speed * PApplet.sin(direction);
    speed += 0.01;
    }

    private void reset() {
    y = PongMain.SCR_H/2;
    x = PongMain.SCR_W/2;

    int n = (int)(Math.random() * 4);
    if (n == 0) {
        direction = ((float)Math.random()*70 +100);
    }else if (n == 1) {
        direction = (float)Math.random()*70 +100;
    }else if (n == 2) {
        direction = (float)Math.random()*70 +190;
    }else if (n == 3) {
        direction = (float)Math.random()*70 +280;
    }
    }

    public void checkCollision(Paddle lPad, Paddle rPad) {
    //if Bleft to the left of LpadRight
        //if  Bally <ytop >ybottom
     if(x <= diameter/2 ) {
         lPad.increScore();
            reset();
     }

     if(x + diameter/2 >= PongMain.SCR_W) {
         rPad.increScore();
            reset();
     }

     if (y <= diameter/2 || y+diameter/2 >= PongMain.SCR_H) {
        direction = -direction;
     }

    if(x-diameter/2 <= lPad.getX() + PongMain.PAD_W/2) {
        if(y<=lPad.getY()+ PongMain.PAD_H/2 && y>=lPad.getY()-PongMain.PAD_H/2) {
                direction = PApplet.PI - direction;
            }   
    }  

    if(x+diameter/2 >= rPad.getX() - PongMain.PAD_W/2) {
        if(y<=rPad.getY()+ PongMain.PAD_H/2 && y>=rPad.getY()-PongMain.PAD_H/2) {
                direction = PApplet.PI - direction;
        }
    }
}

}

这是主要代码:

   import processing.core.PApplet;
   import processing.core.PFont;
   import java.awt.event.KeyEvent;

 public class PongMain extends PApplet {
    final static public int SCR_W = 1000;
    final static public int SCR_H = 800;
    final static public int frameRate = 50;
    public static final int PAD_H = 150;
    public static final int PAD_W = 20;
    public static final int PADDING = 30;
    public static final int PAD_Speed = 15;
    public static final int Ball_Speed = 10;
    public static final int Winningscore = 5;

Ball theBall;
Paddle lPad;
Paddle rPad;

public static void main(String[] args) {
    PApplet.main("PongMain");
    /**PongMain run = new PongMain();
    Thread thread = new Thread(run);
    thread.start();**/
}

public void settings(){
    size(SCR_W, SCR_H);
}

public void setup(){
    frameRate(frameRate);
    theBall = new Ball(SCR_W/2, SCR_H/2,30,Ball_Speed,PI/6,255,45,60);
    PFont f= createFont("Verdana", 16, true);
    lPad = new Paddle(PADDING, SCR_H/2,PAD_W, PAD_H, 
PAD_Speed,'w','s',255,43,80,0,f);
    rPad = new Paddle(SCR_W-PADDING,SCR_H/2, PAD_W, PAD_H, 
PAD_Speed,'i','k',50,79,80,0,f);
    }



/* Run once for every frame */
public void draw(){
    if(lPad.getScore() < Winningscore && rPad.getScore() < Winningscore) {
        lPad.update();
        rPad.update();
        background(0);
        theBall.draw(this);
        theBall.update();
        theBall.checkCollision(lPad, rPad);
        lPad.draw(this);
        rPad.draw(this);
    }else {
        PFont f= createFont("Verdana", 16, true);
        this.textFont(f, 46);
        this.fill(255);
        this.text("Game is ended! Try again?", SCR_W/2-300, SCR_H/2);
        this.text("Press R to restart!", SCR_W/2-200, SCR_H/2+100);
    }
    rPad.bot(theBall);
}

//The keyPressed() function is called once every time a key is pressed. 
//The key that was pressed is stored in the key variable. 
public void keyPressed() {
    lPad.handlePress(key);
    rPad.handlePress(key);
    if(key == 'r') {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setup();
    }
}

public void keyReleased() {
    lPad.handleRelease(key);
    rPad.handleRelease(key);
}

/**@Override
public void run() {
    rPad.bot(theBall);
    // TODO Auto-generated method stub

}**/
}

我希望右桨与球垂直移动,以便它可以接住球并一直反弹。

1 个答案:

答案 0 :(得分:0)

听起来您有点复杂了。您无需花哨的逻辑就可以使游戏由机器人控制。这样的事情可能会让您走得很远:

if(playerTwoY < ballY){
  // player two is above the ball, move player two down
  playerTwoY++;
}
else if(playerTwoY > ballY){
  // player two is below the ball, move player two up
  playerTwoY--;
}

如果您每帧都运行此代码,则两个播放器将不断更新自身。

我强烈建议您先尝试类似的工作,然后再尝试进行更高级的操作。但是,在您完成这项工作后,您可以尝试以下几种方法:

  • 仅每X秒更新一次桨的运动。这会给机器人一个更现实的(更糟糕的)反应时间。
  • 为桨的运动增加一些随机性。这会使机器人的可预测性降低。
  • 计算球的路径并使用它来控制机器人。 (这是相当先进的功能,可能不需要获得工作版本的机器人。)