0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
1

Не могу реализовать обработку столкновений

09.01.2015, 14:18. Показов 2067. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.
Решил написать игру, что то вроде "Танчики 1990". Дошёл до обработки столкновений танка с блоками на карте. Карта рисуется из текстового файла, реализовано это в отдельном классе. Движение танка тоже сделано в отдельном классе. Подскажите пожалуйста, как и в каком классе сделать обработку?
Вот код класса tank
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
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
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace tan4iki
{
    class tank
    {
        Texture2D tankMainTexture;
        Texture2D tankWeaponTexture;
        Rectangle tankMainRectangle;
        Rectangle tankWeaponRectangle;
        
 
        
 
        TTH tth;
 
        float MainRotation;
        float WeaponRotation;
        
 
        Vector2 tankPosition= new Vector2(45, 45);
        Vector2 tankSpeed;
        Vector2 originMain;
 
        Game1 game;
        
 
        
 
        public tank(Texture2D tankTex, Texture2D weaponTex, Texture2D BulletTexture)
        {
            this.tankMainTexture = tankTex;
            this.tankWeaponTexture = weaponTex;
            
            game = new Game1();
            
        }
 
 
       
 
        public void Update(GameTime gameTime)
        {
            
            originMain = new Vector2(tankMainRectangle.Width / 2, tankMainRectangle.Width/2);
            tth = new TTH();
            KeyboardState state = Keyboard.GetState();
            
            //Обработка пользовательского ввода
            
            
 
            if (state.IsKeyDown(Keys.D))
            { 
                MainRotation += tth.RotationSpeed;
                WeaponRotation += tth.RotationSpeed;
            }
            if (state.IsKeyDown(Keys.A))
            { 
                MainRotation -= tth.RotationSpeed;
                WeaponRotation -= tth.RotationSpeed;
            }
            if (state.IsKeyDown(Keys.W))
            {
               
               
                    tankSpeed.X = (float)Math.Cos(MainRotation) * tth.speed;
                    tankSpeed.Y = (float)Math.Sin(MainRotation) * tth.speed;
                    tankPosition += tankSpeed;
               
            }
            if (state.IsKeyDown(Keys.S) && Oldstate.IsKeyUp(Keys.Space))
            {
                    tankSpeed.X = (float)Math.Cos(MainRotation) * tth.speed;
                    tankSpeed.Y = (float)Math.Sin(MainRotation) * tth.speed;
                    tankPosition -= tankSpeed;
                    state = Oldstate;
            }
           
            if (state.IsKeyDown(Keys.Q))
                WeaponRotation -= tth.weaponspeed;
            if (state.IsKeyDown(Keys.E))
                WeaponRotation += tth.weaponspeed;
 
            
            
            
 
            // Конец Обработки пользовательского ввода
 
 
 
            
            
 
            
            tankWeaponRectangle = new Rectangle(tankMainRectangle.X, tankMainRectangle.Y, 23, 10);
            tankMainRectangle =  new Rectangle((int)tankPosition.X, (int)tankPosition.Y, 30, 30);
            
        }
        public void Draw(SpriteBatch spriteBatch)
        {
            Rectangle sourseRect = new Rectangle(0, 0, 30, 30);
 
            
 
            spriteBatch.Draw(tankMainTexture, tankMainRectangle, null, Color.White, MainRotation, originMain, SpriteEffects.None, 0);
            spriteBatch.Draw(tankWeaponTexture, tankWeaponRectangle,null, Color.White, WeaponRotation, new Vector2(tankWeaponRectangle.Width - 17, tankWeaponRectangle.Height /2), SpriteEffects.None, 0);
 
        }
    }
}
Код класса CreateMap
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
55
56
57
58
59
60
61
62
63
64
65
66
67
class CreateMap
    {
        Texture2D hardTexture;
 
        Texture2D kusty;
        Texture2D breaks;
 
        public List<HardBlock> HBlock;
        Game1 game;
        
 
        public CreateMap(Texture2D metall, Texture2D kusty, Texture2D breaks)
        {
            this.kusty = kusty;
            this.hardTexture = metall;
            this.breaks = breaks;
        }
        public void CreateLvl()
        {
            HBlock = new List<HardBlock>();
            game = new Game1();
                
                string[] stringsH = File.ReadAllLines("Content/Maps/Classic.txt");
 
                int x = 0;
                int y = 0;
 
                foreach (string stri in stringsH)
                {
                    foreach (char c in stri)
                    {
                        Rectangle rect = new Rectangle(x, y, 30, 30);
                        if (c == 'm')
                        {
                            HardBlock block = new HardBlock(hardTexture, rect);
                            HBlock.Add(block);
                        }
                        if (c == 'k')
                        {
 
                            HardBlock block = new HardBlock(kusty, rect);
                            HBlock.Add(block);
                        }
                        if (c == 'b')
                        {
 
                            HardBlock block = new HardBlock(breaks, rect);
                            HBlock.Add(block);
                        }
 
                        x += 30;
                    }
                    x = 0;
                    y += 30;
                }
                    
            
        }
        public void Draw(SpriteBatch spriteBatch)
        {
            foreach(HardBlock block in HBlock)
            {
                block.Draw(spriteBatch);
            }
            
        }
    }
код класса Game1
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
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
public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
 
        
        tank Tank;
 
        Texture2D hardTexture;
 
        Texture2D kusty;
        Texture2D breaks;
        CreateMap mapa;
 
        
 
        bool IsFirst = true;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
 
            graphics.PreferredBackBufferWidth = 300;
            graphics.PreferredBackBufferHeight = 300;
 
            IsMouseVisible = false;
        }
 
        
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
 
            
 
            
 
            base.Initialize();
        }
 
        
        protected override void LoadContent()
        {
            
            spriteBatch = new SpriteBatch(GraphicsDevice);
 
            kusty = Content.Load<Texture2D>("Textures/Kust");
 
            hardTexture = Content.Load<Texture2D>("Textures/MetallBlock"); breaks = Content.Load<Texture2D>("Textures/BreaksBlock");
            Tank = new tank(Content.Load<Texture2D>("Textures/MainDetal"), Content.Load<Texture2D>("Textures/Weapon"), Content.Load<Texture2D>("Textures/Bullet"));
            mapa = new CreateMap(hardTexture, kusty, breaks);
 
            
        }
 
                protected override void UnloadContent()
        {
            
        }
 
        
        
        
        
        protected override void Update(GameTime gameTime)
        {
            
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
 
            if (IsFirst)
            {
                mapa.CreateLvl();
                IsFirst = false;
            }
 
            Tank.Update(gameTime);
 
            
            
            base.Update(gameTime);
        }
 
        
        
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin();
 
            mapa.Draw(spriteBatch);
            Tank.Draw(spriteBatch);
 
            
            spriteBatch.End();
 
            base.Draw(gameTime);
        }
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.01.2015, 14:18
Ответы с готовыми решениями:

Реализовать моделирование "столкновений" на примере работы с критическими секциями
Здравствуйте,кто может помочь с программой,как понимаю,проблема с выводом,наспех написал,что...

Как реализовать обработку прерываний в С++?
Надо разработать три программных модуля, каждый процесс после запуска представляет уникальный...

Реализовать обработку исключительных ситуаций
Помогите пожалуйста в эту программу добавить исключения. Реализовать обработку исключительных...

Реализовать последовательную обработку вектора
Реалізуйте послідовну обробку елементів вектора, наприклад, множення елементів вектора на число....

25
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
09.01.2015, 15:28 2
Game1, Посмотрите, что я вам ответил во второй теме по поводу загрузки уровня из Update
По теме:
-Самое простой это сделать Sphere-Box collision (или в вашем случае пересечение окружности с квадратными блоками). Самый качественный вариант этого метода состояит из трех вариантов:
1) Определение пересечения окружности, в которой вписан блок с окружностью, в которую вписан танк
2) Проверка пересечения каждой стороны квадрата с окружностью, в которую вписан танк
Сделайте класс CollisionTester, в нем метод следующего содержания:
C#
1
2
3
4
public static bool CheckCollision(Vector2 boxPos, float boxRadius, Vector2 tankPos, float tankRadius)
{
   return  Vector2.Distance(boxPos, tankPos) < boxRadius + tankRadius;
}
Этот метод определяет, пересекается ли сфера танка и сфера блока
Если он возвращает true, значит нужно более детально проверить коллизию. Для этого используйте такой метод:
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
55
56
57
58
59
60
61
62
63
64
65
66
/// <summary>
        /// Проверяет пересечение сферы и прямой в 2D
        /// </summary>
        /// <param name="E">Начальная точка прямой</param>
        /// <param name="L">Конечная точка прямой</param>
        /// <param name="C">Центр окружности</param>
        /// <param name="r">Радиус окружности</param>
        /// <returns></returns>
        public static bool CollideRayWithSphere2D(Vector2 E, Vector2 L, Vector2 C, float r)
        {
            Vector2 d, f;
            Vector2.Subtract(ref L, ref E, out d);
            Vector2.Subtract(ref E, ref C, out f);
 
            float a = Vector2.Dot(d, d);
            float b = 2 * Vector2.Dot(f, d);
            float c = Vector2.Dot(f, f) - r * r;
 
            float discriminant = b * b - 4 * a * c;
            if (discriminant < 0)
            {
                // no intersection
                return false;
            }
            else
            {
                // ray didn't totally miss sphere,
                // so there is a solution to
                // the equation.
 
                discriminant = (float)Math.Sqrt(discriminant);
 
                // either solution may be on or off the ray so need to test both
                // t1 is always the smaller value, because BOTH discriminant and
                // a are nonnegative.
                float t1 = (-b - discriminant) / (2 * a);
                float t2 = (-b + discriminant) / (2 * a);
 
                // 3x HIT cases:
                //          -o->             --|-->  |            |  --|->
                // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit), 
 
                // 3x MISS cases:
                //       ->  o                     o ->              | -> |
                // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1)
 
                if (t1 >= 0 && t1 <= 1)
                {
                    // t1 is the intersection, and it's closer than t2
                    // (since t1 uses -b - discriminant)
                    // Impale, Poke
                    return true;
                }
 
                // here t1 didn't intersect so we are either started
                // inside the sphere or completely past it
                if (t2 >= 0 && t2 <= 1)
                {
                    // ExitWound
                    return true;
                }
 
                // no intn: FallShort, Past, CompletelyInside
                return false;
            }
        }
Этим методом проверяйте пересечение каждой стороны блока и окружности, в которую вписан танк
Как только для одной из сторон этот метод возвращает true, пересечение есть. Остальные стороны можно не проверять.
1
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
09.01.2015, 15:36  [ТС] 3
CSharpCraft, хорошо, спасибо, но у меня блоки содержатся в коллекции, значит мне нужно проверять это всё для каждого блока в этой коллекции, я правильно понимаю?
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
09.01.2015, 16:02 4
Цитата Сообщение от Game1 Посмотреть сообщение
CSharpCraft, хорошо, спасибо, но у меня блоки содержатся в коллекции, значит мне нужно проверять это всё для каждого блока в этой коллекции, я правильно понимаю?
Верно, это нужно делать для каждого блока. Но не забывайте прерывать цикл проверки, если столкновение уже обнаружено
1
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
09.01.2015, 17:01  [ТС] 5
CSharpCraft, я вроде бы всё сделал правильно, но танк всё равно заезжает в блоки
Вот код, подскажите пожалуйста что не так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void CollisionWith()
        {
            game.HBlock = new List<HardBlock>();
            foreach (HardBlock block in game.HBlock)
            {
                if (CollisionTester.CheckCollision(new Vector2(block.hardRectangle.X + block.hardRectangle.Width / 2, block.hardRectangle.Y + block.hardRectangle.Height / 2), 15, tankPosition, 15))
                {
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(tankMainRectangle.X , tankMainRectangle.Y), new Vector2(tankMainRectangle.X, tankMainRectangle.Y+tankMainRectangle.Height), new Vector2(block.hardRectangle.X + block.hardRectangle.Width/2, block.hardRectangle.Y+block.hardRectangle.Height / 2), 15))
                    {
                        Bottom = true;
                        break;
                    }
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(tankMainRectangle.X + tankMainRectangle.Width, tankMainRectangle.Y + tankMainRectangle.Height), new Vector2(tankMainRectangle.X + tankMainRectangle.Width, tankMainRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width / 2, block.hardRectangle.Y + block.hardRectangle.Height / 2), 15))
                    {
                        Top = true;
                        break;
                    }
                }
                else break;
            }
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
09.01.2015, 17:29 6
Цитата Сообщение от Game1 Посмотреть сообщение
CSharpCraft, я вроде бы всё сделал правильно, но танк всё равно заезжает в блоки
Вот код, подскажите пожалуйста что не так:
Представьте себе квадрат. У него 4 точки ABCD и 4 стороны AB, BC, CD и AD. А у вас я вижу совсем другое
Да и еще: танк обернут сферой, а блок сферой и квадратом

public static bool CollideRayWithSphere2D(Vector2 E, Vector2 L, Vector2 C, float r)
EL: одна из сторон, и C+r: параметры сферы танка
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
09.01.2015, 17:42  [ТС] 7
тогда мне надо в CollisionWith проверять пересечение 4 сторон прямоугольника блока со сферой танка?
Ещё вопрос, если я передаю в Draw вращение, то вращается текстура или прямоугольник?
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
09.01.2015, 18:35 8
Цитата Сообщение от Game1 Посмотреть сообщение
тогда мне надо в CollisionWith проверять пересечение 4 сторон прямоугольника блока со сферой танка?
Ага

Цитата Сообщение от Game1 Посмотреть сообщение
Ещё вопрос, если я передаю в Draw вращение, то вращается текстура или прямоугольник?
Прямоугольник относительно того центра (который является относительным к прямоугольнику), который вы указываете. Если вы передаете позицию в виде вектора, то она смещается на этот центр.
1
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
09.01.2015, 18:58  [ТС] 9
CSharpCraft, хорошо, спасибо. Но почему не работает мой код? Ведь при соприкосновении передней стороны танка со сферой блока он ведб должен выдавать в bool Top true, и в методе Update() класса tank я задал условие :
C#
1
2
3
4
if(!Top && state.IsKeyDown(Keys.W)
{
      Вектор2 позиция + Вектор2 скорость;
}
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
09.01.2015, 21:11 10
Коллизия должна быть твердотельной. Вы должны ее обрабатывать не в логике перемещения, а отодвигать танк от объекта, если обнаружена коллизия. Желательно все делать уже после движения.
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 12:51  [ТС] 11
Ну я просто не понимаю, как мне определять, какой именно частью столкнулся танк с блоком, что бы отодвигать его в противоположную сторону
я попробовал написать так:
проверка столкновения в классе tank
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
void CollisionWith(Vector2 nextPos)
        {
            game.HBlock = new List<HardBlock>();
            foreach(HardBlock block in game.HBlock)
            {
                if (CollisionTester.CheckCollision(new Vector2 (block.hardRectangle.X + (block.hardRectangle.Width/2)), 15, nextPos, 15))
                {
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), nextPos, 15))
                        Top = true;
                    else Top = false;
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        Right = true;
                    else Right = false;
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        Bottom = true;
                    else Bottom = false;
                    
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        Left = true;
                    else Left = false;
                    
                }
            }
        }
код Update класса tank:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (state.IsKeyDown(Keys.W))
            {
 
                tankSpeed.X = (float)Math.Cos(MainRotation) * tth.speed;
                tankSpeed.Y = (float)Math.Sin(MainRotation) * tth.speed;
 
                Vector2 nextPos = tankPosition + tankSpeed;
                CollisionWith(nextPos);
 
                if (Top || Bottom)
                    tankSpeed.Y = 0;
                if (Right || Left)
                    tankSpeed.X = 0;
 
                tankPosition += tankSpeed;
            }
Почему этот код не работает как надо? игра запускается, но танк передвигаясь вперёд всё равно проезжает блоки, может лист game.HBlock пустой? Хотя я в Game1 прописал:
C#
1
2
3
4
5
6
7
protected override void Initialize()
        {
            
 
            HBlock = new List<HardBlock>();
            HBlock = mapa.HBlock;
}
mapa.HBlock коллекция блоков на карте.
Подскажите пожалуйста, может я не так лист передаю? Там не никакой хитрости?
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
10.01.2015, 13:54 12
Game1,
HBlock = new List<HardBlock>();
HBlock = mapa.HBlock;
Первая строчка не имеет смысла, поскольку вы задаете эту переменную во второй

Сделайте так: метод CollisionWith возвращает перечисление, которое указывает, какой стороной он столкнулся. В самом методе в место использования переменный при обнаружении коллизии делайте return [значение перечисления]
Тогда перечисление будет иметь такой вид:
C#
1
2
3
4
5
6
7
enum CollisionWay
{
   Right,
   Left,
   Top,
   Bottom
}
Проверьте, чтобы все параметры задавались правильно, и чтобы каждой стороне соответствовала своя пара координат.
Если не будет работать скиньте исходники, посмотрю.
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 14:09  [ТС] 13
Я не очень понял, какой тип должен иметь метод CollisionWith? Что мне надо в нём изменить?
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 14:25  [ТС] 14
Дело в том, что танк у меня описан прямоугольником, а не Vector2, и как вы сказали, вращается именно он, дак за чем мне знать какой стороной танк столкнулся с блоком?
Мне почему то кажется, что дело всё в листах. вот исходники, может увидите ошибку.
tank class tank.docx
game1 class Game1.docx
и вот, на всякий случай CreateMap class CreateMap.docx
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
10.01.2015, 14:28 15
Цитата Сообщение от Game1 Посмотреть сообщение
Я не очень понял, какой тип должен иметь метод CollisionWith? Что мне надо в нём изменить?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CollisionWay CollisionWith(Vector2 nextPos)
        {
            game.HBlock = new List<HardBlock>();
            foreach(HardBlock block in game.HBlock)
            {
                if (CollisionTester.CheckCollision(new Vector2 (block.hardRectangle.X + (block.hardRectangle.Width/2)), 15, nextPos, 15))
                {
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), nextPos, 15))
                        return CollisionWay.Top;
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Right;
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Bottom;
                    
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Top;                    
                }
            }
        }
Для начала так. Проверьте все вектора и параметры методов.

Добавлено через 1 минуту
Да if (CollisionTester.CheckCollision(new Vector2 (block.hardRectangle.X + (block.hardRectangle.Width/2)), 15, nextPos, 15)) я вот тут что то понять не могу, а где Y координата?

Добавлено через 39 секунд
У вас этот вектор получается XX а не XY
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 15:44  [ТС] 16
Я изменил метод CollisionWith:
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
CollisionWay CollisionWith(Vector2 nextPos)
        {
            game.HBlock = new List<HardBlock>();
            foreach(HardBlock block in game.HBlock)
            {
                if (CollisionTester.CheckCollision(new Vector2(block.hardRectangle.X + (block.hardRectangle.Width / 2), block.hardRectangle.Y + (block.hardRectangle.Height / 2)), 15, nextPos, 15))//здесь была опечатка
                {
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), nextPos, 15))
                        return CollisionWay.Top;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Right;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Bottom;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Left;
                    
 
                }
                
            }
            return CollisionWay.nuull;
        }
Он ведь должен так выглядеть?
И что делать дальше?
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
10.01.2015, 16:31 17
Game1, Вызывайте проверку коллизии непосредственно из обновления танка. Этот метод вернут вам значение CollisionWay, и потом просто проверяете, так же как и с флагами
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 16:40  [ТС] 18
Как это понять с "флагами"? объясните пожалуйста подробней, что, как и где
0
58 / 58 / 9
Регистрация: 09.01.2013
Сообщений: 247
10.01.2015, 16:45 19
Game1, Говоря про флаги я имел ввиду значения bool Top Right Bottom и Left, которые были в вашем коде до использования enum.
Почитайте про enum > тык http://msdn.microsoft.com/ru-r... t4032.aspx
0
0 / 0 / 0
Регистрация: 07.01.2015
Сообщений: 19
10.01.2015, 18:55  [ТС] 20
Вот, готово, только опять ничего не работает, хотя сделал вроде всё как вы сказали, проверку сделал после передвижения танка:
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
int result = (int)CollisionWith(tankPosition);
 
switch (result)
            {
                case 0:
                    {
                        tankPosition.X += 10;
                        break;
                    }
                case 1:
                    {
                        tankPosition.X -= 10;
                        break;
                    }
                case 2:
                    {
                        tankPosition.Y -= 10;
                        break;
                    }
                case 3:
                    {
                        tankPosition.Y += 10;
                        break;
                    }
            }
Вот код Самой проверки:
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
CollisionWay CollisionWith(Vector2 nextPos)
        {
            game.HBlock = new List<HardBlock>();
            foreach(HardBlock block in game.HBlock)
            {
                if (CollisionTester.CheckCollision(new Vector2(block.hardRectangle.X + (block.hardRectangle.Width / 2), block.hardRectangle.Y + (block.hardRectangle.Height / 2)), 15, nextPos, 15))
                {
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), nextPos, 15))
                        return CollisionWay.Top;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Right;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), new Vector2(block.hardRectangle.X + block.hardRectangle.Width, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Bottom;
                    
 
                    if (CollisionTester.CollideRayWithSphere2D(new Vector2(block.hardRectangle.X, block.hardRectangle.Y), new Vector2(block.hardRectangle.X, block.hardRectangle.Y + block.hardRectangle.Height), nextPos, 15))
                        return CollisionWay.Left;
                    
 
                }
                
            }
            return CollisionWay.nuull;
        }
Печально конечно, что бьёмся тут второй день, а толку никакого Может всё дело и правда в листах? а нужно мне в game1 писать вот эту строку:
C#
1
mapa.HBlock = new List<HardBlock>();
перед этой?:
C#
1
HBlock = mapa.HBlock;
0
10.01.2015, 18:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.01.2015, 18:55
Помогаю со студенческими работами здесь

Как реализовать обработку текста в БД
Здравствуйте. Передаю в базу новость, там есть html вставка картинки. Как сделать чтобы эти...

Реализовать обработку сообщений с помощью мьютекса
Всем привет! Нужно код на задачу с помощью мьютекса! Может у кого нибудь есть?? :-[ Производители...

Как реализовать обработку ошибок PHP?
Начал изучать PHP. Возник такой вопрос? Как реализовать обработку ошибок? Если конкретнее, то...

Как лучше реализовать обработку строки?
Здравствуйте, делаю простецкий обработчик HTTP заголовков. Как лучше сделать, с начало узнать длину...

Как реализовать обработку текста через макросы?
Здравствуйте, к примеру, задать маросы начала и конца строки, например, s = 'Text Text1 Text2'...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru