Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/65: Рейтинг темы: голосов - 65, средняя оценка - 4.63
 Аватар для MatrixDeity
7 / 7 / 1
Регистрация: 20.04.2011
Сообщений: 69

Движение объекта по диагонали

07.08.2012, 18:05. Показов 12386. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Пишу маленькое приложение: картинка летает за мышкой. Никак не могу реализовать перемещение Image, в котором и находится картинка, по диагонали. Нужно менять X и Y равномерно, чтобы Image двигался к текущему положению курсора по кратчайшему пути. Как это можно сделать?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.08.2012, 18:05
Ответы с готовыми решениями:

движение графического объекта
привет всем.собственно,проблема : при нажатии мышкой в любом месте формы некий графический объект(далее как г\о),будь то Image, Rect или...

Движение объекта в 2D. Помогите сделать прыжок
Нужно сделать движение объекта на плоскости. С перемещением вперёд-назад справился. А вот прыжок объекта (как в 2D играх) сделать не...

Движение графического объекта по траектории и его вращение
Помогите!!! Нужно нарисовать фигуру и задать движение. Начальное направление задается в виде вектора перемещения. При касании границы...

12
 Аватар для QVO
652 / 462 / 80
Регистрация: 26.10.2010
Сообщений: 1,263
Записей в блоге: 4
07.08.2012, 18:40
C++
1
2
3
4
5
6
7
8
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
 
{
Repaint();
Canvas->Draw(X, Y, KARTINKA);
}
//---------------------------------------------------------------------------
0
 Аватар для MatrixDeity
7 / 7 / 1
Регистрация: 20.04.2011
Сообщений: 69
07.08.2012, 19:16  [ТС]
Видимо я плохо объяснил, что именно мне нужно. Картинка не приклеена к курсору, она следует за ним с опозданием, как бы догоняя его. Может кто-то помнит старое приложение: винни-пух летит на воздушном шаре по рабочему столу вслед за мышкой? Вот я пишу нечто подобное.
0
49 / 44 / 8
Регистрация: 06.09.2010
Сообщений: 419
07.08.2012, 22:25
Чтобы движение было по диагонали, ты добавляешь к У и Х одно и тоже число.
C++
1
2
3
4
for (int i;i<100;i+=2){
            X+=i;
            Y+=i;
                                    }
Тогда картинка будет двигаться по диагонали. (с координатами сам мути, это я для примера показал)
0
11 / 11 / 1
Регистрация: 01.12.2011
Сообщений: 162
Записей в блоге: 2
07.08.2012, 23:53
Ставь таймер на форму
C++
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int realX, realY;
Graphics::TBitmap * vp = new Graphics::TBitmap;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
Timer1->Interval=50;//100
vp->LoadFromFile("vp.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
realX=X;
realY=Y;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Repaint();
Canvas->Draw(realX, realY, vp);
}
//---------------------------------------------------------------------------
vp.jpg прилагаю. В bmp сам конвертнёшь.
Название: vp.jpg
Просмотров: 1254

Размер: 2.1 Кб
1
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.08.2012, 09:04
Как-то так (использовал Label вместо картинки):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        Timer1->Interval = 15;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        POINT p;
        GetCursorPos(&p);
 
        POINT pp;
        pp.x = Label1->Left;
        pp.y = Label1->Top;
        ::ClientToScreen(Handle, &pp);
 
        int iSpeed = 1;
 
        if ( pp.x < p.x ) Label1->Left += iSpeed;
        else if ( pp.x > p.x ) Label1->Left -= iSpeed;
        if ( pp.y < p.y ) Label1->Top += iSpeed;
        else if ( pp.y > p.y ) Label1->Top -= iSpeed;
}
2
 Аватар для MatrixDeity
7 / 7 / 1
Регистрация: 20.04.2011
Сообщений: 69
08.08.2012, 18:05  [ТС]
Итак, ближе всего оказался вариант kzru_hunter'a, однако всё равно не то, что нужно. Да, объект движется плавно, догоняя курсор. Но вот путь его идет по кривой, а нужно по диагонали прямоугольника, образованного точкой позиции курсора и точкой позиции объекта (Label или Image, как угодно).

См. вложения: Точка А - текущая позиция Image; точка B - текущая позиция курсора (эта же точка будет конечной для Image). Если менять положение Image по рецепту kzru_hunter'а, то картинка сначала попадёт в точку С, а уже потом в В, что нежелательно. Движение объекта должно идти по прямой АВ.

Я пробовал воспользоваться формулой y=tg*x (уравнение прямой), но свойства Left и Top - целоисчислительные, а потому значения получаются неточными или не получаются вообще. Да и вообще я запутался с этим методом. Мне интересно, есть ещё какие-нибудь идеи на этот счёт?
Изображения
 
0
11 / 11 / 1
Регистрация: 01.12.2011
Сообщений: 162
Записей в блоге: 2
08.08.2012, 20:13
MatrixDeity, Если я тебя понял тебе нужно движение имэги из точки А сразу в точку B. Тогда тебе нужно учитывать коэффициент скорости на каждой оси.
Например. Квадрат по оси X 1 и по оси Y тоже 1. Получим движение точно по диагонали. Если будет прямоугольник со одной стороны (по X) в 2 раза больше чем с другой (по Y), то по оси X скорость должна быть больше в 2 раза. Дели длину большей стороны на длину меньшей стороны. Получишь коэффициент.

