关于 libgdx:在随机位置生成随机不同的对象

Spawning random different objects at random locations

我正在制作一个游戏,其中有不同的物体从屏幕的上部落到屏幕的下部。我在如何选择要随机生成的 TextureRegion 而不是更改已经生成的 TextureRegions 时遇到问题。当我运行游戏时,假设首先生成了 electronRegion,然后当生成下一个时,假设它是一个 antiprotonRegion,第一个 electronRegion 更改为我不想要的 antiprotonRegion。

这是我的游戏类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public class GameScreenTest implements Screen {
...

@Override
public void render(float delta) {
    camera.update();

    game.batch.setProjectionMatrix(camera.combined);
    game.batch.begin();
    game.batch.disableBlending();
    game.batch.draw(background, 0, 0);
    game.batch.enableBlending();
    for(Particles particle: particles) {
        particlesControl.draw(particle.x, particle.y);
    }
    game.batch.end();

    if(TimeUtils.millis() - lastDropTime > 500) {
        particlesControl.spawn();
        particlesControl.update();
    }

    Iterator<Particles> iter = particles.iterator();
    while(iter.hasNext()) {
        Particles particle = iter.next();
        particle.y -= 200 * Gdx.graphics.getDeltaTime();
        if(particle.y + particle.height < 0) {
            iter.remove();
        }
    }
}

...

private class Particles {

    private int width;
    private int height;
    private int x;
    private int y;

    private Particles() {
    }

    private void spawn() {
        Particles particle = new Particles();
        particle.x = MathUtils.random(0, 480 - width);
        particle.y = 800;
        particle.width = width;
        particle.height = height;
        particles.add(particle);
        lastDropTime = TimeUtils.millis();
    }

    private void update() {
        choice = MathUtils.random(1, 4);
        switch(choice) {
            case 1:
                chosen = new TextureRegion(protonRegion);
                width = 75;
                height = 75;
                break;
            case 2:
                chosen = new TextureRegion(electronRegion);
                width = 75 / 2;
                height = 75 / 2;
                break;
            case 3:
                chosen = new TextureRegion(antiprotonRegion);
                width = 75;
                height = 75;
                break;
            case 4:
                chosen = new TextureRegion(antielectronRegion);
                width = 75 / 2;
                height = 75 / 2;
                break;
        }
    }
    private void draw(int x, int y) {
        game.batch.draw(chosen, x, y, width, height);
    }
}

我想知道为什么每次随机选择时所有生成的对象都会发生变化,当然还有如何解决这个问题。谢谢。


托盘这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
public class GameScreenTest implements Screen {

    final AntimatterBlast game;

    private Texture gameObjects;

    private TextureRegion electronRegion;
    private TextureRegion antielectronRegion;
    private TextureRegion protonRegion;
    private TextureRegion antiprotonRegion;

//===========================================//
//remove private TextureRegion chosen;
//===========================================//

    private TextureRegion background;

    private Music gameMusic;

    private OrthographicCamera camera;

    private Array<Particles> particles;

    private Particles particlesControl;

    private long lastDropTime;

    private int choice;

    public GameScreenTest(final AntimatterBlast game) {
    this.game = game;

    gameObjects = new Texture(Gdx.files.internal("GameObjects.png"));

    electronRegion = new TextureRegion(gameObjects, 105, 103, 50, 50);

    antielectronRegion = new TextureRegion(gameObjects, 105, 155, 46, 46);

    protonRegion = new TextureRegion(gameObjects, 6, 6, 100, 100);

    antiprotonRegion = new TextureRegion(gameObjects, 6, 108, 90, 90);

    background = new TextureRegion(gameObjects, 0, 204, 480, 800);

    gameMusic = Gdx.audio.newMusic(Gdx.files.internal("DST-ElektroHauz.mp3"));

    gameMusic.setLooping(true);

    camera = new OrthographicCamera();

    camera.setToOrtho(false, 480, 800);

    particles = new Array<Particles>();

    particlesControl = new Particles();

//===========================================//
//choice = MathUtils.random(1, 4);           //remove
//chosen = new TextureRegion(protonRegion);  //remove
//===========================================//

}

@Override
public void render(float delta) {
    camera.update();

    game.batch.setProjectionMatrix(camera.combined);
    game.batch.begin();
    game.batch.disableBlending();
    game.batch.draw(background, 0, 0);
    game.batch.enableBlending();

    for(Particles particle: particles) {
    //===========================================//
    particlesControl.draw(particle.chosen, particle.x, particle.y);
    //change
    //particlesControl.draw(particle.x, particle.y);
    //===========================================//
    }

    game.batch.end();

    if(TimeUtils.millis() - lastDropTime > 500) {

    //===========================================//
    particlesControl.spawn();
    //===========================================//

    //===========================================//
    //remove particlesControl.update();
    //===========================================//
    }

        Iterator<Particles> iter = particles.iterator();
        while(iter.hasNext()) {
            Particles particle = iter.next();
            particle.y -= 200 * Gdx.graphics.getDeltaTime();
            if(particle.y + particle.height < 0) {
                iter.remove();
            }
        }


    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void show() {
        gameMusic.play();
        particlesControl.spawn();
    }

    @Override
    public void hide() {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public void dispose() {
        gameObjects.dispose();
        gameMusic.dispose();
    }


    private class Particles {

        //===========================================//
        private TextureRegion chosen; //add variable
        //===========================================//

        private int width;
        private int height;
        private int x;
        private int y;

        private Particles() {

        }

        private void spawn() {

            Particles particle = new Particles();
            particle.x = MathUtils.random(0, 480 - width);
            particle.y = 800;
            particle.width = width;
            particle.height = height;

            //===========================================//
            particle.selectTexture();
            //===========================================//

            lastDropTime = TimeUtils.millis();

            //===========================================//
            selectTexture(); //add call
            //===========================================//

            particles.add(particle);
        }

        //===========================================//
        private void selectTexture() { //change name, but is not nesesari
        //===========================================//
            choice = MathUtils.random(1, 4);
            switch(choice) {
                case 1:
                   //===========================================//
                   //change
                   //chosen = new TextureRegion(antielectronRegion);
                   //if you are not going to change or modific TextureRegion
                   //independet other the textureRegion,
                   //I think you could use it well.It is just an idea
                   chosen = protonRegion;
                   //===========================================//

                    width = 75;
                    height = 75;
                    break;
                case 2:
                   //===========================================//
                   //change
                   //chosen = new TextureRegion(antielectronRegion);
                   //if you are not going to change or modific TextureRegion
                   //independet other the textureRegion,
                   //I think you could use it well.It is just an idea
                   chosen = electronRegion;
                   //===========================================//

                    width = 75 / 2;
                    height = 75 / 2;
                    break;
                case 3:
                   //===========================================//
                   //change
                   //chosen = new TextureRegion(antielectronRegion);
                   //if you are not going to change or modific TextureRegion
                   //independet other the textureRegion,
                   //I think you could use it well.It is just an idea
                   chosen = antiprotonRegion;
                   //===========================================//

                    width = 75;
                    height = 75;
                    break;
                case 4:
                   //===========================================//
                   //change
                   //chosen = new TextureRegion(antielectronRegion);
                   //if you are not going to change or modific TextureRegion
                   //independet other the textureRegion,
                   //I think you could use it well.It is just an idea
                   chosen = antielectronRegion;
                   //===========================================//

                    width = 75 / 2;
                    height = 75 / 2;
                    break;
            }
        }
        //===========================================//
        private void draw(TextureRegion chosen, int x, int y) {
            game.batch.draw(chosen, x, y, width, height);
        //===========================================//
        }
    }
}


就像我在之前的评论中所说的,纹理(选择的)在 GameScreenTest 中,并且您在内部类中使用它,因此 Particles 类的每个实例都将共享相同的纹理。

不会导致错误,但它可能会帮助您组织代码并使其更具可读性,并且无论如何您没有义务让它们只是将它们作为建议:

命名约定
将类命名为 Particles 使该类看起来代表不止 1 个 Particle,但实际上它代表单个 Particle 可能仅将其命名为 Particle。

分离游戏逻辑
让 Particle 类只处理自己的问题,不要用它来生成其他粒子并将其添加到外部类中。

使用构造函数,因为它已经存在
给粒子它应该使用的纹理,也许还有坐标。

绘制"死"粒子
你是先画画,然后再根据你的游戏提问,这可能会让人感觉很奇怪,因为你总是会在它不存在的时候画一个框架。

不太确定这个
但是您也许可以重用纹理区域,而不是为每个粒子创建一个具有相同纹理的新区域