Форум программистов, компьютерный форум, киберфорум
Java
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390

Как в игре Osmos сделан поток частиц у главного шара, которым ты движешь?

05.09.2017, 12:19. Показов 6789. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как в игре Osmos сделан поток частиц у главного шара, которым ты движешь?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.09.2017, 12:19
Ответы с готовыми решениями:

Как сделан задний фон в игре Osmos?
Как сделан задний фон в игре Osmos? https://www.youtube.com/watch?v=GhR6jptGc84

Как сделан самый первый лвл в игре Osmos
Линия вокруг шара идет и закрывается вот это как? https://www.youtube.com/watch?v=GhR6jptGc84 Начинается на 3 минуте. Добавлено...

Как нарисована гибкая линия маршрута движения главного круглишка в игре Osmos?
Как нарисована гибкая линия маршрута движения главного круглишка в игре Osmos? https://www.youtube.com/watch?v=dLgSsBby9ns

15
164 / 170 / 139
Регистрация: 28.11.2016
Сообщений: 301
11.09.2017, 22:00
Лучший ответ Сообщение было отмечено Aassians как решение

Решение

Class Point
Кликните здесь для просмотра всего текста
Java
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
public class Point {
    private double x;
    private double y;
 
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
 
    public double getX() {
        return x;
    }
 
    public void setX(double x) {
        this.x = x;
    }
 
    public double getY() {
        return y;
    }
 
    public void setY(double y) {
        this.y = y;
    }
 
 
 
}

Class Meteor
Кликните здесь для просмотра всего текста
Java
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
import java.awt.*;
import java.util.Random;
 
public class Meteor {
    private static double MAX_RADIUS = 10;                 // 250 метров radius from center
    private static double BASE_SIZE = 250;                 // 250 метров radius from center
    private static double MIN_RADIUS = BASE_SIZE / 100;    // 0.005 radius from center
    private static double MAX_SIZE = BASE_SIZE / 25;      // used as mass
    private static double MIN_SIZE = BASE_SIZE / 100;     // used as mass
    private static double MAX_SPEED = BASE_SIZE / 100;
    private static double MIN_SPEED = BASE_SIZE / 1000;
    private static int MAX_INERTION = 25;  // скорость падает на 100 тиков
    private static Color[] colors = new Color[]{
            Color.BLACK, Color.GREEN, Color.GRAY, Color.BLUE, Color.CYAN, Color.MAGENTA,
            Color.ORANGE, Color.RED, Color.YELLOW, Color.PINK
    };
 
    private static Random rnd = new Random();
 
    private int inertion;  // speed inertion counter
    private Point speed;
    private Point delta;
    private double mass;    // radius used as mass
    private Point point;
    private double radius;  // radius of object
    private Color color;
    private boolean isCollision;
 
 
    public Meteor(Point point) {   // center point around
        isCollision = false;
        radius = getRandom(MIN_SIZE, MAX_SIZE);  // radius of object
        mass = radius;
        this.point = new Point(getRandom(MIN_RADIUS, MAX_RADIUS, rnd.nextBoolean()) + point.getX(),
                getRandom(MIN_RADIUS, MAX_RADIUS, rnd.nextBoolean()) + point.getY());
        speed = new Point(getRandom(MIN_SPEED, MAX_SPEED, rnd.nextBoolean()),
                getRandom(MIN_SPEED, MAX_SPEED, rnd.nextBoolean()));
        delta = new Point(speed.getX() / MAX_INERTION, speed.getY() / MAX_INERTION);
        color = colors[rnd.nextInt(colors.length)];
        inertion = MAX_INERTION;
    }
 
    public Color getColor() {
        return color;
    }
 
