Vectors Newb

Started by
10 comments, last by TreeSaaaaap 10 years, 1 month ago

Hi,

I'm trying to learn Python and program an RPG (perhaps transitioning into a multiplayer RPG someday - once I have a better understanding of what I'm doing!) I've enjoyed tinkering around in C++ over the years, but I still consider myself a big time newb. I learned most of the Python syntax already however, and I'm enjoying it thus far. Also, I've picked up Pygame to help me write this game.

My question is about vectors. I'm not exactly a math genius (and some of you may say to just drop programming now), but I really want to learn...

Basically, I want to move the player object to the location of a mouse click (similar to that in Diablo, UO, etc) whatever angle it might be. Very simply, I want to move the player object from the objects current coordinates to the mouse click position coordinates. I've scratched my head for many hours already trying to figure out exactly how to do it.

I can't understand if it's the vector itself I need, or the magnitude, direction, velocity, angle etc. I just want to move (2,0) to (33,33) arriving smoothly at each x and y coordinate, etc. Perhaps, I'm doing this all the wrong way.

Anyone know of a better resource that might help me understand this a little better/easier?

Thanks!

Advertisement

If you want to arrive there in 10 steps, compute the vector that goes from (2,0) to (33,33), which is just (33-2, 33-0) = (31,33), and divide it by 10. That gives you v = (3.1, 3.3). Now add that to your player position at each step.

If that makes sense, you already understand vectors, to some degree.

You mentioned "arriving smoothly", so perhaps you are looking for a more sophisticated movement that decelerates as you get close to the target. If that's the case, you may want to look into steering behaviors. There is one called "arrive" precisely for this.

Awesome! Thanks for the clarity. I got to the point of computing it, just not factoring in the division of steps.

By arriving smoothly, I was worried that the x and y wouldn't be updated at the same time and cause a rigid movement.

Having some serious trouble, just with line 2, and I have no clue why haha...


import pygame, sys

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("char.png").convert()
        self.rect = self.image.get_rect()

    def update(self, mlocX, mlocY):
        self.rect.x += (mlocX - self.rect.x) / 10
        self.rect.y += (mlocY - self.rect.y) / 10

    def draw(self, screen)
        screen.blit(self.image, (self.rect.x, self.rect.y))
        


import pygame, sys
import oPC


pygame.init()

WINDOWSIZE = (1000, 800)
BLACK = (0, 0, 0)
              
screen = pygame.display.set_mode((WINDOWSIZE))
pygame.display.set_caption("TTB")

screen.fill(BLACK)
terrain = pygame.image.load("terrain.jpg").convert()
terrainRect = terrain.get_rect()
terrain = pygame.transform.scale(terrain, ((WINDOWSIZE)))
screen.blit(terrain, terrainRect)
pygame.display.flip()

oPC = Player()

                                 
running = True

while running == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
                running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            mlocX, mlocY = pygame.mouse.get_pos()
            screen.fill(BLACK)
            screen.blit(terrain, terrainRect)
            oPC.update(mlocX, mlocY)
            oPC.draw(screen)
            pygame.display.flip()

                
pygame.quit()
#sys.exit()


Traceback (most recent call last):
  File "C:/Users/Daniel/Downloads/PyServ/PyServ/TheGame/main.py", line 2, in <module>
    import oPC
  File "C:/Users/Daniel/Downloads/PyServ/PyServ/TheGame\oPC.py", line 15
    def draw(self, screen)
                         ^
SyntaxError: invalid syntax

I'm not sure what is going wrong... Trying to weed out the errors.

Looks like a missing colon?

def draw(self, screen):
    screen.blit(self.image, (self.rect.x, self.rect.y))
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Ahhh..yes...>.< An hour spent skipping over that.... I'm thinking it's quitting time for the day. Thanks so much for the help guys!

Bad error message, naughty error message though, always lighting the grail shaped beacon.

Surely they could come up with something like "did you miss a colon?" instead of SyntaxError: invalid syntax.

First the spanking...

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

So, I'm getting this closer to working it seems. I'm getting it to run through the while loop, and the object actually moves to the location I've clicked. However, when it reaches that point, the program freezes and I really have no clue why. At some point, the conditions should be met (at the same time) and the while loop should end. Is this crashing because x and y are not being met at the same moment? Hmm...


import pygame, sys

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("char.png").convert()
        self.rect = self.image.get_rect()

    def draw(self, screen):
        self.image = pygame.transform.scale(self.image, (75, 75))
        screen.blit(self.image, (self.rect.x, self.rect.y))
        
        
    def update(self, mlocX, mlocY):
        self.rect.x += (mlocX - self.rect.x) / 110
        self.rect.y += (mlocY - self.rect.y) / 110

import pygame, sys
import oPC


pygame.init()

WINDOWSIZE = (1000, 800)
BLACK = (0, 0, 0)
              
screen = pygame.display.set_mode((WINDOWSIZE))
pygame.display.set_caption("TTB")

screen.fill(BLACK)
terrain = pygame.image.load("terrain.jpg").convert()
terrainRect = terrain.get_rect()
terrain = pygame.transform.scale(terrain, ((WINDOWSIZE)))
screen.blit(terrain, terrainRect)

oPC = oPC.Player()
oPC.draw(screen)
pygame.display.flip()

                                 
running = True

while running == True:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
                running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            mlocX, mlocY = pygame.mouse.get_pos()
            while oPC.rect.x != mlocX and oPC.rect.y != mlocY:
                screen.fill(BLACK)
                screen.blit(terrain, terrainRect)
                oPC.update(mlocX, mlocY)
                oPC.draw(screen)
                pygame.display.flip()

                
pygame.quit()
#sys.exit()

Your loop never ends because in each step you only go 1/110th of the way to the target. Is your character's name "Zeno"? :)

You shouldn't run a special loop when the mouse is pressed. If you do (even if you get it to work), your program won't respond to "quit" events until the character makes it to its target, for instance.

The idea is that there is only one loop (the event loop), and when you detect a mouse button has been pressed you set up a plan for your character to move a particular way (for instance by setting some variables). Then each time the loop runs you execute part of the plan.

I don't know much about Python, so sorry if I write something terribly wrong:

[...]
 
    def update(self, mlocX, mlocY, n_steps):
        self.rect.x += (mlocX - self.rect.x) / n_steps
        self.rect.y += (mlocY - self.rect.y) / n_steps

running = True

while running == True:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
                running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            mlocX, mlocY = pygame.mouse.get_pos()
            n_steps = 110
 
        screen.fill(BLACK)
        screen.blit(terrain, terrainRect)
        oPC.update(mlocX, mlocY, n_steps)
        if n_steps > 1:
            n_steps -= 1
        oPC.draw(screen)
        pygame.display.flip()
 
pygame.quit()

Ok, I see what you're saying about not wanting to throw another loop in there, but I'm not sure how to iterate it another way so it moves on it's own and so that I don't need to keep clicking for each movement. Right now, it only moves a step for each mouse event.

This topic is closed to new replies.

Advertisement