Добавлено через 46 минут
Исходный код kzru_hunter.
C++
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        POINT p;
        GetCursorPos(&p);
 
        POINT pp;
        pp.x = Label1->Left;
        pp.y = Label1->Top;
        ::ClientToScreen(Handle, &pp);
 
        int dl, vs, koefX=1, koefY=1, iSpeed = 1;
 
        if (pp.x < p.x) dl=p.x-pp.x;
        else if (pp.x > p.x) dl=pp.x-p.x;
        if (pp.y < p.y) vs=p.y-pp.y;
        else if (pp.y > p.y) vs=pp.y-p.y;
 
        if (dl==0) dl=1;
        if (vs==0) vs=1;
 
        if (dl>vs) {
        koefX=dl/vs;
        if (koefX>3) koefX=3;
        }
        else if (dl<vs) {
        koefY=vs/dl;
        if (koefY>3) koefY=3;
        }
 
 
        if ( pp.x < p.x ) Label1->Left += iSpeed*koefX;
        else if ( pp.x > p.x ) Label1->Left -= iSpeed*koefX;
        if ( pp.y < p.y ) Label1->Top += iSpeed*koefY;
        else if ( pp.y > p.y ) Label1->Top -= iSpeed*koefY;
}
//---------------------------------------------------------------------------
Попробуй. Если что доработай.
2
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.08.2012, 20:51
Лучший ответ Сообщение было отмечено как решение

Решение

Вот рабочий код:
C++
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
#include <math.h>
...
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        Timer1->Interval = 10;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        static double fOstDiffX = 0;
        static double fOstDiffY = 0;
 
        POINT p;
        GetCursorPos(&p);
 
        POINT pp;
        pp.x = Label1->Left;
        pp.y = Label1->Top;
        ::ClientToScreen(Handle, &pp);
 
        int iSpeed = 5; // скорость ( кол-во пикселей за событие таймера )
 
        // дистанция между курсором и Label (в пикселях)
        double fDistance = sqrt( (p.x-pp.x)*(p.x-pp.x) + (p.y-pp.y)*(p.y-pp.y) );
        // если Label рядом с курсором, то выход (сделано для того, чтобы Label не дергался около курсора)
        if (fDistance < iSpeed) return;
 
        // определяем угол в радианах между катетами, образованными позицией курсора и позицией Label'а
        double fRadians = 0;
        if (p.x != pp.x)
        {
                fRadians = atan( 1.0 * abs(p.y-pp.y) / abs(p.x-pp.x) );
        }
 
        // определяем, на сколько нужно изменить позицию Label по осям
        double fDiffX = fabs(iSpeed * cos(fRadians)) + fOstDiffX;
        double fDiffY = fabs(iSpeed * sin(fRadians)) + fOstDiffY;
 
        // преобразование fDiffX, fDiffY в целые числа
        int iDiffX = fDiffX;
        int iDiffY = fDiffY;
 
        // изменение позиции Label
        if ( pp.x < p.x ) Label1->Left += iDiffX;
        else if ( pp.x > p.x ) Label1->Left -= iDiffX;
        if ( pp.y < p.y ) Label1->Top += iDiffY;
        else if ( pp.y > p.y ) Label1->Top -= iDiffY;
 
        // надеюсь, понятно для чего ниже эти переменные
        fOstDiffX = fDiffX - iDiffX;
        fOstDiffY = fDiffY - iDiffY;
}
4
 Аватар для MatrixDeity
7 / 7 / 1
Регистрация: 20.04.2011
Сообщений: 69
09.08.2012, 19:12  [ТС]
kzru_hunter, Всё отлично работает. Спасибо
0
844 / 739 / 342
Регистрация: 22.09.2012
Сообщений: 5,034
18.11.2012, 23:53
Если нужно у меня есть исходник шар летит всегда в лузу, независимо где шар находится а где луза.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
19.11.2012, 00:49
нужно
0
Tierey
12.07.2013, 01:06
kzru_hunter госпади спасибо тебе добрый человек я уже думал что помру пока придумаю как это запилить.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.07.2013, 01:06
Помогаю со студенческими работами здесь

Движение объекта по диагонали
Всем привет, как можно сделать так, что бы при нажатии клавиши объект двигался по диагонали? procedure KeyDown(Key: integer); ...

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

Возможно ли сделать движение зрачков, реагирующее на движение какого-либо объекта
Вообщем благодаря модеру удалось разукрасить картинку,за что ему спасибо. Нужна анимация для нее. Возможно ли сделать движение...

Сформировать меню: 1) свободное движение объекта 2)движение с клавиатуры
Сформировать на экране меню, состоящее из следующих пунктов: 1. Движение вдоль периметра экрана. Через случайное количество тактов...

Движение объекта
&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;utf-8&quot;&gt; &lt;script type=&quot;text/javascript&quot;&gt;var drObj, offsetX, offsetY, bool = false; ...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru