Tuesday, April 4, 2017

trajectory - How to implement the missile trajectories in the classic missile command game - pygame


I am doing a clone of the classic arcade game missile command, i am curious about how to implement the trajectories of the missiles. I have a solution that looks pretty similar to the original game, but it have some problems that i don't know how to avoid.


Here is the relevant code i have right know:


missiles_attack = []

class Missile(object):

def __init__(self, pos_src, pos_dst, color, speed):


# direction of the missile
direction = (pos_dst - pos_src).normalize()

# total distance that missile must travel to reach his target
self.__distance = pos_dst.distance_to(pos_src)

# the current distance traveled
self.__distance_traveled = 0


# how many the head should move each frame
self.__step = speed * direction

# the length of a step
self.__step_length = self.__step.length()

self.pos_head = Vector2(pos_src)
self.points = [(self.pos_head.x, self.pos_head.y)]

self.color = color


def update(self):
self.__distance_traveled += self.__step_length
if self.__distance_traveled < self.__distance:
self.pos_head += self.__step
self.points.append((self.pos_head.x, self.pos_head.y))
else:
self.destroy()

def destroy(self):

missiles_attack.remove(self)

def draw_missiles():
for missile in missiles_attack:
pygame.draw.lines(screen, missile.color, False, missile.points, 2)

def update_missiles():
for missile in missiles_attack:
missile.update()


So when i want to create a missile, i pass the src and dst position of the missile and then add it to the list of attack missiles, both the draw_missiles and update_missiles functions are called for each frame inside the game loop.


The idea behind the trajectory is to work out a new point in the line defined by the src and dst position each frame, i have three problems with this approach:


problem 1


I don't know how to draw the missile heads, in the video you can see that the heads are like a white pixel, i tried to take the last two points of the missile.points list and draw a new line with those points to represent the head, the problem is that the line length changes when the speed of the missile changes so it not works.


problem 2


Seems silly to store all the points of the trajectory in a list, seems like is too much waste of memory, i can't think in another more efficient solution with the same 'graphical results'.


problem 3


Another thing i tried is instead of use the pygame.draw.lines function use the pygame.draw.line one, the draw_missiles function will be something like this:


def draw_missiles():
for missile in missiles_attack:

pygame.draw.line(
screen,
missile.color,
(missile.pos_src.x, missile.pos_src.y),
(missile.pos_head.x, missile.pos_head.y),
2
)

Well, now i don't have to store all the points, which is a good thing i think, the problem is that when the line is draw, the results are different than the 'points approach', seems like the line algorithm that pygame uses under the hood not draws the same pixels for a line going from the point A to the point B, that for a line going from the point A to the point C, where C is a point in the line between A and B.


So how i can deal with this problems, what is the most reasonable approach to implement this kind of behavior?





No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...