С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
383 / 23 / 2
Регистрация: 12.06.2021
Сообщений: 207
Записей в блоге: 2
1

Как сделать так чтобы крюк поворачивался автоматически, не выходя за диапазоны угла?

10.03.2023, 15:06. Показов 331. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь сделать на Delphi пример игры где шахтер добывает сокровища, там нужно чтобы крюк автоматически поворачивался при этом, не выходя за определенные диапазоны угла. На одном языке программирования удалось это сделать так как там есть свойства работы с поворотом (rotation), объекта.
Код
hook.rotation += rotation_dir;
				
if (hook.rotation == 80 || hook.rotation == -80) {
		rotation_dir *= -1;
}
В Delphi 7 не получается сделать. Здесь сразу две переменные cAngle и sAngle. Единственное что удалось сделать это поворот объекта за мышкой. Во что у меня сейчас
GIF-анимация
Как сделать так чтобы крюк поворачивался автоматически, не выходя за диапазоны угла?

А вот что нужно сделать.
GIF-анимация.
Как сделать так чтобы крюк поворачивался автоматически, не выходя за диапазоны угла?

Мой код:
Delphi
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
158
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, AppEvnts,Math;
 
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Image1: TImage;
    Label1: TLabel;
    ApplicationEvents1: TApplicationEvents;
    Label2: TLabel;
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ApplicationEvents1Message(var Msg: tagMSG;
      var Handled: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  THook = class
  private
    x0,y0,x,y:Integer;
    sAngle,vx,t,dt : Double;
    cAngle,vy : Double;
    color : TColor;
  public
    constructor Create(_x0, _y0: Integer; _sAngle, _cAngle: Double; _Color:TColor);
    Procedure Draw(Cs:TCanvas;H:Integer;W:Integer);
    Procedure Move; //Перемещение 
  end;
procedure rotateHook(P:TPoint);
Const
  sLen = 30;
  ds   = 30;
  dss  = 10;
  Speed_H = 40;
  
var
  Form1: TForm1;
  hook: THook;
  H1, W1 : Integer;
 
implementation
 
{$R *.dfm}
 
constructor THook.Create(_x0, _y0: Integer; _sAngle, _cAngle: Double;
_Color: TColor);
begin
  inherited Create;
  x0 := _x0;
  y0 := _y0;
  sAngle := _sAngle;
  cAngle := _cAngle;
  color := _Color;
  x:=x0;
  y:=y0;
 
end;
procedure THook.Move;
begin
  vx:=Speed_H*cAngle;
  vy:=Speed_H*sAngle;
  x:=Round(x0+vx * t);
  y:=Round(y0+vy * t);
  t := t + 0.1;
end;
procedure THook.Draw(Cs: TCanvas; H, W: Integer);
 var
  dx,dy  : Real;
  //xt,yt : Integer;
  xk,yk:Integer;
  sLength:Integer;
begin
  sLength:=sLen;
  Cs.Brush.Color := color;
  Cs.Pen.Color := color;
  Cs.Pen.Width:=1;
  dy := sLength * sAngle;
  dx := sLength * cAngle;
 
  xk:=Round(x+dx);
  yk:=Round(y+dy);
 
  H1 := H;
  W1 := W;
 
 //Cs.Pen.Width:=1;
 
 
 Cs.Polygon(
 [Point(xk,H-yk),
  Point(Round(xk-(((dx*ds)-(dy*dss))/sLength)),
  H-Round(yk-(((dy*ds)+(dx*dss))/sLength))),
  Point(Round(xk-(((dx*ds)+(dy*dss))/sLength)),
  H-Round(yk-(((dy*ds)-(dx*dss))/sLength)))]);
 
 
end;
 
procedure TForm1.FormShow(Sender: TObject);
begin
hook:=THook.Create(344,446,0,1,clBlack);
 
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Form1.Image1.Canvas.Brush.Color:=clWhite;
  Form1.Image1.Canvas.FillRect(Form1.Image1.ClientRect);
  hook.Draw(Image1.Canvas,Image1.ClientHeight, Image1.ClientWidth);
  //hook.Move;
end;
 
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var P : TPoint;
begin
 if Msg.message = WM_MOUSEMOVE then
 begin
   P:=Form1.ScreenToClient(Mouse.CursorPos);
   rotateHook(P);
 end;
end;
 
procedure rotateHook(P:TPoint);
begin
 
    hook.sAngle:=((H1-hook.y0)-P.Y)/
    Sqrt(Sqr((H1-hook.y0)-P.Y) + Sqr(P.X-(hook.x0)));
    hook.cAngle:=(P.X-(hook.x0))/
    Sqrt(Sqr((H1-hook.y0)-P.Y) + Sqr(P.X-(hook.x0)));
 
 
    // hook.sAngle:=0;
    //hook.cAngle:=-1;
 
     //hook.sAngle:=0;
     //hook.cAngle:=1;
 
    // hook.sAngle:=-1;
    // hook.cAngle:=0;
 
    //
 
   // Form1.Label1.Caption:=FloatToStr(RadToDeg(hook.sAngle));
    //Form1.Label2.Caption:=FloatToStr(RadToDeg(hook.cAngle));
 
    Form1.Label1.Caption:=FloatToStr(hook.sAngle);
    Form1.Label2.Caption:=FloatToStr(hook.cAngle);
end;
 
end.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.03.2023, 15:06
Ответы с готовыми решениями:

Как сделать так, чтобы спрайт поворачивался за курсором?
Как сделать чтобы player поворачивался за курсором? Помогите реализовать пожалуйста) using...