    public Meteor(Point point, Point speed) {   // center point around
        isCollision = false;
        radius = getRandom(MIN_SIZE, MAX_SIZE);  // radius of object
        mass = radius;
        this.point = new Point(getRandom(MIN_RADIUS, MAX_RADIUS, rnd.nextBoolean()) + point.getX(),
                getRandom(MIN_RADIUS, MAX_RADIUS, rnd.nextBoolean()) + point.getY());
 
        setSpeed(speed);
        color = colors[rnd.nextInt(colors.length)];
 
    }
 
    private double getRandom(double min, double max, boolean dir) {
        int sign = dir ? 1 : -1;
        return (sign) * (rnd.nextDouble() * (max - min) + min);  // range
    }
 
    private double getRandom(double min, double max) {
        return rnd.nextDouble() * (max - min) + min;  // range
    }
 
 
    /**
     * Проверяет есть ли наложение по трем измерениям
     * данного метеорита с other
     *
     * @param other другой метеорит
     * @return true если по трем измерениям есть наложение, значит есть столкновение
     */
    public boolean collisionCheck(Meteor other) {
 
        if (Math.abs(point.getX() - other.point.getX()) < radius + other.radius &&
                Math.abs(point.getY() - other.point.getY()) < radius + other.radius) {
            return true;            // collision detected по всем трем измерениям идет наложение
        }
        return false;
    }
 
    private int counter = 0;
 
    private void updateSpeed(Meteor other) {         // if collision detected
        // не реализовано
    }
 
    public void update() {
        point.setX(point.getX() + speed.getX());
        point.setY(point.getY() + speed.getY());
 
        if (inertion > 0) {
            inertion--;
            if (Math.abs(speed.getX()) > Math.abs(delta.getX())) {
                speed.setX(speed.getX() - delta.getX());
            } else {
                speed.setX(0);
            }
            if (Math.abs(speed.getY()) > Math.abs(delta.getY())) {
                speed.setY(speed.getY() - delta.getY());
            } else {
                speed.setY(0);
            }
        }
    }
 
 
    /**
     * Проверяет есть ли столкновение метеорита с other
     * если есть столкновение изменить скорости метеоритов
     * для изменения скоростей берется в расчет масса метеорита и скорость
     *
     * @param other другой метеорит
     */
    public boolean collision(Meteor other) {
        if (collisionCheck(other)) {  // столкновения есть
            updateSpeed(other);       // обновить скорости
            isCollision = true;
        }
        return isCollision;
    }
 
    public Point getSpeed() {
        return speed;
    }
 
    public Point getPoint() {
        return point;
    }
 
    public double getRadius() {
        return radius;
    }
 
    public void setSpeed(Point speed) {
        this.speed = speed;
        delta = new Point(speed.getX() / MAX_INERTION, speed.getY() / MAX_INERTION);
        inertion = MAX_INERTION;
    }
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("[ pos: %7.3f,%7.3f ", point.getX(), point.getY()));
        sb.append(String.format("  v:%7.3f,%7.3f ", speed.getX(), speed.getY()));
        sb.append(String.format(" r:%7.4f m:%7.4f ]", radius, mass));
        if (isCollision) {
            sb.append("*");
            isCollision = false;
        }
 
        return sb.toString();
    }
}

Class MeteorFlow
Кликните здесь для просмотра всего текста
Java
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
import edu.princeton.cs.algs4.StdDraw;
 
import java.awt.*;
import java.util.Random;
 
public class MeteorFlow {
    private final Meteor[] flow;
    private final int size;
    private static int count;
    private static Random rnd = new Random();
 
 
    public MeteorFlow(int size, Point point) {   // meteors around point
        this.flow = new Meteor[size];
        this.size = size;
 
        for (int i = 0; i < size; i++) {
            flow[i] = new Meteor(point);
        }
        count = 0; // timer
    }
 
    public MeteorFlow(int size, Point point, Point speed) {   // meteors around point
        this.flow = new Meteor[size];
        this.size = size;
 
        for (int i = 0; i < size; i++) {
            flow[i] = new Meteor(point, speed);
        }
        count = 0; // timer
    }
 
