- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我制作了一个非常简单的 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/
在 Facebook 上,他们似乎有一个阻止您加载他们网站的 iframe 的 block 。 当您这样做时,他们会锁定其网站的全部功能 example . 我只是想知道是否有人知道如何绕过它? 最佳
我只想在已经具有顶部和底部边框(1px 纯灰色)的 div 上添加一个左边框(5px 纯蓝色)。我希望 border-left 位于 border-top 和 border-bottom 之上,但浏览
我看到了这个效果here .滚动页面时,页面的主要内容部分会移动到 div 之上。 我尝试使用视差效果重新创建此效果,但徒劳无功。问题是使用视差,我只能更改同一 div 中的 2 个对象的速度。除此之
我正在为 iOS7 优化网站。我发现,在 safari mobile 上将方向更改为横向时,网站会全屏显示,但浏览器会阻止 View 顶部和底部的一些高度和宽度像素。该区域中的任何触摸或点击事件都不会
我有一个使用 devise 进行身份验证的应用程序。 ruby 1.9.2 上的 Rails 3,passenger 位于 nginx 之上。 这是我的问题:我注意到有时我的 session 会交叉。
我是一名优秀的程序员,十分优秀!