Как сделать так чтобы куб при прыжке поворачивался на 90 градусов по оси Z?
Как сделать так чтобы куб при прыжке поворачивался на 90 градусов по оси Z? using...

Как сделать так чтобы поле цена указывалась автоматически???
Уважаемые форумчане! Помогите пожалуйста, 4 года мучился, и с час вновь мучаюсь с этой...

Как сделать так, чтобы локальные переменные не обнулялись автоматически?
Сижу под Linux, использую Code::Blocks, компилятор gcc. Я заметил одну неприятную вещь: когда я...

7
Модератор
3758 / 2262 / 783
Регистрация: 15.11.2015
Сообщений: 9,000
10.03.2023, 16:15 2
Цитата Сообщение от Olga28 Посмотреть сообщение
Единственное что удалось сделать это поворот объекта за мышкой. Во что у меня сейчас
Не рисует приведённый код ничего.

---
Метод объекта хранит свои данные в глобальной переменной, процедура поворота стоит отдельно и обращается к глобальной переменной. Почему она не является методом THook?

Добавлено через 4 минуты
Нарисовало. Координаты стрелки выходили за пределы Image.

Добавлено через 2 минуты
Цитата Сообщение от Olga28 Посмотреть сообщение
На одном языке программирования удалось это сделать так как там есть свойства работы с поворотом (rotation), объекта.
Ну а в Delphi 7 такого нет, значит, надо реализовать самостоятельно по такому же принципу, чтобы действовало так же, как и "на одном ЯП".
0
3760 / 2264 / 705
Регистрация: 29.05.2013
Сообщений: 9,616
10.03.2023, 17:20 3
Ну можно же не проверять угол, а проверить координаты. У вас есть метод:
Delphi
1
2
3
4
5
6
7
8
procedure THook.Move;
begin
  vx:=Speed_H*cAngle;
  vy:=Speed_H*sAngle;
  x:=Round(x0+vx * t);
  y:=Round(y0+vy * t);
  t := t + 0.1;
end;
Проверьте значение x и y на вхождение в прямоугольник с помощью функции PtInRect(), где прямоугольник имеет координаты cx-d,5,cx+d,5+d.
d-размер указателя
cx-центр экрана по горизонтали.
0
383 / 23 / 2
Регистрация: 12.06.2021
Сообщений: 207
Записей в блоге: 2
10.03.2023, 17:34  [ТС] 4
Ну можно же не проверять угол, а проверить координаты. У вас есть метод:
Метод TMove понадобиться позже, чтобы отправлять крюк по линии, в ту сторону в которую он повернут.
0
3760 / 2264 / 705
Регистрация: 29.05.2013
Сообщений: 9,616
10.03.2023, 17:46 5
С методом я может и ошибся, а вот сама идея вполне рабочая.
0
383 / 23 / 2
Регистрация: 12.06.2021
Сообщений: 207
Записей в блоге: 2
10.03.2023, 19:22  [ТС] 6
Почему-то все равно не получается, вроде вначале нормально поворачивает, а под конец замедляется.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
rotation_dir:Integer = 1;
 
