|
Post by rogercabo on Jun 1, 2023 20:13:50 GMT 1
Hi every, I'm coding a D2D framework jump and run.. but didnt get the following solution. I have a play with position : x,y and dirx, diry, <-- this are the new direction to go. then I calculate the intersection point, the result works perfect.. $Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
Type GameStructure isCircle As Int radius As Int x As Int y As Int use As Integer x1 As Double y1 As Double x2 As Double y2 As Double End Type
Type PlayerStruc x As Double y As Double // ------------ slideEdge As Double dirX As Double dirY As Double colliderSize As Double angle As Double onCircle As Double onCircleIndex As Int // -------------- player movements left As Int right As Int top As Int down As Int jump As Int // ------------- force properties WalkSpeed As Double JumpForce As Double PlayerMaxFall As Double OnGround As Int JumpInAirSteps(10) As Int JumpInAir As Int MaxSpeed As Double Gravitation As Double AccelerationX As Double Friction As Double EndType
Dim ps(1) As Point
ps(0).x = 0, ps(0).y = 700 ps(1).x = 400, ps(1).y = 300 // linie zeigen Line ps(0).x, ps(0).y, ps(1).x, ps(1).y
Dim player As PlayerStruc // player positionieren und bewegung player.x = 200 player.y = 100 player.dirY = 400 player.dirX = 0 player.colliderSize = 20
Circle player.x, player.y, player.colliderSize Line player.x, player.y, player.x + player.dirX, player.y + player.dirY
Dim normalX# Dim normalY# Dim collisionTime = SweptCircleLine(player, ps(0), ps(1), normalX#, normalY#) Dim deltatime# = 1
Dim collisionX# = player.x + player.dirX * deltatime * collisionTime Dim collisionY# = player.y + player.dirY * deltatime * collisionTime
Print AT(1, 1), "normalX#: ", normalX# Print AT(1, 2), "normalY#: ", normalY# Print AT(1, 3), "collisionTime ", collisionTime
Circle collisionX#, collisionY#, player.colliderSize 'Line player.x, player.y, player.x + player.dirX, player.y + player.dirY Function SweptCircleLine(ByRef p As PlayerStruc, ByRef p1 As Point, ByRef p2 As Point, ByRef normalX As Double, ByRef normalY As Double) As Double Dim dirX As Double = p2.x - p1.x Dim dirY As Double = p2.y - p1.y Dim length As Double = Sqrt(dirX * dirX + dirY * dirY) dirX /= length dirY /= length Dim x1 As Double = p1.x '- p.colliderSize * dirY Dim y1 As Double = p1.y '+ p.colliderSize * dirX Dim x2 As Double = p2.x '+ p.colliderSize * dirY Dim y2 As Double = p2.y '- p.colliderSize * dirX Dim x3 As Double = p.x Dim y3 As Double = p.y Dim x4 As Double = p.x + p.dirX Dim y4 As Double = p.y + p.dirY Dim denom As Double = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) If denom = 0 Return 1.0 End If Dim t As Double = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom Dim u As Double = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom If t >= 0 And t <= 1 And u >= 0 Then Dim intersectionX As Double = x1 + t * (x2 - x1) Dim intersectionY As Double = y1 + t * (y2 - y1) normalX = intersectionX - p.x normalY = intersectionY - p.y length = Sqrt(normalX * normalX + normalY * normalY) normalX /= length normalY /= length Return u 'SchnittpunktHypGegenkathete(p, p1, p2, u, normalX, normalY) End If Return 1.0 End Function impotant is, the intersection point is correct, but the player has a collider circle at this point x,y . The blue collider point should touch the line previously, not the center point (red) it self.  is anyone able to get the correct result.. based on the normals of the lines
|
|
|
Post by rogercabo on Jun 2, 2023 13:31:36 GMT 1
Yes.. intersection point between a circle and a line in 2D. The intersection point is the line of circle, and not the center point of the circle. I have already the center point of the circle on the line, but that's not correct. The player sink into the line..
My idea was to calculate point B of the Pythagoras right-angled triangle We have: + Point A, already (hypotenuses) + P3, the player position Player.X, .Y (also the direction between A and Player.X, .Y) + P1 to P2 the Line (adjacent) + The length between point B and C must be the radius of the circle.. + And we have the normals of the Line already. Then we we got the B anyhow  I already pointed the problem in GPT4.0. he needs 15 attempts then he strikes.. haha! 
|
|
|
Post by dragonjim on Jun 2, 2023 13:41:48 GMT 1
I vaguely remember from my school days that you can use quadratic equations to calculate where a line will intersect a curve (and by extension, a circle?)
|
|
|
Post by rogercabo on Jun 2, 2023 19:11:35 GMT 1
I updated my initial suggestion. the ball radius should touch
|
|
|
Post by rogercabo on Jun 4, 2023 16:12:47 GMT 1
Hi.. you posted dy = p2.y-p1.y dx = p2.x-p1.x A_border = Atan2(dy, dx). A_Normal = A_border + Pi/2
P_contact.x = B_pos.x + B_mag * cos(A_normal) P_contact.y = B_pos.y + B_mag * sin(A_normal) Unfortunately, I'm not sure what your code is referring to exactly. A_border is not used, B_mag is undefined. As you can see in my example: The player direction is the blue line. The intersection between player direction is defined by player.x.y. + the new dirx,diry. This works so far.. The intersection point is the red circle.. but it's wrong! The radius of the circle should hit the green collider line, but not the center point. Use the mouse to move the circles, but not too fast.. because they loose track at the moment. :-) $Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
OpenW # 1, 0, 0, 1000, 1000
Type GameStructure isCircle As Int radius As Int x As Int y As Int use As Integer x1 As Double y1 As Double x2 As Double y2 As Double End Type
Type PlayerStruc x As Double y As Double slideEdge As Double dirX As Double dirY As Double colliderSize As Double angle As Double onCircle As Double onCircleIndex As Int // player movements left As Int right As Int top As Int down As Int jump As Int EndType
Type POINTD // Double. Never use default POINT INT inside of a game. x As Double y As Double EndType
Dim ps(1) As POINTD
// Collider Line ps(0).x = 0 ps(0).y = 500 ps(1).x = 800 ps(1).y = 500 Color RGB(0, 100, 0) Line ps(0).x, ps(0).y, ps(1).x, ps(1).y Color 0
// Player position Dim player As PlayerStruc player.x = 500 // Original Position player.y = 100 // Original Position player.dirX = 0 // Direction for the next move player.dirY = 500 // Direction for the next move player.colliderSize = 20
Color RGB(0, 0, 255) Circle player.x, player.y, player.colliderSize Color RGB(0, 0, 200) Line player.x, player.y, player.x + player.dirX, player.y + player.dirY
// we need the normal values later Dim normalX# Dim normalY# Dim pcl As POINTD Dim deltatime# = 1.0 // game deltatime
Color 0 pcl = SweptCircleLineU(player, ps(0), ps(1), normalX#, normalY#, deltatime)
Print AT(1, 1), "normalX#: ", normalX# Print AT(1, 2), "normalY#: ", normalY# Print AT(1, 3), "Circle Center Collision x,y: ", pcl.x, pcl.y
Circle pcl.x, pcl.y, player.colliderSize Dim x# = MouseX Dim y# = MouseY Dim distance#
Do Cls x = MouseX y = MouseY DoEvents distance = Sqr((x - ps(0).x) ^ 2 + (y - ps(0).y) ^ 2) If distance < player.colliderSize If MouseK ps(0).x = x ps(0).y = y EndIf EndIf // Colliderline distance = Sqr((x - ps(1).x) ^ 2 + (y - ps(1).y) ^ 2) If distance < player.colliderSize If MouseK ps(1).x = x ps(1).y = y EndIf EndIf // player distance = Sqr((x - player.x) ^ 2 + (y - player.y) ^ 2) If distance < player.colliderSize If MouseK player.x = x player.y = y EndIf EndIf // player distance = Sqr((x - (player.x + player.dirX)) ^ 2 + (y - (player.y + player.dirY)) ^ 2) If distance < player.colliderSize If MouseK player.dirX = x - player.x player.dirY = y - player.y EndIf EndIf Color 0 pcl = SweptCircleLineU(player, ps(0), ps(1), normalX#, normalY#, deltatime) // Collider Line Color RGB(0, 100, 0) Line ps(0).x, ps(0).y, ps(1).x, ps(1).y Circle ps(0).x, ps(0).y, player.colliderSize Circle ps(1).x, ps(1).y, player.colliderSize Text ps(0).x, ps(0).y, "COLLIDERLINE" // ------------------------------ Color RGB(0, 0, 255) Circle player.x, player.y, player.colliderSize Color RGB(0, 0, 200) Line player.x, player.y, player.x + player.dirX, player.y + player.dirY Circle player.x + player.dirX, player.y + player.dirY, player.colliderSize Text player.x , player.y, "PL destination : " & player.x & " " & player.y Text player.x + player.dirX, player.y + player.dirY, "PL target" Color RGB(255, 0, 0) Circle pcl.x, pcl.y, player.colliderSize DoEvents Sleep(1) Until InKey$ = Chr$(27) || Me Is Nothing
'Line player.x, player.y, player.x + player.dirX, player.y + player.dirY Function SweptCircleLineU(ByRef p As PlayerStruc, ByRef p1 As POINTD, ByRef p2 As POINTD, ByRef normalX As Double, ByRef normalY As Double, deltatime#) As POINTD Dim dirX As Double = p2.x - p1.x Dim dirY As Double = p2.y - p1.y Dim length As Double = Sqrt(dirX * dirX + dirY * dirY) dirX /= length dirY /= length Dim x1 As Double = p1.x Dim y1 As Double = p1.y Dim x2 As Double = p2.x Dim y2 As Double = p2.y Dim x3 As Double = p.x Dim y3 As Double = p.y Dim x4 As Double = p.x + p.dirX Dim y4 As Double = p.y + p.dirY Dim hp1 As POINTD, hp2 As POINTD, hp3 As POINTD, L As Double Dim denom As Double = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) If denom = 0 Then // Kein Kontact hp1.x = p.x hp1.y = p.y Return hp1 End If Dim t As Double = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom Dim u As Double = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom Print AT(1, 7); "t : "; t Print AT(1, 8); "u : "; u Dim intersectPoint As POINTD Dim intersectionX As Double = x1 + t * (x2 - x1) Dim intersectionY As Double = y1 + t * (y2 - y1) normalX = intersectionX - p.x normalY = intersectionY - p.y length = Sqrt(normalX * normalX + normalY * normalY) If length > 0 Else length = _epsDbl EndIf normalX /= length normalY /= length Print AT(1, 11); "normalX : "; normalX Print AT(1, 12); "normaly : "; normalY °'Print AT(1, 1) ; " " If u > 1 && t < 1 hp1.x = p.x + p.dirX hp1.y = p.y + p.dirY Return hp1 'Print AT(1, 1) ; "NOT REACHED!" EndIf If t >= 0 And t <= 1 And u >= 0 Then normalX = intersectionX - p.x normalY = intersectionY - p.y length = Sqrt(normalX * normalX + normalY * normalY) If length > 0 Else length = _epsDbl EndIf normalX /= length normalY /= length // U enthält nun die relative entfernung basierend auf deltatime // Intersection Point! hp1.x = player.x + player.dirX * deltatime * u hp1.y = player.y + player.dirY * deltatime * u intersectPoint.x = hp1.x intersectPoint.y = hp1.y Print AT(1, 11); "normalX : "; normalX Print AT(1, 12); "normaly : "; normalY Return intersectPoint End If // geht vorbei hp1.x = p.x + p.dirX hp1.y = p.y + p.dirY Return hp1 End Function
There are more stuff to solved.. + If the player/ball comes from the down direction, it must ignore the collider line. ( I think by checking the normals, u, t , dirx.y) + The collider line must be extended left and right by the .colliderSize. You will see the reason why you move the player position. + if you got the correct interfering position with the radius of the sphere, you will recognize than the "bouncing back" position is different than the interfering position of the center. There is a lot of stuff must be solved. And GPT is not that much help..  For the Billard gaming, you need SweptCircleCircle AABB, SweptCircleLine AABB and a SweptCircleBox AABB collider.. Otherwise on fast movement the Billard balls do not collide.
|
|
|
Post by (X) on Jun 4, 2023 17:40:04 GMT 1
This is just the kind of problem I wish anyone can solve easily with a physics library: Lib_Phy_Obj.LG32.
This is just a draft:
'################################################################### ' ' DISCLAIMER: THIS CODE IS OFFERED AS IS. ' IT IS INTENDED FOR EDUCATIONAL PURPOSES. ' ' I ACCEPT NO LIABILITY AND MAKE NO CLAIM ' FOR IT'S CORRECTNESS OR SUITABILITY ' IN PART OR IN WHOLE. ' ' THE USE OF THIS CODE IS AT YOUR OWN RISK. ' '################################################################### ' ' Filename Lib_Phy_Obj.G32 ' ' Description This is an attempt to create a useful ' GFA-BASIC 32 library to track physical ' properties of an object providing user ' data types and functions and featuring ' the standard Greek symbols used in science. ' These work for me: Font->Consolas, Charset->Greek ' Select Extra menu item, then, Properties. ' ' For now, I am using Single typed variables ' since Double typed variables calculations ' are unreliable in a compiled library in GFA. ' I am hoping this can be resolved eventually. ' ' Author (X) ' Email xman.gb32@gmail.com ' Web-site https://gb32.proboards.com/ ' Start 2022.03.01 ' Compiling the various physical property symbols, ' formula and definitions. ' Update 2022.03.08 ' Refining the layout and naming conventions ' Update 2023.05.17 ' Review, rename vars, standardize formatting of comments ' $Export "Lib_Phy_Obj.LG32" $Export Proc * $Export Type *
Proc Greek_Symbol_Reference ' ' You can copy-paste symbols from the table or use the Alt-<code> ' to insert the desired character or use a GFA Editor Popup, see: ' ' https://gb32.proboards.com/thread/456/tip-greek-letters-gfa ' ' ====================================================================== ' ASCII CHARACTERS (FAMILY:"Consolas", SCRIPT:"Greek") ' ====================================================================== ' ° 100 = d 110 = n 120 = x 130 = é 140 = î 150 = û 160 = á 170 = ¬ ° 101 = e 111 = o 121 = y 131 = â 141 = ì 151 = ù 161 = í 171 = ½ ° 102 = f 112 = p 122 = z 132 = ä 142 = Ä 152 = ÿ 162 = ó 172 = ¼ ° 103 = g 113 = q 123 = { 133 = à 143 = Å 153 = Ö 163 = ú 173 = ¡ ° 104 = h 114 = r 124 = | 134 = å 144 = É 154 = Ü 164 = ñ 174 = « ° 105 = i 115 = s 125 = } 135 = ç 145 = æ 155 = ø 165 = Ñ 175 = » ° 106 = j 116 = t 126 = ~ 136 = ê 146 = Æ 156 = £ 166 = ª 176 = ¦ ° 107 = k 117 = u 127 = ¦ 137 = ë 147 = ô 157 = Ø 167 = º 177 = ¦ ° 108 = l 118 = v 128 = Ç 138 = è 148 = ö 158 = × 168 = ¿ 178 = ¦ ° 109 = m 119 = w 129 = ü 139 = ï 149 = ò 159 = ƒ 169 = ® 179 = ¦ ' ====================================================================== ° 180 = ¦ 190 = ¥ 200 = + 210 = Ê °220 ='_' 230 = µ 240 = 250 = · ° 181 = Á 191 = + 201 = + 211 = Ë 221 = ¦ 231 = þ 241 = ± 251 = ¹ ° 182 = Â 192 = + 202 = - 212 = È 222 = Ì 232 = Þ 242 = = 252 = ³ ° 183 = À 193 = - 203 = - 213 = i 223 = ¯ 233 = Ú 243 = ¾ 253 = ² ° 184 = © 194 = - 204 = ¦ 214 = Í 224 = ª 234 = Û 244 = ¶ 254 = ¦ ° 185 = ¦ 195 = + 205 = - 215 = Î 225 = ß 235 = Ù 245 = ° 255 = ° 186 = ¦ 196 = - 206 = + 216 = Ï 226 = Ô 236 = ý 246 = ÷ ° 187 = + 197 = + 207 = ¤ 217 = + 227 = Ò 237 = Ý 247 = ¸ ° 188 = + 198 = ã 208 = ð 218 = + 228 = õ 238 = ¯ 248 = ° ° 189 = ¢ 199 = Ã 209 = Ð 219 = ¦ 229 = Õ 239 = ´ 249 = ¨ ' ====================================================================== Proc User_Data_Types '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Single precision, 3 dimensions ' Type T_S3D -Single x -Single y -Single z EndType '////////////////////////////////////////////////////////////////// ' ' Physical Object Data Type ' ' All values of type physical object are expressed ' SI units:{meter, kilogram, second} ' ' SI BASE UNITS ' ================================================ ' Symbol | Name | Quantity ' ========|===========|=========================== ' A | ampere | electric current ' cd | candela | luminous intensity ' K | kelvin | thermodynamic temperature ' kg | kilogram | mass ' m | metre | length ' mol | mole | 6.02214076 × 10²³ of atom, molecule, ion. ' s | second | time ' ================================================ ' Type T_Phy_Obj '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' SCALAR QUANTITIES ' 'TYPE SYMBOL ' NAME : UNIT_DEF. UNIT_NAME FORMULA -Single Äx ' width : (m) meter -Single Äy ' length : (m) meter -Single Äz ' height : (m) meter -Single area ' area : (m²) square meter -Single vol ' volume : (m³) cubic meter -Single m ' mass : (kg) kilogram -Single ñ ' density : (kg/m³) mass per vol = m / vol -Single t0 ' time initial: (s) second -Single t1 ' time final : (s) second -Single Ät ' time delta : (s) second -Single ë ' Latitude : (° " ') deg min sec -Single ö ' Longitude : (° " ') deg min sec ' ' ' Liter (L) is a special name ' ' for the cubic decimeter (dm³) -Single Ep ' pot. energy : (J) joule ' = (m * g * h) = (k * x^2) / 2 ' ' Where: ' ' k is the spring constant, ' ' x is displacement. -Single Ek ' kin. energy : (J) joule ' = (m * v^2) / 2 = F * s = m * a * s = m * (v / t) * (v / 2) * t ' ' = 0.5 * (p / m)^2 = p^2 / (2 * m) ' ' The units of kinetic energy are: ' mass times the square of speed, or kg·m²/s². ' But the units of force are: ' mass times acceleration, kg·m/s², ' so the units of kinetic energy ' are also: ' the units of force times distance, ' which are: ' the units of work, or joules. ' -Single Er ' rot. energy : (J) joule ' = (I * ù^2) / 2 ' ' = ô * è ' ' = I * á * è ' ' = I * (ù / t) * (ù / 2) * t '/ ' Hardness ' -Single har '/ ' Elasticity ' In physics and materials science, elasticity is the ' ability of a body to resist a distorting influence ' and to return to its original size and shape when ' that influence or force is removed. ' -Single ela '/ ' Coefficient of Friction (ì) ' Ratio of the frictional force resisting the motion of ' two surfaces in contact to the normal force pressing ' the two surfaces together. It is usually symbolized ' by the Greek letter mu (µ). Mathematically, µ = F/N, ' where F is the frictional force and N is the normal force. ' Two types of friction coefficient are distinguished: ' the static friction coefficient and the kinetic friction ' coefficient. The former is sometimes called the ' starting friction coefficient, and the latter is ' sometimes called the dynamic or sliding friction coefficient. ' -Single ì0 ' friction coeff. initial -Single ì ' friction coeff. dynamic '/ ' Plasticity ' In physics and materials science, plasticity, ' also known as plastic deformation, is the ' ability of a solid material to undergo ' permanent deformation, a non-reversible ' change of shape in response to applied forces. ' -Single pla ' plasticity -Single T ' temperature : (K) kelvin -Single Q ' heat : (J) joules -Single c ' specific heat : (J/(kg·K)) ' = Q / (m * T) '======================================================================= ' ' VECTOR QUANTITIES ' o As T_S3D ' Orientation : (m) s As T_S3D ' Spatium : (m) ' = Äs = (s1-s0) v As T_S3D ' Velocity : (m/s) ' = Äs / Ät a As T_S3D ' Acceleration: (m/s²) ' = Äv / Ät = Äs' / Ät j As T_S3D ' Jerk : (m/s³) ' = Äa / Ät = Äv' / Ät = Äs'' / Ät ' ' In uniform circular motion, angular velocity ' is a vector quantity and is equal to the angular ' displacement (a vector quantity) divided by the change in time. ' By convention, positive angular velocity indicates ' counter-clockwise rotation, while negative is clockwise. ' ù As T_S3D ' ang. velocity : (radian/s) ' = Äè / Ät L As T_S3D ' ang. momentum : (kg·m²/s) ' = I * ù ' ' Where: ' ' I is rotational inertia, ' ' ù is angular velocity p As T_S3D ' momentum : (kg·m/s) ' = m * v EndType '////////////////////////////////////////////////////////////////// ' ' Point cloud ' Type T_Point_Cloud -Int32 cS3D ' Count of single typed 3D points. -Int32 lpS3D ' Long pointer to array of single typed 3D points. EndType '////////////////////////////////////////////////////////////////// ' ' Triangle Face ' Type T_TriangleFace p1 As T_S3D p2 As T_S3D p3 As T_S3D EndType EndProc
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' PHYSICAL OBJECT PROPERTY UPDATE ' Proc Update_Phy_Obj(ByRef o As T_Phy_Obj) Update_s(o) Update_v(o) Update_a(o) EndProc Proc Update_s(ByRef o As T_Phy_Obj) Update_s_v(o) Update_s_a(o) Update_s_j(o) EndProc Proc Update_v(ByRef o As T_Phy_Obj) Update_v_a(o) Update_v_j(o) EndProc Proc Update_a(ByRef o As T_Phy_Obj) Update_a_j(o) EndProc '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' SPATIUM UPDATE ' Proc Update_s_v(ByRef o As T_Phy_Obj) o.s.x += o.v.x * o.Ät o.s.y += o.v.y * o.Ät o.s.z += o.v.z * o.Ät EndProc Proc Update_s_a(ByRef o As T_Phy_Obj) o.s.x += CSng(1! / 2!) * o.a.x * o.Ät ^ CSng(2!) o.s.y += CSng(1! / 2!) * o.a.y * o.Ät ^ CSng(2!) o.s.z += CSng(1! / 2!) * o.a.z * o.Ät ^ CSng(2!) EndProc Proc Update_s_j(ByRef o As T_Phy_Obj) o.s.x += CSng(1! / 6!) * o.j.x * o.Ät ^ CSng(3!) o.s.y += CSng(1! / 6!) * o.j.y * o.Ät ^ CSng(3!) o.s.z += CSng(1! / 6!) * o.j.z * o.Ät ^ CSng(3!) EndProc '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' VELOCITY UPDATE ' Proc Update_v_a(ByRef o As T_Phy_Obj) o.v.x += o.a.x * o.Ät o.v.y += o.a.y * o.Ät o.v.z += o.a.z * o.Ät EndProc Proc Update_v_j(ByRef o As T_Phy_Obj) o.v.x += CSng(1! / 2!) * o.j.x * o.Ät ^ CSng(2!) o.v.y += CSng(1! / 2!) * o.j.y * o.Ät ^ CSng(2!) o.v.z += CSng(1! / 2!) * o.j.z * o.Ät ^ CSng(2!) EndProc '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' ACCELERATION UPDATE ' Proc Update_a_j(ByRef o As T_Phy_Obj) o.a.x += o.j.x * o.Ät o.a.y += o.j.y * o.Ät o.a.z += o.j.z * o.Ät EndProc
|
|
|
Post by rogercabo on Jun 4, 2023 20:31:02 GMT 1
Why do you use singles for physics calculations or vectors? As far as I know, UNITY3D uses 32-bit floating point (single) values, which can be limiting. This choice may have backfired when it comes to precision. If you perform calculations beyond a distance of 1000 meters from the 3D camera, or if you have complex operations, you cannot achieve a higher precision greater than 9999.999 in every calculation, including complex ones.
Not only are single values used for vectors and mesh positions, but they are also utilized in shaders and command buffers. This reliance on low precision at 32 bits has a consequence: when you perform actions in 3D or 2D spaces that exceed 1000.0 or involve physics and movements using low-precision 32-bit single values, the entire scene can appear jerky and jittery.
If there are other valid reasons for using singles, then it's acceptable.
|
|
|
Post by (X) on Jun 4, 2023 23:11:31 GMT 1
If I perform the same calculations in the main code area as in a library code area using Double precision variables, the results sometimes differ.
I think the main code area produces more accurate results and it is the library code that is in error.
I tried all kinds of variations to isolate the problem. I still don't know why this happens. Thought I read something that hinted other languages may have a similar problem, but, don't quote me on that.
My temporary solution was to stop using Double precision variables in libs until I could find a better solution.
|
|
|
Post by rogercabo on Jun 4, 2023 23:56:32 GMT 1
Move the circles with the mouse. Here is a demo where you can check the line intersection stuff. SweptCircleLine2.G32 (7.69 KB) SweptCircleLine3.G32 (12.99 KB) // better but with some glitches. I have implemented the functionality to that player ignore the line if he jumps up.
The solution was so near and sometimes you don't see it! I use an additional line to test.. but the last error is on the left side of the line. AnotherAttemptCircleLine01.G32 (4.58 KB)
|
|
|
Post by scalion on Jun 6, 2023 12:31:05 GMT 1
Move the circles with the mouse. Here is a demo where you can check the line intersection stuff. View Attachment View Attachment // better but with some glitches. I have implemented the functionality to that player ignore the line if he jumps up. The solution was so near and sometimes you don't see it! I use an additional line to test.. but the last error is on the left side of the line. View AttachmentJe ne sais pas si j'ai bien compris ton problème, il semble que tu veuilles sur une distance donnée, intercepter la colision d'un cercle avec une ligne. J'ai essayé tes programmes et j'obtiens des cas où la collision n'est pas détectée (voir images)/
Je vais me pencher la dessus.
En tous cas bravo pour cette approche du problème de collision, je la trouve plutôt astucieuse, c'est d'ailleurs pour ça que ça m'intéresse.
Well i start with this idea; we must considere the wall to collide as an extended thickness equal to the Player.colliderSize, each extremity as a circle with a radius of the same size. We have to interesect the segment direction with 2 segment of extended wall segment and the 2 circles.
Next step is to select the nearest intersection point from the player (using U value for example) to get the collision position.
|
|
|
Post by scalion on Jun 6, 2023 13:40:37 GMT 1
Well done,i modified your source code, i think it's correct. Note i use the recalculated normal of the line (lx,ly) but you can adapt it with the your own normal values. Try it : SweptCircleLineScalion.G32 (16.72 KB)
Be careful to keep your player's position outside the collision zones (if he is inside your program may bug). 3 solutions, either you detect if it is inside the front collision zone and you exclude the wall from your test, or you detect before moving if it is inside so as not to place it there, or you remove a small percentage of the move so that it is always far away. This is another problem but it seems to me much more complex than your first one.
|
|
|
Post by rogercabo on Jun 7, 2023 21:16:41 GMT 1
New version. I have optimizes as much I can. The edges can now defines with an extra length. extraL and it seem to run well i hope!+ I new idea is to use the angle between the collider-line and playerx,y and set the extraL for a proper edge turn.
|
|
|
Post by scalion on Jun 7, 2023 21:44:02 GMT 1
New version. I have optimizes as much I can. The edges can now defines with an extra length. extraL and it seem to run well i hope!+ I new idea is to use the angle between the collider-line and playerx,y and set the extraL for a proper edge turn. I wait for the next step !
|
|
|
Post by rogercabo on Jun 7, 2023 23:16:38 GMT 1
10000 collisions took about ~1.2ms on my system.. $StepOff Dim t# = Timer, i% For i% = 0 To 1000 r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) r = LineIntersectionWithOffset(p1, p2, pl, 20) Next i% t# = Timer - t# Print AT(2, 10); " Timer : " & t#
I hope this is correct. 
|
|
|
Post by rogercabo on Jun 8, 2023 15:43:34 GMT 1
Here is another optimization I came across. Please look this image. Can you imagine what does that mean? 
I will explain. We create a virtual triangle using three points: player.x, player.y, and the offset points p1 and p2. With just 3-4 lines of code, we can determine if the point player.dirx, player.diry is inside the triangle. This approach helps us avoid unnecessary calculations. If dirx, diry is not inside the triangle, we don't need to perform any further calculations. This is important because in our game structure, we have to iterate and compare each point. You might suggest using a quad-tree, but GB32 doesn't natively support quad-trees. Instead, we dynamically create quads and nodes in structures recursively. To reduce the number of calculations for each game structure against the player, we can use a simple rectangle-intersection algorithm that was previously calculated before the game starts. Let's say our game world has a height of 100000 and a width of 100000, with a million game objects. It's practically impossible to manually create this many pieces. Instead, we chunk them into manageable portions: 1000000 objects / (100000 * 100000) / ((screen.x * screen.y) * 9). For example, on a 4K screen, we distribute around 3200 game objects to each of the 306 chunks. Then, we process 9 chunks simultaneously, resulting in 3200 * 9 = ~30000 objects. This will require approximately 3 milliseconds of CPU processing time, without optimization! Considering that we aim to display 60 frames per second and have only 16 milliseconds until the next frame needs to be drawn, this is a significant amount of processing time. ------------ Je vais expliquer. Nous créons un triangle virtuel en utilisant trois points : player.x, player.y et les points de décalage p1 et p2. Avec seulement 3 à 4 lignes de code, nous pouvons déterminer si le point player.dirx, player.diry se trouve à l'intérieur du triangle. Cette approche nous permet d'éviter des calculs inutiles. Si dirx, diry n'est pas à l'intérieur du triangle, nous n'avons pas besoin d'effectuer d'autres calculs. C'est important car dans notre structure de jeu, nous devons itérer et comparer chaque point. Vous pourriez suggérer d'utiliser un quad-tree, mais GB32 ne prend pas en charge les quad-trees par défaut. À la place, nous créons dynamiquement des quads et des nœuds dans des structures de manière récursive. Pour réduire le nombre de calculs pour chaque structure de jeu par rapport au joueur, nous pouvons utiliser un algorithme simple d'intersection de rectangles précalculé avant le démarrage du jeu. Supposons que notre monde de jeu ait une hauteur de 100000 et une largeur de 100000, avec un million d'objets de jeu. Il est pratiquement impossible de créer manuellement autant d'éléments. Au lieu de cela, nous les divisons en portions gérables : 1000000 objets / (100000 * 100000) / ((screen.x * screen.y) * 9). Par exemple, sur un écran 4K, nous répartissons environ 3200 objets de jeu dans chacun des 306 morceaux. Ensuite, nous traitons 9 morceaux simultanément, ce qui donne 3200 * 9 = ~30000 objets. Cela nécessitera environ 3 millisecondes de temps de traitement du processeur, sans optimisation ! Sachant que nous visons à afficher 60 images par seconde et que nous disposons de seulement 16 millisecondes jusqu'à ce que la prochaine image doive être dessinée, c'est une quantité importante de temps de traitement. ------------ A small test "check point in triangle" it's now about 3 times times faster than before. PointInTriangle.G32 (2.08 KB)
|
|
|
Post by (X) on Jun 9, 2023 12:04:47 GMT 1
If b1, b2, b3 are Integers storing a boolean result of (<some number> > 0), wouldn't this: Return (b1 && b2 && b3) be faster than: Return (b1 == b2) && (b2 == b3) since as Sjouke said, if the first result is false then any further comparisons are rejected?
Or, as ChatGPT Bing put it:
Another suggestion, to avoid up to 2 calculations...
Function PointInTriangle(ByRef p1 As POINTD, ByRef tri() As POINTD) As Boolean Naked Dim b1% = ((p1.x - tri(0).x) * (tri(1).y - tri(0).y) - (p1.y - tri(0).y) * (tri(1).x - tri(0).x)) <= 0 If b1 Return False Dim b2% = ((p1.x - tri(1).x) * (tri(2).y - tri(1).y) - (p1.y - tri(1).y) * (tri(2).x - tri(1).x)) <= 0 If b2 Return False Dim b3% = ((p1.x - tri(2).x) * (tri(0).y - tri(2).y) - (p1.y - tri(2).y) * (tri(0).x - tri(2).x)) <= 0 If b3 Return False
Return True EndFunc
Even faster:
Function PointInTriangle(ByRef p1 As POINTD, ByRef tri() As POINTD) As Boolean Naked Return (((p1.x - tri(0).x) * (tri(1).y - tri(0).y) - (p1.y - tri(0).y) * (tri(1).x - tri(0).x)) > 0) && _ (((p1.x - tri(1).x) * (tri(2).y - tri(1).y) - (p1.y - tri(1).y) * (tri(2).x - tri(1).x)) > 0) && _ (((p1.x - tri(2).x) * (tri(0).y - tri(2).y) - (p1.y - tri(2).y) * (tri(0).x - tri(2).x)) > 0) EndFunc
|
|
|
Post by rogercabo on Jun 9, 2023 16:11:35 GMT 1
yes great.. if you are able something to improve, I'm happy to add!
┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌█████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌███████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌███┌┌┌██┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌██┌┌┌┌██┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌███┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌███┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌██┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌███┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌██┌┌┌┌┌┌████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌┌┌██┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌███┌███┌┌┌┌┌┌┌┌┌┌██┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌████████████┌┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌ ┌┌████████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌ ┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌█████████┌┌ ███┌┌┌┌█████████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌█████┌ ██┌┌┌███████┌████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌███┌ ██┌┌┌┌███┌┌┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ███┌┌┌┌┌┌┌┌┌┌┌█████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌███┌┌┌┌┌┌┌████████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌┌████████████┌┌┌████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌███┌██████┌┌┌┌┌┌┌████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌███┌┌┌┌┌┌┌┌┌┌┌██████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌┌████┌████┌██████████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌██┌ ┌┌┌████████████┌┌┌┌┌███┌┌┌┌┌┌┌┌┌┌┌┌┌███┌ ┌┌┌┌██┌┌┌┌┌┌┌┌┌┌┌███████┌┌┌┌┌┌┌███████┌┌ ┌┌┌┌████┌┌┌┌┌┌████████┌┌┌┌┌┌┌┌████████┌┌ ┌┌┌┌┌████████████┌┌┌███┌┌┌┌┌███┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌███┌█┌█┌┌┌┌┌┌███┌┌┌███┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌███┌┌┌┌┌┌█████┌┌█████┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌██████████████████┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌██████████████┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌ ┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌┌
|
|
|
Post by rogercabo on Jun 9, 2023 23:15:22 GMT 1
Now its possible to create konvex polygons at first. The player circle is not smooth on edge until now but I'm investigating.. New collider Line 10.07.2023.G32 (17.42 KB) The new Type GameStrucPolyStatic will contain a field to hold the edge corner value ".extraL" that defines the smoothness between each polygon point. The smoothness will be calculated automatically for each point and stored into .extraL The goal are convex and concave polygons in any form. (on work) + GameStrucStatic will hold any axis aligned box, circle, and lines. With these elements you can create a Platformer, Jump & Run, a Flipper Bally game, Billiard or adventure. (Bounce back, friction and damping values for each game object.) (mostly done) + GameStrucDynamic hold all moving objects that collides with a player, or moving platforms as well, doors, enemies, fireballs, debris.. + The FPS frame work generates steady fixed frame rates on your needs for any FPS the user system can reproduce. It use the 1ms to keep track of the FPS and DeltaTime functionality. en.wikipedia.org/wiki/Delta_timing (Done). + The Player frame work contains the movements and easy player controller. (mostly done)
|
|
|
Post by scalion on Jun 12, 2023 21:25:42 GMT 1
US Tranlated By Google : The ideal would be to define a triangulation of the view areas (on the same principle as the Doom game engine), in order to perform raycasting, in this principle the element for which a collision test is carried out with the walls is in a triangle that contains the list of "visible" walls from this triangle. When it comes out of the triangle the side of the triangle that is crossed contains the index of the adjacent triangle, etc... Super efficient, but not easy to implement.
In the meantime I also did some crash tests.
FR : L'idéal serait de définir une triangulation des zones de vues (sur le même principe que le moteur du jeu Doom), afin d'effectuer un raycasting, dans ce principe l'élément pour lequel on effectue un test de collision avec les murs est dans un triangle qui contient la liste des mur "visibles" depuis ce triangle. Quand il sort du triangle le coté du triangle qui est traversé contient l'index du triangle adjacent, etc... Super efficace, mais pas simple à implémenter.
En attendant j'ai moi aussi fait quelques tests de collision. Ces 2 fonctions t'intéresseront peut-être : Function CollisionFound(ByRef Shifting As DblLine_Struct, ByRef Wall As DblLine_Struct, Radius, ByRef Collision As Collision_Struct) As Boolean Function InsideWall(x1, y1, x2, y2, Radius, xTest, yTest) As Boolean
|
|
|
Post by (X) on Jun 12, 2023 22:58:24 GMT 1
Mesmerisant! Fabuleux! 
|
|
|
Post by rogercabo on Jun 13, 2023 15:26:38 GMT 1
In the swept algorithm, the objective is to identify or "sweep" a region along the object's trajectory to detect collisions with other objects, once the incremental movement becomes larger than the object's width/depth/length.
However, when I rapidly move the points lines on the demo, the balls pass through the moving line. I'm not sure if I may have overlooked something or need to adjust settings to achieve this blocky "swept" effect, that does not let pass the balls through any line at any speed.
May I overseeing something? Anyway.. amazing work!
----------
Dans l'algorithme swept, l'objectif est d'identifier ou de "balayer" une région le long de la trajectoire de l'objet pour détecter les collisions avec d'autres objets, une fois que le déplacement incrémentiel devient plus grand que la largeur/profondeur/longueur de l'objet.
Cependant, lorsque je déplace rapidement les points sur la démonstration, les balles passent à travers la ligne en mouvement. Je ne suis pas sûr si j'ai peut-être omis quelque chose ou si je dois ajuster les paramètres pour obtenir cet effet de "balayage" bloquant, qui empêche les balles de traverser n'importe quelle ligne à n'importe quelle vitesse.
Est-ce que je néglige quelque chose ?
De toute façon... excellent travail !
|
|
|
Post by rogercabo on Jun 13, 2023 20:14:31 GMT 1
Another version of the version. But I'm not happy with the edges where the collider should turn. I like to save the angle in every node/point. Then calculate the turn based of the player position, and player angle to the current line. But this doesn't work for me, because I have no idea to calculate this correctly.. and GPT does not as well. A triangle is extremely bad in this case, a circle with approx 31 nodes works perfect. Unfortunately I have no idea to solve this. I tried to use Scalions idea as well, but i don't know how to implement. This is a bit confusing to me. New collider Line 04.G32 (18.23 KB)
|
|
|
Post by scalion on Jun 13, 2023 21:36:39 GMT 1
Another version of the version. But I'm not happy with the edges where the collider should turn. I like to save the angle in every node/point. Then calculate the turn based of the player position, and player angle to the current line. But this doesn't work for me, because I have no idea to calculate this correctly.. and GPT does not as well. A triangle is extremely bad in this case, a circle with approx 31 nodes works perfect. Unfortunately I have no idea to solve this. I tried to use Scalions idea as well, but i don't know how to implement. This is a bit confusing to me. View AttachmentView AttachmentEn fait les balles ne traversent pas la ligne en mouvement, c'est la ligne qui passe au dessus de la balle. Si la balle suit une trajectoire ne détectant aucun obstacle elle avance, et si la ligne s'est déplacée entre temps elle peut se retrouver derrière, voir dessus ce qui bloque la balle qui se retrouve à l'intérieur du périmètre de collision entourant la ligne. Ceci n'est pas un bug, la ligne est déplaçable pour les besoins du test, mais elle est sensée être un obstacle fixe.
De plus il reste a écrire une véritable fonction d'itération, je m'explique : Logiquement, après collision, on doit retester les collisions avec le reste à parcourir jusqu'à ce qu'il n'y ai plus de collision du tout. On peut limiter à une dizaine d'itération par exemple, et placer l'objet sur la dernière collision (dans ce cas il faudrait enregistrer une exclusion de test pour éviter une erreur de collision avec l'obstacle touché). On peut pourquoi pas diviser le reste à parcourir ce qui serait relativement réaliste. Dans mon test je me suis contenté de remettre l'objet à sa place initiale et de diminuer sa vitesse.
Voici comment fonctionne l'algorithme de collision :
Le but est d'obtenir les coordonnées de la collision la plus proche avec le rayon incident. Le Type Collision_Struct a été défini pour contenir ces informations en retour des fonctions de collision.
L'objet se déplaçant (le joueur par exemple) est un cercle de rayon R. La coordonnée de l'objet ainsi que son point d'arrivée sont dans la variable Deplacement (Shifting). Le type de cette variable est DblLine_Struct
Ainsi (Deplacement. x1,Deplacement. y1) est la position de l'objet Et (Deplacement. x2,Deplacement. y2) est son point d'arrivée escompté. Les obstacles sont des murs avec des coordonnées x1,y1 , x2,y2 (Type DblLine_Struct). La variable GOW n'est qu'un groupe de murs (G.roup O.f W.all) pour représenter un polygone. Elle ne sert que pour les tests avec plusieurs murs.Les fonction avec le mot clef GOW permettent de la manipuler.
On sait que l'objet est circulaire, donc si il touche un mur on sait qu'il est exactement à une distance égale à son rayon R. Si la distance de l'objet au mur est inférieure à son rayon R, alors l'objet est en train de traverser le mur. La fonction InsideWall() a été écrite pour éviter ce problème. Reste à l'utiliser à bon escient.
Pour détecter la collision entre notre objet et un mur il faut donc calculer l'intersection du vecteur Déplacement avec les lignes parallèles situées de part et d'autre du mur à la distance R = Rayon de l'objet. Il faut aussi calculer L'intersection du vecteur Déplacement avec 2 cercles de rayon R situés aux extrémités du mur. Il ne reste qu'a prendre l'intersection la plus proche et utiliser la normale associée pour calculer la direction incidente.
C'est ce que fait la fonction CollisionFound()
Important : La longueur de cette direction incidente est le reste à parcourir du déplacement.
S'il y a plusieurs murs il faudra retenir la collision la plus proche. Dans la procedure Projectile : If C1.U < C2.U
Les fonctions de collisions renvoie TRUE en cas de collision. La variable Collision passée en Byref contient alors:
- Le point de collision xClash,yClash- La normale au point de collision NormalX,NormalY- Le rayon incident IncidentX,IncidentY- La position unitaire U. (c'est la distance de l'objet à la collision divisée par la distance de déplacement) U permet de comparer les multiples collisions pour ne retenir que la plus proche (de zéro) EDIT : New collider Line 04 - Scalion.G32 (24.97 KB)
|
|
|
Post by rogercabo on Jun 14, 2023 23:56:57 GMT 1
Thanks a lot.. perfect! I didn't know anything about that you posted the result, because I was late today. Today I tried the whole day to use chatGPT by your text description to get a better result. But no way! At first the code from GPT was very promising and it looks very efficient. But when I tried.. for sure it does not! But no Idea what it does.. but the incidentXY values fits! But the player snaps nice to the points! ClashIntersectionWithCircleTrybyChatGPT.G32 (9.97 KB)
Did you use ChatGPT as well for some solutions? I think if you know exactly to came to the solution, then chatGPU can help because you can redirect him.
But anyway.. you have a real nice acknowledge about this math and trigonometry!
--- Merci beaucoup.. parfait ! Je ne savais pas que vous aviez publié le résultat, car j'étais en retard aujourd'hui. Aujourd'hui, j'ai passé toute la journée à essayer d'utiliser ChatGPT en suivant votre description textuelle pour obtenir un meilleur résultat. Mais sans succès ! Au début, le code généré par GPT semblait très prometteur et semblait très efficace. Mais lorsque j'ai essayé.. ça ne fonctionne pas du tout ! Mais je n'ai aucune idée de ce que cela fait.. mais les valeurs incidentXY correspondent ! Mais le joueur se verrouille bien sur les points !  ClashIntersectionWithCircleTrybyChatGPT.G32 (9.97 Ko) Avez-vous également utilisé ChatGPT pour certaines solutions ? Je pense que si vous connaissez précisément la solution, ChatGPT peut aider car vous pouvez le diriger. Quoi qu'il en soit.. vous avez une très bonne compréhension des mathématiques et de la trigonométrie !
|
|
|
Post by scalion on Jun 17, 2023 21:21:14 GMT 1
This thread, this story made me want to make a little maze game.
|
|
|
Post by rogercabo on Jun 19, 2023 15:43:27 GMT 1
Maze And Collision reminds me a bit of Pacman-Pong Edit:uResult = _maxDbl cause a floating point error because if you start to do any arrhythmic and don't change uResult. In this case I'm save, when is comes to any calculation on uResult Const _maxEps As Double = 9007199254740992.0
|
|
|
Post by (X) on Jun 21, 2023 19:48:59 GMT 1
This thread, this story made me want to make a little maze game.
Éblouissant! Je vais tenter de décortiquer tout ça et possiblement l'adapter pour qu'un novice puisse l'adapter en quelques minutes. Plus tôt dit que fait.
“Dazzling! I will try to dissect all this and possibly adapt it so that a novice can adapt it in a few minutes.” Easier said than done.
|
|
|
Post by rogercabo on Jun 21, 2023 21:27:04 GMT 1
New collider Line 04 - Scalion.G32 (24.97 KB) Hi Scalion, CreateRegularPolygon(plg32(0), 400, 400, 3, 200, 0) I need some little help with the New collider Line 04 - Scalion.G32 (24.97 KB)How do you run through the points in the CollisionGOWFound() ? J'ai besoin d'un peu d'aide avec le nouveau collider Ligne 04 - Scalion.G32 (24,97 Ko) Comment parcourez-vous les points dans CollisionGOWFound() ? A) -------- Unfortunately the layer stuck in the wall. During a shot or teleport, then hes will placed inside.. Malheureusement, la couche est coincée dans le mur. Pendant un tir ou une téléportation, il sera alors placé à l'intérieur. Ceci est désagréable si le joueur se trouve sur un bord, alors que le bord est plus petit que le rayon du collider.  B) ---------------------- What does First Circle Test? Not sure.. it doesn't matter if in in or not.  Que signifie le First Circle Test ? Je ne suis pas sûr... peu importe s'il est dedans ou pas.  ' Test First circle Dim temp1 As Double = Shifting.x1 - xStart Dim temp2 As Double = Shifting.y1 - yStart b = 2 * ( xs * temp1 + ys * temp2 ) c = xStart * xStart + yStart * yStart + xx + yy - 2 * (xStart * Shifting.x1 + yStart * Shifting.y1 ) - rr v = b * b - 4 * a * c
If v >= 0 v = Sqr(v) uTest = (-b - v) / a2 If uTest < 0 || uTest > 1 uTest = (-b + v) / a2 If uTest >= 0 && uTest <= 1 Collision.xClash = Shifting.x1 + uTest * xs Collision.yClash = Shifting.y1 + uTest * ys Collision.NormalX = (Collision.xClash - xStart) / Radius Collision.NormalY = (Collision.yClash - yStart) / Radius Color RGB(255, 0, 0) PCircle Collision.xClash, Collision.yClash, pl.colliderSize u = uTest EndIf
|
|
|
Post by rogercabo on Aug 31, 2023 22:12:45 GMT 1
This thread, this story made me want to make a little maze game.
Bonjour Scalion, malheureusement, il y a une erreur dans le calcul des collisions. Et malheureusement, je ne comprends pas pourquoi. Le polygone a 8 lignes. Dans cet exemple, la ligne du joueur traverse la ligne du polygone et tourne la ligne opposée de l'extérieur vers l'intérieur. J'ai simplifié le programme pour que l'erreur apparaisse immédiatement au démarrage. Ne pourrait-on pas, dans une première étape, tester toutes les lignes pour l'extérieur et l'intérieur, et seulement tester celles où le joueur touche la ligne de l'extérieur? Je pense que cela serait aussi plus rapide, non? Merci pour ton aide. Voir l'image: 
|
|
|
Post by scalion on Sept 2, 2023 13:05:49 GMT 1
Bonjour Roger, Il faut bien prendre en compte qu'il s'agit d'un algorithme de collision ligne/ligne et non ligne/polygone. Comme je l'ai dit plus haut il est nécessaire de checker la position du joueur AVANT de tester une collision. Si le joueur est trop près d'une ligne (à l'intérieur de la zone de collision) le test de collision est erroné. Dans un programme qui utilise ce genre d'algorithme (comme DOOM) la position du joueur doit être impérativement connue.
Par exemple avec ton polygone à 8 coté, tu dois "savoir" si le joueur est dans ou en dehors du polygone, ceci est possible si tu définis préalablement le sens des lignes (cw,ccw). Si le joueur passe "à traver la ligne" si le point destination est à gauche ou droite de la ligne il est donc à l'intérieur ou à l'extérieur. Je n'ai pas le temps pour l'instant de te coder un example mais je vais revenir.
|
|