java - 在 render() 中随机更改图像,而不更改所有其他图像

标签 java android opengl-es libgdx

我关注了this tutorial用于在 LibGDX 中构建一个简单的游戏。游戏的基本思想是:有水滴落下,玩家应该通过将水桶拖到水滴落下的地方来放置它们。

在原始版本中,所有水滴都是从一个水滴图像创建的,我尝试做的是制作一系列不同水滴(不同水滴图像)的雨,因此我创建了一个不同TextureList - someDrops,并在我替换的render()中:

     batch.draw(dropImage, raindrop.x, raindrop.y); 

与:

       int random = MathUtils.random(0, 3;
       batch.draw(someDrops.get(random), raindrop.x, raindrop.y); 

我得到的是一场由不同水滴组成的雨,但它们不会分别以不同的图像落下,而是它们落下并同时改变图像。

我如何设置,以便每个水滴都会带有来自 someDrops 的随机图像,因为它以随机的 x,y 位置掉落。 我还想为每个掉落添加不同的点,我应该将其保存在哪里以及选择什么类型的集合?

public class Drop implements ApplicationListener {
   private Texture dropImage;
   private Texture bucketImage;
   private Sound dropSound;
   private Music rainMusic;
   private SpriteBatch batch;
   private OrthographicCamera camera;
   private Rectangle bucket;
   private Array<Rectangle> raindrops;
   private long lastDropTime;
   private List<Texture> someDrops;

   private Texture drop0;   
   private Texture drop1;
   private Texture drop2;
   private Texture drop3;

   @Override
   public void create() {
      // load the images for the droplet and the bucket, 64x64 pixels each
      dropImage = new Texture(Gdx.files.internal("droplet.png"));

      drop0 = new Texture(Gdx.files.internal("droplet0.png"));
      drop1 = new Texture(Gdx.files.internal("droplet1.png"));
      drop2 = new Texture(Gdx.files.internal("droplet2.png"));
      drop3 = new Texture(Gdx.files.internal("droplet3.png"));
      bucketImage = new Texture(Gdx.files.internal("bucket.png"));

      someDrops = new ArrayList<Texture>();

            someDrops.add(new Texture(drop0));
            someDrops.add(new Texture(drop1));
            someDrops.add(new Texture(drop2));
            someDrops.add(new Texture(drop3));

      camera = new OrthographicCamera();
      camera.setToOrtho(false, 800, 480);
      batch = new SpriteBatch();

      // create a Rectangle to logically represent the bucket
      bucket = new Rectangle();
      bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
      bucket.y = 20; // bottom left corner of the bucket is 20 pixels above the bottom screen edge
      bucket.width = 64;
      bucket.height = 64;

      //raindrops array and spawn the first raindrop
      raindrops = new Array<Rectangle>();
      spawnRaindrop();

   private void spawnRaindrop() {
      Rectangle raindrop = new Rectangle();
      raindrop.x = MathUtils.random(0, 800-64);
      raindrop.y = 480;
      raindrop.width = 64;
      raindrop.height = 64;
      raindrops.add(raindrop);
      lastDropTime = TimeUtils.nanoTime();
   }

   @Override
   public void render() {
      Gdx.gl.glClearColor(0, 0, 0.2f, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      camera.update();
      batch.setProjectionMatrix(camera.combined);

      // begin a new batch and draw the bucket and
      // all drops
      batch.begin();
      batch.draw(bucketImage, bucket.x, bucket.y);
      for(Rectangle raindrop: raindrops) {
         //batch.draw(dropImage, raindrop.x, raindrop.y); 
           int random = MathUtils.random(0, 4);
           batch.draw(someDrops.get(random), raindrop.x, raindrop.y); 

      }
      batch.end();

      // check if we need to create a new raindrop
      if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop();

      Iterator<Rectangle> iter = raindrops.iterator();
      while(iter.hasNext()) {
         Rectangle raindrop = iter.next();
         raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
         if(raindrop.y + 64 < 0) iter.remove();
         if(raindrop.overlaps(bucket)) {
            dropSound.play();
            iter.remove();
         }
      }
   }

最佳答案

在你的render()函数中,我相信你每帧都会调用它,你会绘制所有现有的水滴,如果需要的话创建一​​个新的水滴,并减少水滴的y位置。 问题的出现是因为每次你想要绘制现有的水滴时,你都会使用

int random = MathUtils.random(0, 4);

这可能会给你一个与之前绘制的图像不同的图像,即当它处于更高的 y 位置时。因此,当它落下时(y 递减),每次渲染时图像都会不断变化,直到它落入桶中时最终被移除。

要解决此问题,请仅在第一次渲染新水滴时获取随机图像,然后保存该图像并在水滴的整个生命周期中使用相同的图像进行绘制。用于保存相应图像的新数组的大小将与雨滴数组保持相同,除非添加了新的雨滴,在这种情况下您将获得新的随机图像。

我将添加一些代码来说明这一点,但我从未用 Java 编程或使用过 libgdx,因此您必须修复此编译器错误:)

首先创建雨滴纹理

   private Array<Texture> raindropTextures; // need an ArrayList here?

在 create() 中添加此 -

   raindropTextures = new Array<Texture>();

然后在 render() 中

   // if the sizes aren't equal, a new raindrop must have been added!!
   if(raindrops.size() != raindropTextures.size())  {
     int random = MathUtils.random(0, 4);
     raindropTextures.add(someDrops.get(random));
   }        
   for(Rectangle raindrop: raindrops, Texture texture: raindropTextures) {
        // make sure the textures and raindrops correspond here; theoritically they should
        batch.draw(texture, raindrop.x, raindrop.y); 
   }

最后 -

   Iterator<Rectangle> iter = raindrops.iterator();
   Iterator<Texture> iter2 = raindropTextures.iterator();
   //later
   iter.remove()
   iter2.remove()

关于java - 在 render() 中随机更改图像,而不更改所有其他图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27870598/

相关文章:

Android OpenGL ES 触摸添加对象

android - 使用适用于 Android 的 OpenGLEs 绘制像素

java - 创建具有样式但没有属性的 TextView(在代码中)

Java - 并发标记清除 GC 中的标记/未标记对象

android - 在android中删除内部存储文件的内容

java - Android GridView 滚动循环

java - Android:渲染器的两种不同用途

java - Double 与双数组上的 Arrays.asList().contains()

java - jetty 不关闭连接

java - 如何设置全屏OnTouchListener?