procedure rotateHook(P:TPoint);
 
begin
    x:=x+rotation_dir;
    y:=y+rotation_dir;
    if ((y = 30) or (x = 315)) and ((y = 0) or (x = 605)) then
      rotation_dir:=rotation_dir*-1;
 
    hook.sAngle:=
    ((H1-hook.y0)-y)/
    Sqrt(Sqr((H1-hook.y0)-y) + Sqr(x-(hook.x0)));
    hook.cAngle:=
    (x-(hook.x0))/
    Sqrt(Sqr((H1-hook.y0)-y) + Sqr(x-(hook.x0)));
 
 
    Form1.Label1.Caption:=FloatToStr(x);
    Form1.Label2.Caption:=FloatToStr(y);
end;
0
3760 / 2264 / 705
Регистрация: 29.05.2013
Сообщений: 9,616
10.03.2023, 20:19 7
Ну а если так:
Delphi
1
if PtInRect(Rect(315,0,605,30), Point(x,y)) then rotation_dir:=rotation_dir*-1;
0
383 / 23 / 2
Регистрация: 12.06.2021
Сообщений: 207
Записей в блоге: 2
10.03.2023, 22:17  [ТС] 8
Я все же нашла решение, просто создала еще одну переменную специально для X, rotation_dir2 и дополнительное условие для x.
Delphi
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
 rotation_dir:Integer = 1;
 rotation_dir2:Integer = 1;
....
procedure rotateHook(P:TPoint);
 
begin
    x:=x+rotation_dir2;
    y:=y+rotation_dir;
 
 
   
 
   if((x=375) or (x=315)) then rotation_dir2:=rotation_dir2*-1;
 
   if ((y = 30) or (y = 0)) then
      rotation_dir:=rotation_dir*-1;
 
    hook.sAngle:=
    ((H1-hook.y0)-y)/
    Sqrt(Sqr((H1-hook.y0)-y) + Sqr(x-(hook.x0)));
    hook.cAngle:=
    (x-(hook.x0))/
    Sqrt(Sqr((H1-hook.y0)-y) + Sqr(x-(hook.x0)));
 
 
    Form1.Label1.Caption:='X= '+FloatToStr(x);
    Form1.Label2.Caption:='Y= '+FloatToStr(y);
end;
Теперь все нормально, работает.
Как сделать так чтобы крюк поворачивался автоматически, не выходя за диапазоны угла?
0
10.03.2023, 22:17
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.03.2023, 22:17
Помогаю со студенческими работами здесь

Как сделать так, чтобы значения выводили автоматически, а не вручную?
есть решенная задача, но нужно, чтобы элементы массива выводились автоматически( рандомно ). Как...

Как сделать так чтобы автоматически слова выстроились в одну строчку
Здравствуйте, уважаемые форумчане. Подскажите пожалуйста как решить мою проблему. Перевернул книгу...

Как сделать так, чтобы сервер автоматически перезагружался раз в 12 часов?
Имею WINDOWS SERVER 2012R2, подскажите как сделать так, чтобы сервер автоматически перезагружался...

Как сделать так чтобы подвал сайта автоматически съезжал вниз
Как сделать так,чтобы подвал сайт уезжал вниз при увеличении содержимого основного сайта? ...

Как сделать так, чтобы данные в прорамму с экрана забивались автоматически?
Друзья! Вопрос сложный, конечно. Я даже не знаю, с чего начать. (Может, даже не тот раздел) Прошу...

Как сделать так, чтобы в форме автоматически отоброжались записи по дате?
Спасибо!


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
Параллельное программировани­е: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka, REST и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS, Swagger и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru