Использование float, когда методы требуют аргументов int?

1

Я пишу игру в java, где астероиды летают по экрану, чтобы попасть в космический корабль. Скорость астероидов - это поплавок, но значения X и Y каждого астероида являются целыми числами. В результате движение астероидов прыгает каждый раз, когда скорость достигает нового целочисленного значения. Я не могу использовать значения float или double для значений X и Y, потому что для класса прямоугольника, который мне нужен для столкновения, требуется ints в качестве аргументов.

Я попробовал функцию с использованием двойников, чтобы использовать функцию потолка,

    public static int doubleToInt(double d){
    int i = Math.ceil(d);       
}

но это тоже дало проблему с преобразованием в целые числа. Есть лучший способ сделать это?

edit: применимый код для класса астероидов:

import java.awt.*;
import java.util.Random;

public class Asteroid {
// the main enemy class of the game, an asteroid!
// these are generated through a for loop in the main game loop.
int x ;
int y ;
int r = 4; // radius of each asteroid. 
static float speed = 1;; // speed of asteroids, increases as time goes by.

void move(Asteroid rock){
    if(hasReachedBottom(rock)){
        //rock.x = randInt(520,550); // random to start, so that the asteroids may be offset a bit.
        //rock.y = randInt(0,Game.theGame.getHeight()); // y position, constant for each asteroid. Casted as an int. random number
        initAsteroids(rock,rock.r + 500,501 + rock.r );// this range is for after the asteroids spawn.
        //rock.x = 100;
    }
    x -= speed;
}

private boolean hasReachedBottom(Asteroid rock){
    if(rock.x + rock.r < 0){
        return true;
    } else {
        return false;
        }

}
void paint(Graphics2D g){ // render an asteroid
    g.setColor(Color.RED);
    g.fillOval(x, y, r, r);
}

public Rectangle getBounds(Asteroid rock){
    return new Rectangle(rock.x,rock.y,rock.r,rock.r);

}

}

  • 0
    Вы можете опубликовать обновление позиции для астероида? «В результате движение астероидов скачет каждый раз, когда скорость достигает нового целочисленного значения» -> если это происходит пиксель за пикселем, он не должен прыгать и не быть «резким». Может быть, есть умножение / деление, неправильно округленное до int перед фактическим размещением прямоугольника, и это делает движение прерывистым
  • 1
    Почему это дает слишком много проблем? Пиксели на экране дискретны. Вы не можете рисовать между пикселями на экране. Кстати, я бы использовал Math.round (d) или обычный (int) d
Показать ещё 5 комментариев
Теги:

5 ответов

1
Лучший ответ

Если вы хотите использовать двойное значение для int, вы можете просто:

int i = (int)d;

Если вы посмотрите на это, вы увидите, что произойдет в случае двойных чисел от 0 до 2:

    for(double d = 0; d < 2; d+=0.1) {
        System.out.print((int)d);
    }

Вот распечатка:

0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1

В вашем случае двойной (скорость) будет увеличиваться и влиять на космический корабль каждый раз, когда он достигает нового целого. Это будет иметь место, если ваша система координат дискретна.

1

Да, просто выполните:

int i = ((int)d); // cast to int - same like applying Math.floor()
i += (d-i > 0 ? 1 : 0); // in case the fraction part of the integer is bigger than zero, add 1 (ciel)

Это фактически реализует одно и то же поведение Math.ciel()

  • 0
    пожалуйста, добавьте небольшое объяснение вашего кода
  • 0
    @Philip хорошая идея
0

Тип возврата Math.ceil(double) - только double. поэтому лучше использовать Double-wrappper-класс Double, у которого есть функция, чтобы получить значение int double и вернуть значение int из intValue(), метод intValue внутренне выполняет typecasting для int, то, что уже делает java, то зачем писать некоторые дополнительные код -
вы можете сделать это.

Double k= Math.ceil(d);
int i=k.intValue();
  • 1
    Не могли бы вы уточнить это?
  • 0
    Возвращаемый тип Math.ceil (double) - только double. так что лучше использовать класс Double-обертки Double, который имеет функцию для получения значения int из double и возврата значения int из intValue (). Метод intValue внутренне выполняет типизацию типов в int, что уже делает Java, зачем писать некоторый дополнительный код
Показать ещё 1 комментарий
0

Присвоение double int является сужающим преобразованием, поэтому неявный листинг (то, что вы имели в своем коде) не допускается языком. Если вы четко укажете свои намерения с актом, код будет скомпилирован:

int i = (int) Math.ceil(d);

Я должен сказать, что ваш метод округления немного необычен, но если это то, что вам нужно, пусть будет так. Некоторые альтернативы состоят в том, чтобы использовать Math.round(d) и отбрасывать это, или округлять, путем литья d в int.

  • 0
    Вы можете разыграть удвоение до int.
  • 0
    ... что я сказал?
Показать ещё 2 комментария
0

Вы можете легко смешивать математику с плавающей запятой и целым числом (практически на любом языке), только компилятор требует, чтобы она говорила явно, когда вы желали преобразований типов, которые могут потенциально переполняться.

Простым дизайном было бы просто использовать float (или double) для координат и просто сбрасывать int при создании прямоугольника:

int i = (int) floatValue;

На самом деле не имеет большого значения, какой метод преобразования вы выбрали, альтернативой будет Math.round(), floor() или ceil() - если вы постоянно используете его везде (избегая сравнивать яблоки с апельсинами).

Поскольку позиция уже инкапсулирована в вашем классе астероидов, а также метод перемещения находится в классе астероидов, это не должно требовать много изменений.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню