Get coords of GL_QUAD for collision detection? - python

I have a GL_QUAD which is basically a big field that the player is able to walk on. However, I want the player to have the abilty to 'jump,' meaning when he returns to his original y position he must stop falling. How do I access the world coordinates of a GL_QUAD so I can compare the y values of the quad and the player to determine whether he should stop falling?

Related

Problem With Collision Detection In Turtle [Python]

Im using an if statement to detect whether the player's coordinates after moving up (y coordinate increases) are equal to an open space's coordinates.
Ex:
player_coordinate = player.pos() # We can say that the coordinate returned is (-10.00,10.00)
space_coordinate = space.pos() # And the coordinate returned is (-10.00,20.00)
movement = 10 # How far the player can move at once
if (player_coordinate[0], player_coordinate[1] + movement) == space_coordinate:
player can move
Now, I used this same method, however when the player's position has a negative y value, the statement is false.
For example:
# Works:
if (-90.0, 30.0) == (-90.00,30.00)
# Doesn't Work
if (-90.0, -10.0) == (-90.00,-10.00)
(By the way the first tuple uses the vales stated previously, player_coordinate[0], player_coordinate[1] + movement, so i have no clue why it returns with one decimal place instead of two like in the original .pos() tuple but it shouldn't matter because the problem only occurs when the y-value is negative)
It looks like it is saying that -10.0 is not equal to -10.00. Any ideas on why this might not be working?
Here is the actual code too if it helps. I use 'in' because Im storing all of the space coordinates in a dictionary:
def player_movement(player, total, direction):
current = player.pos()
if direction == 'up':
if (current[0], current[1] + total) in space_coordinates.values():
player.shape('Player_Up.gif') # Changes player sprite
player.goto(current[0], current[1] + total) # Moves player
I already checked if the coordinate I needed was in the dictionary and it was
Turtles wander a floating point plane so exact comparisons are to be avoided. Instead of asking:
turtle_1.position() == turtle_2.position()
you should consider asking:
turtle_1.distance(turtle_2) < 10
That is, are they in close proximity to each other, not on the exact same coordinate.

How can I stop enemies from overlapping pygame

I'm trying to find a way to have enemies track the player in my 2d game (pygame) but not clump up
Currently, when I shoot at them, the bullet collides into and damages all of the enemies that are clumped. I would like it to be a hoard but spread out just enough to where I can't hit every single enemy at once
It looks like this
Here's a gif of them clumping
I'm not sure how I would get the individual values of the enemies' positions so I can move them when they collide or how I should move them
This is what I currently have for the enemies to track the player:
for aliveEnemies in enemy:
if playerObj.rect.x - aliveEnemies.rect.x != 0:
if playerObj.rect.x > aliveEnemies.rect.x:
aliveEnemies.rect.x += 1
if playerObj.rect.x < aliveEnemies.rect.x:
aliveEnemies.rect.x -= 1
if playerObj.rect.y - aliveEnemies.rect.y != 0:
if playerObj.rect.y > aliveEnemies.rect.y:
aliveEnemies.rect.y += 1
if playerObj.rect.y < aliveEnemies.rect.y:
aliveEnemies.rect.y -= 1"
Any help or points in the right direction would be greatly appreciated
You can do collision detection between the enemies, to determine which ones are too close. You'll also need to change their behavior, to decide what to do when they actually get too close.
If you know you'll never get too many enemies, you can try comparing every enemy with every other enemy. This will take O(N^2) work, but that is probably OK if N is limited.
If you are comparing every enemy to every other anyway, you have a wider variety of options than just "collision detection": like the Boids algorithm (which does collision avoidance instead).
Pygame rect objects have a function called "colliderect" which tests whether two rect objects are overlapping: https://www.pygame.org/docs/ref/rect.html#pygame.Rect.colliderect
You can use this to test each enemy whether they're overlapping any other enemy before moving them.

How to handle index out of range

Im building an A star algorithm and i want to store the 8 possible directions to move to in a dictionary like so: ["NW: a location north west, which i call from a 2D list which stores all units on my map]
For the North west example, i would call the unit like so:
["NW": map[p.x -1][p.y-1]]
which stores the top left (or NW) unit (p is the starting location unit, from which i call its x and y coordinate. map is what I'm using to illustrate my 2D list which holds all the units on my grid).
I have to do a similar thing for all 8 directions around a starting unit.
The issue is that the starting unit could at any point be on the edge of the map, so if i try to go NW,W, or SW when the start node is at the left border of my map, ill obviously get an index out of bounds error of some sort.
how can i efficiently test for all the 8 cases at once? i don't want to add them all to my dictionary individually and surround them each with their own try statement. In essence i want to add this piece of code into my program:
dic = ["NW": map[p.x -1][p.y-1], "N": map[p.x][p.y-1], "NE" map[p.x
+1][p.y-1], ...]
and so on, for all 8 directions.

generate mouse velocity when only integer steps are allowed

I write a simple program in python which includes moving my mouse (I do his with PyUserInput).
However: It is only allowed to move the mouse in integer steps (say pixels).
So mouse.move(250.3,300.2) won't work.
I call the move function about 30 times in a second and move the mouse a few pixels. The speed with which I move the mouse varies from 0.5-2.5px/call. Rounding gives me 1-3 (move only want ints) which does not really represent the speed.
I search for a solution (maybe generator?) which takes my current speed (e.g. 0.7px) and gives me back a pattern (like a PWM Signal) out of 0 and 1 (e.g. 1,1,0,1,1,0...) which yields the 0.7px in average.
However this generator has to be adaptive because speed is constantly changing.
I am quite new to python and stuck with the last point: The variability of the generator function.
Here is what I have so far:
# for 0.75px/call
def getPWM(n):
nums = [1,0,1,1]
yield nums[n%4]
What you need to do is keep track of the previous position and the desired current position, and hand out the rounded coordinate. You could track the previous position in a function but it's much easier to do it in a class.
class pwm:
def __init__(self):
self.desired_position = 0.0
self.actual_position = 0
def nextPWM(self, speed):
self.desired_position += speed
movement = round(self.desired_position - self.actual_position)
self.actual_position += movement
return movement

Pygame Random Terrain Spawning

I'm trying to create a game in which 100 rocks are scattered through a large series of coordinates randomly. The problem is that sometimes the rocks may overlap each other. The solution I came up with was to check if the rocks overlap each other, and if they do, create new randomly generate coordinates for the rock again and again until it collides with nothing. I'm not entirely sure how to do this; I've tried detecting collision between the rock and the rock list, but all that ends up happening is that it thinks that it collides with itself and always returns as True. The __init__ function generates the coordinates with random.randint(-2500,2500). When the rocks are created in the for loop, each rock is added to the list. In the update function it checks for rectangular collision between the rocks. How can I fix this? Thanks, an answer would be much appreciated. Ask me if you need more information.
Well, I guess there are a few ways you can approach this problem:
1) The first would be the one you already used, you would check for collisions each time you generate a rock and if a collision exist you would regenerate a position for the given rock
2) The second one would be to slice your "field" into rectangles of the size of the rock, just like a tilemap, therefore creating a list of possible positions, something like this:
possible_positions = [(i, j) for i in range(x_size_field//x_size_rock) for j in range(y_size_field//y_size_rock)]
for i in range(n_of_rocks):
rock_pos = random.choice(possible_positions)
possible_positions.remove(rock_pos)
But this approach would implicate in a given set of possible positions that make a "uniform" rock distribution
3) So if its really necessary to make put the rocks on absolute random positions you could create a list of possible positions like the following:
possible_positions = [[(i, j) for j in range(y_size_field-y_size_rock)] for i in range(x_size_field-x_size_rock)]
for i in range(n_of_rocks):
# X and Y represente positions on the list not on the field
x = random.randint(0, len(possible_positions))
y = random.randint(0, len(possible_positions[x]))
# The rock positions
rock_pos = possible_positions[x][y]
# Now we remove the positions on the region of the new rock
for i in range(x,x+x_size_rock):
possible_positions[i] = possible_positions[i][0:y] + possible_positions[i][y+y_size_rock:-1]
if [] in possible_positions:
possible_positions.remove([])
Of course this code may generate errors (its a rather simple code) and it needs some optimizations, but i think you may get the general ideia from this.
Sorry about my english

Categories

Resources