    public void update() {
        for (int i = 0; i < size; i++) {  // смена позиции каждого метеорита
            flow[i].update();
        }
 
        for (int i = 0; i < size; i++) {        // проверка коллизий
            for (int j = 0; j < size; j++) {
                if (i == j) {
                    continue;
                }
                flow[i].collision(flow[j]);
            }
        }
        count++;
    }
 
    public Meteor get(int index) {
        if (flow == null || index < 0 || index >= flow.length) {
            throw new IllegalArgumentException();
        }
        return flow[index];
    }
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Meteors flow state: " + count + "\n");
        for (int i = 0; i < size; i++) {
            sb.append(flow[i].toString() + "\n");
        }
 
        return sb.toString();
    }
 
 
    private static MeteorFlow genFlow(Point center, Point mouse, double size, int n) {
 
        double distance = Math.sqrt(Math.pow(center.getX() - mouse.getX(), 2) +
                Math.pow(center.getY() - mouse.getY(), 2));
 
        double coeff = size / (distance * 10);  // coeff
        Point point = new Point(center.getX() + coeff * (mouse.getX() - center.getX()),
                center.getY() + coeff * (mouse.getY() - center.getY()));
 
        MeteorFlow flow = new MeteorFlow(n,
                new Point(point.getX(), point.getY()),
                new Point(0, 0));               // поток на 10 метеоритов вокруг 0.5,0.5
        return flow;
    }
 
    private static void setFlow(MeteorFlow flow, Point mouse) {
        for (int i = 0; i < flow.flow.length; i++) {
            Meteor meteor = flow.flow[i];
            Point point = meteor.getPoint();
            double dx = mouse.getX() - point.getX();
            double dy = mouse.getY() - point.getY();
            double speedX = rnd.nextDouble() * dx / 20 + dx / 100;  // speed = 0.01..0.05 od distance
            double speedY = rnd.nextDouble() * dy / 20 + dy / 100;  // speed = 0.01..0.05 od distance
            meteor.setSpeed(new Point(speedX, speedY));
        }
    }
 
 
    public static void main(String[] args) {
 
        int n = 10;
        double size = 1000; // size of canvas  1000 point
        Meteor circle = new Meteor(new Point(size * 0.5, size * 0.5), new Point(0,0));
 
        MeteorFlow flow = genFlow(circle.getPoint(), circle.getPoint(), size, n);
 
        StdDraw.enableDoubleBuffering();
        StdDraw.clear();
        StdDraw.setPenColor(StdDraw.BLACK);
        StdDraw.setCanvasSize(800, 800);
        StdDraw.setXscale(-0.05 * size, 1.05 * size);
        StdDraw.setYscale(-0.05 * size, 1.05 * size);   // leave a border to write te
        StdDraw.setPenColor(StdDraw.BLACK);
        StdDraw.setPenRadius(0.001);
 
 
        while (true) {
            if (StdDraw.mousePressed()) {
                Point mouse = new Point(StdDraw.mouseX(), StdDraw.mouseY());
                flow = genFlow(circle.getPoint(), mouse, size, n);
                setFlow(flow, mouse);
 
                double dx = mouse.getX() - circle.getPoint().getX();
                double dy = mouse.getY() - circle.getPoint().getY();
                circle.setSpeed( new Point(-dx/100,-dy/100));
            }
 
 
            StdDraw.setPenColor(Color.BLACK);
            StdDraw.circle(circle.getPoint().getX(),circle.getPoint().getY(),size/10);
 
            for (int j = 0; j < flow.size; j++) {
                Meteor meteor = flow.flow[j];
                Point point = meteor.getPoint();
                StdDraw.setPenColor(meteor.getColor());
                StdDraw.filledCircle(point.getX(), point.getY(), meteor.getRadius());
            }
 
 
            StdDraw.show();
            StdDraw.pause(100);
            StdDraw.clear();
            flow.update();    // update all meteors
            circle.update();  // update central circle
        }
 
    }
}

Сморите код. Если кликнуть мышкой по любой точке экрана вылетят метеориты как в Osmos.
При запуске иммитируется нажатие мышкой.
В проекте использована библиотека университета Prinston agls4.jar http://algs4.cs.princeton.edu/code/
Проект с подключенной библиотекой для Intellij IDEA по ссылке https://cloud.mail.ru/public/DyYr/w7FbM2UQq
2
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
16.08.2018, 05:46  [ТС]
А такое можно сделать на С# для Unity 3D?
0
0 / 0 / 0
Регистрация: 15.08.2018
Сообщений: 7
16.08.2018, 07:03
А такое можно сделать на С# для Unity 3D?
Можно конечно. Никаких преград я здесь не вижу
0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
17.08.2018, 07:50  [ТС]
Там используется библиотека университета Prinston такую можно найти на C#?
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
17.08.2018, 11:31
Цитата Сообщение от Aassians Посмотреть сообщение
такую можно найти на C#
Почему бы это не спросить в теме по C#?
0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
16.09.2018, 16:56  [ТС]
Запускал код очень похоже , как в игре , но немного не так.

Добавлено через 27 секунд
Ещё интересно, Как сделано в игре увеличение и уменьшение.
0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
19.01.2019, 14:05  [ТС]
В Osmos струя шикарнее, такая четкая.
0
19.01.2019, 14:26

Не по теме:

Очень информативное сообщение. Очччень

0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
20.01.2019, 06:56  [ТС]
Нашел про частицы на си++ с примером, может кто поможет переделать , чтобы как тут на 4 минуте получилось?

https://www.youtube.com/watch?v=hftJD4Yt_Dk

пример на си++
https://yadi.sk/i/8XnrjNx86954mw

книга
https://yadi.sk/d/RqxMKbTzuJwckg

Добавлено через 2 минуты
DEMO13_10.CPP
0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
13.04.2019, 05:01  [ТС]
Как струю сделать, как в игре? Тут жалкая породия.
0
Эксперт Java
 Аватар для KEKCoGEN
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
13.04.2019, 10:01
Очередное обострение?)
0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
13.04.2019, 13:23  [ТС]
хочу завершить проект...
0
13.04.2019, 22:02

Не по теме:

оптимистичненько :D

0
12 / 4 / 0
Регистрация: 23.11.2014
Сообщений: 390
14.04.2019, 09:04  [ТС]
Ещё частицы в игре поворачиваются по бывшей траектории , могут закруглённо лететь.
0
wound up as Aussie
462 / 114 / 20
Регистрация: 15.05.2019
Сообщений: 452
10.05.2025, 20:36
Цитата Сообщение от Aassians Посмотреть сообщение
Как в игре Osmos сделан поток частиц у главного шара, которым ты движешь?
Игра Osmos с увеличением гравитации от массы игрока
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.05.2025, 20:36
Помогаю со студенческими работами здесь

Как в игра Osmos в F 1 0 сделано притяжение главного круга?
Как в игра Osmos в F 1 0 сделано притяжение главного круга? Круга, которым ты движешь, вначале там кольцо потом , когда начинаешь...

Создать отчет из формы на которым сделан поиск
Создана форма с поиском. Поиск работает, как сделать что бы создалось отчет с итогами поиска... :wall::scratch:

Как сделать вторичный поток с постоянный жизненным циклом и управлением из главного потока
Имеется объект, который живёт в другом потоке и выполняет различные задачи по запросам или выполняет повторяющиеся задачи. Более...

Как усыплять дочерний поток реализуя управление элементами из главного потока методом Invoke
как управлять элементами из главного потока в дочернем? Если напишите методом Invoke, то объясните тогда - как заставять в определённых...

Найти зависимость напряженности и потенциала шара от расстояния до центра шара как внутри, так и вне шара
2.Имеется шар радиусом R, равномерно заряженный по объему с объемной плотностью ρ (нКл/м3). Найти зависимость напряженности и потенциала...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru