HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Screen wraparound

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
screenwraparoundstackoverflow

Problem

I'm implementing a game with a classical screen wraparound effect. It is very simple: if the player goes out-of-screen, it reappears on the opposite side (Asteroids is a good example).

float x = getX();
float y = getY();

float screenW = screen.getWidth();
float screenH = screen.getHeight();

if (x > screenW)
    x = 0;
else if (x  screenH)
    y = 0;
else if (y < 0)
    y = screenH;

setPosition(x,y);


How can I improve this code to make it cleaner? Those multiple similar if statements especially look ugly to me.

Solution

This situation calls for a modulus operator.

The modulus operator returns the remainder from a division. So 5 % 2 = 1, 10 % 15 = 10 and so on. This is because 5 goes into 2 twice, with remainder 1. This gets a bit tricky with negative numbers, as -5 % 2 could either be -1 or 1, since -5 = -4 + -1 or -6 + 1. However, the Java language specification specifies that it will match the sign of the dividend, making -5 % 2 be -1. However, if we add the divisor, 2, we get the positive result.

Try this:

x %= screenW + 1; // the + 1 is so you get numbers from 0 to screenW
y %= screenH + 1;
/* Below is correction for negative numbers
 * (as -10 % 3 = -1 in java, whereas you want the result to be 2)
 */
if (x < 0)
    x += screenW;
if (y < 0)
    y += screenH;


You can also wrap this in a function:

private float wrapAround(float coordinate, float max) {
    coordinate %= max + 1;
    if (coordinate < 0)
        coordinate += max;
    return coordinate;


Or if you prefer a ternary conditional:

private float wrapAround(float coordinate, float max) {
    coordinate %= max + 1;
    return (coordinate < 0) ? coordinate + max : coordinate;


Then your code is:

x = wrapAround(x, screenW);
y = wrapAround(y, screenH);

Code Snippets

x %= screenW + 1; // the + 1 is so you get numbers from 0 to screenW
y %= screenH + 1;
/* Below is correction for negative numbers
 * (as -10 % 3 = -1 in java, whereas you want the result to be 2)
 */
if (x < 0)
    x += screenW;
if (y < 0)
    y += screenH;
private float wrapAround(float coordinate, float max) {
    coordinate %= max + 1;
    if (coordinate < 0)
        coordinate += max;
    return coordinate;
private float wrapAround(float coordinate, float max) {
    coordinate %= max + 1;
    return (coordinate < 0) ? coordinate + max : coordinate;
x = wrapAround(x, screenW);
y = wrapAround(y, screenH);

Context

StackExchange Code Review Q#58063, answer score: 13

Revisions (0)

No revisions yet.