That moving-through-space effect

That is, black background and white pixels moving towards and “past” the screen. I suspect this is a common question, but I coundn’t find a thread about it using the search function so here it goes.

What I want to do is have this feature as background in a Tetris clone I’m writing so that the area around the playing field will be moving space.

This sounds a lot like something which could (should) be implemented using a particle system. Has anyone got any advice, code examples or useful links to tutorials etc? :slight_smile:

A full-blown particle system is probably overkill. As you only need a small subset of typical functionality, it might be easier to just “brute force” it.

Keep an array of all the stars’ positions and an angle, each tick calculate the new position using trigonometry, and render the lot as points. When a star moves out of the screen, reset the (x, y) position to the centre of the screen and pick a new angle.

If you want to be really smart, make the stars towards the middle darker than the ones nearer the edges to give the impression of moving towards the camera; have some stars moving slower and give them a darker maximum brightness to represent stars a long way away.

This is taken from my old ‘Duke Rogers’ game:


import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;

/**
 * @author Erik Duijs
 */
public class StarField {
      
      int STARS;
      int SCREEN_W;
      int SCREEN_H;
      int X_SPR;
      int Y_SPR;

      float[] starX;
      float[] starY;
      float[] starZ;
      
      int x,y,z,c,s;
      
      public StarField(int stars, Component c) {
            STARS = stars;
            starX = new float[STARS];
            starY = new float[STARS];
            starZ = new float[STARS];
            SCREEN_W = c.getWidth();
            SCREEN_H = c.getHeight();
            X_SPR = SCREEN_W * 25;
            Y_SPR = SCREEN_H * 25;
        for (int i = 0; i < STARS; i++) {
              starX[i] = (int)(X_SPR * Math.random()) - X_SPR / 2;
              starY[i] = (int)(Y_SPR * Math.random()) - Y_SPR / 2;
              starZ[i] = (int)(1000 * Math.random()) + 1;
        }
      }
      
      public void update(Graphics g, float speed) {
        for (int i = 0; i < STARS; i++) {
              x = (int)(SCREEN_W / 2 + (starX[i] / starZ[i]) * 32);
              y = (int)(SCREEN_H / 2 + (starY[i] / starZ[i]) * 32);
              c = (int)((1020 - starZ[i]) / 4);
              s = c >> 6;
              //if (s < 1) s = 1;
              g.setColor(new Color(c,c,c));
              starZ[i] -= speed;
               if (starZ[i] < .1 || x < 0 || y < 0 || x >= SCREEN_W || y >= SCREEN_H) {
                    starZ[i] = 1000;
                        starX[i] = (int)(X_SPR * Math.random()) - X_SPR / 2;
                        starY[i] = (int)(Y_SPR * Math.random()) - Y_SPR / 2;
              }
              g.fillRect(x,y,s,s);
        }
      }      

}

It’s old code and uncommented, but you just create the StarField by passing the number of stars and the component on which to draw to the constructor (the starfield will take the size of the component), then you draw it by calling update() and passing the Graphics object and the speed of the starfield to it.

I hope this helps.

Erik

Hey, that code worked perfectly! Thanks! :slight_smile: