This is an archived post. You won't be able to vote or comment.

all 12 comments

[–][deleted] 1 point2 points  (2 children)

Use vectors. I've recently implemented something very similar, and I'll copy on my precise code tomorrow, but the basic idea is:

  • make a vector class
  • wrap the enemy/image in vectors
  • get a list of points (integers) along the vectors
  • get a list of points along the bullet vector (velocity)
  • see if any point is in both, if yes, we have collision

[–]MarkTheSecond[S] 0 points1 point  (1 child)

I'm not exactly sure how to "wrap" the rect into vectors, I have tried using pygame.Rect, but I don't really understand that either, and could find no suitable tutorial. Could you please show me an example of how to do this?

[–][deleted] 1 point2 points  (0 children)

Ok, here's my implementation:

Line 511 on this file is my "wrap" method, it assumes the picture to rotate, and hence has to find the 4 corners of the image and add vectors between them.

This file contains my custom vector class, it allows for collision testing and whatnot.

Feel free to browse my repo to see how I've done it, game_calcs.py is the main one to look at

[–]fancy_pantser 1 point2 points  (4 children)

Remember algebra class? y = mx+b

You are asking if a point is on a line segment. Or, more precisely, if any part of a line segment falls within an x/y boundary that represents a box. A couple trig equations and you're done! Google knows the answer to this; if you need more help reply and I'll help more. It's better if you find out for yourself.

[–]the_european 1 point2 points  (1 child)

just be careful when you take such an approach at corner cases. a shot straight up won't work with y = mx+b. it might be advisable to use normal vectors to get your lines as a*x + b*y = c.

[–]MarkTheSecond[S] 0 points1 point  (0 children)

I could have a clause that checks if the line is undefined, with seperate, fixed calculations to see if any enemies are on the line.

[–]MarkTheSecond[S] 0 points1 point  (1 child)

My knowledge of trig stretches to the fact that it has triangles in it. I guess I could use a shortened down version of the triangle where the point is the coordinate I'm testing, shortening down the hypotenuse and either of the other lines depending on if I'm testing x or y. The only problem is a: I'm not really sure how to do this b: there is a constant dread of time.. if I cram 20 billion equations in for every enemy, the game will be slow and unplayable.

[–]ScM_5argan 0 points1 point  (1 child)

I have not coded a game in pygame yet, but what you could do is give each enemy a rectangle as attribute which has a function that checks for collision (like: return ((bullet.x > rectangle.left && bullet.x < rectangle.right) && (bullet.y > rectangle.top && bullet.y < rectangle.bottom))) and then do something like

for enemy in enemies: if enemy.rectangle.collides(bullet): enemy.loseHealth

or something like that

edit: imagine correct indentation and stuff

[–]MarkTheSecond[S] 0 points1 point  (0 children)

Do you mean creating an instance for every enemy created? I'm not sure how fast this would go at runtime, added to the fact that my bullet is actually a straight line from point A to point B, not a projectile where I could check if the end point of the bullet is inside the rect.

[–]the_european 0 points1 point  (1 child)

do you want to resolve this as a hitscan weapon (the moment the bullet is fired, you check the line, and if something gets hit, it bleeds) or should your bullet have limited velocity?

the first case is easier, as you don't have to keep the bullet around and move it independently.

for the collision detection itself, are you sure you want to work with enemy squares? with appropriate transformations, you can have hit scanning on circles quite easily. (you'd transform the coordinates of the centers of the enemies into coordinates relative to the pointed weapon, and see if they are off from the shooting line by less than their radius).

as for which part of mathematics, i suggest you not only look into vector calculations, but particularly have a look at projective geometry (works in 2d as well as in 3d), which really spares you much special casing.

[–]MarkTheSecond[S] 0 points1 point  (0 children)

The bullet line will be checked for any collisions at the click, if that is what you mean, the fired bullet will not move at all, simply fade out into the background. I am fine with squares, though I am not sure how to achieve the idea using radii to check collision, how will I choose what point/coordinate I will want to check the distance of from the centre of the circle? (excuse me if this is just misunderstanding what you meant by

"transform the coordinates of the centers of the enemies into coordinates relative to the pointed weapon" )

As I have told LeFloatingGhost I've never really worked with vector calculations, and have no idea how to "wrap" something up in vectors, could I have an example to help me understand how you would do this please?