gpt4 book ai didi

Java游戏-如何阻止玩家越过障碍物

转载 作者:行者123 更新时间:2023-11-30 07:20:24 25 4
gpt4 key购买 nike

我制作了一个非常简单的 2D Java 游戏类,由一般的 2D 游戏方法(如渲染和更新)组成,我设置了所有 if 语句,以便玩家使用键盘箭头输入在 map 上移动。我现在正在尝试设置我读过的是碰撞检测,我知道我需要做什么的基础知识,因为在我真正来这里问问题之前我做了很多阅读,从我读过的内容来看像这样:

制作2个矩形

Rectangle rectOne = new Rectangle(playerX, playerY, 40, 40); 
//keep in mind that the variables playerX and playerY are already made previously
Rectangle rectTwo = new Rectangle(50, 50, 100,100);

然后在我的更新方法下我会说:

if(rectOne.intersects(rectTwo)){//change the player direction so that he 
can go no further}

我只是不明白我的 if 语句中会包含什么,我需要一些东西来阻止我的玩家在交叉点发生时继续前进,但我该如何写这个,因为玩家可以在 4 个不同的方向(向上,向下)移动, 左右)。如果它只是一维的,它会简单得多,因为我可以将方向更改为与原来相反的方向,但它是二维的,所以有点困惑。

附加信息:

我玩游戏的 View 类似于以下内容: http://www.2dplay.com/awesome-tanks/awesome-tanks-play.htm

编辑 3:

                package javagame;

import java.awt.Rectangle;

IMPORTS ARE HERE


public class Play extends BasicGameState{

Animation bucky, movingUp, movingDown, movingLeft, movingRight;
Image worldMap;
boolean quit = false;//gives user to quit the game
int[] duration = {200, 200};//how long frame stays up for
int buckyPositionX = 0;
int buckyPositionY = 0;
int x = buckyPositionX + 320;//keeps user in the middle of the screem
int y = buckyPositionY + 160;//the numbers are half of the screen size

Rectangle rectOne = new Rectangle(x, y,90,90);
Rectangle rectTwo = new Rectangle(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);



private int xSpeed, ySpeed;///////////////////////////CODE FOR COLLISION


public Play(int state){
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
worldMap = new Image("res/world.png");
Image[] walkUp = {new Image("res/b.png"), new Image("res/b.png")}; //these are the images to be used in the "walkUp" animation
Image[] walkDown = {new Image("res/f.png"), new Image("res/f.png")};
Image[] walkLeft = {new Image("res/l.png"), new Image("res/l.png")};
Image[] walkRight = {new Image("res/r.png"), new Image("res/r.png")};


movingUp = new Animation(walkUp, duration, false);
movingDown = new Animation(walkDown, duration, false);
movingLeft = new Animation(walkLeft, duration, false);
movingRight = new Animation(walkRight, duration, false);

bucky = movingDown;//facing screen initially on startup
}


public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
worldMap.draw(buckyPositionX, buckyPositionY);//position 0,0
bucky.draw(x, y);//makes him appear at center of map
g.fillRect(x, y,90,90);
g.fillRect(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);


if(quit==true){
g.drawString("Resume(R)", 250, 100);
g.drawString("Main(M)", 250, 150);
g.drawString("Quit Game(Q)", 250, 200);
if(quit==false){
g.clear();//wipe off everything from screen
}
}
}

public void setSpeedWithDirection(int speed, int direction)////////////CODE FOR COLLISION
{
xSpeed = (int) (Math.cos(direction) * speed);//////////////////////////CODE FOR COLLISION
ySpeed = (int) (Math.sin(direction) * speed);//////////////////////////CODE FOR COLLISION
}

public void update(GameContainer gc, StateBasedGame sbg, int delta)throws SlickException{
Input input = gc.getInput();



x += xSpeed;//////////////////////////////////////////CODE FOR COLLISION
y += ySpeed;//////////////////////////////////////////CODE FOR COLLISION

if(rectOne.intersects(rectTwo))///////////////////////CODE FOR COLLISION
{
xSpeed = 0;////////////////////////////CODE FOR COLLISION
ySpeed = 0;////////////////////////////CODE FOR COLLISION
}



//up
if(input.isKeyDown(Input.KEY_UP)){
bucky = movingUp;//changes the image to his back
buckyPositionY += 2;;//increase the Y coordinates of bucky (move him up)
if(buckyPositionY>162){//if I reach the top
buckyPositionY -= 2;//stops any further movement in that direction
}
}

//down
if(input.isKeyDown(Input.KEY_DOWN)){
bucky = movingDown;
buckyPositionY -= 2;
if(buckyPositionY<-550){
buckyPositionY += 2;//basically change the direction if + make -
}}
//left
if(input.isKeyDown(Input.KEY_LEFT)){
bucky = movingLeft;
buckyPositionX += 2;
if(buckyPositionX>324){
buckyPositionX -= 2;//delta * .1f
}}
//right
if(input.isKeyDown(Input.KEY_RIGHT)){
bucky = movingRight;
buckyPositionX -= 2;
if(buckyPositionX<-776){
buckyPositionX += 2;
}}



//escape
if(input.isKeyDown(Input.KEY_ESCAPE)){
quit=true;
}
//when the menu is up
if(quit==true){//is the menu on the screen
if(input.isKeyDown(Input.KEY_R)){
quit = false;//resumes the game, makes menu dissapear
}
if(input.isKeyDown(Input.KEY_M)){
sbg.enterState(0);//takes you to the main menu
}
if(input.isKeyDown(Input.KEY_Q)){
System.exit(0);//quits the game
}
}

}


public int getID(){
return 1;
}
}

最佳答案

作为先决条件,您的播放器类(或其父类(super class)之一)应该有几个字段来描述它们的速度(一对 x 速度和 y 速度的字段非常有效,尽管您需要触发来设置给定方向的玩家)。下面是一个带有 x 和 y 速度字段的简单播放器类的示例:

public class Player
{
//coordinates of the player
private int x, y;

//horizontal and vertical components of the player's speed.
private int xSpeed, ySpeed;

//call a method similar to this one every time your player updates its position
public void updatePosition()
{
x += xSpeed;
y += ySpeed;
}

//Converts a speed and a direction (much easier to deal with)
//to an x speed and a y speed (much easier for actually moving)
//and sets the player's motion
public void setSpeedWithDirection(int speed, float direction)
{
xSpeed = Math.cos(direction) * speed;
ySpeed = Math.sin(direction) * speed;
}
}

为了使其真正反射(reflect)玩家的速度,每次玩家更新时将 x 速度添加到玩家的 x 坐标,并将 y 速度添加到玩家的 y 坐标。现在,碰撞发生时可能会发生很多事情。最简单的方法是通过将其 x 速度和 y 速度设置为零来停止播放器。然而,这看起来有点问题,因为无论玩家朝哪个方向前进,玩家都会停止移动。稍微好一点的方法是分析交叉点的形状(假设您使用的是 java.awt.Rectangle 您可以使用 intersection() 方法,几乎​​所有 Rectangle 类都有类似的东西)并确定是否应将 x 速度、y 速度或两者都设置为零。例如,如果交叉路口的宽度大于高度(x 轴大于 y 轴),您可能应该将 y 速度设置为零,但 x 速度不受影响。如果你想让玩家转身(180 度),只需翻转 x-speed 和 y-speed 的符号。如果您希望玩家“弹跳”而不是停止,请像之前的情况一样分析路口,但要反转速度而不是将其设置为零。这里有一些代码示例(可能不会完全按照写的那样工作,因为我不知道你的类是如何设置的):

//simple stop
if(rectOne.intersects(rectTwo))
{
player.xSpeed = 0;
player.ySpeed = 0;
}

//variable-axis stop
if(rectOne.intersects(rectTwo))
{
//depending on Rectangle implementation may need to use other method
Rectangle overlap = rectOne.intersection(rectTwo);
if (overlap.height >= overlap.width)
{
player.xSpeed = 0;
}
if (overlap.width >= overlap.height)
{
player.ySpeed = 0;
}
}

//simple turn-around (about face)
if(rectOne.intersects(rectTwo))
{
player.xSpeed *= -1;
player.ySpeed *= -1;
}

//bounce (variable-axis turn around)
if(rectOne.intersects(rectTwo))
{
Rectangle overlap = rectOne.intersection(rectTwo);
if (overlap.height >= overlap.width)
{
player.xSpeed *= -1;
}
if (overlap.width >= overlap.height)
{
player.ySpeed *= -1;
}
}

请注意,无论您选择做什么,碰撞往往都很难顺利进行。我认为所有这些选项都是很好的起点,可以始终构建。我希望这会有所帮助。

关于Java游戏-如何阻止玩家越过障碍物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14046535/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com