简体   繁体   English

Slick2d如何检查一个形状是否包含任何对象? Java的

[英]Slick2d how to check if a shape contains any object? Java

i'm new to Slick2d and to this page too, i tried asking the slick forums, but there aren't many people so i couldn't get an answer 我是Slick2d和这个页面的新手,我试过询问光滑的论坛,但是没有多少人,所以我无法得到答案

Anyway, i've been trying to create a platformer engine in Slick2d java game library, and i was thinking of using the contains and intersects methods of the Shape class. 无论如何,我一直在尝试在Slick2d java游戏库中创建一个平台游戏引擎,我正在考虑使用Shape类的contains和intersects方法。

The thing is, if I want to check if a shape contains any object of any kind (or any object from a specific class), Is there a way to do that? 问题是,如果我想检查一个形状是否包含任何类型的任何对象(或来自特定类的任何对象),有没有办法做到这一点? all tutorials i've found explain how to test collision with one single shape, but what if i want to check for any object? 我发现的所有教程都解释了如何用单一形状测试碰撞,但如果我想检查任何对象怎么办?

package juegoconslick;

import java.util.ArrayList;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
public class JuegoConSlick extends BasicGame {

Jugador player;
Input entrada;
 Shape hitbox;
bloque bloq;
ArrayList<bloque> bloques = new ArrayList<>();
public JuegoConSlick(){

    super("Mi prueba");

}

public static void main(String[] args) {

    AppGameContainer juegito;
    try{
     juegito = new AppGameContainer(new JuegoConSlick());
     juegito.setDisplayMode(630,400,false);
     juegito.setMaximumLogicUpdateInterval(60);
     juegito.setMaximumLogicUpdateInterval(50);
     juegito.setAlwaysRender(true);
     juegito.setVSync(true);
     juegito.start();

    }catch(Exception ex){
        System.exit(0);
    }
}

@Override
public void init(GameContainer gc) throws SlickException {

     player = new Jugador();
     hitbox = new Rectangle(player.X, player.Y, 10, 10);
     bloq = new bloque(50,50,50,50);



}

@Override
public void update(GameContainer gc, int i) throws SlickException {
   intersecta();
    Input entrad = gc.getInput();
   if(entrad.isKeyDown(Input.KEY_RIGHT) && player.X<600){
       player.X+=3;
       player.sprite.update(1);
       hitbox.setX(player.X);
   }
   if(entrad.isKeyDown(Input.KEY_LEFT) && player.X>0){
       player.X-=3;
       player.sprite.update(1);
       hitbox.setX(player.X);
   }
   if(entrad.isKeyDown(Input.KEY_UP) && player.Y>0){
       player.Y-=3;
       player.sprite.update(1);
       hitbox.setY(player.Y);
   }
   if(entrad.isKeyDown(Input.KEY_DOWN) && player.Y<370){
       player.Y+=3;
       player.sprite.update(1);
       hitbox.setY(player.Y);
   }
}

@Override
public void render(GameContainer gc, Graphics grphcs) throws SlickException {
    grphcs.draw(bloq.bloque);
    grphcs.draw(hitbox);

    }

public void intersecta(){
    try{
if(hitbox.contains(null)){//i tried checking if it didnt contain any object,           

}else{
     System.exit(0);

}

    }catch(Exception ex){

    }



}

} }

EDIT: i think i have found a solution, though im not sure if its the most efficient. 编辑:我想我找到了一个解决方案,虽然我不确定它是否最有效。

basiaclly, i'll save all objects of the same class in an ArrayList: basiaclly,我将在ArrayList中保存同一个类的所有对象:

ArrayList<bloque> bloques = new ArrayList<>();
 bloques.add(new bloque(50,50,100,100));
     bloques.add(new bloque(100,100,100,100));

Then, what im going to do is check the entire arraylist each time i call the intersects method: 然后,我要做的是每次调用intersects方法时检查整个arraylist:

  public boolean intersecta(){
    boolean devuelve=false;
   for(int i=0; i<bloques.size(); i++){          
       if(hitbox.intersects(bloques.get(i).bloque)){

           devuelve=true;
       }

   }

    return devuelve;

}

then im going to use the value i get from intersects to decide whether the player can move or not 然后我将使用从交叉点得到的值来决定玩家是否可以移动

 public void update(GameContainer gc, int i) throws SlickException {

    Input entrad = gc.getInput();
   if(entrad.isKeyDown(Input.KEY_RIGHT) && player.X<600 && intersecta()==false){

       player.X+=3;
       player.sprite.update(1);
       hitbox.setX(player.X);
   }

and so on with the other keys.... so im not sure if its the best solution, but as far as i have seen it seems to be working. 等等其他键....所以我不确定它是否是最好的解决方案,但据我所知它似乎正在工作。 I hope this results useful for others. 我希望这个结果对其他人有用。

I recommend to create a new Class. 我建议创建一个新类。 This class Needs to inherit an Slick2d Shape, so for instance: 这个类需要继承Slick2d Shape,例如:

public class ShapeWithReference extends Rectangle{}

This class can have a list or a single object reference: 该类可以有一个列表或单个对象引用:

public class ShapeWithReference Rectangle{
Object reference = new String("hello"); //This is dirty and can be replaced by any object.
}

Since your new class is a Slick2D shape you can now find out whether it is contained by another shape: 由于您的新类是Slick2D形状,您现在可以找出它是否包含在另一个形状中:

Rectangle rec = new Rectangle();
if(rec.contains(ShapeWithReference)){
   if(ShapeWithReference.reference instanceof String){
       System.out.println((String)ShapeWithReference.reference);
   }
}

Contains checks whether the shape really contains another shape. 包含检查形状是否真的包含其他形状。 So they are not just intersecting. 所以他们不只是交叉。 So that's the first part you check, the second one is whether the reference Attribute of the Shape is for eg a String. 所以这是你检查的第一部分,第二部分是形状的引用属性是否用于例如字符串。 So if our first rectangle contains our new class and the reference of this class is type of a String this String is supposed to be written in to the console. 因此,如果我们的第一个矩形包含我们的新类,并且此类的引用是String的类型,则此String应该写入控制台。

Hope this helps or gives you a hint. 希望这有助于或给你一个提示。


EDIT: 编辑:

public class SlickGame extends BasicGame {

static AppGameContainer appgc;
Rectangle rec;
ShapeWithReference swr;

public SlickGame(String title) {
    super(title);
}

@Override
public void render(GameContainer container, Graphics g) throws SlickException {

}

@Override
public void init(GameContainer container) throws SlickException {
    rec = new Rectangle(0, 0, 64, 64);
    swr = new ShapeWithReference(0, 0, 1, 1);
}

@Override
public void update(GameContainer container, int delta) throws SlickException {
    if(rec.intersects(swr)){
       if(swr.reference instanceof String){
           System.out.println((String)swr.reference);
       }
       else if(swr.reference instanceof Integer){
           System.out.println((Integer)swr.reference);
       }
       else if(swr.reference instanceof Shape){
           Shape temp = (Shape)swr.reference;
           System.out.println(temp.getWidth());
       }
    }
}

public static void main(String[] args) {
    try {

        appgc = new AppGameContainer(new SlickGame("title"));
        appgc.setDisplayMode(800, 600, false);
        appgc.setTargetFrameRate(60);
        appgc.setFullscreen(false);
        appgc.start();

    } catch (SlickException ex) {
        ex.printStackTrace();
    }
}

} }

This is the code you should be able to copy & paste directly. 这是您应该能够直接复制和粘贴的代码。 It does work for me, I'm not sure if I got your problem right but after the instanceof Operator you can just add the Class Name and check for it, I added some examples with an Integer and a Shape. 它确实对我有用,我不确定我的问题是否正确但是在instanceof运算符之后你可以添加类名并检查它,我添加了一些带有整数和形状的例子。

This is the 2nd class: 这是第二课:

public class ShapeWithReference extends Rectangle {

private static final long serialVersionUID = 1L;

public ShapeWithReference(float x, float y, float width, float height) {
    super(x, y, width, height);
}

Object reference = new String("hello");

} }

Does this work for you? 这对你有用吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM