Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Vectors Newb


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 26 February 2014 - 02:58 PM

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!

 

 



Sponsor:

#2 Álvaro   Crossbones+   -  Reputation: 13934

Like
6Likes
Like

Posted 26 February 2014 - 03:18 PM

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.



#3 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 26 February 2014 - 04:41 PM

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.



#4 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 26 February 2014 - 05:54 PM

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.


Edited by TreeSaaaaap, 26 February 2014 - 06:04 PM.


#5 Paradigm Shifter   Crossbones+   -  Reputation: 5440

Like
2Likes
Like

Posted 26 February 2014 - 06:06 PM

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

#6 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 26 February 2014 - 06:23 PM

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!



#7 Paradigm Shifter   Crossbones+   -  Reputation: 5440

Like
0Likes
Like

Posted 26 February 2014 - 06:28 PM

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...


Edited by Paradigm Shifter, 26 February 2014 - 06:28 PM.

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

#8 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 27 February 2014 - 02:54 PM

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()

Edited by TreeSaaaaap, 27 February 2014 - 02:55 PM.


#9 Álvaro   Crossbones+   -  Reputation: 13934

Like
2Likes
Like

Posted 27 February 2014 - 03:06 PM

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()


#10 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 27 February 2014 - 04:43 PM

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.


Edited by TreeSaaaaap, 27 February 2014 - 04:44 PM.


#11 Álvaro   Crossbones+   -  Reputation: 13934

Like
0Likes
Like

Posted 28 February 2014 - 09:34 AM

Perhaps you should post your code...



#12 TreeSaaaaap   Members   -  Reputation: 139

Like
0Likes
Like

Posted 01 March 2014 - 03:13 PM

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, n_steps):
        self.rect.x += (mlocX - self.rect.x) / n_steps
        self.rect.y += (mlocY - self.rect.y) / n_steps

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
n_steps = 80

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 mlocX != oPC.rect.x and mlocY != oPC.rect.y:
                oPC.update(mlocX, mlocY, n_steps)
                if n_steps > 1:
                    screen.fill(BLACK)
                    screen.blit(terrain, terrainRect)
                    n_steps -= 1
                    oPC.draw(screen)
                    pygame.display.flip()
            n_steps = 80
            
pygame.quit()
#sys.exit()

I understand the point of not wanting to have another loop running inside of there, but I'm not quite sure how to iterate it another way so it gradually moves towards the mouses target location (without having to click or roll the mouse wheel constantly).  I was thinking, would it be more efficient to control the movement by time somehow as opposed to using steps?  It works this way now, but the image makes it to different distances at the same amount of time, which isn't exactly great for character movement.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS